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()

 

posted @ 2015-10-23 21:14  荆书凝  阅读(4821)  评论(2编辑  收藏  举报