nmap
高效端口扫描器 官方demo
使用三步骤
安装: pip3 install python-nmap
导入: import nmap
实例化: nm=nmap.PortScanner()
# linux使用, 必须先安装 nmap这个软件 yum -y install nmap
# windows使用, 也必须先安装 nmap,配置环境变量,并重启pycharm
PortScanner
端口扫描
nm.scan('127.0.0.1', '22,6379','-sV') # 端口扫描
{'nmap': {'command_line': 'nmap -oX - -p 22,6379 -sV 127.0.0.1', 'scaninfo': {'tcp': {'method': 'syn', 'services': '22,6379'}}, 'scanstats': {'timestr': 'Thu Sep 05 10:36:11 2019', 'elapsed'
: '17.35', 'uphosts': '1', 'downhosts': '0', 'totalhosts': '1'}}, 'scan': {'127.0.0.1': {'hostnames': [], 'addresses': {'ipv4': '127.0.0.1', 'mac': '00:50:56:8A:04:53'}, 'vendor': {'00:5
0:56:8A:04:53': 'VMware'}, 'status': {'state': 'up', 'reason': 'arp-response'}, 'tcp': {22: {'state': 'open', 'reason': 'syn-ack', 'name': 'ssh', 'product': 'OpenSSH', 'version': '6.6.1', 'extra
info': 'protocol 2.0', 'conf': '10', 'cpe': 'cpe:/a:openbsd:openssh:6.6.1'}, 6379: {'state': 'open', 'reason': 'syn-ack', 'name': 'redis', 'product': 'Redis key-value store', 'version': '', 'ext
rainfo': '', 'conf': '10', 'cpe': ''}}}}}
nm.scan('127.0.0.1,'22-25,6379,3333,4444','-sV')
# 参数: 地址 端口 0-100逗号分割, 端口1, 端口2-端口N 命令行参数,格式为"-sU -sX -sC"表示
# 扫描其实就是发了几个空消息过去
# -sU代表扫描UDP
# -sT代表扫描TCP
# -Pn 这个主要是针对有些服务器禁用ping的处理(ping不通也尝试)
command_line
nm.command_line() # 返回的扫描方法映射到具体的nmap命令行
nmap -oX - -p 22,6379 -sV 192.168.x.x
scaninfo
nm.scaninfo() # 返回nmap扫描信息,格式为字典类型
# {'tcp': {'method': 'syn', 'services': '22,6379'}}
nm.all_hosts()
# 获取地址
nm.all_hosts() # ['192.168.x.x']
all_udp()
nm.scan('192.168.x.x','23456-23557','-sU')
print(nm['192.168.x.x'].all_udp())
nmap状态说明
| 状态返回结果 | 说明 |
| ------------------ | ---------------------------------------- |
| open | 开放 |
| closed | 关闭 |
| filtered | 端口被防火墙IDS/IPS 屏蔽,无法确定其状态 |
| unfiltered | 端口没有被屏蔽,但是否开放需要进一步确定 |
| open | filtered | 端口是开放的或被屏蔽 |
| closed | filtered | 端口是关闭的或被屏蔽 |
PortScannerHostDict
注: windows下使用 PortScannerHostDict 下的方法会有问题
class PortScanner() # 下的某个调用方法 374行
scan_result['scan'][host] = PortScannerHostDict({'hostnames': hostnames})
PortScannerHostDict 支持的方法
class PortScannerHostDict(dict):
def hostnames(self): pass
def hostname(self): pass
def state(self): pass
def uptime(self): pass
def all_protocols(self): pass
def _proto_filter(x): pass
def all_tcp(self): pass
def has_tcp(self, port): pass
def tcp(self, port): pass
def all_udp(self): pass
def has_udp(self, port): pass
def udp(self, port): pass
def all_ip(self): pass
def has_ip(self, port): pass
def ip(self, port): pass
def all_sctp(self): pass
def has_sctp(self, port): pass
def sctp(self, port): pass
错误的示范
>>> import nmap
>>> nm = nmap.PortScanner()
>>> nm['127.0.0.1'].hostname() # 注意一定要先扫描 然后在调用PortScannerHostDict下的方法
# 没有scan_result 扫描结果也就无法调用相应的方法了
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/python/lib/python3.6/site-packages/nmap/nmap.py", line 568, in __getitem__
return self._scan_result['scan'][host]
KeyError: 'scan'
正确示范
import nmap
nm = nmap.PortScanner()
# 需要注意的是使用 hostDict下的方法,得先扫描然后才能调用!!!!!
nm.scan('127.0.0.1', '22-443')
nm['127.0.0.1'].all_protocols() # ['tcp'] 获取协议
nm['127.0.0.1']['tcp'] # 获取tcp的结果
{22: {'state': 'open', 'reason': 'syn-ack', 'name': 'ssh', 'product': 'OpenSSH', 'version': '6.6.1', 'extrainfo': 'protocol 2.0', 'conf': '10', 'cpe': 'cpe:/a:openbsd:openssh:6.6.1'}}
udp检测
status = ['closed', 'closed|filtered']
addr = '192.168.9.39'
nm.scan(addr, '23450-23550', '-sU')
for port in nm[addr].all_udp():
xx = nm['192.168.9.39']['udp'][port]
if xx['state'] not in status:
print("端口: {} 状态: {}".format(port,xx['state']))
# 端口: 23456 状态: open|filtered
# 端口: 23457 状态: open|filtered
# 端口: 23459 状态: open|filtered
多线程扫描测试
一个地址多个端口: 多线程每次扫描一个结果 17.6秒, 不开结果一样
两个地址多个端口: 多线程每次扫描一个IP+多个端口 结果 17.6秒 不开结果也一样
三个地址多个端口: 多线程扫描结果17.6秒 不开 将近 35.96秒
结论: 如果扫描多个地址,那么就开多线程,如果是单个 开了无意义
demo-多线程
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# import os
# print(os.path.dirname(os.path.dirname(__file__)))
import queue
import time
import nmap
import threading
q = queue.Queue(10)
def xx(arg, que):
nm = nmap.PortScanner()
close = ['closed', 'unfiltered', 'closed | filtered']
ip = q.get()
scan = nm.scan(ip, '22,6379, 3307,3308,3309', '-sV')
print(scan)
for port in nm[ip].all_tcp():
status = nm[ip]['tcp'][port]["state"]
if status in close:
print("端口未开放")
print(port)
q.task_done()
if __name__ == '__main__':
ctime = time.time()
print(ctime)
for i in range(10):
x = threading.Thread(target=xx, args=(i, q))
x.setDaemon(True)
x.start()
# 注: 地址不通的情况下会报错,需另行处理
iplist = ['192.168.x.x','192.168.x.x', '192.168.x.x', '192.168.x.x']
for i in iplist:
q.put(i)
q.join()
etime = time.time()
print(etime)
print(etime - ctime) # 四次 17.901024103164673
普通扫描
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
import nmap
import time
stime = time.time()
nm = nmap.PortScanner()
close = ['closed', 'unfiltered', 'closed | filtered']
iplist = ['192.168.x.x','192.168.x.x', '192.168.x.x', '192.168.x.x']
for ip in iplist:
scan = nm.scan(ip, '22,6379, 3307,3308,3309', '-sV')
for port in nm[ip].all_tcp():
status = nm[ip]['tcp'][port]["state"]
if status in close:
print("端口未开放")
print(port)
etime = time.time()
print(etime - stime) # 单次 38.53420376777649
单独使用
nmap -O -Pn IP地址
# 识别系统
]# nmap -O -PN 192.168.9.158
Starting Nmap 6.40 ( http://nmap.org ) at 2019-09-05 14:04 CST
Nmap scan report for 192.168.9.158
Host is up (0.00045s latency).
Not shown: 991 closed ports
PORT STATE SERVICE
135/tcp open msrpc
139/tcp open netbios-ssn
445/tcp open microsoft-ds
3389/tcp open ms-wbt-server
49152/tcp open unknown
49153/tcp open unknown
49154/tcp open unknown
49160/tcp open unknown
49161/tcp open unknown
MAC Address: 00:50:56:8A:1B:2B (VMware)
Device type: general purpose
Running: Microsoft Windows 2008|7
OS CPE: cpe:/o:microsoft:windows_server_2008::sp2 cpe:/o:microsoft:windows_7::- cpe:/o:microsoft:windows_7::sp1 cpe:/o:microsoft:windows_8
OS details: Microsoft Windows Server 2008 SP2, Microsoft Windows 7 SP0 - SP1, Windows Server 2008 SP1, or Windows 8
Network Distance: 1 hop
TCP扫描:端口扫描中最稳定的,TCP三次握手
常用:nmap -sT -Pn ip地址
]# nmap -sT -Pn 127.0.0.1
Starting Nmap 6.40 ( http://nmap.org ) at 2019-09-05 14:06 CST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00015s latency).
Not shown: 996 closed ports
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
2222/tcp open EtherNet/IP-1
8011/tcp open unknown
完整:nmap -sT -p- -Pn ip地址
]# nmap -sT -p- -Pn 127.0.0.1
Starting Nmap 6.40 ( http://nmap.org ) at 2019-09-05 14:07 CST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000081s latency).
Not shown: 65530 closed ports
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
2222/tcp open EtherNet/IP-1
8011/tcp open unknown
37075/tcp open unknown
-sT TCP连接扫描(s=>哪种类型扫描? ==>t TCP类型)
-p- 扫描所有端口 (不加就默认扫描1000个常用端口)
-Pn 禁用Nmap网络发现功能,假定所有系统都是活动的
SYN 扫描:★端口扫描中用的最多的,TCP两次握手(隐形扫描,速度快)
常用:nmap -sS -Pn ip地址
]# nmap -sS -Pn 127.0.0.1
Starting Nmap 6.40 ( http://nmap.org ) at 2019-09-05 14:12 CST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.0000030s latency).
Not shown: 996 closed ports
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
2222/tcp open EtherNet/IP-1
8011/tcp open unknown