1 #coding=utf-8 2 3 import nmap 4 import optparse 5 import threading 6 import sys 7 import re 8 ''' 9 需安装python_nmap包,支持2.x以及3.x 10 python_nmap包提供了python调用nmap的一系列接口 11 12 (一)重要类及方法: 13 1.创建nmap扫描器 14 class PortScanner() 15 __init__(self, nmap_search_path=('nmap', '/usr/bin/nmap', '/usr/local/bin/nmap', '/sw/bin/nmap', '/opt/local/bin/nmap')) 16 Initialize PortScanner module 17 18 * detects nmap on the system and nmap version 19 * may raise PortScannerError exception if nmap is not found in the path 20 21 :param nmap_search_path: tupple of string where to search for nmap executable. Change this if you want to use a specific version of nmap. 22 :returns: nothing 23 2.扫描器方法 24 scan(self, hosts='127.0.0.1', ports=None, arguments='-sV', sudo=False) 25 Scan given hosts 26 27 May raise PortScannerError exception if nmap output was not xml 28 29 Test existance of the following key to know if something went wrong : ['nmap']['scaninfo']['error'] 30 If not present, everything was ok. 31 32 :param hosts: string for hosts as nmap use it 'scanme.nmap.org' or '198.116.0-255.1-127' or '216.163.128.20/20' 33 :param ports: string for ports as nmap use it '22,53,110,143-4564' 34 :param arguments: string of arguments for nmap '-sU -sX -sC' 35 :param sudo: launch nmap with sudo if True 36 37 :returns: scan_result as dictionnary 38 39 (二)例子 40 import nmap 41 scanner = nmap.PortScanner() #nmap_search_path已包含了nmap所在路径,若默认路径中没有nmap,则需指出 42 results = scanner.scan(hosts='192.168.2.1',ports='80') 43 pprint.pprint(results) 44 {'nmap': {'command_line': 'nmap -oX - -p 80 -sV 192.168.2.1', 45 'scaninfo': {'tcp': {'method': 'syn', 'services': '80'}}, 46 'scanstats': {'downhosts': '0', 47 'elapsed': '11.59', 48 'timestr': 'Thu Jul 21 10:08:34 2016', 49 'totalhosts': '1', 50 'uphosts': '1'}}, 51 'scan': {'192.168.2.1': {'addresses': {'ipv4': '192.168.2.1', 52 'mac': 'D0:C7:C0:6A:F6:A0'}, 53 'hostnames': [], 54 'status': {'reason': 'arp-response', 55 'state': 'up'}, 56 'tcp': {80: {'conf': '3', 57 'cpe': '', 58 'extrainfo': '', 59 'name': 'http', 60 'product': '', 61 'reason': 'no-response', 62 'state': 'filtered', 63 'version': ''}}, 64 'vendor': {'D0:C7:C0:6A:F6:A0': 'Tp-link ' 65 'Technologies'}}}} 66 67 ''' 68 def anlyze_port(target_port): 69 #解析-p参数传入的值,返回端口列表 70 try: 71 pattern = re.compile(r'(d+)-(d+)') #解析连接符-模式 72 match = pattern.match(target_port) 73 if match: 74 start_port = int(match.group(1)) 75 end_port = int(match.group(2)) 76 return([x for x in range(start_port,end_port + 1)]) 77 else: 78 return([int(x) for x in target_port.split(',')]) 79 except Exception as err: 80 print('请注意错误1:',sys.exc_info()[0],err) 81 print(parser.usage) 82 exit(0) 83 84 def portscanner(target_host,target_port): 85 scanner = nmap.PortScanner() 86 results = scanner.scan(hosts=target_host,ports=target_port,arguments='-T4 -A -v -Pn ') #禁ping的快速扫描 87 print('扫描语句是:',results['nmap']['command_line']) 88 print('[*]主机' + target_host + '的' + str(target_port) + '端口状态为:' + results['scan'][target_host]['tcp'][int(target_port)]['state']) 89 90 def main(): 91 usage = 'Usage:%prog --host <target_host> --port <target_port>' 92 parser = optparse.OptionParser(usage,version='v1.0') 93 parser.add_option('--host',dest='target_host',type='string', 94 help='需要扫描的主机,域名或IP') 95 parser.add_option('--port',dest='target_port',type='string', 96 help='需要扫描的主机端口,支持1-100或21,53,80两种形式') 97 (options,args) = parser.parse_args() 98 if options.target_host == None or options.target_port == None: 99 print(parser.usage) 100 exit(0) 101 else: 102 target_host = options.target_host 103 target_port = options.target_port 104 105 target_port = anlyze_port(target_port) 106 for port in target_port: 107 t = threading.Thread(target=portscanner,args=(target_host,str(port))) 108 t.start() 109 110 if __name__ == '__main__': 111 main()
运行后的结果为:
1 c:python34python.exe NmapScanner.py --host 192.168.1.1 --port 80 2 扫描语句是: nmap -oX - -p 80 -T4 -A -v -Pn 192.168.1.1 3 [*]主机192.168.1.1的80端口状态为:filtered