This was the challenge which scored us the last couple of points and put us on the second place. We thought a write up would be nice. This challenge gave us some headache, and if you see the final solution it looks so easy, but it was a long way to get there.
The server involved was the 192.168.0.5. After a nmap scan we noticed the server was listening on port 21/tcp, or ftp. The service info also gives us the first clue of the challenge, it was a port knocking exercise.
This is how we solved it.
One of the parts of the PHDays Quals was the ‘meteorite rain’ archive, containing many small and not so small challenges. One of these (M100) was tougher than most and quite interesting, so we decided to do a writeup.
The file M100 is a Windows console program written in C++. This means it’s a bit of a pain to reverse engineer. One of my teammates did the reverse engineering but then got stuck, so he asked if I could take a look at it. Basically the program looked like this when translated to a simple C program:
The zip file found on the Monolith server (seemingly) contains a VMware image of Ubuntu Server 10.10.
Archive: jhc_rc2.zip Length Date Time Name --------- ---------- ----- ---- 1298 2011-05-06 13:40 jhc_rc2/readme 1834352640 2011-05-06 17:10 jhc_rc2/Ubuntu 10.10 Server i386.vmdk 536870912 2011-04-25 12:40 jhc_rc2/Ubuntu 10.10 Server i386.vmem 2496 2011-05-06 17:10 jhc_rc2/Ubuntu 10.10 Server i386.vmx
Shit, we didn’t focus enough on/crack this during the game, but we did get it shortly after. Anyway, this service was a little java client/server implementation of a card game. Client connects to server and asks for a new game, server sends back a ‘crypted’ deck of cards, client shuffles it. Oops, why let the client shuffle the deck? Maybe he ends up not (fairly) shuffling it at all.
The ‘crypto’ used here is a basic substitution cipher using a fixed alphabet.
After sending back the final crypted deck to the server we’re supposed to “pick” cards using their position in the deck and the correct key for that position. In theory the client has enough info to make correct guesses! Without further ado, our exploit:
Challenge #11 consists of two binaries, chal1 and chal2. As if exploiting one binary
wasn’t worth any points!
Chal1 is an NX-protected x86-64 binary with fixed addresses for libc and ASLR for the stack.
It suffers from a strcpy() vulnerability. A string is copied from argv to a fixed size buffer.
But not before we overcome the fact that the binary exits when there are *any* arguments
at all. Luckily, when there are 0 elements in argv, argv points to envp.
While the convention for environment variables is “VARNAME=value”, the kernel does not
enforce it, it just copies NULL-terminated strings. This means we can put any binary data
on the top of the process’ stack, encoding the NULL-bytes by just starting another string.
The ps3game.c program looks pretty simple to exploit: it receives code from the network, executes it, and sends back the response. So… just send your shellcode and you’re done, right?
The mysocksd binary is a SOCKS5 proxy written in C++. The binary is vulnerable
to an integer overflow when using SOCKS5’s feature of connecting to a remote
host by specifying a domain name. The domain name length is specified using a
single byte which gets overflown when set to ‘\xff’. This in turn leads to a
heap overflow. So, suspecting a classic unlink attack, we first check where it
The second hashcalc challenge is much the same as the first (make sure to read it!). Except this version is launched from inetd instead of being a forking server. This is annoying because it means that stack cookies and library offsets change every run. Let’s verify that by adapting our exploit to dump the GOT to the new binary.
The control flow relevant to the bug is as follows:
So what we have is a blind format string bug in request_handler, and a buffer overflow in reply_func. The buffer overflow is normally detected because of a damaged stack cookie however. Since the stack and libs are randomized we really want to have the freedom to explore the address space using ROP instead of just using a printf exploit, so let’s see if we can find a way to make the overflow work.
This is a quick write up of the Django webchallenge from PlaidCTF 2011.
Web application is a guestbook written using Django and can be found at: http://a12.amalgamated.biz/DjangoProblem1
Upon investigation it turns out they have pagecaching in Django enabled using Memcache. Memcache is a key/value store accessible over TCP. The memcache server is publicly accessible on the default memcached port 11211.
Some snooping around on the memcached server reveals Django uses python serialized objects in the cache. Serialized objects in the memcache keystore have a flag of ‘1’. (We missed this detail for a long time :/)