First off I’d like to say a big thank-you to all the KPMG bods who put this bonus challenge together, it was great fun and a damn site harder than the main part of the challenge.

I’ve put this solution up as I was the only person to solve it (outside of KPMG), whether that’s because it was too hard, people just ran out of time or that they lost the will to live we’ll probably never know, but if you did try it and didn’t quite get there then maybe this will give you some pointers.

DISCLAIMER: In this blog I’ve tried to show the methodology and my thought process used in solving this problem, so before going any further I’d like to make it clear that this may not be the best way of solving this problem and more than likely not the only way of solving it. This is the first time I had ever reverse engineered a piece of software such as this, I’m not a programmer or professional pen-tester but I am methodical, logical, a good lateral thinker who know a bit or two about networking and systems! There was also lot of researching, learning applications and trial and error involved.

OK, so lets begin. After completing the main part of the KPMG BSides London challenge you get access to a file called bonus-challenge.exe. No clues as to what it is or does, so it’s a case of search, seek and explore.

I suspected it was some benign Malware application and would therefore do various network or service type things but first a bit of investigate of the file, which revealed it to be an MS-DOS executable. I know the .exe extension is a give away but the first rule of forensics (well mine anyway), never trust what it says on the tin!

Blue text – inputs
Red text – outputs

$ file bonus-challenge.exe
bonus-challenge.exe: MS-DOS executable, MZ for MS-DOS

Are there any visible strings in it?
$ strings bonus-challenge.exe | head
!Win32 .EXE.

Definitely a win32 file. With what looks like a packer of some form. So I loaded it into a Windows Vista VM.

Note: I spent the first part of the analysis actually running the application in a Windows 7 32bit VM until I found a bug in the program (or with my VM) so I switched to Vista, more on that when we get there though. I’ve since tested it on Windows 7 64bit and it worked fine.

First thing to do in the Windows VM is to see if there is anything in the packer. So I used PiED which told me about the packer but not much else. I spent a while looking through the source code to see if it could be exploited but to no avail.

Next I loaded bonus-challenge.exe it into Ollydbg. On initial load the bonus-challenge application is still packed so there is not much to see, press F9 to start the debugging and unpack the file.

With the file unpacked I did a reference string search to see what I could see and got a “useful” list of output. I worked on the assumption that the developer (and compiler) of the program wrote the routines sequentially (is this correct?), so on that basis the strings depict a probably flow that the program will take, with a few gaps of course!

