The target has 2 tcp ports opened running a ssh and a web server, nothing much to see here except nmap discovering the /writeup/ directory exposed into the robots.txt file. I always like to include the –reason flag with nmap scans as it tells you the actual reason for reporting the port’s state as shown. For more detailed information on flags like this I highly recommend watching Fyodor’s video, the actual author of nmap, presented at DEF CON 16 and titled Nmap: Scanning the Internet – it’s a fun and pleasant to watch video containing plenty of useful information on some advanced nmap techniques.
There is an additional thing to notice here except the /writeup directory in the robots.txt file – this particular version of OpenSSH is usually vulnerable to username enumeration attacks.
Enumerating the web application
The landing page suggests that there’s some kind of DoS protection, which could be seen in case you try to run dirb, dirbuster, gobuster or some kind of a directory brute-force on it as your IP will get blocked for several minutes.
The /writeup directory
The /writeup directory shows several links to some kind of write ups or hackthebox.eu retired machine walkthroughs, and the url structure may suggest a possible LFI.
Trying anything related to an LFI attack, like providing the /etc/passwd file, altering the string with a null byte, or just providing an index to its parent directory did not work. The next step here was hidden into the source code of the web application, which is some kind of a simple CMS:
Exploiting CMS Made Simple
The CMS Made Simple application is vulnerable to various attacks, including several RCE ones, however they all required user authentication.
As there is no version included in the banner, one of the ways to enumerate the exact version of the web application is to deploy it locally and check what documentation files are included. There’s usually either a README or a CHANGELOG in cms applications like this, which authors do not bother to delete after installation. I usually always try the following strings in the root directory:
/license.txt or /LICENSE.txt
/readme.txt or /README.txt
/changes.txt or /CHANGES.txt
/changelog.txt or /CHANGELOG.txt
In most cases, those files will be uppercased with the extension lowercase in the following format:
In the case with CMS Made Simple these are located within the docs directory, and by requesting the /CHANGELOG.txt file some valuable piece of information is being shown:
So what this suggests is we the server is running either CMS MAde Simple version 18.104.22.168 or this was the previous release so we are dealing with CMS Made Simple >= 22.214.171.124
There’s an SQL Injection exploit prior to CMS Made Simple 2.2.10 which could be easily discovered using a simple searchsploit search so we have an exact match on exploit-db.
Not going to explain the CMS Made Simple Exploit mechanism in details, but it’s a Blind SQL Injection exploit leveraging the timing between the responses and guessing each character of the result stored into the database per each character, then concatenating the character found with the next guess in case there is a match, until no match is found and this way constructing the full password hash, salt, username, and user email. I strongly suggest reading the exploit code for a more comprehensive understanding on what it does and the way it uses to exfiltrate user data as it’s something really useful and commonly used in penetration testing.
As most hackthebox users run in a shared environment you may want to tweak the TIME variable, which is set to 1 second by default, and increase it to something more reliable up to 10 – the higher value you set the more reliable result you would get and the slower the script would complete. In my case I was able to exfiltrate the necessary hashes with its default settings.
In case you want to have a more invisible experience on the process, you may modify the python exploit code to use a proxy when making a GET/POST request to the target, a trick often used and demonstrated by @ippsec in his videos – for example, you may alter line 114 to look as following:
This way you would be able to track requests from burpsuite as they happen, on the condition that you have configured burpsuite to run on the same port, in this case 8080.
As shown below, the exploit exfiltrated the hash, salt, username and email from the first row (that’s 0x31 in case you reviewed the exploit source code):
The hash is a bit tricky to discover, as hashcat or any other program would accept other modes as valid, but the correct hashcat mode I used was -m 20.
# Getting available hashcat md5 modes
hashcat --example-hashes | grep md5 -b1
# Cracking the hash using -m 20
hashcat -a 0 -m 20 '62def4866937f08cc13bab43bb14e6f7:5a5
Once the password is retrieved the first thing one may end up to is try it on the CMS Made Simple’s admin interface, however as I could not log in there using it the next thing to try was log in via the ssh service running on hackthebox’swriteup.
And that’s the initial intented vector:
Privilege Escalation on this box is rather tricky, and requires you to follow the path and instance of something specific running in the process. The easiest way to find your path through is using DominicBreuker’s pspy, an application enumerating processes as they run, even those belonging to other users.
While writing this I even found out there is an actual exploit for this for Ubuntu systems, even though I did it completely manually so I will show it this way. In case you are interested in the exploit I’m referring to look up for MOTD file tampering which acts into a similar way, however I just tested it and didn’t actually work, and by reviewing the source code the idea behind id is a bit different although it still uses the message at login called MOTD (Message of the Day) and it’s triggered in the exact same way by logging in to the target.
I achieved privilege escalation in two steps:
By monitoring running processes using pspy. I got into a bit of a rabbit hole at first sight as the fail2ban script running as a cron job was really what was looking like a promising vector.
After I enumerated the actual process related to the privilege escalation, I enumerated all the directories related to the process running, their related groups and permissions, and wrote a script which is supposedly run with high privileges under the path which is loaded at first place within the user defined PATH directories.
This is the interesting bits from pspy:
Obviously this is being run with each user login, and in case you watch over pspy processes while logging in from another terminal to the system you will observe the process occurring with each login of yours, or in case someone else logins to the system via ssh as well.
Let’s disassemble each of the interesting lines into smaller pieces:
-> This calls the /etc/update/motd.d/10-uname script
The important detail to note here is that the script /etc/update-motd.d/10-uname actually calls uname with its short path, meaning we could try to hijack its execution by creating a malicious file in our PATH environment variable, as long as we have the necessary permisisons for this:
-> This is calling the run-parts script with the –lsbsysinit option, which according to the man page tells the script to “use LSB namespaces instead of classical behavior.”. The run-parts script is a script running each script or program within a provided directory, in this case /etc/update-motd.d. As there’s just the file 10-uname in it, this one will be executed with each login of the user. What’s interesting is the contents of the file, which are just running uname with some parameters:
-> This one is setting the environment variables and the PATH for the user, meaning in this case when a command is typed, the first place to look in will be the /usr/local/sbin directory. Then run-parts being run again with the –lsbsysinit option, and outputting the result to /run/motd.dynamic.new
By tracking all the users’ directories and permissions, and having in mind that the /etc/update-motd.d/10-uname file can not be modified directly, you would note that the actual uname binary called resides within the /bin directory. As the first directory within the user PATH environment is /usr/local/bin, this would mean in case we create the file “/usr/local/bin/uname”, it will be the one called instead of the actual uname.
Inspecting directory permissions further would also show that jkr is member of the “staff” group, and /usr/local/bin, and the directory itself has read and write permissions granted to the ‘staff’ group, we could conclude we may be able to write a file in it.
And that’s our path to privilege escalation. You could either use a reverse shell script, or create a sudo binary like this:
If you are following the timing you would see that the dash file was created after logging in from the second terminal, which actually calls run-scripts with sudo privileges and calls the uname file just created.
Upgrading the group and uid – getting a full root
In case you want to upgrade your session to a full root, you could either use a C script or do it from python like this:
Source code in python (one liner):
The privilege escalation was rather tricky and requires either much observation or having the skill to already have met this on another boxes or on a real penetration testing assignment.
Additional stuff related to the CMS Made Simple login
And in case you wondered, this is the reason the CMS Made Simple password was not working within the web interface, even though its being extracted from the database:
The author has put a custom htpasswd filed directly within the apache2 configuration, preventing the CMS Made Simple login page from showing unless proper credentials which match those in /etc/apache2/passwords are provided.
And after changing jkr’s password in/etc/apache2/password, you could be able to see the actual CMS Made Simple Admin panel:
htpasswd -b /etc/apache2/passwords jkr jkr123456
That was my way of getting root on htb‘s Writeup. Overall a fun box to do, not too hard, but with many tricky vectors which require detailed observation and some basic Linux knowledge, especially with Privilege Escalation and how paths in a Linux environment are defined. I believe it’s also quite a fit as a resource in case you want to prepare for OSCP.
In case you liked this walkthrough you may follow me on twitter for additional security tweaks and hints.