# 33C3 CTF 2016 : Exfil
**Category:** Forensic **Points:** 100 **Solves:** 137
> We hired somebody to gather intelligence on an enemy party. But apparently they managed to lose the secret document they extracted. They just sent us this and said we should be able to recover everything we need from it.> Can you help?
## Write-up
For this challenge, we have a PCAP file and a Python server. It's clear that we have to recover a 'secret document' with this. Let see what we have :
### Python Server
We have a Python server which is used to communicate and execute commands over DNS, here are some interesting parts :
```python...from dnslib import * # dnslib...data = base64.b32encode(data).rstrip(b'=') # BASE32 Encoded...    chunk_size = 62    for i in range(0, len(data), chunk_size): # Chunks every 62 chars        chunks.append(data[i:i+chunk_size])    chunks += domain.encode().split(b'.')...domain = 'eat-sleep-pwn-repeat.de' # Domain...def parse_name(label):    return decode_b32(b''.join(label.label[:-domain.count('.')-1])) # No domain for the BASE32...class RemoteShell: # A little RemoteShell to execute commands and extract the secret document :)...```
### PCAP dump
Here is our PCAP :```bash$ file dump.pcap dump.pcap: tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 262144)```
Protocol hierarchy :```bash$ $ tshark -qr dump.pcap -z io,phs===================================================================Protocol Hierarchy StatisticsFilter: eth                                      frames:1804 bytes:306168  ip                                     frames:1804 bytes:306168    udp                                  frames:1804 bytes:306168      dns                                frames:1804 bytes:306168===================================================================```
Communication : ```bash$ tshark -r dump.pcap -z ip_hosts,tree -q===============================================================================================================================IP Statistics/IP Addresses:Topic / Item    Count         Average       Min val       Max val       Rate (ms)     Percent       Burst rate    Burst start  -------------------------------------------------------------------------------------------------------------------------------IP Addresses    1804                                                    0,0177        100%          3,4600        19,865        192.168.0.121  1804                                                    0,0177        100,00%       3,4600        19,865        192.168.0.1    1804                                                    0,0177        100,00%       3,4600        19,865       -------------------------------------------------------------------------------------------------------------------------------```
So, it looks like we have the server '192.168.0.1' and the enemy party '192.168.0.121' from where they extracted the 'secret document'.
From the Python Server code, we may be interested to extract the 'A' query and the CNAME response to anlyses them :
```bash$ tshark -r dump.pcap -Tfields -e dns.qry.name -e dns.cname```
First look, we have a lot of duplicate data. Then, I tried to figure out how exactly the server encode de communication. After several (hundreds...) test part by part and the domain name 'eat-sleep-pwn-repeat.de' removed, I was able to decode manually some some data with BASE32 :
Original query : `G4JUSBIXCV2G65DBNQQDKNSLBIZDMMRUGE4DIIDEOJ3XQ4RNPBZC26BAGMQGM4.DFORZHSIDGOBSXI4TZEA2C4MCLEBCGKYZAGE3SAMJTHIZTCIBOBIZDMMRRGQ2D.CIDEOJ3XQ4RNPBZC26BAGUQHE33POQQCAIDSN5XXIIBAEA2C4MCLEBCGKYZAGE.3SAMJTHIYDMIBOFYFDENRT.eat-sleep-pwn-repeat.de````python>>> import base64>>> print(base64.b32decode('G4JUSBIXCV2G65DBNQQDKNSLBIZDMMRUGE4DIIDEOJ3XQ4RNPBZC26BAGMQGM4DFORZHSIDGOBSXI4TZEA2C4MCLEBCGKYZAGE3SAMJTHIZTCIBOBIZDMMRRGQ2DCIDEOJ3XQ4RNPBZC26BAGUQHE33POQQCAIDSN5XXIIBAEA2C4MCLEBCGKYZAGE3SAMJTHIYDMIBOFYFDENRT'))7?I??total 56K2624184 drwxr-xr-x 3 fpetry fpetry 4.0K Dec 17 13:31 .2621441 drwxr-xr-x 5 root   root   4.0K Dec 17 13:06 ..263```
We can see that from the server code, each query begins with 6 bytes which contain the the acknowledgement, conversation ID and sequence number. I simply removed it to decode all communication.
So, the idea here is, we need to : * Have one query/response per line to decode it easly* Remove duplicate line* Remove '.eat-sleep-pwn-repeat.de' and all '.' for each line* Decode each line from BASE32* Remove the first 6 bytes for each decoded line
PCAP Extraction, one query/response per line and unique one :```bash$ tshark -r dump.pcap -Tfields -e dns.qry.name | awk '!a[$0]++' > extracted.txt && tshark -r dump.pcap -Tfields -e dns.cname | awk '!a[$0]++' >> extracted.txt```
Decode```python#!/usr/bin/env python2import base64with open("extracted.txt") as f:    pcap_decoded = ""    for line in f:        s = ""        l = line.split('.', line.count('.'))        for i in range(line.count('.')-1):            s += str(l[i])        try:            pcap_decoded += base64.b32decode(s)[6:]        except:            passdecoded = open('decoded.txt', 'w')decoded.write(pcap_decoded)decoded.close()f.close()```
Got it![pcap_decoded.txt](https://github.com/zbetcheckin/33C3_CTF_2k16/blob/master/pcap_decoded.txt)
Wait a minute, not done yet, it looks like we have our 'secret document' encrypted... with the file and the key :)```bash...2631216 -rw-r--r-- 1 fpetry fpetry 4.0K Dec 17 13:17 secret.docx2631222 -rw-rw-r-- 1 fpetry fpetry 4.4K Dec 17 13:31 secret.docx.gpg2631218 -rw------- 1 fpetry fpetry  908 Dec 17 13:21 .START_OF_FILE�???L+??�0�j??...H��0ʟ�=END_OF_FILE...-----BEGIN PGP PUBLIC KEY BLOCK-----lv+fGfdzCZnubp254S3mLsyokuyZ7xjy/i0m2a5fVQ===XS5g-----END PGP PUBLIC KEY BLOCK----------BEGIN PGP PRIVATE KEY BLOCK-----
lQOYBFhNxEIBCACokqjLjvpwnm/lCdKTnT/vFqnohml2xZo/WiMAr4h3CdTal4yf...```
We need to extract our secret.docx.gpg :```python#!/usr/bin/env python2with open("decoded.txt") as f:    s = f.read().replace('\n', '')    start = s.index("START_OF_FILE") + len("START_OF_FILE")    end = s.index("END_OF_FILE", start )    secret = open('secret.docx.gpg', 'w')    secret.write(s[start:end])    secret.close()    f.close()```
secret.docx.gpg```bash$ file secret.docx.gpgsecret.docx.gpg: PGP RSA encrypted session key - keyid: 1B142B4C 6AA230BF RSA (Encrypt or Sign) 2048b .```
Finally :```bash$ gpg --import pub.key$ gpg --import private.key$ gpg --decrypt secret.docx.gpg > secret.docx```
Here we go, we have a nice [secret.docx](https://github.com/zbetcheckin/33C3_CTF_2k16/blob/master/secret.docx) with the flag :```bash$ file secret.docxsecret.docx: Microsoft Word 2007+```
**Flag:**The secret codeword is 33C3_g00d_d1s3ct1on_sk1llz_h0mie