All pastes #430040 Raw Edit

Miscellany

public python v1 · immutable
·published 2007-04-08 17:58 UTC
rendered paste body
import structimport copyimport sysdef xors(a,b):    return "".join([chr(ord(x1)^ord(x2)) for x1,x2 in zip(a,b)])class PCAPPacket:    def __init__(self,pheader):        pheader = struct.unpack("IIII",pheader)        self.ts_sec = pheader[0]        self.ts_usec = pheader[1]        self.incl_len = pheader[2]        self.orig_len = pheader[3]        class PCAPReader:    def __init__(self,fname):        f = open(fname,"rb")        buf = f.read(4+2+2+4+4+4+4)        header = struct.unpack("IHHiIII",buf)                self.magic = header[0]        self.version_major = header[1]        self.version_minor = header[2]        self.thiszone = header[3]        self.sigfigs = header[4]        self.snaplen = header[5]        self.network = header[6]        self.packets = []                buf = f.read(4+4+4+4)        while len(buf) > 0:            pkt = PCAPPacket(buf)            pkt.data = f.read(pkt.incl_len)            self.packets.append(pkt)            buf = f.read(4+4+4+4)class EthPacket:    def __init__(self,data):        headlen = 6+6+2        head = struct.unpack("!6s6sH",data[:headlen])        self.dst = head[0]        self.src = head[1]        self.type = head[2]        self.data = data[headlen:]class IPPacket:    def __init__(self,data):        headlen = 1+1+2+2+2+1+1+2+4+4        head = struct.unpack("!BBHHHBBH4s4s",data[:headlen])        self.version = head[0] >> 4        self.hlen = head[0] & 0xF        self.TOS = head[1]        self.len = head[2]        self.id = head[3]        self.flags_fragment = head[4]        self.TTL = head[5]        self.protocol = head[6]        self.checksum = head[7]        self.src = head[8]        self.dst = head[9]        optsend = self.hlen*4        self.opts = data[headlen:optsend]        self.data = data[optsend:self.len]        self.trailer = data[self.len:]class TCPPacket:    def __init__(self,data):        headlen = 2+2+4+4+1+1+2+2+2        head = struct.unpack("!HHIIBBHhH",data[:headlen])        self.srcport = head[0]        self.dstport = head[1]        self.seq = head[2]        self.ack = head[3]        self.hlen = head[4] >> 4        self.flags = head[5]        self.window = head[6]        self.checksum = head[7]        self.urgent = head[8]        optsend = self.hlen * 4        self.opts = data[headlen:optsend]        self.data = data[optsend:]        def filter_tcp_packets_only(packets):    out = []    for p in packets:        e = EthPacket(p.data)        if e.type != 0x800:            continue        e.data = IPPacket(e.data)        if e.data.protocol != 6:            continue        e.data.data = TCPPacket(e.data.data)        out.append(e)    return outdef make_constr(srcip,srcport,dstip,dstport):    return struct.pack("4sH4sH",srcip,srcport,dstip,dstport)def make_constr_from_packet(e,reverse = False):    if not reverse:        return make_constr(e.data.src,e.data.data.srcport,e.data.dst,e.data.data.dstport)    else:        return make_constr(e.data.dst,e.data.data.dstport,e.data.src,e.data.data.srcport)    def split_constr(str):    return struct.unpack("4sH4sH",str)def split_into_streams(pkts):    streams = {}    for p in pkts:        connstr1 = make_constr_from_packet(p)        connstr2 = make_constr_from_packet(p,True)        if connstr1 in streams:            connstr = connstr1        elif connstr2 in streams:            connstr = connstr2        else:            connstr = connstr1            streams[connstr] = []        streams[connstr].append(p)         return streams    def produce_data_stream(tcpstrm):    fstr = make_constr_from_packet(tcpstrm[0])    return [(make_constr_from_packet(x) == fstr,x.data.data.data) for x in tcpstrm if len(x.data.data.data) != 0]def find_wow_streams(streams):    wowstreams = []    realmlists = [(12,129,232,116),(80,239,180,116),(211,115,104,109)]    realmlists = ["".join([chr(x) for x in y]) for y in realmlists]        for k in streams.keys():        data = split_constr(k)        if data[1] != 3724 and data[3] != 3724:            continue        dstrm = produce_data_stream(streams[k])        if len(dstrm) < 5:            continue                if len(dstrm[0][1]) != 8:            continue                wowstreams.append(dstrm)    return wowstreamsdef split_streams(dstrm):    ins = []    insizes = []    outs = []    outsizes = []    in_inpkt = False    in_tsize = 0    out_inpkt = False    out_tsize = 0        for d in dstrm:        size = len(d[1])-2        if d[0]:            data = d[1][:6]            if not out_inpkt:                outs.append(data)                out_inpkt = True            out_tsize += size                        if size != 1458:                outsizes.append(out_tsize)                out_inpkt = False                out_tsize = 0                    else:            data = d[1][:4]            if not in_inpkt:                ins.append(data)                in_inpkt = True            in_tsize += size                                        if size != 1458:                insizes.append(in_tsize)                in_inpkt = False                in_tsize = 0    # Remove first unencrypted packet from each part    outs = outs[1:]    ins = ins[1:]    outsizes = outsizes[1:]    insizes = insizes[1:]                return [("".join(outs),outsizes),("".join(ins),insizes)]def remove_j_part(stream,j=0):    out = []    for i in range(len(stream)):        x = (ord(stream[i]) - j) % 256        j = ord(stream[i])        out.append(chr(x))    return "".join(out)def remove_js(ss):    return [(remove_j_part(ss[0][0]),ss[0][1]),(remove_j_part(ss[1][0]),ss[1][1])]def assume0s(data):    out = []    for i in range(40):        out.append([])    i = 0    for x in range(0,len(data),6):        i += 4        i %= 40        out[i].append(data[x+4])        i += 1        i %= 40        out[i].append(data[x+5])        i += 1        i %= 40            return outdef decrypt(buf,k,i=0):    out = []    for c in buf:        i %= len(k)        out.append(chr(ord(c)^ord(k[i])))        i += 1    return "".join(out)def make_straight_datastream(dstrm):    outx = []    inx = []    for pkt in dstrm:        if pkt[0]:            outx.append(pkt[1])        else:            inx.append(pkt[1])    return ("".join(outx),"".join(inx))def try_decrypt_data(dstrm,k,sz):    i = 0    j = 0    pkts = []    curr = 0    while curr < len(dstrm):        header = decrypt(remove_j_part(dstrm[curr:curr+sz],j),k,i)        i += sz        i %= 40        j = ord(dstrm[curr+sz-1])                size = struct.unpack("!H",header[:2])[0]        data = dstrm[curr+2:curr+2+size]        pkts.append(data)        curr += size + 2    return pktsif len(sys.argv) != 2:    print "Useage: %s <capfile> - capfile is the path to the cap file."%sys.argv[0]    sys.exit(1)    print "Reading cap file..."reader = PCAPReader(sys.argv[1])print "Filtering for TCP packets..."tcp = filter_tcp_packets_only(reader.packets)print "Splitting into streams..."strms = split_into_streams(tcp)print "Finding WoW streams..."wstrm = find_wow_streams(strms)print "%u streams found."%len(wstrm)for i in range(len(wstrm)):    print "Stream %u:"%i    print "Removing J part..."    sj = remove_js(split_streams(wstrm[i]))    print "Getting K from 0s..."    kx = assume0s(sj[0][0])    k = "".join([x[0] for x in kx])    print "Getting data for decryption..."    data = make_straight_datastream(wstrm[0][2:])[0]    print "Decrypting..."    dc = try_decrypt_data(data,k,6)    if sum([len(x) for x in dc]) + 2 * len(dc) == len(data):        print "Success!"        print [hex(ord(x)) for x in k]    else:        print "Failure :("print "Done :)"