Book is a Medium Linux box created by MrR3boot. It was released on February 22nd, 2020 and retired on July 11th, 2020. The users rated the difficulty 6.2/10 and gave an appreciation score of 4.1/5.
TL;DR
We access a virtual library where we can download, upload and comment books. The account registration flow contains a vulnerability that allows overwriting any user’s password. We overwrite the admin’s and to access the admin panel. There, we can download a PDF file containing the list of the books of the virtual library. There is a Server-Side XSS vulnerability during the generation of PDFs. From a user account, we can inject some XSS code to read local files that will be executed server-side when we generate a PDF as admin. We leak the user reader
SSH private key this way and grab the user flag. The server uses a version of logrotate
vulnerable to a Race Condition. As it is run as a cronjob as root
, we can elevate our privileges and get the root flag.
Reconnaissance & Enumeration
Open Ports
An NMAP scan shows the following (partial) output:
$ sudo nmap -sS -sV -p- 10.10.10.176
PORT | STATE | SERVICE | VERSION |
---|---|---|---|
22/tcp | open | ssh | OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) |
80/tcp | open | http | Apache httpd 2.4.29 ((Ubuntu)) |
We discover the usual SSH server and HTTP ports opened.
Web discovery
We access a login page where we can register to access a virtual library:
As a user, we have access to the following features:
- we can download PDFs on flowers:
The download links are like:
and the files downloaded are like 1.pdf
. So maybe a good spot for Arbitrary File Read or Local File Inclusion.
- we can search for books in the database:
Maybe a SQL Injection to exploit here? The GET request is like:
- we can submit books feedbacks:
When we do that we get the following message:
So maybe an XSS or CSRF to exploit here.
- we can submit new documents:
Whatever we submit, we get the following message:
This could be a good spot for file upload vulnerabilities.
- we can contact the admin:
Another spot for XSS or CSRF vulnerabilities. We get as well the admin email address that could be useful later.
- finally, we can view our profile and modify our name:
Maybe we can exploit a missing access control check issue here and force our account with an Admin role instead of User.
A basic file/directory scan discovers the following:
[…]
/admin (Status: 301)
/books.php (Status: 302)
/contact.php (Status: 302)
/db.php (Status: 200)
/docs (Status: 301)
/download.php (Status: 302)
/feedback.php (Status: 302)
/home.php (Status: 302)
/images (Status: 301)
/index.php (Status: 200)
/logout.php (Status: 302)
/profile.php (Status: 302)
/search.php (Status: 302)
/settings.php (Status: 302)
The /admin
page shows a Sign In feature, but it is disabled.
Gaining Access
As we have seen, there is room for plenty of vulnerabilities to exploit. Unfortunately, most of them are rabbit-holes. There is an XSS vulnerability in the name but it is limited to 10 characters, so except injecting some basic HTML like "><<h1>A
we cannot do much.
When we create an account, a Javascript code checks that the username is not longer than 10 characters and that the email address is not longer than 20. This check is as well done server-side. The account ID seems to be the email address as we can create multiple accounts with the same name as long as the email is unique. But what if the email truncation is done after the ID is checked and before the data is persisted in the database? This means that we could possibly rewrite another user account data…like the admin account. By creating an account with the following POST data:
we successfully overwrite the admin password! The email address is first checked to be unique, then truncated to 20 characters, trimmed and finally, a SQL query persists the password. We can now login into the admin panel:
We now have access to the following admin features:
- list users and delete them,
- read user messages and delete them,
- read user feedbacks and delete them,
- download the list of users and books as PDF.
When downloading the user list, we see that one of the tests we did previously (the HTML injection in the name) is output:
But we are still limited to 10 characters here. The other PDF lists the book names and authors, let’s try the same there. From a user account, we make a new book submission and inject some HTML code like <h1>TESTTEST</h1>
. This results in:
Good, we can execute Javascript without filters apparently. After a little research on what to do with that, I came upon this article describing how to exploit a Server-Side XSS when generating a PDF dynamically. That’s quite neat. Let’s try to read /etc/passwd
. The payload is:
|
|
We put it as the book title or the author…and we get:
We find the unique user reader
. Let’s check if it holds an SSH private key:
|
|
And surprise:
We can simply copy/paste the whole content and use it to grab the user flag:
Local Reconnaissance & Enumeration
We find an lse.sh
script in reader
home folder which is a Linux enumeration script. We can launch it but it does not show any useful information.
There is as well a backup
folder that contains some Apache access.log*
files. This suggests that logrotate
is used. The version of logrotate
is 3.11.0. This version is vulnerable to a Race Condition and the tool logrotten
can be used to exploit it.
With pspy64
, we confirm that there is a cronjob that calls logrotate
as root:
Privilege Escalation
As per the logrotten
readme file, we check all the prerequisites:
logrotate
is run asroot
,- we have write access in the folder where
access.log
is rotated, - we do not have access to
/root/log.cfg
file but we can see thatlogrotate
can create files.
Let’s compile logrotten
on the server:
$ chmod +x lr
We can execute the following command:
This will create an empty access.log
file under /etc/bash_completion.d
with reader
as owner. All files in this folder are loaded with each new user session:
We can now write our reverse shell in /etc/bash_completion.d/access.log
, start a Netcat listener and wait for root
to execute it:
We can grab root
private SSH key on the way in /root/.ssh
.
Conclusion
This was a really enjoyable box where I learned a new attack vector: Arbitrary File Read through server-side XSS!
Resources
[1] Server Side XSS (Dynamic PDF)
https://book.hacktricks.xyz/pentesting-web/xss-cross-site-scripting/server-side-xss-dynamic-pdf
[2] Linux Smart Enumeration
https://github.com/diego-treitos/linux-smart-enumeration
[3] logrotten
https://github.com/whotwagner/logrotten