Pwtent Pwnables 500 Solution?

During the DEFCON Capture the Flag qualifiers (aka quals) run by ddtek this past weekend, I was banging my head against forensics 300 for much longer than I care to admit. When I wasn’t working on one of the other challenges, I’d go back and dig deeper into it. There’s something to be said for a good challenge, but it’s an altogether different beast when you have more red herrings than…well, I don’t have a good analogy, but if you worked f300, you know.

On Sunday evening in the Hack-V, wrffr or JRod called my name through Skype. “Mezzy, look at Pwtent Pwnables 500–there’s a PCAP.” Sweet! Being the team’s nose, sniffer, or whatever @tlas wants to call me, I have an affinity for digging into packets during CTF at DEFCON. It’s what I did for two of the three years we competed, and I think it’s fun. It’s exciting to what exploits as they’re being fired off from one of the other 7 teams against our server.

One of my duties was ripping apart the attacks as they came through to see if it wasn’t something we already had. If we hadn’t seen it or exploited that particular service yet, then I’d dissect it, replay it if I could or pass it off to our core reversers, and write a Snort rule to drop future attacks.

The challenge said, “Kenshoto never handed you 0day! Use it wisely and a key shall be yours.” (PCAP here) Sounds right up my alley and the guys knew it.

I started off looking through the PCAP with Wireshark to see what the service looked like, how it had to be interacted with in order to exploit it, and information about where it was running.

The target was running on port 6913/tcp. It was easy to see the prompts, password, and exploit in the PCAP. Below is an example.

? to see the menu.>
How many bytes to donate?

….followed by d, 141, the payload, and shell interaction (ls, uname, etc.)

At first, I started scripting up the interaction with Ruby exactly as you see above. I got to the payload and tried to cheat by piping it through a couple of different tools to get it in a nice \x format to deliver via print. Nothing worked quite right, so Cutaway stepped in seeing my frustration and typed it for me while I laid on the couch. You’ll see why that was important in a moment.

I hopped into irb and pasted my script to watch it exploit pp500. While watching the exploit via tcpdump in another window, I noticed something was wrong as I wasn’t getting the same response. I tried it a few different ways until I realized the difference. The 0day wasn’t interactive–it pushed the entire sequence of password, menu interaction, and exploit during the initial connection. Crap!

So, I went back and took out the code where I was accepting a response back from the server and starting putting all of my side of the conversation into one print statement. When I was done, I tried again. This time it still didn’t work. Cutaway noticed that my bytes didn’t match. When I was converting “antagonist” to hex, I botched it. I sometimes transpose numbers and I did it more than once here. That’s why I was glad cutaway typed in all of the payload for me earlier.

I fixed all my screwups, pasted it back into IRB, and BLAM! Tcpdump started scrolling looking just like example PCAP. Bingo! We did it. Now, all I had to do with confirm my shell was there and cat the key. Typing in mysocket.print “ls -la\n” and nothing. The socket was hung. Looking back at tcpdump, and I saw there wasn’t as many \x20‘s as there should have been. Weird.

Then, I realized it was 10:00pm EST time. Quals was over. I missed fully landing Pwtent Pwnables 500 by seconds…

Below is the Ruby that I used. If you were one of the teams who snagged a copy of the actual pp500 binary when you were shelled in during pp200, please send me a copy. I’d love to complete the feeling of accomplishment by getting a shell through it.

require ‘socket’

mysocket =, port)

mysocket.print “\x61\x6e\x74\x61\x67\x6f\x6e\x69\x73\x74\x0a\x64″+

#[read back 10 megs]
# I was lazy & entered the following 10 times

# The following assumes the key is in the same directory
# and that it is named key. I don’t know for sure.
mysocket.print “cat key\n”
response =  mysocket.recv(1024).chomp
puts response




~ by John Sawyer on May 26, 2010.

4 Responses to “Pwtent Pwnables 500 Solution?”

  1. […] My write-up for Pwtent Pwnables 500 […]

  2. You can find the actual binary that goes with the exploit here If you really want to play along, you will just run the binary on a FreeBSD8.0 host and figure out what to do from there. Since you didn’t get access to the binary during the challenge, its cheating if you look at this one 🙂

  3. […] My write-up for Pwtent Pwnables 500 […]

  4. […] (unsolved) […]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: