【问题标题】:parsing an nmap result解析 nmap 结果
【发布时间】:2015-09-15 06:31:54
【问题描述】:

我正在 linux 上使用 Python 2.6 开发一个项目,我正在使用终端中的 nmap 来获取这些扫描结果,我在一个字符串中得到了这个:

Starting Nmap 6.47 ( http://nmap.org ) at 2015-06-28 23:15 IDT
Nmap scan report for 10.0.0.5
Host is up (0.010s latency).
Not shown: 999 closed ports
PORT      STATE SERVICE
62078/tcp open  iphone-sync
MAC Address: 70:3E:AC:22:A0:B0 (Unknown)
Device type: general purpose|media device|phone
Running: Apple Mac OS X 10.7.X|10.9.X|10.8.X, Apple iOS 4.X|5.X|6.X
OS CPE: cpe:/o:apple:mac_os_x:10.7 cpe:/o:apple:mac_os_x:10.9 cpe:/o:apple:mac_os_x:10.8 cpe:/o:apple:iphone_os:4 cpe:/a:apple:apple_tv:4 cpe:/o:apple:iphone_os:5 cpe:/o:apple:iphone_os:6
OS details: Apple Mac OS X 10.7.0 (Lion) - 10.9.2 (Mavericks) or iOS 4.1 - 7.1 (Darwin 10.0.0 - 14.0.0)
Network Distance: 1 hop

Nmap scan report for 10.0.0.16
Host is up (0.011s latency).
Not shown: 998 closed ports
PORT     STATE SERVICE
443/tcp  open  https
1111/tcp open  lmsocialserver
MAC Address: 94:EB:CD:2E:39:DC (Research In Motion Limited)
Device type: phone
Running: RIM BlackBerry 10.X
OS CPE: cpe:/o:blackberry:blackberry_os:10.0
OS details: BlackBerry 10
Network Distance: 1 hop

Nmap scan report for 10.0.0.30
Host is up (0.11s latency).
Not shown: 984 closed ports
PORT     STATE SERVICE
80/tcp   open  http
139/tcp  open  netbios-ssn
443/tcp  open  https
445/tcp  open  microsoft-ds
515/tcp  open  printer
631/tcp  open  ipp
6839/tcp open  unknown
7435/tcp open  unknown
8080/tcp open  http-proxy
9100/tcp open  jetdirect
9101/tcp open  jetdirect
9102/tcp open  jetdirect
9110/tcp open  unknown
9111/tcp open  DragonIDSConsole
9220/tcp open  unknown
9290/tcp open  unknown
MAC Address: EC:9A:74:98:3C:9D (Hewlett Packard)
Device type: printer|VoIP adapter
Running: HP VxWorks, Vocality embedded
OS CPE: cpe:/o:hp:vxworks
OS details: VxWorks: HP printer or Vocality BASICS Four Wire VoIP gateway
Network Distance: 1 hop

Nmap scan report for 10.0.0.4
Host is up (0.000040s latency).
All 1000 scanned ports on 10.0.0.4 are closed
Too many fingerprints match this host to give specific OS details
Network Distance: 0 hops

OS detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 50 IP addresses (4 hosts up) scanned in 56.74 second

我想把它解析成这样的:(第一个块的例子)

['10.0.0.5', [['62078/tcp', 'open', 'iphone-sync']], '70:3E:AC:22:A0:B0', 'Apple Mac OS X 10.7.0 (Lion) - 10.9.2 (Mavericks) or iOS 4.1 - 7.1 (Darwin 10.0.0 - 14.0.0)']

这是我想要的模式[IP, [list of [port, state, service], MAC, OS] 有没有简单的方法用 Python 做到这一点?

【问题讨论】:

  • 到目前为止,您是否进行过任何研究?
  • 我不知道在这种情况下我到底要搜索什么,我尝试在数据上使用循环,但效果不佳..
  • ...我倾向于从谷歌搜索 "python nmap parser" 开始,看看这对我有多大帮助。见meta.stackoverflow.com/q/261592/3001761
  • Nmap 的文本输出不适合可编程解析,因为它会随着版本的变化而变化。为此使用XML output

标签: python parsing nmap


【解决方案1】:

您看过以下 Python 模块吗?

  • python-nmap: 这是一个使用 nmap 并从 python3 访问扫描结果的 python 类
  • python-libnmap:Python NMAP 库使您能够启动异步 nmap 任务、解析和比较/比较扫描结果

特别是,python-nmap 正是您想要做的。

python-nmap 用法示例:

>>> import nmap
>>> nm = nmap.PortScanner()
>>> nm.scan('127.0.0.1', '22-443')
>>> nm.command_line()
'nmap -oX - -p 22-443 -sV 127.0.0.1'
>>> nm.scaninfo()
{'tcp': {'services': '22-443', 'method': 'connect'}}
>>> nm.all_hosts()
['127.0.0.1']
>>> nm['127.0.0.1'].hostname()
'localhost'
>>> nm['127.0.0.1'].state()
'up'
>>> nm['127.0.0.1'].all_protocols()
['tcp']
>>> nm['127.0.0.1']['tcp'].keys()
[80, 25, 443, 22, 111]
>>> nm['127.0.0.1'].has_tcp(22)
True
>>> nm['127.0.0.1'].has_tcp(23)
False
>>> nm['127.0.0.1']['tcp'][22]
{'state': 'open', 'reason': 'syn-ack', 'name': 'ssh'}
>>> nm['127.0.0.1'].tcp(22)
{'state': 'open', 'reason': 'syn-ack', 'name': 'ssh'}
>>> nm['127.0.0.1']['tcp'][22]['state']
'open'

>>> for host in nm.all_hosts():
>>>     print('----------------------------------------------------')
>>>     print('Host : %s (%s)' % (host, nm[host].hostname()))
>>>     print('State : %s' % nm[host].state())
>>>     for proto in nm[host].all_protocols():
>>>         print('----------')
>>>         print('Protocol : %s' % proto)
>>> 
>>>         lport = nm[host][proto].keys()
>>>         lport.sort()
>>>         for port in lport:
>>>             print ('port : %s\tstate : %s' % (port, nm[host][proto][port]['state']))
----------------------------------------------------
Host : 127.0.0.1 (localhost)
State : up
----------
Protocol : tcp
port : 22   state : open
port : 25   state : open
port : 80   state : open
port : 111  state : open
port : 443  state : open


>>> print(nm.csv())
host;protocol;port;name;state;product;extrainfo;reason;version;conf
127.0.0.1;tcp;22;ssh;open;OpenSSH;protocol 2.0;syn-ack;5.9p1 Debian 5ubuntu1;10
127.0.0.1;tcp;25;smtp;open;Exim smtpd;;syn-ack;4.76;10
127.0.0.1;tcp;53;domain;open;dnsmasq;;syn-ack;2.59;10
127.0.0.1;tcp;80;http;open;Apache httpd;(Ubuntu);syn-ack;2.2.22;10
127.0.0.1;tcp;111;rpcbind;open;;;syn-ack;;10
127.0.0.1;tcp;139;netbios-ssn;open;Samba smbd;workgroup: WORKGROUP;syn-ack;3.X;10
127.0.0.1;tcp;443;;open;;;syn-ack;;


>>> nm.scan(hosts='192.168.1.0/24', arguments='-n -sP -PE -PA21,23,80,3389')
>>> hosts_list = [(x, nm[x]['status']['state']) for x in nm.all_hosts()]
>>> for host, status in hosts_list:
>>>     print('{0}:{1}'.host)
192.168.1.0:down
192.168.1.1:up
192.168.1.10:down
192.168.1.100:down
192.168.1.101:down
192.168.1.102:down
192.168.1.103:down
192.168.1.104:down
192.168.1.105:down
[...]



>>> nma = nmap.PortScannerAsync()
>>> def callback_result(host, scan_result):
>>>     print '------------------'
>>>     print host, scan_result
>>> 
>>> nma.scan(hosts='192.168.1.0/30', arguments='-sP', callback=callback_result)
>>> while nma.still_scanning():
>>>     print("Waiting >>>")
>>>     nma.wait(2)   # you can do whatever you want but I choose to wait after the end of the scan
>>> 
192.168.1.1 {'nmap': {'scanstats': {'uphosts': '1', 'timestr': 'Mon Jun  7 11:31:11 2010', 'downhosts': '0', 'totalhosts': '1', 'elapsed': '0.43'}, 'scaninfo': {}, 'command_line': 'nmap -oX - -sP 192.168.1.1'}, 'scan': {'192.168.1.1': {'status': {'state': 'up', 'reason': 'arp-response'}, 'hostname': 'neufbox'}}}
------------------
192.168.1.2 {'nmap': {'scanstats': {'uphosts': '0', 'timestr': 'Mon Jun  7 11:31:11 2010', 'downhosts': '1', 'totalhosts': '1', 'elapsed': '0.29'}, 'scaninfo': {}, 'command_line': 'nmap -oX - -sP 192.168.1.2'}, 'scan': {'192.168.1.2': {'status': {'state': 'down', 'reason': 'no-response'}, 'hostname': ''}}}
------------------
192.168.1.3 {'nmap': {'scanstats': {'uphosts': '0', 'timestr': 'Mon Jun  7 11:31:11 2010', 'downhosts': '1', 'totalhosts': '1', 'elapsed': '0.29'}, 'scaninfo': {}, 'command_line': 'nmap -oX - -sP 192.168.1.3'}, 'scan': {'192.168.1.3': {'status': {'state': 'down', 'reason': 'no-response'}, 'hostname': ''}}}

>>> nm = nmap.PortScannerYield()
>>> for progressive_result in nm.scan('127.0.0.1/24', '22-25'): print(progressive_result)

【讨论】:

  • 上述两个库都可以异步使用。
【解决方案2】:

如果只想解析xml的结果,可以使用xmltodict

import xmltodict
import json

with open("nmap_results.xml") as f:
    xml = f.read()
d = json.loads(json.dumps(xmltodict.parse(xml)))
# d = xmltodict.parse(xml) # you may also try using xmltodict directly without using json, but I'd some issues doing so, give it a try.

要将nmap 结果写入xml,请使用-oX arg,即:

nmap -oX nmap_results.xml x.x.x.x

【讨论】:

    猜你喜欢
    • 2019-01-22
    • 1970-01-01
    • 1970-01-01
    • 2021-10-14
    • 2018-07-20
    • 1970-01-01
    • 1970-01-01
    • 2011-05-06
    • 2012-08-01
    相关资源
    最近更新 更多