Search – Text strings referenced in bonus-challenge:
Address Command Comments
00401102 PUSH bonus-challenge.0043908C ASCII “A key, I need a key”
00401124 PUSH bonus-challenge.004390A4 ASCII “prancingPony”
00401136 PUSH bonus-challenge.004390B4 ASCII “I am a pink pony! What do I do?!”
0040114A PUSH bonus-challenge.004390D8 ASCII “You got one “
0040116E PUSH bonus-challenge.004390E8 ASCII “I wish I had a blue pill 1”
004011A1 PUSH bonus-challenge.00439104 ASCII “%s%s”
00401212 PUSH bonus-challenge.00439124 ASCII “…but not the other!”
00401226 PUSH bonus-challenge.0043913C ASCII “… and the other!”
00401286 PUSH bonus-challenge.0043916C UNICODE “OLLYDBG”
004012AE PUSH bonus-challenge.00439104 ASCII “%s%s”
004012BE PUSH bonus-challenge.0043918C ASCII “#g8á¥ä¾”
004012E8 PUSH bonus-challenge.00439198 ASCII “”
00401358 PUSH bonus-challenge.00439150 ASCII “…but where is the other?”
0040138F PUSH bonus-challenge.00439198 ASCII “”
00401434 PUSH bonus-challenge.0043917C ASCII “Hello, olly!”
00401485 PUSH bonus-challenge.004391F4 ASCII “+OK”
004014BE PUSH bonus-challenge.00439048 ASCII “USER blacktulip”
00401504 PUSH bonus-challenge.004391F4 ASCII “+OK”
00401537 PUSH bonus-challenge.0043905C ASCII “PASS theBlackSwan”
0040157D PUSH bonus-challenge.004391F4 ASCII “+OK”
004015B0 PUSH bonus-challenge.004391F8 ASCII “LIST”
004015F8 PUSH bonus-challenge.00439200 ASCII “”
00401606 PUSH bonus-challenge.004391F4 ASCII “+OK”
00401635 PUSH bonus-challenge.00439070 ASCII “I wish I had a blue pill”
0040164E PUSH bonus-challenge.00439200 ASCII “”
0040168E PUSH bonus-challenge.00439204 ASCII “%i %i”
004016C2 PUSH bonus-challenge.00439200 ASCII “”
0040171E PUSH bonus-challenge.00439210 ASCII “RETR %i”
004017A0 PUSH bonus-challenge.00439200 ASCII “”
004017B2 PUSH bonus-challenge.004391F4 ASCII “+OK”
00401817 PUSH bonus-challenge.0043921C ASCII “What happened to my clock????”
004018A4 PUSH bonus-challenge.0043923C ASCII “\sFrom:\s.*?([\w_\.]+@[\w\.-]+)”
00401A12 PUSH bonus-challenge.00439104 ASCII “%s%s”
00401A5D PUSH bonus-challenge.00439298 ASCII “I don’t recognise %s, do they like me?”
00401A72 PUSH bonus-challenge.004392DC ASCII “Match error %d”
00401A81 PUSH bonus-challenge.004392C0 ASCII “Annymous letters? For me?”
00401AA2 PUSH bonus-challenge.0043925C ASCII “%s”
00401AB6 PUSH bonus-challenge.0043926C ASCII “this is house of my master, but who is it?”
00401AF7 PUSH bonus-challenge.00439104 ASCII “%s%s”

So using the above as a summary you can assume that the program needs a key (0x401102), a parameter (0x40114A) or two (0x401212) which are strings (0x4011A1), is associated with the domain (0x4012E8), uses POP3 (0x4014BE, 0x401547, 0x4015F8, 0x40171E) and reads emails (0x4018A4). Simple, er, no, but that was my initial assessment. Also, with the benefit of hindsight it also checks for Ollydbg (0x401286) and uses a ciphered hostname (0x4012BE) to prefix the

So where to start with that lot. First thing that jumped out was “prancingPony”. Lets try that:

Hmmm, that got a response. But what is the other one, I couldn’t see another in the code. So it was time to see if I could find it somewhere in memory.

I spent the next few evenings stepping through the instructions one-by-one. The way I did this was to step through the unpacker with Ollydbg (F9) and then through the first routine (Shift-F9) as I knew this was probably checking for the first parameter, “prancingPony” was successful. This stops at the privileged command (an I/O routine) at 0x401E8D.

The next routine I would need to take a closer look at, so I reload the .exe back into Ollydbg (with a second parameter this time), step over the unpacker (F9) and then through the next routine (F9) which in theory (remember I’m using some common sense here, not learned knowledge) is processing the first parameter, we should be ready to look at the second parameter. So armed with some common sense I assembled the program (Ctrl-A) and work through the code starting at 0x401000. It’s not until you get to 0x401212 that you see two strings that look like they are part of a boolean decision to me, “…but not the other!” being false and “…and the other!” being true, therefore using some common sense the bit of code before this must be the logic. The decryption of the second parameter occurs at 0x4011F0, this is taking a value and dumping it on the stack (EAX in this case), so I put a breakpoint in there (F2).

With the breakpoint in place, press Shift-F9 three times to run through the code. The key thing I was looking for here were suspicious things coming into the stack registers (top right window). After the third F9 you will see EAX populated with the second parameter “Bucephalusbouncingball”. Little did I know I would be typing this phrase a lot for the next week or so!

