def test_customlayer(self): from polymorph.tlayer import TLayer self.template.addlayer(TLayer("TEST", lslice="", raw="", custom=True)) clayers = self.template.customlayers() self.assertEqual(len(clayers), 3) self.assertEqual(clayers[0].name, "RAW.HTTP") self.assertEqual(clayers[1].name, "RAW.OCSP") self.assertEqual(clayers[2].name, "TEST")
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 test_addlayer(self): from polymorph.tlayer import TLayer layer = TLayer("TEST", lslice="", raw="", custom=True) self.template.addlayer(layer) self.assertEqual( self.template.layernames(), ['ETHER', 'IP', 'TCP', 'RAW', 'RAW.HTTP', 'RAW.OCSP', 'TEST']) self.assertEqual(type(self.template.getlayer('TEST')), TLayer) self.assertEqual(len(self.template.getlayers()), 7)
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 _layer(self, command): """Manages the access to a `TLayer` of the `Template`.""" if len(command) == 1: Interface.print_help(TemplateInterface._layer_help()) elif len(command) == 2 and command[1].upper() in self._t.layernames(): li = LayerInterface(self._t.getlayer(command[1].upper()), self._index, self._poisoner) li.run() else: cp = CommandParser(TemplateInterface._layer_opts()) args = cp.parse(command) if not args: Interface._argument_error() return # Print the help if args["-h"]: Interface.print_help(TemplateInterface._layer_help()) # Adds a new layer elif args["-a"]: hexdump.hexdump(self._t.raw) print() start = input("Start byte of the custom layer: ") end = input("End byte of the custom layer: ") if start.isdecimal() and end.isdecimal(): lslice = str(slice(int(start), int(end))).encode().hex() new_layer = TLayer(args["-a"], raw=self._t.raw.hex(), lslice=lslice, custom=True) self._t.addlayer(new_layer) Interface._print_info( "New layer %s added to the Template" % args["-a"]) else: Interface._print_error( "The start or end byte is not a number") # Deletes an existing layer elif args["-d"]: del_layer = self._t.getlayer(args["-d"]) if del_layer: self._t.dellayer(del_layer) Interface._print_info("Layer %s deleted" % args["-d"]) else: Interface._print_error("The layer %s does not exist" % args["-d"])
def read(self, path): """Reads a `Template` from disk. Parameters ---------- path: str Path from which the template will be read. """ with open(path) as t: template = json.load(t) # Reading layers self._name = template['Name'] self._version = template['Version'] self._timestamp = template['Timestamp'] self._description = template['Description'] self._raw = template['raw'] self._functions = template['Functions'] for layer in template['layers']: l = TLayer(layer['name'], raw=self._raw, lslice=layer['lslice'], custom=layer['custom']) # Reading the structs structs = layer["structs"] # Reading fields for field in layer['fields']: ftype = field['type'] if ftype[0] == str(int): ftype = (int, ftype[1]) elif ftype[0] == str(str): ftype = (str, ftype[1]) elif ftype[0] == str(bytes): ftype = (bytes, ftype[1]) f = TField(name=field['name'], value=bytearray.fromhex(field['value']), raw=self._raw, tslice=field['slice'], custom=field['custom'], size=field['size'], ftype=ftype, frepr=field['frepr']) f.layer = l l.addfield(f) # Initialization of the structs for f in structs: l.add_struct(f, structs[f]['fdeps'], structs[f]['sb'], structs[f]['exp']) self.addlayer(l)
def read(self, path): """Reads a `Template` from disk. Parameters ---------- path: str Path from which the template will be read. """ with open(path) as t: template = json.load(t) # Reading and loading the template self._name = template['Name'] self._version = template['Version'] self._timestamp = template['Timestamp'] self._description = template['Description'] self._raw = bytes.fromhex(template['raw']) self._functions = template['Functions'] # Reading and loading the layers for layer in template['layers']: l = TLayer(layer['name'], pkt_raw=self._raw, lslice=eval(layer['lslice'])) # Reading the structs structs = layer["structs"] # Reading and loading the fields for field in layer['fields']: f = TField(fname=field['name'], fslice=eval(field['slice']), fsize=field['size'], pkt_raw=self._raw, trepr=field['trepr'], ttype=field['ttype'], tmask=field['mask'], layer=l, ftype=Ftype(field['type']), frepr=field['frepr'] if Ftype(field['type']) != Ftype.FT_BYTES else bytes.fromhex(field['frepr'])) l.addfield(f) # Initialization of the structs for f in structs: l.add_struct(f, structs[f]['fdeps'], structs[f]['sb'], structs[f]['exp']) self.addlayer(l)