2016-11-20

RC3 CTF 2016: Some Pang - Forensics 50

This challenge starts off with the flavor text:

Some Pang
50

we captured some iseeempee pang pakets. do the thing. get the flag. win the POINTS!
Download Link: here

author: wumb0

The download link provided sompang.zip which unzips to somepang.pcap (and __MACOSX which is always fun to see ;)) which is a network packet capture file. I ran the tcpdump program on the pcap which produced the following (truncated) output:

-> % tcpdump -r ./somepang.pcap
13:57:58.398546 IP 192.168.1.198 > 192.168.1.1: ICMP echo request, id 35767, seq 0, length 40
13:57:58.401087 IP 192.168.1.1 > 192.168.1.198: ICMP echo reply, id 35767, seq 0, length 40
13:57:58.405026 IP 192.168.1.198 > 192.168.1.1: ICMP echo request, id 36023, seq 0, length 40
...
14:01:23.821293 IP 192.168.1.1 > 192.168.1.198: ICMP echo reply, id 49533, seq 0, length 40
14:01:23.824038 IP 192.168.1.198 > 192.168.1.1: ICMP echo request, id 49789, seq 0, length 40
14:01:23.824980 IP 192.168.1.1 > 192.168.1.198: ICMP echo reply, id 49789, seq 0, length 40

Hm! Lots of ICMP packets. It looks like these ICMP packets (oddly) have payloads, so lets take a look at them:

-> % tcpdump -X -r ./somepang.pcap 
reading from file ./somepang.pcap, link-type EN10MB (Ethernet)
13:57:58.398546 IP 192.168.1.198 > 192.168.1.1: ICMP echo request, id 35767, seq 0, length 40
    0x0000:  4500 003c 6a89 0000 4001 8c20 c0a8 01c6  E..<j...@.......
    0x0010:  c0a8 0101 0800 9d38 8bb7 0000 581e 2bb6  .......8....X.+.
    0x0020:  0006 1487 2f39 2f39 2f39 2f39 2f39 2f39  ..../9/9/9/9/9/9
    0x0030:  2f39 2f39 2f39 2f39 2f39 2f39            /9/9/9/9/9/9
13:57:58.401087 IP 192.168.1.1 > 192.168.1.198: ICMP echo reply, id 35767, seq 0, length 40
    0x0000:  4500 003c 645a 0000 4001 924f c0a8 0101  E..<dZ..@..O....
    0x0010:  c0a8 01c6 0000 a538 8bb7 0000 581e 2bb6  .......8....X.+.
    0x0020:  0006 1487 2f39 2f39 2f39 2f39 2f39 2f39  ..../9/9/9/9/9/9
    0x0030:  2f39 2f39 2f39 2f39 2f39 2f39            /9/9/9/9/9/9
13:57:58.405026 IP 192.168.1.198 > 192.168.1.1: ICMP echo request, id 36023, seq 0, length 40
    0x0000:  4500 003c 495c 0000 4001 ad4d c0a8 01c6  E..<I\..@..M....
    0x0010:  c0a8 0101 0800 bf64 8cb7 0000 581e 2bb6  .......d....X.+.
    0x0020:  0006 2dd0 6a2f 6a2f 6a2f 6a2f 6a2f 6a2f  ..-.j/j/j/j/j/j/
    0x0030:  6a2f 6a2f 6a2f 6a2f 6a2f 6a2f            j/j/j/j/j/j/
...
<snip>
...
14:01:23.821293 IP 192.168.1.1 > 192.168.1.198: ICMP echo reply, id 49533, seq 0, length 40
    0x0000:  4500 003c 7e55 0000 4001 7854 c0a8 0101  E..<~U..@.xT....
    0x0010:  c0a8 01c6 0000 56b1 c17d 0000 581e 2c83  ......V..}..X.,.
    0x0020:  000c 8444 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d  ...D============
    0x0030:  3d3d 3d3d 3d3d 3d3d 3d3d 3d3d            ============
14:01:23.824038 IP 192.168.1.198 > 192.168.1.1: ICMP echo request, id 49789, seq 0, length 40
    0x0000:  4500 003c fbc4 0000 4001 fae4 c0a8 01c6  E..<....@.......
    0x0010:  c0a8 0101 0800 a5aa c27d 0000 581e 2c83  .........}..X.,.
    0x0020:  000c 92b1 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a  ................
    0x0030:  0a0a 0a0a 0a0a 0a0a 0a0a 0a0a            ............
14:01:23.824980 IP 192.168.1.1 > 192.168.1.198: ICMP echo reply, id 49789, seq 0, length 40
    0x0000:  4500 003c 7e56 0000 4001 7853 c0a8 0101  E..<~V..@.xS....
    0x0010:  c0a8 01c6 0000 adaa c27d 0000 581e 2c83  .........}..X.,.
    0x0020:  000c 92b1 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a  ................
    0x0030:  0a0a 0a0a 0a0a 0a0a 0a0a 0a0a            ............

Using the -X directive with tcpdump shows a hexdump-style output of the packet data, and shows us that the ICMP packet data appears to be a series of repeating bytes. Since it's ICMP data, the data sent and the data that is the response should be the same. So I ran tcpdump again, but supplied a bpf filter to select only the packets coming from the router (192.168.1.1), and suppressed the output to be less verbose:

