我正在开发一个使用 Nmap 和 Python 自动化网络侦察的项目。我的目标是:
但是,我正在努力解决以下问题:
我使用 python-nmap 库使用以下代码在本地子网 (192.168.1.0/24) 上启动 Nmap 扫描:
import nmap
nm = nmap.PortScanner()
scan_result = nm.scan(hosts='192.168.1.0/24', arguments='-sV')
print(scan_result)
我希望扫描结果作为字典返回,其中包含有关子网中每个主机的开放端口、服务及其版本的详细信息。
Nmap 扫描成功运行并返回一个字典,但它相当复杂且嵌套。我正在努力解析字典以以易于阅读的格式提取特定的详细信息,例如开放端口、服务和版本。
最好的办法就是从顶层开始,查看可用的键及其包含的数据。
在顶层,有两个键:
>>> scan_results.keys()
dict_keys(['nmap', 'scan'])
nmap
键具有有关扫描的全局元数据:
>>> scan_results['nmap'].keys()
dict_keys(['command_line', 'scaninfo', 'scanstats'])
command_line
显示传递给 nmap
scaninfo
显示扫描期间生成的任何错误(在 errors
中)以及有关扫描方法和扫描端口的信息(在 tcp
中,假设进行 tcp
扫描)scanstats
包含有关扫描的总体统计信息(例如,{'timestr': 'Tue Dec 24 14:46:23 2024', 'elapsed': '186.75', 'uphosts': '3', 'downhosts': '253', 'totalhosts': '256'}
)scan
键包含扫描结果:
>>> scan_results['scan'].keys()
dict_keys(['192.168.124.1', '192.168.124.62', '192.168.124.83'])
显然每个发现的主机都有一个密钥。对于每个主机,有几个键:
>>> scan_results['scan']['192.168.124.62'].keys()
dict_keys(['hostnames', 'addresses', 'vendor', 'status', 'tcp'])
hostnames
和 addresses
包含有关与主机关联的主机名和地址的信息。
vendor
包含有关已发现操作系统供应商的信息(如果 nmap 能够确定)。
status
具有主机的高级别状态(up
或 down
)
tcp
有该主机端口扫描的详细信息。每个端口有一把钥匙。例如,在仅打开 ssh
的主机上,我们会看到:
"tcp": {
"22": {
"state": "open",
"reason": "syn-ack",
"name": "ssh",
"product": "OpenSSH",
"version": "9.9",
"extrainfo": "protocol 2.0",
"conf": "10",
"cpe": "cpe:/a:openbsd:openssh:9.9"
}
}
而在具有两个端口(
ssh
和 Web 服务器)的主机上,我们看到:
{
"22": {
"state": "open",
"reason": "syn-ack",
"name": "ssh",
"product": "OpenSSH",
"version": "8.7",
"extrainfo": "protocol 2.0",
"conf": "10",
"cpe": "cpe:/a:openbsd:openssh:8.7"
},
"80": {
"state": "open",
"reason": "syn-ack",
"name": "http",
"product": "",
"version": "",
"extrainfo": "",
"conf": "10",
"cpe": ""
}
}