今天分享一个使用subprocess
模块来执行nmap命令,并使用csv
模块来将结果写入CSV文件的方法。
代码如下:
import subprocess
import csv
# 定义扫描的参数
ip_address = '172.18.0.1/24' # 扫描的IP地址或CIDR
port_range = '-p 443' # 扫描的端口范围
output_filename = 'scan_results.csv' # 输出的CSV文件名
# 构建nmap命令
nmap_command = ['nmap', '-oX', '-', ip_address, port_range]
# 执行nmap命令并获取输出
try:
result = subprocess.run(nmap_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)
nmap_output = result.stdout.decode('utf-8')
except subprocess.CalledProcessError as e:
print(f"nmap scan failed with error: {e}")
exit(1)
# 解析nmap的XML输出并转换为CSV格式
try:
import xml.etree.ElementTree as ET
root = ET.fromstring(nmap_output)
# 打开CSV文件准备写入
with open(output_filename, 'w', newline='') as csvfile:
csvwriter = csv.writer(csvfile)
# 写入CSV文件的标题行
csvwriter.writerow(['Host', 'Port', 'State', 'Service', 'Protocol'])
# 遍历nmap扫描结果中的每个主机和端口
for host in root.findall('host'):
address = host.find('address').get('addr')
# 遍历主机的所有端口
for port_elem in host.findall('ports/port'):
protocol = port_elem.get('protocol')
portid = port_elem.get('portid')
state_elem = port_elem.find('state')
state = state_elem.get('state') if state_elem is not None else 'unknown'
service_elem = port_elem.find('service')
service = service_elem.get('name') if service_elem is not None else 'unknown'
# 写入CSV文件的一行数据
csvwriter.writerow([address, portid, state, service, protocol])
print(f"Scan results have been written to {output_filename}")
except ET.ParseError as e:
print(f"Failed to parse nmap output: {e}")
输出结果如下: