Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
from scapy.all import *
from scapy.utils import rdpcap
import sys
import struct
from pwn import *
MESSAGE_TYPE_SYN = 0x00
MESSAGE_TYPE_MSG = 0x1
MESSAGE_TYPE_PING = 0xFF
class Decoder:
def __init__(self, outfile):
try:
self.fd = open(outfile, "w")
except Exception as e:
print "Could not open output file: %s" % outfile
print "Reason: %s" % e
quit(1)
self.lastdata = []
def decode(self, data):
try:
# Remove additional '.' as per the spec
data = data.replace(".","").decode("hex")
except:
# Throw away any corrupted data
pass
# Decode our packet header to identify the packet type
(id, type) = struct.unpack(">Hb", data[0:3])
if type == MESSAGE_TYPE_MSG:
print "MSG PACKET"
(id, type, session_id, seq, ack) = struct.unpack(">HbHHH", data[:9])
bytes = data[9:]
if self.lastdata != bytes and session_id == 65013:
self.fd.write(bytes)
self.lastdata = bytes
#print "Session [%d] Data Hash [%s]" % (session_id, enhex(md5sum(data[9:])))
elif type == MESSAGE_TYPE_SYN:
print "SYN PACKET"
elif type == MESSAGE_TYPE_PING:
print "PING PACKET"
elif type == MESSAGE_TYPE_FIN:
print "FIN PACKET"
if len(sys.argv) != 3:
print "Usage: %s pcap output" % (sys.argv[0])
quit(2)
pkts=rdpcap(sys.argv[1])
d = Decoder(sys.argv[2])
for pkt in pkts:
if pkt[UDP].dport == 53 and pkt[IP].dst == "4.2.2.4":
if pkt.haslayer(DNS) and pkt.qdcount > 0 and isinstance(pkt.qd, DNSQR):
try:
d.decode(pkt.qd.qname.split('.skull')[0])
except Exception as e:
print "Exception occured decoding: %s" % e
print "Data extracted to %s" % sys.argv[2]
@kaetir
Copy link

kaetir commented Sep 16, 2020

python3 version

from scapy.all import *
from scapy.utils import rdpcap
import sys
import struct
from pwn import *
import codecs

decode_hex = codecs.getdecoder("hex_codec")

MESSAGE_TYPE_SYN = 0x00
MESSAGE_TYPE_MSG = 0x01
MESSAGE_TYPE_PING = 0xFF
MESSAGE_TYPE_FIN = 0x02

class Decoder:
    def __init__(self, outfile):
        try:
            self.fd = open(outfile, "wb")
        except Exception as e:
            print( "Could not open output file: %s" % outfile)
            print( "Reason: %s" % e)
            quit(1)
        self.lastdata = []
        
    def decode(self, data):
        try:
            data = decode_hex(data)[0]
        except:
            # Throw away any corrupted data
            return

        # Decode our packet header to identify the packet type
        (id, type_m) = struct.unpack("Hb", data[0:3])
        if type_m == MESSAGE_TYPE_MSG:
            print("MSG PACKET")
            (id, type_m, session_id, seq, ack) = struct.unpack(">HbHHH", data[:9])
            bytes_m = data[9:]
            if self.lastdata != bytes_m and session_id == 65013:
                self.fd.write(bytes_m)
                self.lastdata = bytes_m
                

                #print( "Session [%d] Data Hash [%s]" % (session_id, enhex(md5sum(data[9:]))))

        elif type_m == MESSAGE_TYPE_SYN:
            print( "SYN PACKET")
        elif type_m == MESSAGE_TYPE_PING:	
            print( "PING PACKET")
        elif type_m == MESSAGE_TYPE_FIN:
            print( "FIN PACKET")

if len(sys.argv) != 3:
    print( "Usage: %s pcap output" % (sys.argv[0]))
    quit(2)

pkts=rdpcap(sys.argv[1]) 
d = Decoder(sys.argv[2])

for pkt in pkts:
    if pkt[UDP].dport == 53 and pkt[IP].dst == "4.2.2.4":
        if pkt.haslayer(DNS) and pkt.qdcount > 0 and isinstance(pkt.qd, DNSQR):
            try:
                # Split the dns and remove additional '.' as per the spec
                d.decode(pkt.qd.qname.decode("utf-8").split('.skull')[0].replace(".","").encode("utf-8"))
            except Exception as e:
                print( "Exception occured decoding: %s" % e)

print( "Data extracted to %s" % sys.argv[2])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment