Python調用nmap掃描網段主機信息生成xml


  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 '\nTime:'+str(t)+'s'
135         print 'Scan results have been saved to scan_result.xml.\n'
136         print '*'*48
137         
138         #xml文件操作
139         f = file("scan_result.xml","w")
140         f.write(doc.toprettyxml(indent = "\t", newl = "\n", encoding = "utf-8"))
141         f.close()
142 
143 if __name__=='__main__':
144     start()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM