@@ -94,8 +94,11 @@ def parse_nmap_subnetscan(self, xml_root):
9494 for port in host .find ("ports" ).findall ("port" ):
9595 port_attrib = port .attrib
9696 ports .append (
97- {"port" :port_attrib .get ("portid" ), "protocol" :port_attrib .get ("protocol" ),
98- "state" :port .find ("state" ).attrib .get ("state" )
97+ {
98+ "port" : port_attrib .get ("portid" ),
99+ "protocol" : port_attrib .get ("protocol" ),
100+ "state" : port .find ("state" ).attrib .get ("state" ),
101+ "scripts" : self .parse_scripts (port .findall ('script' )) if port .findall ('script' ) is not None else []
99102 }
100103 )
101104
@@ -179,6 +182,9 @@ def parse_nmap_idlescan(self, xml_root):
179182
180183 if open_ports .find ('service' ) is not None :
181184 port_dict ['service' ]= open_ports .find ('service' ).attrib
185+
186+ if port .findall ('script' ) is not None :
187+ open_ports ['scripts' ] = self .parse_scripts (port .findall ('script' ))
182188
183189 idle_scan ["ports" ]= port_dict
184190
@@ -299,9 +305,12 @@ def filter_top_ports(self, xmlroot):
299305 for key in port .find ('state' ).attrib :
300306 open_ports [key ]= port .find ("state" ).attrib .get (key )
301307
302- if port .find ("service" ) is not None :
308+ if port .find ("service" ) is not None :
303309 open_ports ["service" ]= port .find ("service" ).attrib
304310
311+ if port .findall ('script' ) is not None :
312+ open_ports ['scripts' ] = self .parse_scripts (port .findall ('script' ))
313+
305314 port_results .append (open_ports )
306315 port_result_dict [address ]= port_results
307316
@@ -343,7 +352,10 @@ def filter_stealth_scan(self, xmlroot):
343352
344353 if port .find ("extrareasons" ) is not None :
345354 for extra in port .findall ("extrareasons" ):
346- open_ports ["extrareasons" ]= extra .attrib
355+ open_ports ["extrareasons" ]= extra .attrib
356+
357+ if port .findall ('script' ) is not None :
358+ open_ports ['scripts' ] = self .parse_scripts (port .findall ('script' ))
347359
348360 port_results .append (open_ports )
349361 port_result_dict [address ]= port_results
@@ -400,6 +412,9 @@ def version_parser(self, xmlroot):
400412 cpe_list = []
401413 cpe_list .append ({"cpe" : cp .text })
402414 service ["cpe" ] = cpe_list
415+ if port .findall ('script' ) is not None :
416+ service ['scripts' ] = self .parse_scripts (port .findall ('script' ))
417+
403418 services_result .append (service )
404419
405420 service_version_dict [address ] = services_result
@@ -434,4 +449,56 @@ def os_identifier_parser(self, xmlroot):
434449 raise (e )
435450 else :
436451 return os_identified
437-
452+
453+ def parse_scripts (self , scripts_xml ):
454+ scripts = []
455+
456+ for script_xml in scripts_xml :
457+ script_name = script_xml .attrib .get ('id' )
458+ raw_output = script_xml .attrib .get ('output' )
459+
460+ data = self .convert_xml_elements (script_xml )
461+ if script_xml .findall ('table' ) is not None :
462+ tables = script_xml .findall ('table' )
463+ child_data = self .convert_xml_tables (tables )
464+ for k in child_data :
465+ if {} != k :
466+ data [k ] = child_data [k ]
467+
468+ scripts .append ({
469+ 'name' : script_name ,
470+ 'raw' : raw_output ,
471+ 'data' : data
472+ })
473+
474+ return scripts
475+
476+ def convert_xml_tables (self , xml_tables ):
477+ data = {}
478+ for xml_table in xml_tables :
479+ key = xml_table .attrib .get ('key' )
480+ child_data = self .convert_xml_elements (xml_table )
481+ if key is None :
482+ if {} != child_data :
483+ a = data .get ('children' , [])
484+ data ['children' ] = a + [child_data ]
485+ else :
486+ if xml_table .findall ('table' ) is not None :
487+ data [key ] = self .convert_xml_tables (xml_table .findall ('table' ))
488+ if {} != child_data :
489+ a = data .get (key , {})
490+ b = a .get ('children' , [])
491+ a ['children' ] = b + [child_data ]
492+
493+ return data
494+
495+ def convert_xml_elements (self , xml_obj ):
496+ elements = {}
497+ elem_counter = 0
498+ for elem in xml_obj .findall ('elem' ):
499+ if None == elem .attrib .get ('key' ):
500+ elements [elem_counter ] = elem .text
501+ else :
502+ elements [elem .attrib .get ('key' )] = elem .text
503+ elem_counter += 1
504+ return elements
0 commit comments