-> % tcpdump -qns 0 -A -r somepang.pcap ip src 192.168.1.1
reading from file somepang.pcap, link-type EN10MB (Ethernet)
13:57:58.401087 IP 192.168.1.1 > 192.168.1.198: ICMP echo reply, id 35767, seq 0, length 40
E..<dZ..@..O...........8....X.+...../9/9/9/9/9/9/9/9/9/9/9/9
13:57:58.406007 IP 192.168.1.1 > 192.168.1.198: ICMP echo reply, id 36023, seq 0, length 40
E..<.,..@.7}...........d....X.+...-.j/j/j/j/j/j/j/j/j/j/j/j/
13:57:58.410435 IP 192.168.1.1 > 192.168.1.198: ICMP echo reply, id 36279, seq 0, length 40
E..<i...@.............<.....X.+...?\4A4A4A4A4A4A4A4A4A4A4A4A
13:57:58.414484 IP 192.168.1.1 > 192.168.1.198: ICMP echo reply, id 36535, seq 0, length 40
E..<.-..@.7|...........F....X.+...OXAQAQAQAQAQAQAQAQAQAQAQAQ
...
<snip>
...
14:01:23.809774 IP 192.168.1.1 > 192.168.1.198: ICMP echo reply, id 48765, seq 0, length 40
E..<~R..@.xW..........<j.}..X.,...WoCjCjCjCjCjCjCjCjCjCjCjCj
14:01:23.813323 IP 192.168.1.1 > 192.168.1.198: ICMP echo reply, id 49021, seq 0, length 40
E..<~S..@.xV.......... ..}..X.,...d.////////////////////////
14:01:23.817445 IP 192.168.1.1 > 192.168.1.198: ICMP echo reply, id 49277, seq 0, length 40
E..<~T..@.xU........... .}..X.,...t.2Q2Q2Q2Q2Q2Q2Q2Q2Q2Q2Q2Q
14:01:23.821293 IP 192.168.1.1 > 192.168.1.198: ICMP echo reply, id 49533, seq 0, length 40
E..<~U..@.xT..........V..}..X.,....D========================
14:01:23.824980 IP 192.168.1.1 > 192.168.1.198: ICMP echo reply, id 49789, seq 0, length 40
E..<~V..@.xS.............}..X.,.....

Lastly, the data we want is on the payload line, not the header info line, so we use an inverse grep filter to remove lines containing the string length 40. Additionally, from the above output, it seems like the data we're looking at is base64-encoded data. Since base64 data can only comprise the characters A-Za-z0-9/+=, I've also filtered out lines which do not contain any of those characters:

-> % tcpdump -qns 0 -A -r somepang.pcap ip src 192.168.1.1| grep -vP 'length 40' | grep -vP '[^A-Za-z0-9=+/]$'
reading from file somepang.pcap, link-type EN10MB (Ethernet)
E..<dZ..@..O...........8....X.+...../9/9/9/9/9/9/9/9/9/9/9/9
E..<.,..@.7}...........d....X.+...-.j/j/j/j/j/j/j/j/j/j/j/j/
E..<i...@.............<.....X.+...?\4A4A4A4A4A4A4A4A4A4A4A4A
E..<.-..@.7|...........F....X.+...OXAQAQAQAQAQAQAQAQAQAQAQAQ
...
<snip>
...
E..<....@.1...........8.?...X.+....+B6B6B6B6B6B6B6B6B6B6B6B6
E..<....@.1...........7.@...X.+....CV5V5V5V5V5V5V5V5V5V5V5V5
.HbHbHbHbHbHbHbHbHbHbHbHb
E..<....@.1
...........0B...X.+...!'6V6V6V6V6V6V6V6V6V6V6V6V
E..<....@.1 ..........N.C...X.+...2zOBOBOBOBOBOBOBOBOBOBOBOB
...

As can be seen above in the highlighted line, some lines which don't end in the base64 data are still included, which means we'll need to further process this output to isolate the last byte.

Enter the Python

My thinking at this point is that each ICMP packet has 2 characters of a base64 data stream (12 bits) which is duplicated several times to ensure successful transmission/recognition. Therefore, we just need to isolate these bytes and decode them as a base64 stream. First I prepare a file (output.herp) which will hold the output of my above tcpdump command:

tcpdump -qns 0 -A -r somepang.pcap ip src 192.168.1.1| grep -vP 'length 40' | grep -vP '[^A-Za-z0-9=+/]$' > output.herp

Here is the simple program which accomplishes this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env python3

#Read each tcpdump output lines into list 'lines'
with open("output.herp") as f:
    lines = f.readlines()

#prepare output string to write to file
outstring = ''

#remove leading and trailing whitespace from each line
lines = [line.strip() for line in lines]

for line in lines:
    #check if the last two characters in the line are a repeat of the previous two characters
    if (line[-2:] == line[-4:-2]):
    #if they are, add the two characters to the output string
        outstring += (line[-2:])

#write the output to file
with open("output2.herp", "w") as f:
    f.write(outstring)

Now we have the file output2.herp which should be a big bas64 blob, which we can decode into whatever data might lie within:

cat output2.herp | base64 -d > output3.herp

Running file output3.herp reveals:

-> % file output3.herp 
output3.herp: JPEG image data, JFIF standard 1.01, aspect ratio, density 72x72, segment length 16, Exif Standard: [TIFF image data, 
big-endian, direntries=2, orientation=upper-left], baseline, precision 8, 720x449, frames 3

And when we view the image with eog output3.herp, we get the flag:

PANG

RC3-2016-PANG-ME-LIKE-ONE-OF-YOUR-FRENCH-GORILLAZ