HTB - Book
Zweilosec's writeup on the medium-difficulty Linux machine Book from https://hackthebox.eu
Last updated
Zweilosec's writeup on the medium-difficulty Linux machine Book from https://hackthebox.eu
Last updated
A medium Linux box that was fairly straightforward, but still challenging enough to teach some interesting use cases for 'standard' attacks.
This tool is invaluable for doing any sort of website or web app testing. From the developers:
Burp Repeater is a simple tool for manually manipulating and reissuing individual HTTP requests, and analyzing the application's responses. You can send a request to Repeater from anywhere within Burp, modify the request and issue it over and over.
First, give your private key file the proper secure permissions chmod 600 root.id_rsa
Next use -i <keyfile>
to identify the key to use: ssh -i id_rsa <user>@10.10.10.176
If prompted, enter the user's key decryption passphrase (sometimes not set by the user, and separate from the user's Unix password.)
This amazing script automates a lot of useful enumeration tasks, and is geared towards helping you find privilege escalation routes. It won't always find everything you need, but is a good place to start when you gain a new user account on a system. You can find the newest version of this script here.
I started my enumeration with an nmap scan of 10.10.10.176
. The options I regularly use are: -p-
, which is a shortcut which tells nmap to scan all ports, -sC
is the equivalent to --script=default
and runs a collection of nmap enumeration scripts against the target, -sV
does a service scan, and -oN <name>
saves the output with a filename of <name>
.
With only two ports open, 22 - SSH
and 80 - HTTP
, there was nothing to do except check to see what was hosted on port 80.
I navigated to http://10.10.10.176
which led to a login page. Peeking at the source code of the page revealed an interesting script embedded in the html.
I had to do quite a bit of reading before I found anything that gave me any information on exploiting this. Essentially the problem boiled down to a timing issue between checking the database for an existing user, and the default configuration for MySQL, which truncates strings that are entered. So, when a user inputs a username (which in this case is the email
field, based on the login page), the code will compare the inputted string against the list of users to see if it already exists or not. If not, it will enter it into the database, truncating the string down to the maximum length.
In this case, the script tells us that the admin has modified this truncation to be 10 characters for name
and 20 characters for email
. After truncating the string, MySQL also removes any trailing whitespace when adding entries, which gives us a perfect attack avenue. More information can be found at: https://resources.infosecinstitute.com/sql-truncation-attack/#gref
Unfortunately, I did not currently have any valid usernames to do this attack against, so I created a random user account and logged in.
Since I had decided I was looking for a username and/or email address I thought that the most likely place to find those would be on the Contact page.
My hunch was correct, and I found what I was looking for on the Contact Us
page. The email address admin@book.htb
seemed likely to be the email address for logging into the Admin account.
Before going through contortions to execute some sort of exploit I first tried some basic passwords to log in, but just got this message each time.
Next, I tried creating an admin account without using the information I had gained from reading about SQL truncation to see what it would do.
Trying to (re)create the admin account without using SQL truncate results in the following alert message:
This was the output I expected. Next I tried doing the attack by putting a lot of spaces and the word 'test' after the email address so that it was well past the 20 character maximum.
Unfortunately, it gave an error: A part following '@' should not contain the symbol ' '.
. (This was in Chromium). I tried it again in Firefox, but it also did not seem to work and just gave an unspecified "Please enter an email address" error. Next, I fired up Burp and captured my POST request to do some troubleshooting. I sent the request to Repeater so I could easily recreate and modify it as needed.
I sent the same exact request using Burp and to my surprise it went through. I'm guessing that the browsers themselves were doing some form validation in order to prevent attacks of this sort.
Thinking that my password choice had perhaps been a bit too weak, I went back and used !AmA$up3r@dmin!!!
as a password rather than something super-overly-simplistic in order to prevent other users from accidentally stumbling upon the admin account without learning anything about the proper attack.
I then logged in using my shiny new admin password and started looking around. Nothing seemed to be different in this account other than the username I was logged in as.
I played around with sending different payloads in the collections submission form, but could not find a way to execute any type of code I sent. This message was the same as when I uploaded files as my basic user account. Seemingly I had hit a dead end.
I decided to check my Dirbuster output to see if there were any useful hidden pages.
I was pleasantly surprised to see an /admin/index.php
page listed.
At first I tried to see if the "Forgot your password?" link would do anything, but it wasn't linked to anything and didn't work. I tried using my new admin credentials I had created and logged in.
Thankfully, the Administrator panel had some new options.
Downloading the Collections PDF showed me something interesting. While l was playing around in the regular account I had done a test upload with the Book Title and Author fields as "a".
My 'book' was listed in the collection! You can see that the author and book name is reflecting in the pdf, in what looks like a standard HTML table. This seems like it could be the code reflection vulnerability I was looking for. Hopefully there was a way to get it to execute code as well.
The number next to my book seems to be random, and was a link to download exactly whatever I had uploaded with a name of the random number, probably to reduce the possibility of additional code execution vectors.
I also downloaded the Users collection to see if there was anything useful, but just got a good laugh instead.
You can see the attempts by other users at brute forcing the login page (looks like burp intruder), and also at the bottom you can see what appears to be an attempt at SQL injection. This document had hundreds of lines of similar attacks. You can see one of my test
accounts up at the top (and that peter
guy seems like a very friendly fellow!). Sadly no one but me had sent any messages to the admin in the hopes they would get XSS execution on the Feedback page.
Since I had seen the name and title I had assigned my book submission in the pdf in what looked like a rendered HTML table format, I wanted to see if it was possible to do cross site scripting through this route. Luckily for me, there was already a write-up on exactly this scenario at https://www.noob.ninja/2017/11/local-file-read-via-xss-in-dynamically.html. First, I tried again sending just the word 'test' in each field to validate what I found.
I captured this POST in Burp and once again sent it to Repeater. Sending this resulted in the same pdf collection as before, with a random number next to the the word 'test'. Next, I changed the Book Title field to contain a simple XSS attack with <img src=x onerror=document.write('test')>
.
In case you were wondering, 51091.pdf
is just one of the randomly named files that I had gotten back from downloading the Collections PDF. The file you upload doesn't seem to have any bearing on this vulnerability.
This time only the word 'test' was written to the pdf! The XSS vulnerability was confirmed.
The Collections PDF itself contains a dynamically created HTML table. Therefore, any code in fields that the page would normally render prior to being saved as a PDF should get executed. This can be exploited with JavaScript to do XSS. I decided the next thing I needed to do was to try to get a list of usernames by downloading/etc/passwd
. My next request contained the following JavaScript in the title field:
After I submitted my "book" with command to get /etc/passwd
through burp, I was happy to see the output in my browser.
Now I had not only used an XSS vulnerability, but also a LFI vulnerability was also confirmed. From this output I could see that there were only two users who could log in: reader
and root
.
Through all of my enumeration I was not able to find any passwords, so I decided to try and see if I could use the LFI vulnerability to determine if reader
had an SSH key file I could download since port 22 was open. I modified the example code from the blog post to blindly try to download the most common location and name for a user's SSH key file.
My blind LFI attack was a success! However, copying all of the text from this PDF resulted in output that looked a bit strange, and didn't work for logging in. Looking at the right edge of the output, I noticed that the text was cut off for some reason. Hoping it was a rendering issue and not something more difficult to troubleshoot, I opened the file in another program.
Opening the PDF file in Firefox resulted in the same view, but when I used ctrl-a
, ctrl-c
to copy all of the text I was able to copy everything. For some reason the text was being truncated on the side, and in the default Kali PDF reader it was inaccessible. Opening it in a browser allowed the HTML embedded in the PDF file to be copied, which in this case included the whole SSH key.
Also, as always remember to run chmod 600 $key_file
before using SSH keys to log in.
First thing to do after logging in...collect my proof!
reader
After checking sudo permissions with sudo -l
(nothing for this user sadly) the next thing I do while enumerating Linux machines is try to run linpeas.sh
. This script automates a lot of the standard enumeration, and also has a nice and easy to read output. It also has an additional benefit that came in handy for this machine.
The linpeas.sh
script also includes links to a blog with writeups on a lot of different vulnerabilities. The links are included in relevant sections of the output that shows files that relate to each vulnerability or exploit. It looked like I might not have to do much searching to find a vulnerability this time, as one of the sections showed a lot of log files along with a link to an interesting privilege escalation route related to logrotate
.
The linpeas.sh
script also told me that there were writable log files in reader
's home directory, and that this could potentially by exploited through the logrotate
service. Checking out the provided link gave me the following helpful information:
There is a vulnerability on logrotate that allows a user with write permissions over a log file or any of its parent directories to make logrotate write a file in any location. If logrotate is being executed by root, then the user will be able to write any file in
/etc/bash_completion.d/
that will be executed by any user that login. So, if you have write perms over a log file or any of its parent folder, you can privesc (on most linux distributions, logrotate is executed automatically once a day as user root). Also, check if apart of/var/log
there are more files being rotated. More detailed information about the vulnerability can be found in this page https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition. You can exploit this vulnerability with logrotten.
Reading the logrotten
documentation, I found that I needed to do a bit more enumeration first to determine if I met all of the prerequisites.
reader
The backups/
folder in /home/reader
contained two log files, which were writable by reader
.
While using pspy to monitor running processes I found this interesting line: 2020/06/07 17:08:01 CMD: UID=0 PID=16535 | mysql book -e delete from users where email='admin@book.htb' and password<>'Sup3r_S3cur3_P455';
It looked to me like a script (probably in a cron job) that was resetting the password of the admin account I had used to get in. I tried this password on the root account hoping it would let me in, but no dice.
Inside /etc/logrotate.conf
I found that the "create" option had been set. There was only one condition remaining to meet the requirements for this exploit: I had to know that logrotate
was actually running (as root).
After running pspy for awhile, this entry showed up: 2020/06/07 17:08:30 CMD: UID=0 PID=16773 | /usr/sbin/logrotate -f /root/log.cfg.
So the system was indeed running logrotate
, and it was loading a configuration file from the /root directory
. This seemed like enough evidence the process was running as root to me to test it. It was now time to test out this exploit to see if I could escalate privileges to root.
From the exploit writer at https://github.com/whotwagner/logrotten:
Precondition for privilege escalation
To run the exploit:If "create"-option is set in logrotate.cfg:
If "compress"-option is set in logrotate.cfg:
Based on my enumeration I found that all of the conditions for vulnerability to this exploit were met for the "create" option, except for one thing that wasn't in the checklist. I could not find any configuration files related to logrotate
that mentioned access.log
in the /home/reader/backups
folder. Since this was my writeable log file, it was pretty important that it be rotated by the service. I decided to go ahead and try it anyway since it still looked like a likely approach. I created a payload that would hopefully get me root access, and ran the exploit.
My payload was designed to exfiltrate both root.txt
and root
's SSH key.
However, just running the exploit was not enough. In order to execute my script, I had to force log rotation by writing to the log a valid entry. I simply copied the valid entry from the backup in the same folder:
It was time to collect my loot and see if I got the output I expected.
The first file indeed contained the root flag!
And file number two also contained the root SSH key. The exploit had worked without too much fuss, except for figuring out how to make logrotate
run. I wasn't entirely certain of the interval that was set for access.log
to be backed up since I didn't ever see it's configuration file.
And, as always, remember to chmod 600
your private SSH key files before use! (Yes I say this a lot. It's also easy to forget for some reason...)
After gaining root access I found out why I was unable to discover what was causing the logs in /home/reader/backups
to be rotated. In the /root
directory there were some files for cleaning up the system of other user's artifacts, and also the script and config that rotated access.log
in the backup/
folder.
Mystery solved!
Thanks to MrR3boot
for creating a machine that had some new and interesting routes to gain privileges. I definitely liked how there were few to no rabbit holes to lose myself in!
If you like this content and would like to see more, please consider buying me a coffee!