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     #?????ж??????????????????????ж?????????????????????????‘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()