В 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()