def seedGen(self, iv, keyText): """Currently works with 40-bit and 104-bit""" ### BEGIN HERE # [b"\x15'\x00"] <<< iv -- This is str() in Python2x # <class 'bytes'> # b"\x15'\x00" # 1234567890 <<< keyText str() keyLen = len(keyText) ## 40-bit if keyLen == 5: key = binascii.unhexlify( hexstr(keyText, onlyhex=1).replace(' ', '')) elif keyLen == 10: key = binascii.unhexlify(keyText) ## 104-bit elif keyLen == 13: key = binascii.unhexlify( hexstr(keyText, onlyhex=1).replace(' ', '')) elif keyLen == 26: key = binascii.unhexlify(keyText) return iv + key
def fcsGen(self, ourObj, output='bytes'): """Return the FCS for a given set of bytes If you want to chop bytes for calculation, leverage self.byteRip(): fcsGen(self.byteRip(ourObj, chop = True, output = 'str') Works with native scapy object, or the str() style representation of bytes """ if type(ourObj) != str: sObj = binascii.unhexlify( hexstr(ourObj, onlyhex=1).replace(' ', '')) else: sObj = ourObj frame = crc32(sObj) & 0xffffffff fcs = hex(frame).replace('0x', '') while len(fcs) < 0: ## I forget why we do this fcs = '0' + fcs fcs = self.endSwap(fcs) if output == 'bytes': return fcs elif output == 'str': return binascii.unhexlify(fcs) else: return fcs
def etherleak(target, **kargs): """Exploit Etherleak flaw""" return srp(Ether() / ARP(pdst=target), prn=lambda s_r: conf.padding_layer in s_r[1] and hexstr(s_r[1][ conf.padding_layer].load), filter="arp", **kargs)
def decode(self): lines = self.handle.readlines() self.lines = [] self.decoded = [] L = len(lines) for x in range(L): line = self.clean(lines[x]) p = CLMMComm(line) logger.debug("Line: %s" % x) logger.debug(utils.hexstr(str(p.stick))) if len(self.lines) <= 1: self.lines.append(p) else: if len(self.lines) == 2 and self.lines[0].dir == p.dir: one = self.lines[0] two = self.lines[1] pair = CLMMPair(send=one, recv=two) #pair. #pair. pair.show() self.decoded.append(pair) self.lines = [p] else: self.lines.append(p) for p in self.lines: print "###", "XXX unusual line!", p.dir p.show()
def getStats(self, pkt): """Returns statistics for a given packet based upon the driver in use Currently this function supports the following: - Channel - Frequency - RSSI If you think that this function should added to, submit a PR via github """ notDecoded = hexstr(str(pkt.notdecoded), onlyhex=1).split(' ') try: chan = self.chanFreq.twoFour( int(notDecoded[self.offset] + notDecoded[self.offset - 1], 16)) except: chan = -256 try: freq = int(notDecoded[self.offset] + notDecoded[self.offset - 1], 16) except: freq = -256 try: rssi = -(256 - int(notDecoded[self.offset + 3], 16)) except: rssi = -256 return {'chan': chan, 'freq': freq, 'rssi': rssi}
def decode(self): lines = self.handle.readlines( ) self.lines = [ ] self.decoded = [ ] L = len(lines) for x in range(L): line = self.clean(lines[x]) p = CLMMComm(line) logger.debug("Line: %s" % x) logger.debug(utils.hexstr(str(p.stick))) if len(self.lines) <= 1: self.lines.append(p) else: if len(self.lines) == 2 and self.lines[0].dir == p.dir: one = self.lines[0] two = self.lines[1] pair = CLMMPair( send = one, recv = two) #pair. #pair. pair.show( ) self.decoded.append(pair) self.lines = [p] else: self.lines.append(p) for p in self.lines: print "###", "XXX unusual line!", p.dir p.show( )
def fcsGen(self, frame, start=None, end=None, mLength=0, output='bytes'): """Return the FCS for a given frame MODIFYING THIS PROBABLY BREAKS OTHER THINGS Where objFrame is the frame x = hexstr(objFrame, onlyhex = 1).replace(' ', '').lower() crc32(binascii.unhexlify(x.replace(' ', ''))) """ ## Original Python2x way of doing it -- when str(frame) worked nicely... # frame = str(frame) # frame = frame[start:end] # frame = crc32(frame) & 0xffffffff ## Python 2x or 3x way # frame = str(frame) ## As we're using the raw object to get to 2x str() format, this is no longer needed frame = frame[start:end] frame = hexstr(frame, onlyhex=1).replace(' ', '').lower() frame = crc32(binascii.unhexlify(frame.replace(' ', ''))) & 0xffffffff fcs = hex(frame).replace('0x', '') while len(fcs) < mLength: fcs = '0' + fcs fcs = self.endSwap(fcs) if output == 'bytes': return fcs elif output == 'str': return binascii.unhexlify(fcs) else: return fcs
def etherleak(target, **kargs): # type: (str, **Any) -> Tuple[SndRcvList, PacketList] """Exploit Etherleak flaw""" return srp( Ether() / ARP(pdst=target), prn=lambda s_r: conf.padding_layer in s_r[1] and hexstr(s_r[1][ conf.padding_layer].load), # noqa: E501 filter="arp", **kargs)
def seedGen(self, iv, keyText): """Currently works with 40-bit and 104-bit""" keyLen = len(keyText) ## 40-bit if keyLen == 5: key = binascii.unhexlify( hexstr(keyText, onlyhex=1).replace(' ', '')) elif keyLen == 10: key = binascii.unhexlify(keyText) ## 104-bit elif keyLen == 13: key = binascii.unhexlify( hexstr(keyText, onlyhex=1).replace(' ', '')) elif keyLen == 26: key = binascii.unhexlify(keyText) return iv + key
def compare_pktload(pkt1=None, pkt2=None, layer="L2"): l_idx = 0 if layer == "L2": l_idx = 0 elif layer == "L3": l_idx = 1 elif layer == "L4": l_idx = 2 try: load1 = hexstr(str(pkt1.pktgen.pkt.getlayer(l_idx))) load2 = hexstr(str(pkt2.pktgen.pkt.getlayer(l_idx))) except: # return pass when scapy failed to extract packet return True if load1 == load2: return True else: return False
def crcShave(self, sObj, shaveLeft=True, swVal=False): """Given a scapy object, iterate through all possible crc32 values Shave from left to right by default Calculate the CRC32 until there are no more bytes Returns True and stops if swVal is found Useful for throwing things against a wall and seeing what sticks If you know the scapy/wireshark version of the FCS you are hunting, use the swVal. As an example --> crcShave(sObj, swVal = '0x153e3ebd') If you want to shave the bytes from right to left, shaveLeft = False Don't forget to remove the FCS bytes on the end of a frame before using, if those bytes are the FCS you hunt. Example usage as a simple function: import binascii import packetEssentials as PE from scapy.all import * from textwrap import wrap p = RadioTap(binascii.unhexlify('00 00 38 00 2F 40 40 A0 20 08 00 A0 20 08 00 00 20 33 7B CD 04 00 00 00 10 0C 9E 09 C0 00 A7 00 00 00 00 00 00 00 00 00 61 32 7B CD 00 00 00 00 16 00 11 03 A7 00 A3 01 C4 00 32 05 E0 3E 44 08 00 00 BD 3E 3E 15'.replace(' ', ''))) swVal = hex(p[Dot11FCS].fcs) btVal = ' '.join(wrap(PE.pt.endSwap(swVal).upper()[2:], 2)) ## Useful to know for Endianness lbVal = PE.pt.byteRip(p, output = 'hex', qty = 4, order = 'last') choppedP = PE.pt.byteRip(p, chop = True, output = 'str', qty = 4, order = 'last') x = PE.pt.crcShave(choppedP, swVal = swVal, shaveLeft = False) print(x) """ if shaveLeft is True: dir = 'first' else: dir = 'last' for n in range(len(sObj)): ourByte = self.byteRip(sObj, order=dir, chop=True, output='str', qty=n) ourCrc = crc32(ourByte) ourHex = hex(0xffffffff & ourCrc) print('{0} --> {1} {2}'.format(n, ourHex, hexstr(ourByte, onlyhex=1))) ## Check sw if hex(crc32(self.byteRip(sObj, chop=True, output='str', qty=n))) == swVal: return True return False
def strip_pktload(pkt=None, layer="L2"): if layer == "L2": l_idx = 0 elif layer == "L3": l_idx = 1 elif layer == "L4": l_idx = 2 else: l_idx = 0 try: load = hexstr(str(pkt.pktgen.pkt.getlayer(l_idx)), onlyhex=1) except: # return pass when scapy failed to extract packet load = "" return load
def pktCallback(pkt): global PACKET_COUNT packet = {'layers': []} all_layers = list(getAllLayers(pkt)) print("\r[+] Collected {} packets | Current packet contains {:40}".format( PACKET_COUNT, ":".join(all_layers)), end='') packet['layers'] = all_layers # -------------------- IP -------------------- if (pkt.haslayer(IP)): ip = pkt.getlayer(IP) packet[ip.name] = {} packet[ip.name]['ttl'] = ip.ttl packet[ip.name]['protocol'] = ip.proto packet[ip.name]['src'] = ip.src packet[ip.name]['dst'] = ip.dst # -------------------- TCP -------------------- if (pkt.haslayer(TCP)): tcp = pkt.getlayer(TCP) packet[tcp.name] = {} packet[tcp.name]['sport'] = tcp.sport packet[tcp.name]['dport'] = tcp.dport packet[tcp.name]['seq'] = tcp.seq packet[tcp.name]['ack'] = tcp.ack packet[tcp.name]['flags'] = str(tcp.flags) # -------------------- UDP -------------------- if (pkt.haslayer(UDP)): udp = pkt.getlayer(UDP) packet[udp.name] = {} packet[udp.name]['sport'] = udp.sport packet[udp.name]['dport'] = udp.dport packet[udp.name]['len'] = udp.len # -------------------- RAW -------------------- if (pkt.haslayer(Raw)): raw = pkt.getlayer(Raw).load raw_ascii = hexstr(raw, onlyasc=True) print_interesting_things(raw_ascii) packet['raw'] = raw_ascii # Write packet to temporary external data structure TEMP_STORAGE[str(PACKET_COUNT)] = packet PACKET_COUNT += 1
def generate_seed(iv: bytes, pwd: bytes) -> bytes: """ Formats the Wi-Fi password and concatenates it to the IV. params: iv: WEP IV pwd: wi-fi password returns: bytes: packet key """ keyLen = len(pwd) if keyLen == 5: key = unhexlify(hexstr(pwd, onlyhex=1).replace(' ', '')) elif keyLen == 10: key = unhexlify(pwd) return iv + key
ccmpCrypto = Ccmp() hs = Handshake() ## PCAP specific data ssid = 'wifi4' passphrase = 'P@$$w0rd1!P@$$w0rd1!' pcap = 'demo.pcap' pktStream = rdpcap(pcap) anoPkt = pktStream[0] snoPkt = pktStream[1] tgtPkt = pktStream[4] ap_mac = binascii.a2b_hex(re.sub(':', '', snoPkt[Dot11].addr1)) s_mac = binascii.a2b_hex(re.sub(':', '', anoPkt[Dot11].addr1)) anonce = binascii.a2b_hex( re.sub(' ', '', hexstr(anoPkt.load, onlyhex=1)[39:134])) snonce = binascii.a2b_hex( re.sub(' ', '', hexstr(snoPkt.load, onlyhex=1)[39:134])) pke = "Pairwise key expansion" pmk = PBKDF2(passphrase, ssid, 4096).read(32) objPMK = pmk.encode('hex') key_data = min(ap_mac, s_mac) + max(ap_mac, s_mac) + min( anonce, snonce) + max(anonce, snonce) ptk = hs.xPRF512(pmk, pke, key_data) tk = ptk[32:48] if os.path.isfile('example.pcap'): os.remove('example.pcap') if os.path.isfile('inbound.pcap'): os.remove('inbound.pcap')
def etherleak(target, **kargs): """Exploit Etherleak flaw""" return srp(Ether() / ARP(pdst=target), prn=lambda s_r: conf.padding_layer in s_r[1] and hexstr(s_r[1][conf.padding_layer].load), # noqa: E501 filter="arp", **kargs)
def eapolGrab(self, pkt): """Insert an EAPOL pkt into the DB for retrieval later""" eNum = self.pt.nonceDict.get(self.pt.byteRip(pkt[Raw], qty = 3)[6:]) if eNum[1] == '1' or eNum[1] == '2' or eNum[1] == '3': nonce = hexstr(str(pkt.load), onlyhex = 1)[39:134] hexPkt = hexstr(str(pkt), onlyhex = 1) ### Discard EAPOL 4 of 4 if nonce != '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00': vMAC = '' ## Store EAPOLs if requested if self.pcap is True: self.eapolTrack.write(pkt) ## FROM-DS if eNum == 'a1' or eNum == 'a3' or eNum == 't1' or eNum == 't3': vMAC = pkt[Dot11].addr1 bMAC = pkt[Dot11].addr2 self.eapolStore(hexPkt, vMAC, bMAC, nonce, eNum) ## TO-DS if eNum == 'a2' or eNum == 't2': vMAC = pkt[Dot11].addr2 bMAC = pkt[Dot11].addr1 encType = self.pt.byteRip(pkt[Raw], qty = 3)[3:] if encType == '01 0a': encType = 'ccmp' elif encType == '01 09': encType = 'tkip' else: encType = None print '***** Unknown encryption type *****' print '***** Contact ICSec on github for assistance *****' sys.exit(1) self.encDict.update({vMAC: encType}) self.eapolStore(hexPkt, vMAC, bMAC, nonce, eNum) ## DEBUG #print 'stored %s -- %s' % (eNum, nonce) ## Begin catchDict checks ## Need to deal with clearing out existing entries ## Currently, this isn't done, so we might have good anonce, but bad snonce ## Deal with vMAC not in catchDict if vMAC not in self.catchDict: if eNum[1] == '1': anonce = True snonce = False elif eNum[1] == '2': anonce = False snonce = True elif eNum[1] == '3': anonce = True snonce = False self.catchDict.update({vMAC: (anonce, snonce)}) print 'EAPOL STARTED: %s' % vMAC ## Deal with vMAC in catchDict else: ## Grab current anonce/snonce status storedAnonce, storedSnonce = self.catchDict.get(vMAC) ## Decide how to update if eNum[1] == '1': anonce = True snonce = False elif eNum[1] == '2': anonce = False snonce = True elif eNum[1] == '3': anonce = True snonce = False ## Deal with anonce if anonce: self.catchDict.update({vMAC: (True, storedSnonce)}) if snonce: self.catchDict.update({vMAC: (storedAnonce, True)}) ## DEBUG #print 'Our catchDict:\n%s\n' % self.catchDict ## Check for anonce and snonce for the given vMAC if self.catchDict.get(vMAC)[0] is True and self.catchDict.get(vMAC)[1] is True: ## Grab anonce, vbin, bbin and bssid q = self.db.execute('SELECT `vmac`, `bmac`, `nonce` FROM `shakes` WHERE vMAC = "{0}" AND `e_num` LIKE "%1" or `e_num` LIKE "%3" LIMIT 1;'.format(vMAC)) r = q.fetchone() ## Grab snonce q2 = self.db.execute('SELECT `nonce` FROM `shakes` WHERE vMAC = "{0}" AND `e_num` LIKE "%2";'.format(vMAC)) r2 = q.fetchone() ## Gather tgt specific data authMac = binascii.a2b_hex(r[0].replace(':', '')) supMac = binascii.a2b_hex(r[1].replace(':', '')) aNonce = binascii.a2b_hex(r[2].replace(' ', '')) sNonce = binascii.a2b_hex(r2[0].replace(' ', '')) key_data = min(authMac, supMac) + max(authMac, supMac) + min(aNonce, sNonce) + max(aNonce, sNonce) ### Pull the encryption type and generate PTK encType = self.encDict.get(vMAC) ptk = self.xPRF512(self.pmk, self.pke, key_data)[32:48] ### Once RC4 is dealt with, change back to simple dict ## CCMP cipher generation if encType == 'ccmp': aesCipher = AES.new(str(ptk), AES.MODE_ECB) self.tgtInfo.update({vMAC: (ptk, aesCipher)}) ## TKIP ### Until we deal with RC4 handling this at the lib level ### Must regen new just like with WEP so that it doesn't cycle through else: self.tgtInfo.update({vMAC: (ptk, None)}) ## Add vMAC to list of available targets self.availTgts.add(vMAC) ## Let user know success if vMAC not in self.alert: print 'EAPOL COMPLETE: %s\n' % vMAC self.alert.add(vMAC)
def eapolGrab(self, pkt): """Insert an EAPOL pkt into the DB for retrieval later A bug was found at BSides Charleston, thus the try statement. As no logs exist on this level, we are now hunting this bug. If you receive the warning, please pass along to ICSec. Thanks! """ try: eNum = self.pt.nonceDict.get(self.pt.byteRip(pkt[Raw], qty=3)[6:]) ## Deal with bug if seen again ##File "/usr/local/lib/python2.7/dist-packages/pyDot11/lib/handshake.py", line 49, in eapolGrab ##eNum = self.pt.nonceDict.get(self.pt.byteRip(pkt[Raw], qty = 3)[6:]) ##File "/usr/lib/python2.7/dist-packages/scapy/packet.py", line 817, in __getitem__ ##raise IndexError("Layer [%s] not found" % lname) ##IndexError: Layer [Raw] not found except: wrpcap('IndexError.pcap', pkt) print('\n***** Unknown encryption type *****') print('***** Contact ICSec on github for assistance *****') print('***** Bad frame saved to IndexError.pcap *****') return ### Lazy workaround for eNum == None try: if eNum[1] == '1' or eNum[1] == '2' or eNum[1] == '3': nonce = hexstr(str(pkt.load), onlyhex=1)[39:134] hexPkt = hexstr(str(pkt), onlyhex=1) ### Discard EAPOL 4 of 4 if nonce != '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00': vMAC = '' ## Store EAPOLs if requested if self.pcap is True: self.eapolTrack.write(pkt) ## FROM-DS if eNum == 'a1' or eNum == 'a3' or eNum == 't1' or eNum == 't3': vMAC = pkt[Dot11].addr1 bMAC = pkt[Dot11].addr2 self.eapolStore(hexPkt, vMAC, bMAC, nonce, eNum) ## TO-DS if eNum == 'a2' or eNum == 't2': vMAC = pkt[Dot11].addr2 bMAC = pkt[Dot11].addr1 encType = self.pt.byteRip(pkt[Raw], qty=3)[3:] if encType == '01 0a': encType = 'ccmp' elif encType == '01 09': encType = 'tkip' else: wrpcap('encType.pcap', pkt) print( '\n***** Unknown encryption type *****' ) print( '***** Contact ICSec on github for assistance *****' ) print( '***** Bad frame saved to encType.pcap *****' ) return self.encDict.update({vMAC: encType}) self.eapolStore(hexPkt, vMAC, bMAC, nonce, eNum) ## DEBUG # print ('stored {0} -- {1}'.format(str(eNum), str(nonce))) ## Begin catchDict checks ## Need to deal with clearing out existing entries ## Currently, this isn't done, so we might have good anonce, but bad snonce ## Deal with vMAC not in catchDict if vMAC not in self.catchDict: if eNum[1] == '1': anonce = True snonce = False elif eNum[1] == '2': anonce = False snonce = True elif eNum[1] == '3': anonce = True snonce = False self.catchDict.update({vMAC: (anonce, snonce)}) print('EAPOL STARTED: {0}'.format(str(vMAC))) ## Deal with vMAC in catchDict else: ## Grab current anonce/snonce status storedAnonce, storedSnonce = self.catchDict.get(vMAC) ## Decide how to update if eNum[1] == '1': anonce = True snonce = False elif eNum[1] == '2': anonce = False snonce = True elif eNum[1] == '3': anonce = True snonce = False ## Deal with anonce if anonce: self.catchDict.update({vMAC: (True, storedSnonce)}) if snonce: self.catchDict.update({vMAC: (storedAnonce, True)}) ## DEBUG # print ('Our catchDict:\n{0}\n'.format(str(self.catchDict))) ## Check for anonce and snonce for the given vMAC if self.catchDict.get(vMAC)[ 0] is True and self.catchDict.get(vMAC)[1] is True: ## Grab anonce, vbin, bbin and bssid q = self.db.execute( 'SELECT `vmac`, `bmac`, `nonce` FROM `shakes` WHERE vMAC = "{0}" AND `e_num` LIKE "%1" or `e_num` LIKE "%3" LIMIT 1;' .format(vMAC)) r = q.fetchone() ## Grab snonce q2 = self.db.execute( 'SELECT `nonce` FROM `shakes` WHERE vMAC = "{0}" AND `e_num` LIKE "%2";' .format(vMAC)) r2 = q.fetchone() ## Gather tgt specific data authMac = binascii.a2b_hex(r[0].replace(':', '')) supMac = binascii.a2b_hex(r[1].replace(':', '')) aNonce = binascii.a2b_hex(r[2].replace(' ', '')) sNonce = binascii.a2b_hex(r2[0].replace(' ', '')) key_data = min(authMac, supMac) + max( authMac, supMac) + min(aNonce, sNonce) + max( aNonce, sNonce) ### Pull the encryption type and generate PTK encType = self.encDict.get(vMAC) ptk = self.xPRF512(self.pmk, self.pke, key_data)[32:48] ### Once RC4 is dealt with, change back to simple dict ## CCMP cipher generation if encType == 'ccmp': aesCipher = AES.new(str(ptk), AES.MODE_ECB) self.tgtInfo.update({vMAC: (ptk, aesCipher)}) ## TKIP ### Until we deal with RC4 handling this at the lib level ### Must regen new just like with WEP so that it doesn't cycle through else: self.tgtInfo.update({vMAC: (ptk, None)}) ## Add vMAC to list of available targets self.availTgts.add(vMAC) ## Let user know success if vMAC not in self.alert: print('EAPOL COMPLETE: %s\n'.format(str(vMAC))) self.alert.add(vMAC) except: print('eNum for EAPOL is NULL\n')
def byteRip(self, stream, chop=False, compress=False, order='first', output='hex', qty=1): """Take a scapy hexstr(str(pkt), onlyhex = 1) and grab based on what you want chop is the concept of removing the qty based upon the order compress is the concept of removing unwanted spaces order is concept of give me first <qty> bytes or gives me last <qty> bytes output deals with how the user wishes the stream to be returned qty is how many nibbles to deal with QTY IS DOUBLE THE NUMBER OF BYTES THINK OF QTY AS A NIBBLE 2 NIBBLES FOR EVERY BYTE Important to note that moving to a pure string versus a list, will probably help with memory consumption Eventually, need to add a kwarg that allows us to specify, which bytes we want, i.e. first and last based on order """ def pktFlow(pkt, output): if output == 'hex': return pkt if output == 'str': return binascii.unhexlify(str(pkt).replace(' ', '')) stream = hexstr(str(stream), onlyhex=1) streamList = stream.split(' ') streamLen = len(streamList) ## Deal with first bytes if order == 'first': ## Deal with not chop and not compress if not chop and not compress: return pktFlow(' '.join(streamList[0:qty]), output) ## Deal with chop and not compress if chop and not compress: return pktFlow(' '.join(streamList[qty:]), output) ## Deal with compress and not chop if compress and not chop: return pktFlow(' '.join(streamList[0:qty]).replace(' ', ''), output) ## Deal with chop and compress if chop and compress: return pktFlow(' '.join(streamList[qty:]).replace(' ', ''), output) ## Deal with last bytes if order == 'last': ## Deal with not chop and not compress if not chop and not compress: return pktFlow(' '.join(streamList[streamLen - qty:]), output) ## Deal with chop and not compress if chop and not compress: return pktFlow(' '.join(streamList[:-qty]), output) ## Deal with compress and not chop if compress and not chop: return pktFlow( ' '.join(streamList[streamLen - qty:]).replace(' ', ''), output) ## Deal with chop and compress if chop and compress: return pktFlow(' '.join(streamList[:-qty]).replace(' ', ''), output)
def byteRip(self, stream, chop=False, compress=False, order='first', output='hex', qty=1): """Take a packet and grab a grouping of bytes, based on what you want byteRip can accept a scapy object or a scapy object in str() format Allowing byteRip to accept str() format allows for byte insertion Example of scapy object definition: - stream = Dot11WEP() Example of scapy object in str() format - stream = str(Dot11WEP()) chop is the concept of removing the qty based upon the order compress is the concept of removing unwanted spaces order is concept of give me first <qty> bytes or gives me last <qty> bytes output deals with how the user wishes the stream to be returned qty is how many bytes to remove """ def pktFlow(pkt, output): if output == 'hex': return pkt.lower() if output == 'str': return binascii.unhexlify(str(pkt).replace(' ', '')).lower() ## Python 2x and 3x seem to align on this method now # stream = hexstr(str(stream), onlyhex = 1) stream = hexstr(stream, onlyhex=1) streamList = stream.split(' ') streamLen = len(streamList) ## Deal with first bytes if order == 'first': ## Deal with not chop and not compress if not chop and not compress: return pktFlow(' '.join(streamList[0:qty]), output) ## Deal with chop and not compress if chop and not compress: return pktFlow(' '.join(streamList[qty:]), output) ## Deal with compress and not chop if compress and not chop: return pktFlow(' '.join(streamList[0:qty]).replace(' ', ''), output) ## Deal with chop and compress if chop and compress: return pktFlow(' '.join(streamList[qty:]).replace(' ', ''), output) ## Deal with last bytes if order == 'last': ## Deal with not chop and not compress if not chop and not compress: return pktFlow(' '.join(streamList[streamLen - qty:]), output) ## Deal with chop and not compress if chop and not compress: return pktFlow(' '.join(streamList[:-qty]), output) ## Deal with compress and not chop if compress and not chop: return pktFlow( ' '.join(streamList[streamLen - qty:]).replace(' ', ''), output) ## Deal with chop and compress if chop and compress: return pktFlow(' '.join(streamList[:-qty]).replace(' ', ''), output)