В CSV-файл сохраняется только первый открытый номер порта.

Только первый открытый порт в теге <ports> </ports> указан в выходном файле CSV; другие открытые порты не указаны. Вывод печатается в CSV-файл, но в CSV-файл выводится только первая строка в теге ports. Вы можете попробовать запустить команду nmap "nmap -sV -Pn -oX Output_3.xml scanme.nmap.org"

      `import xml.etree.ElementTree as ET
import csv

def main():
    in_xml_port = 'Output_1.xml'
    xml_tree_port = ET.parse(in_xml_port)
    xml_root_port = xml_tree_port.getroot()
    
   # To save the output to csv file 
    with open('detected_hosts.csv', 'w', newline='') as file:
        writer = csv.writer(file)
        writer.writerow(['IP', 'Hostname', 'Status', 'Port', 'Service', 'Protocol', 'Product'])

        for host in xml_root_port.findall('host'):

            # finding all the necessary details from the xml tags
            master_ip = host.find('address').get('addr')
            
            master_hostnames = host.findall('hostnames')
            master_hostname = master_hostnames[0].findall('hostname')[0].attrib['name']
            
            port_status = host.findall('ports')
            port_status_1 = port_status[0].findall('port')
            port_state = port_status_1[0].findall('state')[0].attrib['state']
            
            port_element = host.findall('ports')
            port_id = port_element[0].findall('port')[0].attrib['portid']

            open_service = host.findall('ports')
            open_service_1 = open_service[0].findall('port')
            service_name = open_service_1[0].findall('service')[0].attrib['name']
            
            potocol_element = host.findall('ports')
            port_protocol = potocol_element[0].findall('port')[0].attrib['protocol']

            product_element = host.findall('ports')
            product_element_1 = product_element[0].findall('port')
            product_name = product_element_1[0].findall('service')[0].attrib['product']
       
            if port_state == 'open':
                host_status = 'open'
                writer.writerow([master_ip, master_hostname, port_state, port_id, service_name, port_protocol, product_name])

                
if __name__ == '__main__':
    main()`

1 ответ

Проблема в том, что при поиске код получает только первый ответ. Например, эти две строки:

      port_status_1 = port_status[0].findall('port')
port_state = port_status_1[0].findall('state')[0].attrib['state']

port_status_1представляет собой список портов, однако при запросеport_state, код ограничивается только первым портомport_status_1[0]. Следовательно, в сгенерированном файле CSV записывается информация только о первом открытом порте.

Попробуйте следующий скрипт. Основная логика не изменилась, за исключением того, что она использует цикл для получения всех'port'От всех'ports'. Кроме того, он используетfind()иget()для упрощения запроса атрибута.

      import xml.etree.ElementTree as ET
import csv

def main():
    in_xml_port = 'Output_1.xml'
    xml_tree_port = ET.parse(in_xml_port)
    xml_root_port = xml_tree_port.getroot()
    
   # To save the output to csv file 
    with open('detected_hosts.csv', 'w', newline='') as file:
        writer = csv.writer(file)
        writer.writerow(['IP', 'Hostname', 'Status', 'Port', 'Service', 'Protocol', 'Product'])

        for host in xml_root_port.findall('host'):

            # finding all the necessary details from the xml tags
            master_ip = host.find('address').get('addr')
            
            master_hostnames = host.findall('hostnames')
            master_hostname = master_hostnames[0].findall('hostname')[0].attrib['name']

            for ports in host.findall('ports'):
                for port in ports.findall('port'):
                    port_state = port.find('state').get('state')
                    port_id = port.get('portid')
                    service_name = port.find('service').get('name')
                    port_protocol = port.get('protocol')
                    product_name = port.find('service').get('product')
                    if port_state == 'open':
                        writer.writerow([master_ip, master_hostname, port_state, port_id, service_name, port_protocol, product_name])
                
if __name__ == '__main__':
    main()

Другие вопросы по тегам