sábado, 13 de agosto de 2011

WriteUp - forensicK - ptrace.net

After taking part in Sibctf quals, I saw a related tweet from Ptrace Security group that took me to their website, where I found this nice challenge:


http://ptrace.net/files/challenges/4.txt

Here is my solution, probably not the best one:


We are given a pcap network capture, which we can know by verifying the magic number, but when we try to open it, Wireshark says it is corrupted. Only six packets are viewed, which we assume to be correct.



We open the file in 010 Editor and apply the pcap template by Didier Stevens to see what is happening. The file fomat seems to be quite easy... just a header for the file and a little header for each packet consisting of:


timestamp seconds
timestamp microseconds
number of octets of packet saved in file
actual length of packet

After playing for a while with 010 Editor I realized that some packets were overlapping the next ones. The sizes reflected for each packet in the cap metadata seemed to match the ones in the IP header and TCP sequences, so I guess some bytes were deleted from the original capture, although I was not able to determine which ones for sure.


For example, in the next image we see the 6th packet overlaps 10 bytes from the next packet. In fact it should finish in offset 43Ch, and then begin the header for 7th packet, but according to its header, it finishes in 446h:"

Since the metadata in the pcap file let us indicate the size of the packet that was captured, I decided to use that field to fix the file.


The problem is that the header for each packet has no fixed token, so we must guess where each packet begins. In this case it was not difficult because in the network capture there was only two MAC addresses involved, so we used them to identify each packet.


I admit I did it manually the first time, but since there are more than a handful, later I made this python script.



import re
import mmap
import binascii
from struct import *

def nextframe(map, last, pat1, pat2):
next1=map.find(pat1,last+1)
next2=map.find(pat2,last+1)
if next1 < 0:
if next2 <0:
next=-1
else:
next=next2
else:
if next2 < 0:
next=next1
else:
next=min(next1,next2)
return next

with open("4_forensicK.bin.cap", "r+") as f:
# memory-map the file, size 0 means whole file
map = mmap.mmap(f.fileno(), 0)
map2 = map
previous=0
next=0
#I only expect 1 unicast comunication on layer 2, with only IP packets
#so I use 2 different ethernet frame headers to locate frames
pat1=binascii.unhexlify('00c049d2e4640016d32987a10800')
pat2=binascii.unhexlify('0016d32987a100c049d2e4640800')
next=nextframe(map,next,pat1,pat2)

while True:
previous=next
captnum=unpack('<i',map[next-8:next-4])[0]
next=nextframe(map,next,pat1,pat2)
if next!=-1:
distanciapaq=next-previous-16 #Each packet has a 16 byte header
if distanciapaq != captnum:
if distanciapaq > captnum:
print "Next packet is further than expected. There may be more layer 2 comunications. Review manually."
else:
#Actual packet is overlapping next one
map2[previous-8:previous-4]=pack('<i',distanciapaq)
print 'Cap fixed at offset', previous-8,' Previous capture size', captnum, 'actual size', distanciapaq
else:
break

map.close()



Be careful, it overwrites the input file. You don't want to tamper your evidences ;-)


After that, I could open the file without problems, so I reviewed the connections, decoded connections to tcp port 8086 as HTTP and could see the server answers uncompressed to find the flag:



So, the flag is: 3406654e25675f56ce7922cf5ec12952


Of course, it could be resolved much faster just by following the hints in the http queries, visible with strings, and uncompressing the gzip streams in the answers that followed them, but we are not here for the money, you know!! ;-)

No hay comentarios:

Publicar un comentario