def test_malformed(self): from credslayer.core import manager pcap = FileCapture("samples/smb-crash.pcap") self.assertRaises(manager.MalformedPacketException, manager._process_packet, Session(pcap[8]), pcap[8], False) pcap.close()
def __init__(self, filename, summary=True, keep_packets=False): self.result = [] self.cap = FileCapture(filename, only_summaries=summary, keep_packets=keep_packets) if filename in packet2num: self.length = packet2num[filename] else: self.length = self.packet_length()
def test_credit_cards_false_positives(self): pcap = FileCapture("samples/imap.pcap") credit_cards_found = set() for packet in pcap: strings = utils.extract_strings_splitted_on_end_of_line_from( packet) credit_cards_found |= extract.extract_credit_cards(strings) pcap.close() print(credit_cards_found) self.assertTrue(len(credit_cards_found) == 0)
def test_extract_emails(self): pcap = FileCapture("samples/imap.pcap") emails_found = set() for packet in pcap: strings = utils.extract_strings_splitted_on_end_of_line_from( packet) emails_found |= extract.extract_emails(strings) pcap.close() print(emails_found) self.assertTrue(len(emails_found) >= 46) self.assertTrue("*****@*****.**" in emails_found) self.assertTrue("*****@*****.**" in emails_found) self.assertTrue("*****@*****.**" in emails_found) # TODO: make this one work... The thing is, the email address is splitted in 2 different packets... Give up ? # self.assertTrue("*****@*****.**" in emails_found) pcap = FileCapture("samples/ldap-simpleauth.pcap") emails_found.clear() for packet in pcap: strings = utils.extract_strings_splitted_on_end_of_line_from( packet) emails_found |= extract.extract_emails(strings) pcap.close() print(emails_found) self.assertTrue(len(emails_found) == 1) self.assertTrue("*****@*****.**" in emails_found)
def __init__(self, pcapfile, userfilter=None): """Initialization method of the class. Parameters ---------- pcapfile : str Path to a previously captured pcap. """ self._tshark_pkts = FileCapture( input_file=pcapfile, keep_packets=False, use_json=True, include_raw=True, display_filter=userfilter)
def listen(self, sniff_sni=False, sniff_cn=False, sniff_san=False, packet_count: int = None, debug: bool = False) -> Iterator[TLSHandshakeMessage]: # Workaround for pyshark, because SIGINT handling does not work properly original_sigint_handler = signal.getsignal(signal.SIGINT) if original_sigint_handler == signal.default_int_handler: signal.signal(signal.SIGINT, lambda *args: os._exit(0)) try: # Currently only IPv4 is supported for BPF tcp data access. Manpage says: "this will be fixed in the future" for IPv6. # Until then, only the 'tcp' filter is applied # bpf_filter = 'tcp[((tcp[12:1] & 0xf0) >> 2):1] = 22' bpf_filter = 'tcp' display_filter = f'(ssl.record.content_type == 22 && ssl.handshake.type)' if self.bpf_filter != '': bpf_filter += f' && {self.bpf_filter.strip()}' if self.display_filter != '': display_filter += f' && {self.display_filter.strip()}' if packet_count is not None and packet_count <= 0: packet_count = None if self.input_file is not None: packet_iterator = FileCapture( input_file=self.input_file, display_filter=display_filter, keep_packets=False, debug=debug ) elif not sys.stdin.isatty(): packet_iterator = PipeCapture( pipe=sys.stdin.buffer, display_filter=display_filter, debug=debug ) else: capture = LiveCapture( interface=self.interface, bpf_filter=bpf_filter, display_filter=display_filter, debug=debug ) packet_iterator = capture.sniff_continuously() if not (sniff_sni or sniff_cn or sniff_san): sniff_sni = True sniff_cn = True sniff_san = True for packet in packet_iterator: handshake_message = self._get_handshake_message( packet, sniff_sni=sniff_sni, sniff_cn=sniff_cn, sniff_san=sniff_san ) if handshake_message is not None: yield handshake_message if packet_count is not None: packet_count -= 1 if packet_count <= 0: break except Exception: pass # Restore original SIGINT handler signal.signal(signal.SIGINT, original_sigint_handler) return
def process_training_file(app_name: str, file_path: str) -> List[Connection]: """ Returns list of connections extracted from a training pcap file. Args: app_name: training app file_path: path to the training pcap file Returns: list of connections (TLS client hello + TLS server hello) """ client_hellos = [] server_hellos = [] # Process all the packets from the file for packet in FileCapture(file_path): wpacket = WrappedPacket(packet) if wpacket.is_tls_client_hello() and wpacket.is_server_name_ok( app_name): tls_packet = TlsPacket(wpacket, app_name=app_name) client_hellos.append(tls_packet) if wpacket.is_tls_server_hello(): server_hellos.append(TlsPacket(wpacket, app_name=app_name)) return extract_connections(client_hellos, server_hellos)
def __init__(self, path): """Construct packet class.""" self._log = log() import parsers.packet.models as models self._log.info("Reading {} packet file.".format(path)) try: self.pcapfile = FileCapture(path, display_filter='coap or xmpp or mqtt') except: self.log.error("Unable to read {} packet file".format(path), exc_info=True) self.packets = [] for packet in self.pcapfile: time = int(float(packet.frame_info.time_epoch)) src_macaddr = packet.eth.src dst_macaddr = packet.eth.dst protocol = packet.highest_layer src_ipaddr = packet.ip.src dst_ipaddr = packet.ip.dst if protocol == "COAP": src_port = packet.udp.srcport dst_port = packet.udp.dstport message = self.parse_coap(packet.coap) elif protocol == "XMPP": src_port = packet.tcp.srcport dst_port = packet.tcp.dstport message = self.parse_xmpp(packet.xmpp) elif protocol == "MQTT": src_port = packet.tcp.srcport dst_port = packet.tcp.dstport message = self.parse_mqtt(packet.mqtt) self.packets.append(models.Packet( time, src_macaddr, dst_macaddr, src_ipaddr, src_port, dst_ipaddr, dst_port, protocol, message )) self.pcapfile.close()
def __init__(self): Thread.__init__(self) self._messages: List[Message] = [] self._is_split: bool = False self._current_message_id: int = -1 self._current_message_instance_id: int = -1 self._current_message_size: int = -1 self._current_message_data: ByteArray = ByteArray(bytes()) # self._capture: LiveCapture = LiveCapture('enp0s31f6', bpf_filter='tcp port 5555') self._capture: FileCapture = FileCapture('assets/port-5555.pcap')
def test_extract_credit_cards(self): pcap = FileCapture("samples/smtp-creditcards.pcap") credit_cards_found = set() for packet in pcap: strings = utils.extract_strings_splitted_on_end_of_line_from( packet) credit_cards_found |= extract.extract_credit_cards(strings) pcap.close() print(credit_cards_found) self.assertTrue( CreditCard("Visa", "4111-4000-4321-3210") in credit_cards_found) self.assertTrue( CreditCard("Visa", "4321 4444 3214 3212") in credit_cards_found) self.assertTrue( CreditCard("Mastercard", "5555 5555 5555 5555") in credit_cards_found)
def __init__(self, pcapfile, scapy_pkts=None, tshark_pkts=None): """Initialization method of the class. Parameters ---------- pcapfile : str Path to a previously captured pcap. scapy_pkts : :obj:`PacketList` List of packets generated by Scapy. tshark_pkts : :obj:`FileCapture` List of packets generated by Pyshark. """ if scapy_pkts: self._scapy_pkts = scapy_pkts else: self._scapy_pkts = rdpcap(pcapfile) if tshark_pkts: self._tshark_pkts = tshark_pkts else: self._tshark_pkts = FileCapture(pcapfile) self._i = -1
def file_capture(pcap_files, bpf, out_file, count=0, dump=False): """ :param dump: Dump to stdout if true, does not send packets :type dump: bool :type count: int :type out_file: str :type bpf: str :type pcap_files: List[str] """ # try: # es = None # if node is not None: # es = Elasticsearch(node) logging.debug('Loading packet capture file(s)') for pcap_file in pcap_files: logging.debug("Pcap file is: %s", pcap_file) capture = FileCapture(pcap_file, bpf, out_file) if not dump: decode_packets(capture, count) else: dump_packets(capture, count)
def get_connections(file_path: str) -> List[Connection]: """ Returns list of connections extracted from a pcap file. Args: file_path: path to the pcap file Returns: list of connections (TLS client hello + TLS server hello) """ client_hellos = [] server_hellos = [] # Process all the packets from the file for packet in FileCapture(file_path): wpacket = WrappedPacket(packet) if wpacket.is_tls_client_hello(): client_hellos.append(TlsPacket(wpacket)) elif wpacket.is_tls_server_hello(): server_hellos.append(TlsPacket(wpacket)) return extract_connections(client_hellos, server_hellos)
def test_sessions_extract(self): from credslayer.core.session import SessionsManager sessions = SessionsManager() pcap = FileCapture("samples/ftp.pcap") for packet in pcap: sessions.get_session_of(packet) pcap.close() print(sessions) self.assertTrue(len(sessions) == 1) self.assertTrue( "TCP 10.10.30.26:43958 <-> 129.21.171.72:21" in sessions) sessions.clear() pcap = FileCapture("samples/imap.pcap") for packet in pcap: if "tcp" in packet: sessions.get_session_of(packet) pcap.close() print(sessions) self.assertTrue(len(sessions) == 3) self.assertTrue( "TCP 131.151.32.21:4167 <-> 131.151.37.122:143" in sessions) self.assertTrue( "TCP 131.151.32.91:3614 <-> 131.151.37.122:1065" in sessions) self.assertTrue( "TCP 131.151.32.91:1065 <-> 131.151.37.117:1065" in sessions) sessions.clear() pcap = FileCapture("samples/snmp-v1.pcap") for packet in pcap: if "udp" in packet: sessions.get_session_of(packet) pcap.close() print(sessions) self.assertTrue(len(sessions) == 3) self.assertTrue("UDP 172.31.19.54 <-> 172.31.19.73" in sessions) self.assertTrue("UDP 172.31.19.73 <-> 224.0.1.35" in sessions) self.assertTrue("UDP 172.31.19.255 <-> 172.31.19.73" in sessions)
def readPackets(filepath) -> PacketList: fileCapture = FileCapture(str(filepath)) packets = [p for p in fileCapture] return packets
def read_pcap_file(pcap_file): packs = filter(None, map(make_obj, FileCapture(pcap_file))) return packs
class Packet(object): """Packet filter by IoT related packet.""" def __init__(self, path): """Construct packet class.""" self._log = log() import parsers.packet.models as models self._log.info("Reading {} packet file.".format(path)) try: self.pcapfile = FileCapture(path, display_filter='coap or xmpp or mqtt') except: self.log.error("Unable to read {} packet file".format(path), exc_info=True) self.packets = [] for packet in self.pcapfile: time = int(float(packet.frame_info.time_epoch)) src_macaddr = packet.eth.src dst_macaddr = packet.eth.dst protocol = packet.highest_layer src_ipaddr = packet.ip.src dst_ipaddr = packet.ip.dst if protocol == "COAP": src_port = packet.udp.srcport dst_port = packet.udp.dstport message = self.parse_coap(packet.coap) elif protocol == "XMPP": src_port = packet.tcp.srcport dst_port = packet.tcp.dstport message = self.parse_xmpp(packet.xmpp) elif protocol == "MQTT": src_port = packet.tcp.srcport dst_port = packet.tcp.dstport message = self.parse_mqtt(packet.mqtt) self.packets.append(models.Packet( time, src_macaddr, dst_macaddr, src_ipaddr, src_port, dst_ipaddr, dst_port, protocol, message )) self.pcapfile.close() def get_method(self, code): """Get method from coap code.""" if code == "0.01": return "GET" elif code == "0.02": return "POST" elif code == "0.03": return "PUT" elif code == "0.04": return "DELETE" else: return "Unassigned" def packet_type(self, _type): """Get type of coap packet.""" if _type == 0x00: return "Confirmable" elif _type == 0x01: return "Non-confirmable" elif _type == 0x02: return "Acknowledgement" elif _type == 0x03: return "Reset" def get_msgtype(self, _type): """Get message type of MQTT.""" if _type == 0x01: return "CONNECT" elif _type == 0x02: return "CONNACK" elif _type == 0x03: return "PUBLISH" elif _type == 0x04: return "PUBACK" elif _type == 0x05: return "PUBREC" elif _type == 0x06: return "PUBREL" elif _type == 0x07: return "PUBCOMP" elif _type == 0x08: return "SUBSCRIBE" elif _type == 0x09: return "SUBACK" elif _type == 0x0A: return "UNSUBSCRIBE" elif _type == 0x0B: return "UNSUBACK" elif _type == 0x0C: return "PINGREQ" elif _type == 0x0D: return "PINGRESP" elif _type == 0x0E: return "DISCONNECT" else: return "Reserved" def get_qostype(self, qos): """Get QoS type in MQTT.""" if qos == 0x00: return "Fire and Forget" elif qos == 0x01: return "Acknowledged delivery" elif qos == 0x02: return "Assured delivery" else: return "Reserved" def parse_coap(self, packet): """Parse CoAP packet.""" message = { 'message_id': packet.mid, 'code': self.get_method(packet.code), 'type': self.packet_type(int(packet.type)), } if message['type'] == "Confirmable": try: message['token'] = packet.token except: pass try: message['payload'] = { 'description': packet.payload_desc, 'data': packet.payload.binary_value.decode(), } except: pass return message def parse_xmpp(self, packet): """Parse XMPP Protocol.""" return { 'xml_tag': packet.xml_tag } def parse_mqtt(self, packet): """Parse MQTT Protocol.""" message = { 'qos': self.get_qostype(int(packet.qos)), 'retain': bool(packet.retain), 'message_type': self.get_msgtype(int(packet.msgtype)), } try: message['topic'] = packet.topic message['message'] = packet.msg except: pass try: message['client_id'] = packet.clientid except: pass return message def __del__(self): """Destruct packet class.""" self._log.info("Finishing packet parser...") del self
def get_raw_cap(path_to_cap: str): return FileCapture(input_file=path_to_cap, display_filter='icmp', use_json=True, include_raw=True)
from pyshark import FileCapture from binascii import unhexlify # prevent error output import os import sys f = open(os.devnull, 'w') sys.stderr = f # What is the IP address of the device that is pinging other devices? cap = FileCapture('Basics.pcap', display_filter='icmp.type == 8') print('IP of device pinging other devices:', cap[0]['ip'].addr) # According to the ping traffic, what is the IP address of the host that is not up? cap = FileCapture('Basics.pcap', display_filter='icmp.type == 8 && icmp.resp_not_found') print('IP of device pinging other devices:', cap[0]['ip'].dst) # What is the IP address of the device at 00:50:56:F9:77:70 given by ARP cap = FileCapture('Basics.pcap', display_filter='arp.src.hw_mac == 00:50:56:f9:77:70') print('ip address of device at 00:50:56:F9:77:70:', cap[0]['arp'].get('arp.src.proto_ipv4')) # What is the first website that 10.0.0.132 visited? cap = FileCapture('Basics.pcap', display_filter='http && ip.addr==10.0.0.132') print('first website visited by 10.0.0.132:', cap[0]['http'].get('http.host')) # How many bytes large is the only .ico file downloaded via HTTP? cap = FileCapture('Basics.pcap', display_filter='http.request.uri contains ".ico"') req = cap[0].frame_info.number cap = FileCapture('Basics.pcap', display_filter='http.response') for c in cap:
from sys import exit from pyshark import FileCapture packets = None try: packets = FileCapture("files/home.pcapng") except Exception as e: print("===== Datei kann nicht eingelesen =====") exit(0) #for packet in packets: #print(packet) packets.close()
def get_cap(path_to_cap: str): return FileCapture(input_file=path_to_cap, display_filter='icmp')
class TGenerator(object): """This class is responsible for generating the templates from scapy packages and completing the remaining layers with the dissectors of tshark through pyshark.""" def __init__(self, pcapfile, scapy_pkts=None, tshark_pkts=None): """Initialization method of the class. Parameters ---------- pcapfile : str Path to a previously captured pcap. scapy_pkts : :obj:`PacketList` List of packets generated by Scapy. tshark_pkts : :obj:`FileCapture` List of packets generated by Pyshark. """ if scapy_pkts: self._scapy_pkts = scapy_pkts else: self._scapy_pkts = rdpcap(pcapfile) if tshark_pkts: self._tshark_pkts = tshark_pkts else: self._tshark_pkts = FileCapture(pcapfile) self._i = -1 def __del__(self): self._tshark_pkts.close() def __iter__(self): return self def __next__(self): """Generates a list of templates from a pcap file combining scapy and tshark dissectors. Returns ------- :obj:`Template` A `Template` generated from the packets. """ if self._i == len(self._scapy_pkts) - 1: # Closing the file self._tshark_pkts.close() raise StopIteration else: self._i += 1 return self.tgenerate(self._scapy_pkts[self._i], self._tshark_pkts[self._i], self._name(self._scapy_pkts[self._i])) def tgenerate(self, scapy_pkt, tshark_pkt, name): """Generates a template from a scapy and tshark packet. Parameters ---------- scapy_pkt : :obj:`` The packet generated by Scapy. tshark_pkt : :obj:`` The packet generated by Pyshark. name : str The name of the `Template`. Returns ------- :obj: `Template` The `Tempalate` generated from the packets. """ raw = bytes(scapy_pkt).hex() pkt_len = len(scapy_pkt) template = Template(name, raw=raw) # Adding the layers that scapy is able to dissect to the template for l in self._getlayers(scapy_pkt): offset = pkt_len - len(l) lslice = str(slice(offset, pkt_len)).encode().hex() layer = TLayer(name=l.__class__.__name__, lslice=lslice, raw=raw) for f in self._scapyfields(l, offset, scapy_pkt, layer): layer.addfield(f) template.addlayer(layer) # Adding layers that scapy is not able to dissect using tshark if scapy_pkt.lastlayer().name == "Raw": nlayers = len(list(self._getlayers(scapy_pkt))) for l in tshark_pkt.layers[nlayers - 1:]: # Use it in case you want to delete scapy layers # offset = len(scapy_pkt) - len(raw) offset = 0 fields_slices = self._slices(l, offset) if fields_slices: lslice = str(slice(fields_slices[0][1].start, pkt_len)).encode().hex() else: lslice = str( slice(pkt_len - len(scapy_pkt['Raw']), pkt_len)).encode().hex() layer = TLayer(name="Raw." + str(l.layer_name.upper()), lslice=lslice, raw=raw, custom=True) for f in self._tsharkfields(tshark_pkt, l, scapy_pkt, fields_slices, layer): layer.addfield(f) template.addlayer(layer) return template def _scapyfields(self, layer, offset, spkt, tlayer): """Generates template fields for a given scapy layer.""" fdissect = self._dissect_fields(layer, offset) raw = bytes(spkt) for f in layer.fields_desc: # Obtain the scapy repr of the field frepr = layer.getfieldval(f.name) # Extract the type of the field if type(frepr) is int: ftype = (int, 'big') else: frepr = str(frepr) ftype = (str, None) # Initialization of the field field = TField(name=str(f.name), value=raw[eval(fdissect[f.name])], raw=raw.hex(), tslice=fdissect[f.name].encode().hex(), custom=False, size=eval(fdissect[f.name]).stop - eval(fdissect[f.name]).start, frepr=frepr, ftype=ftype, layer=tlayer) yield field def _tsharkfields(self, tshark_pkt, layer, scapy_pkt, fields_slices, tlayer): """Returns the layers of a pyshark package.""" raw = bytes(scapy_pkt) for sl in fields_slices: # Obtain the tshark repr of the field field = layer.get_field(sl[0]) frepr = layer.get_field_value(sl[0]) # Extract the type of the field if field.isdecimal(): frepr = int(frepr) ftype = (int, 'big') else: frepr = str(frepr) ftype = (str, None) # Initialization of the tfield field = TField(name="_".join(sl[0].split('.')[1:]), value=raw[sl[1]], raw=raw.hex(), tslice=str(sl[1]).encode().hex(), custom=True, size=sl[1].stop - sl[1].start, ftype=ftype, frepr=frepr, layer=tlayer) yield field @staticmethod def _getlayers(pkt): """Returns the layers of a scapy package.""" yield pkt while pkt.payload: pkt = pkt.payload yield pkt def _name(self, pkt): """Generates a name for each template based on the layers of the packet.""" name = 'Template:' for l in self._getlayers(pkt): name += '/' + l.__class__.__name__ return name @staticmethod def _dissect_fields(layer, offset=0): """Create the default layer regarding fields_desc dict.""" diss_fields = OrderedDict() start = 0 p = b"" flist = [] for f in layer.fields_desc: val = layer.getfieldval(f.name) p = f.addfield(layer, p, val) if type(p) is tuple or len(p) == 0: flist.append(f.name) elif start == len(p): diss_fields[f.name] = diss_fields[list(diss_fields)[-1]] else: flist.append(f.name) for f in flist: diss_fields[f] = str(slice(start + offset, len(p) + offset)) flist = [] start = len(p) return diss_fields @staticmethod def _slices(layer, offset): """Get the slice of the fields in the packet.""" slices = [] for fname in layer.field_names: field = layer.get_field(fname) if field.size is not None and int( field.size) > 0 and field.name != '': slices.append([ field.name, slice( int(field.pos) - offset, int(field.pos) + int(field.size) - offset) ]) return slices
class TGenerator(object): """This class is responsible for generating the templates from tshark packets.""" def __init__(self, pcapfile, userfilter=None): """Initialization method of the class. Parameters ---------- pcapfile : str Path to a previously captured pcap. """ self._tshark_pkts = FileCapture( input_file=pcapfile, keep_packets=False, use_json=True, include_raw=True, display_filter=userfilter) def __iter__(self): return self def __next__(self): """Generates a list of templates from a tshark file Returns ------- :obj:`Template` A `Template` generated from the packets. """ try: tshark_pkt = self._tshark_pkts.next() return self.tgenerate(tshark_pkt) except UnicodeDecodeError: self.__next__() except StopIteration: self._tshark_pkts.close() raise except KeyboardInterrupt: self._tshark_pkts.close() raise StopIteration def tgenerate(self, tshark_pkt): """Generates a template from a tshark packet. Parameters ---------- tshark_pkt : :obj:`` The packet generated by Pyshark. Returns ------- :obj: `Template` The `Tempalate` generated from the packets. """ pkt_raw = tshark_pkt.get_raw_packet() pkt_len = len(tshark_pkt) # Generation of the `Template` template = Template( "Building", raw=pkt_raw, description="Template automatically generated by polymorph.") # Filtering and adding the `TLayer` objects to the `Template` tshark_layers = [ l for l in tshark_pkt.layers if "_raw" not in l.layer_name.lower()] for tshark_layer in tshark_layers: # Generation of the `Tlayer` try: lraw = getattr( tshark_pkt, tshark_layer.layer_name + "_raw").value except AttributeError: continue if type(lraw) is list: lraw = lraw[0] lraw = bytes.fromhex(lraw) tlayer_len = len(lraw) try: tlayer_start = pkt_raw.index(lraw) lslice = slice(tlayer_start, tlayer_start + tlayer_len) tlayer = TLayer(name=tshark_layer.layer_name.upper(), lslice=lslice, pkt_raw=pkt_raw) # Filtering and adding the `TField` objects to the `TLayer` for f in self._get_tlayer_fields(tshark_layer, tlayer, pkt_raw): tlayer.addfield(f) # If it corresponds to a reassembled layer except ValueError: lslice = slice(0, tlayer_len) lname = tshark_layer.layer_name.upper() + " (REASSEMBLED)" tlayer = TLayer(name=lname, lslice=lslice, pkt_raw=lraw) # Filtering and adding the `TField` objects to the `TLayer` for f in self._get_tlayer_fields(tshark_layer, tlayer, lraw): tlayer.addfield(f) # Adding the `TLayer` to the `Template` template.addlayer(tlayer) # We changed the name of the template template.name = self._name(template.layernames()) return template def _get_tlayer_fields(self, tshark_layer, tlayer, pkt_raw): """Generates template fields for a given tshark layer.""" tshark_fields = self._traverse_fields(tshark_layer._all_fields) for tname, tvalue in tshark_fields.items(): # Building the TField tfield = TField( fname=tname, fslice=slice(tvalue[2], tvalue[2]+tvalue[3]), fsize=tvalue[3], pkt_raw=pkt_raw, trepr=tvalue[0], ttype=tvalue[5], tmask=tvalue[4], layer=tlayer) yield tfield def _traverse_fields(self, all_fields): """Traverse and parse all tshark fields from a tshark layer.""" parse_fields = OrderedDict() # Filter all fields without _raw try: fields = [f for f in all_fields.keys( ) if "_raw" not in f and "_tree" not in f] except: return parse_fields for f in fields: # If not present the equivalent field with _raw it is a title if f + "_raw" not in all_fields.keys(): if type(all_fields[f]) is str: continue elif type(all_fields[f]) is list: for subf in range(len(all_fields[f])): newfield = self._traverse_fields(all_fields[f][subf]) parse_fields = self._update(parse_fields, newfield) continue else: newfield = self._traverse_fields(all_fields[f]) parse_fields = self._update(parse_fields, newfield) continue # Get the _raw equivalent of the field if f + "_raw_raw" in all_fields.keys(): raw_f = all_fields[f + "_raw_raw"] else: raw_f = all_fields[f + "_raw"] # If this condition match, f is a field if type(raw_f[-1]) is int and raw_f[-1] != 0: # Some fields can have subfields if type(all_fields[f]) is dict: newfield = self._traverse_fields(all_fields[f]) parse_fields = self._update(parse_fields, newfield) continue else: new_f = f.split(".") if len(new_f) == 1: new_f = new_f[0] elif len(new_f) > 1: new_f = ".".join(new_f[1:]) parse_fields = self._update( parse_fields, {new_f: [all_fields[f]] + raw_f}) elif type(raw_f[-1]) is int and raw_f[-1] == 0: if type(all_fields[f]) is str: raw_f[-1] = -1 newfield = self._traverse_fields({f + "_raw": raw_f, f: all_fields[f]}) parse_fields = self._update(parse_fields, newfield) else: newfield = self._traverse_fields(all_fields[f]) parse_fields = self._update(parse_fields, newfield) elif type(raw_f[-1]) is list: for subf in range(len(raw_f)): newfield = self._traverse_fields({f + "_raw": raw_f[subf], f: all_fields[f][subf]}) parse_fields = self._update(parse_fields, newfield) else: print("[ERROR] Parsing field:", f) # Return the parsed fields without duplicates return parse_fields def _update(self, od1, od2): """Updates the list of fields without duplicate names.""" for k, v in od2.items(): # Delete duplicate fields duplicate = False for k2, v2 in od1.items(): if v[2] == v2[2] and v[3] == v2[3] and v[4] == v2[4]: duplicate = True if duplicate: continue new_k = self._new_fname(k, od1) od1[new_k] = v return od1 def _new_fname(self, fname, all_fields): """Generates new names for fields with duplicate name.""" if fname in all_fields: if fname[-1].isnumeric(): return self._new_fname(fname[:-1] + str(int(fname[-1]) + 1), all_fields) else: return self._new_fname(fname + str(2), all_fields) else: return fname def _name(self, layers): """Generates a name for each template based on the layers of the packet.""" return "Template: " + " / ".join(layers)
class PcapReader: def __init__(self, filename, summary=True, keep_packets=False): self.result = [] self.cap = FileCapture(filename, only_summaries=summary, keep_packets=keep_packets) if filename in packet2num: self.length = packet2num[filename] else: self.length = self.packet_length() def packet_length(self): length = [0] def decode(packet): length[0] += 1 self.cap.apply_on_packets(decode) return length[0] def get_specify(self, start, end): # page split def decode(packet): item = { "id": packet.no, "src": packet.source, "dst": packet.destination, "time": round(float(packet.time), 5), "protocol": packet.protocol, "info": packet.info, "length": packet.length } self.result.append(item) for index in range(start, end): pack = self.cap[index - 1] decode(pack) return self.result, self.length def get_detail(self, id): packet = self.cap[id - 1] old_stdout = sys.stdout sys.stdout = mystdout = StringIO() packet.pretty_print() sys.stdout = old_stdout info = mystdout.getvalue() detail = [] index = -1 # packet.pretty_print() for line in info.split('\n'): if "Layer" in line: index += 1 detail.append({'layer': line, 'fields': []}) continue if line.strip() in detail[index]['fields']: continue detail[index]['fields'].append(line.strip()) return detail def close(self): self.cap.clear() self.cap.close()
from pyshark import FileCapture access_points = set() cap = FileCapture('Radius.pcap', display_filter='radius.User_Name == "sally.berro"') print('user mac: ' + cap[0]['radius'].get('radius.Calling_Station_Id')) cap = FileCapture('Radius.pcap', display_filter='radius') for c in cap: access_points.add(c['radius'].get('radius.Called_Station_Id')) access_points.remove(None) print(len(access_points), ' access points received requests')
from pyshark import FileCapture pcap = FileCapture("incident.pcap", include_raw=True, use_json=True) data = b'' ct = 0 for packet in pcap: try: check_type = packet.icmp if ct % 2 == 0: data += packet.get_raw_packet()[58:74] print(packet.get_raw_packet()[58:74]) ct += 1 except AttributeError: pass with open("out.png", 'wb') as f: f.write(data)
from pyshark import FileCapture import re # ignore stdout import os import sys f = open(os.devnull, 'w') sys.stderr = f try: """ software running voip proxy """ cap = FileCapture('SIP.pcap', display_filter='ip.src == 10.21.128.1 && sip') print('proxy software:', cap[0]['sip'].get('sip.Server').split(' ')[0]) """ number of voice mails for user 542 """ cap = FileCapture('SIP.pcap', display_filter='sip.Method == NOTIFY && sip.r-uri.user == "542"') hdr = cap[0]['sip'].get('sip.msg_hdr') match = re.search(r'Voice-Message: (\d)/(\d)', hdr) print('number of voice mails', int(match.group(1)) + int(match.group(2))) cap = FileCapture('SIP.pcap', display_filter='sip.Method == INVITE') """ What is the SIP address of the caller in the only call? """ print('initializer of only call:', cap[0]['sip'].get('sip.from.addr')) """ What is the SIP address of the recipient of the only call? """ print('recipient of only call:', cap[0]['sip'].get('sip.to.addr')) """ What is the IP address of the recipient of the only call? """ cap = FileCapture('SIP.pcap', display_filter='sip.r-uri.user == "635"') print('ip of recipient:', cap[0]['ip'].src) """ What brand of physical phone was the recipient of the call using? """ print('type of device:', cap[0]['sip'].get('sip.User-Agent'))