So now armed with two parameters “prancingPony” and “Bucephalusbouncingball”, I tried the program again.

This went a bit further, however, the developer had anticipated me using Ollydbg and put in an exception routine (cunning!), so to go further I would either need to bypass the routine or run the rest from DOS. I tried the former first but only with limited success, I did notice that the stack was being populated with random host names for the domain, so I shutdown Ollydbg and prepared Wireshark.

Firstly, being inquisitive I looked at the website, checked its Whois records and tried to see if the DNS would tell me anything about it, but no, nothing of use. The web site was just a holding page, with nothing in the source code:

     | \/ |
 | | |
  \ \ /
  || ,
  | \ || |\
    | | || | |
  | | || / /
  \ \||/ /
  jgs `\ \//`
  This domain is part of a reverse engineering challenge and does not host any malware or C2. 
 ABSOLUTELY NO permission to attack this site is given.

So, next I tried Nmap, on the domain, just to get an idea of what ports were available.

Starting Nmap 5.51 ( ) at 2012-04-17 21:24 BST
Nmap scan report for (
Host is up (0.13s latency).
rDNS record for
Not shown: 977 filtered ports
20/tcp closed ftp-data
21/tcp open ftp?
22/tcp open ssh OpenSSH 4.3p2 Debian 9etch3 (protocol 2.0)
|_ssh-hostkey: 1024 ad:73:97:f5:76:13:de:77:2d:e3:33:de:de:78:83:51 (DSA)
25/tcp closed smtp
80/tcp open http lighttpd
|_http-methods: No Allow or Public header in OPTIONS response (status code 301)
| http-title: Black Tulip
|_Requested resource was
143/tcp open imap Cyrus imapd 2.2.13-Debian-2.2.13-10+etch4
443/tcp closed https
465/tcp open ssl/smtp Postfix smtpd
587/tcp closed submission
990/tcp open ssl/ftp
|_ftp-bounce: no banner
993/tcp open imaps?
995/tcp open ssl/pop3 Cyrus pop3d 2.2.13-Debian-2.2.13-10+etch4 (Debian)
|_pop3-capabilities: USER EXPIRE(NEVER) UIDL APOP TOP OK(K List of capabilities follows) RESP-CODES PIPELINING IMPLEMENTATION(Cyrus POP3 server v2 2 13-Debian-2 2 13-10 etch4) AUTH-RESP-CODE LOGIN-DELAY(0)
2121/tcp closed ccproxy-ftp
2222/tcp closed EtherNet/IP-1
8080/tcp closed http-proxy
38292/tcp closed landesk-cba
40911/tcp closed unknown
41511/tcp closed unknown
42510/tcp closed caerpc
44176/tcp closed unknown
44442/tcp closed coldfusion-auth
44443/tcp closed coldfusion-auth
44501/tcp closed unknown

A few ports open, I tried the userid (blacktulip) and password (theBlackSwan) from the .exe file for the services but didn’t get anywhere, so went back to the .exe. As I was running this in a sandboxed VirtualBox environment, one thing I did notice before even starting up Wireshark was that with both parameters on the command line the network icon at the bottom of the window lit up when run, so it was obviously up to something.

With Wireshark running, I could see what exactly it was up to. The application was systematically sending out DNS requests to what seemed to be random hostnames, so, the obvious thing to do there is set up a DNS.

With my DNS running I configured it to resolve the first DNS name, success, the application responded with a SYN to port 3245.

What was it sending?  I started Netcat up to listen on port 3245 and ran it again.

That looked a lot more promising, SYN, SYN-ACK, ACK and loads of data. Cracked it, erm, well not quite. A quick look at the pay load and the netcat listener showed that N3ro had thought of this, hmmm!

HAHAHAHAHAHAHHAHAHA! Such simple tricks, Black Tulip is better than this!HAHAHAHAHAHAHHAHAHA! Such simple tricks, Black Tulip is better than this!HAHAHAHAHAHAHHAHAHA! Such simple tricks, Black Tulip is better than this!HAHAHAHAHAHAHHAHAHA! Such simple tricks, Black Tulip is better than this!HAHAHAHAHAHAHHAHAHA! Such simple tricks, Black Tulip is better than this!HAHAHAHAHAHAHHAHAHA! Such simple tricks, Black Tulip is better than this!HAHAHAHAHAHAHHAHAHA! Such simple tricks, Black Tulip is better than this!HAHAHAHAHAHAHHAHAHA! Such simple tricks, Black Tulip is better than this!HAHAHAHAHAHAHHAHAHA!

With netcat off I ran the .exe again and watched Wireshark with the next DNS entry configured.  This time it tried connecting to port 51421, so I started the netcat listening on that port and ran it again except now it was talking on 51422, so I set netcat to listen on port 51423, pre-empting the next move but all the .exe did was send a SYN and carry on sending DNS requests to random names. I let the application carry on running though and the next interesting DNS lookup was, this triggered a SYN to TCP port 110 (POP3), remember in the string dump of the application above, a series of POP3 commands?  This looked promising.

I was using Fedora as server for this VM, so I used the default POP3 server which is Dovecot and changed the following configuration from standard:
# 2.0.19: /etc/dovecot/dovecot.conf
# OS: Linux 3.1.2-1.fc16.i686 i686 Fedora release 16 (Verne) ext4
disable_plaintext_auth = no
login_greeting = honeypot
mail_location = mbox:/var/spool/mail/pop3/%u:INBOX=/var/spool/mail/%u
mbox_write_locks = fcntl
passdb {
driver = pam
service imap-login {
inet_listener imap {
address = localhost
service pop3-login {
inet_listener pop3 {
address =
port = 110
inet_listener pop3s {
port = 995
service pop3 {
executable = pop3 postlogin
service postlogin {
executable = script-login -d rawlog

Note: The postlogin service I created, this is optional, it gives you extra debug information if you have problems. I configured this because my Windows 7 VM had issues and wouldn’t issue the RETR command and I need this on to check that it wasn’t the server that was broken. From this point on I moved to a Windows Vista VM and that worked fine.

I then created blacktulip a user account on the server, I don’t think it is really necessary but it came in use with some testing I did. With the user account created and the POP3 server running I ran the .exe again. Firstly without any email which wasn’t much use, however from the network trace I could see that it was logging on correctly and then issuing a LIST command.

If you look back at the string dump above you can see the sequence it is following:
USER blacktulip – Logon
PASS theBlackSwan – Enter password
LIST – Show messages
%i %i
RETR %i – Retrieve messages

Now the %i %i if you know your POP3 will be the index and the byte size of the messages it receives, so obviously bonus-challenge.exe is expecting a message.

So I started to try some messages (a lot of messages!) and run the bonus-challenge.exe against them. Most were variations on this theme:
From Thu Apr 29 00:00:00 2035 -0500
Date: Sat, 24 Nov 2035 11:45:15 -500
User-Agent: blacktulip
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Status: N


Which resulted in a friendly message from N3ro:

Then after a lot of attempts I decided to give the original N3ro’s email a go, findingn3ro, which resulted in this:

Now it was a simple case of putting the coordinates: 51.505293,-0.016078 into Google maps and finding the master.  This is where a little lateral thinking comes in, who lives at 30 N Colonnade, London?  This is a KPMG challenge, they have offices in Canary Wharf, hmmm, let’s try a as the email address.

Getting closer!  The next bit is probably there to test that people doing this test completed the initial challenges as the chap in charge of the Cyber Security at KPMG is Martin Jordan and his email is displayed in the final solution. So I put this in and bingo:

I found the master but I’m merely an apprentice!


Tagged with:

Leave a Reply

Your email address will not be published. Required fields are marked *