1 #!/usr/bin/env python 2 # -*- coding: utf_8 -*- 3 # Date: 2015年10月23日 4 # Author:蔚蓝行 5 # 博客 http://www.cnblogs.com/duanv/ 6 7 from IPy import IP 8 import threading 9 import nmap 10 import time 11 import sys 12 import subprocess 13 from xml.dom import minidom 14 15 def usage(): 16 print 'The script requires root privileges!' 17 print 'example:python scan.py 192.168.0.1/24' 18 19 #生成xml文件的模板函数 20 def addResult(newresult): 21 global doc 22 global scan_result 23 24 ip = doc.createElement("ip") 25 ip.setAttribute("address", newresult["address"]) 26 27 osclass = doc.createElement("osclass") 28 osclass.appendChild(doc.createTextNode(newresult["osclass"])) 29 ip.appendChild(osclass) 30 31 port = doc.createElement("port") 32 33 tcp = doc.createElement("tcp") 34 tcp.appendChild(doc.createTextNode(newresult["tcp"])) 35 port.appendChild(tcp) 36 37 udp = doc.createElement("udp") 38 udp.appendChild(doc.createTextNode(newresult["udp"])) 39 port.appendChild(udp) 40 41 ip.appendChild(port) 42 scan_result.appendChild(ip) 43 44 #扫描函数,调用nmap库 45 def ip_scan(ip): 46 global nm 47 #这里调用系统ping命令来判断主机存活 48 p = subprocess.Popen("ping -c 1 -t 1 "+ip,stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = True) 49 out = p.stdout.read() 50 #如过没有100%丢包则主机存活,对是否丢包的判断是抓取系统回显内容,测试用的是‘MAC OS X’系统,抓取内容为‘100.0% packet loss’ 51 if '100.0% packet loss' not in out: 52 try: 53 #调用nmap扫描主机操作系统,同时进行SYN扫描和UDP扫描探测开放的端口 54 nm.scan(ip,arguments='-O -sS -sU -F') 55 sr={'address':ip,'osclass':str(nm[ip]['osclass'])[1:-1],'tcp':str(nm[ip].all_tcp())[1:-1],'udp':str(nm[ip].all_udp())[1:-1]} 56 addResult(sr) 57 except: 58 pass 59 60 #循环,遍历未扫描的IP 61 def loop(): 62 global mutex 63 global ipx 64 65 while 1: 66 #线程锁,扫描一个IP就将IPX列表中的该IP移除 67 mutex.acquire() 68 #如果列表中没有IP,则跳出循环结束该线程 69 if len(ipx)<=0: 70 mutex.release() 71 break 72 ip=ipx[0] 73 ipx.remove(ipx[0]) 74 mutex.release() 75 #调用扫描函数 76 ip_scan(str(ip)) 77 78 #创建线程的函数,默认创建40个 79 def creat_threads(): 80 threads=[] 81 for i in range(40): 82 threads.append(threading.Thread(target=loop,)) 83 for t in threads: 84 t.start() 85 for t in threads: 86 t.join() 87 88 89 def start(): 90 #mutex:线程锁 91 global mutex 92 #ipx:存储要扫描的IP地址段列表 93 global ipx 94 #nm:nmap模块扫描对象 95 global nm 96 #doc:xml文档对象 97 global doc 98 #scan_result:xml文档的根元素 99 global scan_result 100 101 if '-h' == sys.argv[1]: 102 usage() 103 exit() 104 else: 105 #获取命令行输入的要扫描的IP段 106 ip=sys.argv[1] 107 #xml文档一些对象的初始化 108 doc = minidom.Document() 109 doc.appendChild(doc.createComment("scan_result xml.")) 110 scan_result = doc.createElement("scan_result") 111 doc.appendChild(scan_result) 112 113 #初始化参数 114 ipx=[] 115 nm=nmap.PortScanner() 116 mutex=threading.Lock() 117 118 #调用IPy模块的IP函数,将IP地址段的每个IP存入列表 119 ipp=IP(ip, make_net=True) 120 for x in ipp: 121 ipx.append(x) 122 #去掉首尾代表子网和全部主机的IP 123 ipx=ipx[1:-1] 124 125 print("please wait...") 126 #计算时间 127 time_start=time.time() 128 #创建线程 129 creat_threads() 130 131 time_end=time.time() 132 t=time_end-time_start 133 print '*'*48 134 print ' Time:'+str(t)+'s' 135 print 'Scan results have been saved to scan_result.xml. ' 136 print '*'*48 137 138 #xml文件操作 139 f = file("scan_result.xml","w") 140 f.write(doc.toprettyxml(indent = " ", newl = " ", encoding = "utf-8")) 141 f.close() 142 143 if __name__=='__main__': 144 start()