1# Copyright (c) 2003-2016 CORE Security Technologies 2# 3# This software is provided under under a slightly modified version 4# of the Apache Software License. See the accompanying LICENSE file 5# for more information. 6# 7 8from impacket import ImpactPacket, ImpactDecoder, structure 9 10O_ETH = 0 11O_IP = 1 12O_ARP = 1 13O_UDP = 2 14O_TCP = 2 15O_ICMP = 2 16O_UDP_DATA = 3 17O_ICMP_DATA = 3 18 19MAGIC = '"\xD4\xC3\xB2\xA1' 20 21class PCapFileHeader(structure.Structure): 22 structure = ( 23 ('magic', MAGIC), 24 ('versionMajor', '<H=2'), 25 ('versionMinor', '<H=4'), 26 ('GMT2localCorrection', '<l=0'), 27 ('timeAccuracy', '<L=0'), 28 ('maxLength', '<L=0xffff'), 29 ('linkType', '<L=1'), 30 ('packets','*:=[]'), 31 ) 32 33class PCapFilePacket(structure.Structure): 34 structure = ( 35 ('tsec', '<L=0'), 36 ('tmsec', '<L=0'), 37 ('savedLength', '<L-data'), 38 ('realLength', '<L-data'), 39 ('data',':'), 40 ) 41 42 def __init__(self, *args, **kargs): 43 structure.Structure.__init__(self, *args, **kargs) 44 self['data'] = '' 45 46class PcapFile: 47 def __init__(self, fileName = None, mode = 'rb'): 48 if not fileName is None: 49 self.file = open(fileName, mode) 50 self.hdr = None 51 self.wroteHeader = False 52 53 def reset(self): 54 self.hdr = None 55 self.file.seek(0) 56 57 def close(self): 58 self.file.close() 59 60 def fileno(self): 61 return self.file.fileno() 62 63 def setFile(self, file): 64 self.file = file 65 66 def setSnapLen(self, snapLen): 67 self.createHeaderOnce() 68 self.hdr['maxLength'] = snapLen 69 70 def getSnapLen(self): 71 self.readHeaderOnce() 72 return self.hdr['maxLength'] 73 74 def setLinkType(self, linkType): 75 self.createHeaderOnce() 76 self.hdr['linkType'] = linkType 77 78 def getLinkType(self): 79 self.readHeaderOnce() 80 return self.hdr['linkType'] 81 82 def readHeaderOnce(self): 83 if self.hdr is None: 84 self.hdr = PCapFileHeader.fromFile(self.file) 85 86 def createHeaderOnce(self): 87 if self.hdr is None: 88 self.hdr = PCapFileHeader() 89 90 def writeHeaderOnce(self): 91 if not self.wroteHeader: 92 self.wroteHeader = True 93 self.file.seek(0) 94 self.createHeaderOnce() 95 self.file.write(str(self.hdr)) 96 97 def read(self): 98 self.readHeaderOnce() 99 try: 100 pkt = PCapFilePacket.fromFile(self.file) 101 pkt['data'] = self.file.read(pkt['savedLength']) 102 return pkt 103 except: 104 return None 105 106 def write(self, pkt): 107 self.writeHeaderOnce() 108 self.file.write(str(pkt)) 109 110 def packets(self): 111 self.reset() 112 while 1: 113 answer = self.read() 114 if answer is None: break 115 yield answer 116 117def process(onion): 118 # for dhcp we only want UDP packets 119 if len(onion) <= O_UDP: return 120 if onion[O_UDP].protocol != ImpactPacket.UDP.protocol: 121 return 122 123 # we only want UDP port 67 124 if ((onion[O_UDP].get_uh_dport() != 67) and 125 (onion[O_UDP].get_uh_sport() != 67)): return 126 127 # we've got a dhcp packet 128 129def main(): 130 import sys 131 132 f_in = open(sys.argv[1],'rb') 133 try: 134 f_out = open(sys.argv[2],'wb') 135 f_out.write(str(PCapFileHeader())) 136 except: 137 f_out = None 138 139 hdr = PCapFileHeader() 140 hdr.fromString(f_in.read(len(hdr))) 141 142 #hdr.dump() 143 144 decoder = ImpactDecoder.EthDecoder() 145 while 1: 146 pkt = PCapFilePacket() 147 try: 148 pkt.fromString(f_in.read(len(pkt))) 149 except: 150 break 151 pkt['data'] = f_in.read(pkt['savedLength']) 152 hdr['packets'].append(pkt) 153 p = pkt['data'] 154 try: in_onion = [decoder.decode(p[1])] 155 except: in_onion = [decoder.decode(p[0])] 156 try: 157 while 1: in_onion.append(in_onion[-1].child()) 158 except: 159 pass 160 161 process(in_onion) 162 pkt.dump() 163 #print "%r" % str(pkt) 164 165 if f_out: 166 #print eth 167 168 pkt_out = PCapFilePacket() 169 pkt_out['data'] = str(eth.get_packet()) 170 171 #pkt_out.dump() 172 173 f_out.write(str(pkt_out)) 174 175if __name__ == '__main__': 176 main() 177 178