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