GoodGames - HackTheBox
GoodGames machine(10.10.11.130)
This box was an easy box with chance of exploring vulnerabilities like password reuse in organization, Server Side Template Injection and SQL injection to pwn a gaming website.
Recon
Starting with recon, port scan shows only 1 port is open.
rustscan -a $IP -u 5000 -- -A
PORT STATE SERVICE REASON VERSION
80/tcp open ssl/http syn-ack Werkzeug/2.0.2 Python/3.9.2
|_http-favicon: Unknown favicon MD5: 61352127DC66484D3736CACCF50E7BEB
| http-methods:
|_ Supported Methods: OPTIONS HEAD GET POST
|_http-server-header: Werkzeug/2.0.2 Python/3.9.2
|_http-title: GoodGames | Community and Store
In website footer it reveals hostname GoodGames.HTB Let's add that to our /etc/hosts file.
Other enumeration like directory scan and vhost fuzzing doesn't reveal much other than that there is login panel, where we can sign-in and sign-up.
Foothold: Sql injection and SSTI
Clicking on account icon gives a login panel and option to signup.
And any wrong credential will lead to 500 server error, also email field strictly needs a email.
Let's check signup page
Here you can signup for a new account, say test:test and you can also sign-in from here and the thing is this form doesn't need a valid email in email field.
trying to signup with admin@goodgames.htb will tell that account already exists. Let's login with our test account.
although it's says we can update our profile picture and email, there is no such option here. And password reset also doesn't work. Otherwise we could have tested for resetting admin's password but it straight out give 500 error. There isn't much here around to do now. Let's move on and try to login as admin. We haven't tested SQLi yet anyway on login.
As login field takes valid email, one way is to capture one valid request and play with it in burp or you can test sqli on other panel.
And it was a sql injection and an easy one.
Also there is a new option on admin portal, setting icon , which redirect to another vhost internal-administration.goodgames.htb which has another login panel.
At this point i started searching for vulnerabilites for flask volt dashboard and wasted a few time, without realizing that we have sql injection and we haven't explored that yet. We could:
- Dump database.
- Check if we have read and write privilege to read files from system.
- can we spawn a shell from it using sqlmap by uploading a file.
Let's focus on sql injection and explore that:
- starting with sqlmap
sqlmap -u http://goodgames.htb/login --data "email=admin*&password=admin"
. Telling sqlmap to send post request and field to test i.e. email. - And sqlmap detects's injection after few moment. Let's check our privilege on system with "--privileges" flag.
sqlmap -u http://goodgames.htb/login --data "email=admin*&password=admin" --privileges
. And it detects we are running as usage permission which means we can't read or write from and to system. Let's dump the database. sqlmap -u http://goodgames.htb/login --data "email=admin*&password=admin" -D main -T user --dump
. dumping user table from main database.
+------+-----------------------+---------+----------------------------------+
| id | email | name | password |
+------+-----------------------+---------+----------------------------------+
| 1 | admin@goodgames.htb | admin | 2b22337f218b2d82dfc3b6f77e7cb8ec |
| 2 | muk****@gmail.com | blitz | 81dc9bdb52d04dc20036dbd8313ed055 |
| 3 | test@gmail.com | test | cc03e747a6afbbcbf8be7668acfebee5 |
| 4 | test@goodgames.htb | test | 098f6bcd4621d373cade4e832627b4f6 |
| 5 | test1@gmail.com | {{7*7}} | 098f6bcd4621d373cade4e832627b4f6 |
+------+-----------------------+---------+----------------------------------+
We can see all the account's created on system and their password hashes. don't put your real email address and password in ctfs. Let's try to crack admin's hash and we can do that easily by googling it or simply putting it in https://crackstation.net/ . And password is superadministrator.
Let's try to login with this password on second vhost panel. And we are amdin.
Now from setting option you can edit your name and other stuff. Let's do that and as it is a python application don't forget to test for SSTI. **{{7*7}}
indeed it's reflected as 49. Also it's running jinja2 template. Now we can get a shell from here using SSTI payloads. Now 0xdf have done a fantastic video on how these payloads actually work you can find it here. Also if you want written version of it i have explained this in htb epsillon blog.
I will be using {{ namespace.__init__.__globals__.os.popen('id').read() }}
paylaod to get shell. Basically what happens is that you access namespace class in jinja2 and in that you can access init function, in python every class has this function defined it's like constructor of that class, after that you access
globals function accessible by init and then you finally can access python modules like popen or os to run commands.
Let's get a reverse shell from here. One thing although we are entering dob and phone number to update but in request only name is getting processed. Let's look into that request.
only name field is being sent, so anyway other field are just to annoy us :) Let's modify the request and look if anything changes.
But nothing changes. Let's move on.
Privilege Escalation: Docker escape
After getting rev. shell we are already running as root.
but ofcourse we are in docker, looking at hostname and dockerfile all over the place. Also one way to confirm if you are running in dockerenv to check /proc/1/cgroup. cgroup is control groups which in combination with namespaces isolate different processes for container environments. They both are linux kernel feature. Namespace allocate resources(CPU,ram etc.) to different processes to give user a VM like feel, and cgroups control that allocation how much resource should be accessible to which process. More on it here.
So coming back to topic. If you will cat /proc/1/cgroup and you see some docker ids means you are in docker and these are control groups are being used by docker. Else these will be blank. In our case:
Let's try to escape this docker.
There is a home directory for user augustus. But /etc/passwd has no such user and you can't change user as augustus. Looks like it's mounted from the host machine. You can also run mount command to see that indeed it's mounted from host machine and read write permission.
Let's enumerate a little bit, looking for processes running and something vulnerable script etc. nothing, but one thing stand out. Running ifconfig gives docker ip.
Now our instance has ip 172.19.0.2, which can mean that there is a 172.19.0.1 which is the first ip in network assigned to host machine generally. Let's check that. Or you could have enumerated running a for loop for a range.
172.19.0.1 is listening unlike others. We need to scan for port it listening for. But this box neither *nc nor nmap. But we can use some bash trick using /dev/tcp or /dev/udp to check if particular port is open. We will send data using tcp or udp protocol on differetn ports and if data is received means it's open.
for port in $(seq 1 1000); do (echo "blah" > /dev/tcp/172.19.0.1/$port && echo "open - $port") 2>/dev/null; done
It will echo blah on evry port from 1 to 1000 using /dev/tcp and if it succeeds it will say it's open.
Port 22 is open and 80 is open. Port 80 is website we saw on goodgames.htb but 22 was not open when we scanned 10.10.11.130. Let's try ssh as augustus user. with our cracked password.
Now this is same directory as we had on docker machine, just here we are as augustus user and in docker as root. What we create in this directory either way is accessible other way. Outside/inside of docker.
Now there are multiple way's to get root from here.
- copy /bin/bash as augustus on host machine into home directory then in docker change it's user to root with suid binary. Then as augustus o host run it as root.
- Or in docker copy /bin/sh which will automatically be owned by root, as you are root in docker, set suid permission. Now on host run it & you will be root.
- but you can't copy /bin/bash in docker and run it on host, as for bash different shared libraries are used.
Let's do that
and we are root on box.
Let's look at ip rules.
And we can see that ssh is open for 172.19.0.1 host only.
Learning:
- scanning hosts without nmap and nc
- How docker utilise cgroup and namespace to utilise kernel resources and isolate different processes.
Thank you for reading and feedbacks are welcome.
Twitter: Avinashkroy
Comments
Post a Comment