1#!/usr/bin/env python2#-*- coding: utf_8 -*-3#Date: 2015年10月23日4#Author:蔚蓝行5#博客 http://www.cnblogs.com/duanv/67fromipyimportIP8importthreading9importnmap10importtime11importsys12importsubPRocess13fromxml.domimportminidom1415defusage():16print'The script requires root privileges!'17print'example:python scan.py 192.168.0.1/24'1819#生成xml文件的模板函数20defaddResult(newresult):21globaldoc22globalscan_result2324ip = doc.createElement("ip")25ip.setAttribute("address", newresult["address"])2627osclass = doc.createElement("osclass")28osclass.appendChild(doc.createTextNode(newresult["osclass"]))29ip.appendChild(osclass)3031port = doc.createElement("port")3233tcp = doc.createElement("tcp")34tcp.appendChild(doc.createTextNode(newresult["tcp"]))35port.appendChild(tcp)3637udp = doc.createElement("udp")38udp.appendChild(doc.createTextNode(newresult["udp"]))39port.appendChild(udp)4041ip.appendChild(port)42scan_result.appendChild(ip)4344#扫描函数,调用nmap库45defip_scan(ip):46globalnm47#这里调用系统ping命令来判断主机存活48p = subprocess.Popen("ping -c 1 -t 1"+ip,stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell =True)49out =p.stdout.read()50#如过没有100%丢包则主机存活,对是否丢包的判断是抓取系统回显内容,测试用的是‘MAC OS X’系统,抓取内容为‘100.0% packet loss’51if'100.0% packet loss'notinout:52try:53#调用nmap扫描主机操作系统,同时进行SYN扫描和UDP扫描探测开放的端口54nm.scan(ip,arguments='-O -sS -sU -F')55sr={'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]}56addResult(sr)57except:58pass5960#循环,遍历未扫描的IP61defloop():62globalmutex63globalipx6465while1:66#线程锁,扫描一个IP就将IPX列表中的该IP移除67mutex.acquire()68#如果列表中没有IP,则跳出循环结束该线程69iflen(ipx)<=0:70mutex.release()71
break72ip=ipx[0]73ipx.remove(ipx[0])74mutex.release()75#调用扫描函数76ip_scan(str(ip))7778#创建线程的函数,默认创建40个79defcreat_threads():80threads=[]81foriinrange(40):82threads.append(threading.Thread(target=loop,))83fortinthreads:84t.start()85fortinthreads:86t.join()878889defstart():90#mutex:线程锁91globalmutex92#ipx:存储要扫描的IP地址段列表93globalipx94#nm:nmap模块扫描对象95globalnm96#doc:xml文档对象97globaldoc98#scan_result:xml文档的根元素99globalscan_result100101if'-h'== sys.argv[1]:102usage()103exit()104else:105#获取命令行输入的要扫描的IP段106ip=sys.argv[1]107#xml文档一些对象的初始化108doc =minidom.Document()109doc.appendChild(doc.createComment("scan_result xml."))110scan_result = doc.createElement("scan_result")111doc.appendChild(scan_result)112113#初始化参数114ipx=[]115nm=nmap.PortScanner()116mutex=threading.Lock()117118#调用IPy模块的IP函数,将IP地址段的每个IP存入列表119ipp=IP(ip, make_net=True)120forxinipp:121ipx.append(x)122#去掉首尾代表子网和全部主机的IP123ipx=ipx[1:-1]124125print("please wait...")126#计算时间127time_start=time.time()128#创建线程129creat_threads()130131time_end=time.time()132t=time_end-time_start133print'*'*48134print'\nTime:'+str(t)+'s'135print'Scan results have been saved to scan_result.xml.\n'136print'*'*48137138#xml文件操作139f = file("scan_result.xml","w")140f.write(doc.toprettyxml(indent ="\t", newl ="\n", encoding ="utf-8"))141f.close()142143if__name__=='__main__':144start()