Sunday, May 25, 2014

DEFCON 2014 quals - Fritas

Fritas
Fritas:
fritas_91a318f87f384a080595696b3c73fc39.2014.shallweplayaga.me 6908
For the sake of brevity we will call the address fritas.net. Despite the fact that our mothers taught us all not to talk to strangers, the first thing we all do when presented with a strange address/port is talk to it. Connecting to the port with netcat a few times gave us the interesting interaction:
$nc fritas.net 6908
&
$aufy7df9-ase4-1234-00acd0001
$nc fritas.net 6908
&
$aufy7df9-ase4-1234-00ace0001
$nc fritas.net 6908
&
$aufy7df9-ase4-1234-00ad20001

The first line makes no sense, but the second one appears to be some sort of UUID that increments all but the last 4 digits, which are always 0001. We want to take a closer look at the data so we create a simple Python script to connect to it and display:
from socket import socket
HOST = (‘fritas.net’,6908)
s = socket()
print repr(s.connect(HOST).read(1024))
repr allows us to print the data so that non printable bytes are printed in their hex representation. It is good practice when printing unknown data for analysis and it pays off!
$python fritas.py
\x00\x00\x00\x00&\n$aufy7df9-ase4-1234-00ae20001
This looks like it could be a handshake so we modify fritas.py to send the data we get back.
$python fritas.py
\x01\x00\x00\x00
This is a good sign, and it is beginning to look like this challenge is protocol busting. We modify the python to send back a modified Hello with the first byte incrementing every time from 1 to 255. For some codes we get interesting behavior:
$python fritas.py
1 : Expected Hello, got Fritas::Messages::Ready
11: Expected Hello, got Fritas::Messages::StorePostReq
14: Expected Hello, got Fritas::Messages::GetPostResp
15: Expected Hello, got Fritas::Messages::ListPostReq
21: Expected Hello, got Fritas::Messages::ListTagReq
31: Expected Hello, got Fritas::Messages::GetRelatedTagReq
From the replies to these messages we can determine that the protocol consists of:
And the data consists of section preceded by two bytes, the first of which appeared to be a flag (usually a newline) and the second was the length of the section. It also appears that every Req has a code that is one less than its corresponding Resp. We crafted a request with no data to list posts and list tags. Each tag had a TagID which matched the UUID except the last 4 digits which were 0002 through 0008. So if your uuid was xxxxxx-xxxx-xxxx-xxxx0001, the first post would be xxxxxx-xxxx-xxxx-xxxx0002. The tags were all random collections of 20 letters and numbers. We sent a “GetPostReq” for each post revealing that post 0002 was password protected while all the other posts contained their TagID, a header (preceded by the ‘\n’ flag) and a body (preceded by the ‘\x12’ flag). Each post also had two tags with it, which presented an interesting issue: one of the tags from the ListTagReq was un accounted for! We figured it was probably related to the password protected post. WHY NOT GET RELATED TAGS! Sending a GetRelatedTagReq with the data section containing a tag returns a large data structure, one element in the structure contained the line “password=X” where X is about 20 random characters. After some trial and errors, we settle on sending the GetPostReq with the format: <code>\nTagID\x12 This request returned the post containing the flag! As a side note, the name of the challenge “Fritas” is a type of beef cake. This is a clue, as the server for this challenge is implemented using the beefcake ruby library https://github.com/protobuf-ruby/beefcake which is a ruby implementation of the Google protobuf https://code.google.com/p/protobuf/ which is worth looking into.

No comments:

Post a Comment