python编写类似nmap的扫描工具

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python编写类似nmap的扫描工具相关的知识,希望对你有一定的参考价值。

本文主要是利用scapy包编写了一个简易扫描工具,支持ARP、ICMP、TCP、UDP发现扫描,支持TCP SYN、UDP端口扫描,如下:

 1 usage: python scan.py <-p ping扫描类型> <-s 端口发现类型> [-t target] [--port ports]
 2 
 3 简单扫描工具,可以进行存活扫描及端口扫描.
 4 存活扫描包括:ARP扫描、ICMP扫描、TCP扫描、UDP扫描.
 5 端口扫描包括:TCP SYN扫描、TCP ACK扫描、TCP FIN扫描.
 6 
 7 optional arguments:
 8   -h, --help         show this help message and exit
 9   -v, --version      show programs version number and exit
10 
11 target group:
12   用于设置IP、PORT参数
13 
14   --target TARGET    target为IP或IP段,如192.168.1.1,192.168.1.x,或1
15                      92.168.1.1-254
16   --port PORT        port为待扫描的端口,如21,80,...或21-80
17 
18 ping group:
19   用于开启存活扫描相关选项
20 
21   -p                 开启存活扫描
22   --ARP              启动ARP扫描
23   --ICMP             启动ICMP扫描
24   --TCP              启动TCP扫描
25   --UDP              启动UDP扫描
26 
27 port scan group:
28   用于开启端口扫描相关选项
29 
30   -s                 开启端口扫描
31   --SYN              开启SYN扫描
32   --ACK              开启ACK扫描
33   --FIN              开启FIN扫描
34   --UPORT            开启UDP端口扫描
35 
36 utils group:
37   用于开启扫描过程中的一些实用选项
38 
39   --timeout TIMEOUT  设置发包超时时间,默认0.5秒
40   --retry RETRY      设置发包重试次数,默认不重试
41 
42 以上做为说明,祝好运!

一、发现扫描

1.首先进行ARP扫描

python scan.py -p --target 192.168.1.1-254 --ARP
[+]IP: 192.168.1.1 => MAC: 14:75:90:xx:xx:xx
[+]IP: 192.168.1.111 => MAC: c6:36:55:xx:xx:xx
[+]总共耗时9.84091806412秒.

通过retry参数增加发包尝试次数,如下:

1  python scan.py -p --target 192.168.1.1-254 --ARP --retry 2
2 [+]IP: 192.168.1.1 => MAC: 14:75:90:xx:xx:xx
3 [+]IP: 192.168.1.111 => MAC: c6:36:55:xx:xx:xx
4 [+]IP: 192.168.1.102 => MAC: 58:1f:28:xx:xx:xx
5 [+]IP: 192.168.1.114 => MAC: 6c:8d:c1:xx:xx:xx
6 [+]IP: 192.168.1.103 => MAC: 84:38:38:xx:xx:xx
7 [+]总共耗时20.429942131秒.

2.使用ICMP扫描,若没有指定任何扫描类型参数,默认会启用ICMP扫描,如下:

1 python scan.py -p --target 192.168.1.1-254
2 [+]没有指定任何ping扫描方式,默认选择ICMP扫描
3 [+]IP:主机192.168.1.1 echo-reply.
4 [+]IP:主机192.168.1.111 echo-reply.
5 [+]总共耗时10.7177450657秒.

通过timeout参数,设置较长的超时,可以防止网络状况不好造成的丢包,如下:

1 python scan.py -p --target 192.168.1.1-254 --timeout 2
2 [+]没有指定任何ping扫描方式,默认选择ICMP扫描
3 [+]IP:主机192.168.1.1 echo-reply.
4 [+]IP:主机192.168.1.111 echo-reply.
5 [+]IP:主机192.168.1.114 echo-reply.
6 [+]总共耗时10.7566649914秒.

3.使用TCP扫描

 1 python scan.py -p --target 192.168.1.100-120 --TCP --timeout 1
 2 [+]请稍等,时间较长!
 3 [!]扫描... 192.168.1.100
 4 [!]扫描... 192.168.1.101
 5 [!]扫描... 192.168.1.102
 6 [!]扫描... 192.168.1.103
 7 [!]扫描... 192.168.1.104
 8 [!]扫描... 192.168.1.105
 9 [!]扫描... 192.168.1.106
10 [!]扫描... 192.168.1.107
11 [!]扫描... 192.168.1.108
12 [!]扫描... 192.168.1.109
13 [!]扫描... 192.168.1.110
14 [!]扫描... 192.168.1.111
15 [!]扫描... 192.168.1.112
16 [!]扫描... 192.168.1.113
17 [!]扫描... 192.168.1.114
18 [!]扫描... 192.168.1.115
19 [!]扫描... 192.168.1.116
20 [!]扫描... 192.168.1.117
21 [!]扫描... 192.168.1.118
22 [!]扫描... 192.168.1.119
23 [!]扫描... 192.168.1.120
24 [+]正在处理扫描信息.
25 
26 
27 ====================
28 [+]主机 192.168.1.102 在线.
29 [+]主机 192.168.1.103 在线.
30 [+]主机 192.168.1.111 在线.
31 [+]主机 192.168.1.114 在线.
32 [+]总共耗时16.4359779358秒.

4.使用UDP扫描

 1 python scan.py -p --target 192.168.1.100-120 --UDP --retry 3
 2 [+]请稍等,时间较长!
 3 [!]扫描... 192.168.1.100
 4 [!]扫描... 192.168.1.101
 5 [!]扫描... 192.168.1.102
 6 [!]扫描... 192.168.1.103
 7 [!]扫描... 192.168.1.104
 8 [!]扫描... 192.168.1.105
 9 [!]扫描... 192.168.1.106
10 [!]扫描... 192.168.1.107
11 [!]扫描... 192.168.1.108
12 [!]扫描... 192.168.1.109
13 [!]扫描... 192.168.1.110
14 [!]扫描... 192.168.1.111
15 [!]扫描... 192.168.1.112
16 [!]扫描... 192.168.1.113
17 [!]扫描... 192.168.1.114
18 [!]扫描... 192.168.1.115
19 [!]扫描... 192.168.1.116
20 [!]扫描... 192.168.1.117
21 [!]扫描... 192.168.1.118
22 [!]扫描... 192.168.1.119
23 [!]扫描... 192.168.1.120
24 [+]正在处理扫描信息.
25 
26 
27 ====================
28 [+]主机 192.168.1.102 在线.
29 [+]主机 192.168.1.103 在线.
30 [+]主机 192.168.1.111 在线.
31 [+]主机 192.168.1.114 在线.
32 [+]总共耗时33.5198891163秒.

二、端口扫描

1、TCP SYN端口扫描,不设置端口参数,则默认扫描1-1024端口

 1 python scan.py --target 192.168.1.110-115 -s --SYN
 2 [+]没有指定任何扫描端口,默认扫描1-1024
 3 [!]扫描... 192.168.1.110
 4 [!]扫描... 192.168.1.111
 5 [!]扫描... 192.168.1.112
 6 [!]扫描... 192.168.1.113
 7 [!]扫描... 192.168.1.114
 8 [!]扫描... 192.168.1.115
 9 [+]正在处理扫描信息.
10 
11 
12 ====================
13 [+]主机 192.168.1.111 开放的TCP端口有:[80]
14 [+]总共耗时165.125555992秒.

扫描指定端口:

 1 python scan.py --target 192.168.1.1-254 -s --SYN --port 80 --timeout 1
 2 [!]扫描... 192.168.1.1
 3 [!]扫描... 192.168.1.2
 4 [!]扫描... 192.168.1.3
 5 [!]扫描... 192.168.1.4
 6 ...
 7 [!]扫描... 192.168.1.253
 8 [!]扫描... 192.168.1.254
 9 [+]正在处理扫描信息.
10 
11 
12 ====================
13 [+]主机 192.168.1.111 开放的TCP端口有:[80]
14 [+]主机 192.168.1.1 开放的TCP端口有:[80]
15 [+]总共耗时9.72222185135秒.

2、扫描UDP端口

1 python scan.py --target 192.168.1.1 -s --UPORT --timeout 1
2 [+]没有指定任何扫描端口,默认扫描1-1024
3 [!]扫描... 192.168.1.1
4 [+]正在处理扫描信息.
5 
6 
7 ====================
8 [+]主机 192.168.1.1 开放的UDP端口有:[520]
9 [+]总共耗时27.4742250443秒.

也可同时进行发现扫描与端口扫描,如下:

 1 python scan.py --target 192.168.1.1-254 -p --ARP -s --SYN --port 80 --timeout 1 --retry 2
 2 [+]IP: 192.168.1.1 => MAC: 14:75:90:xx:xx:xx
 3 [+]IP: 192.168.1.102 => MAC: 58:1f:28:xx:xx:xx
 4 [+]IP: 192.168.1.114 => MAC: 6c:8d:c1:xx:xx:xx
 5 [+]IP: 192.168.1.103 => MAC: 84:38:38:xx:xx:xx
 6 [+]IP: 192.168.1.101 => MAC: 5c:f7:e6:xx:xx:xx
 7 [!]扫描... 192.168.1.1
 8 [!]扫描... 192.168.1.2
 9 ...
10 [!]扫描... 192.168.1.253
11 [!]扫描... 192.168.1.254
12 [+]正在处理扫描信息.
13 
14 
15 ====================
16 [+]主机 192.168.1.1 开放的TCP端口有:[80]
17 [+]主机 192.168.1.111 开放的TCP端口有:[80]
18 [+]总共耗时45.2775988579秒.

 

OK,最后附上源码:

  1 import argparse
  2 import re
  3 import time
  4 import threading
  5 from scapy.all import *
  6 
  7 import logging
  8 logging.getLogger(scapy.runtime).setLevel(logging.ERROR)
  9 
 10 
 11 class Discovery_Scan(object):
 12     ‘‘‘
 13     说明:用于发现扫描
 14     ‘‘‘
 15 
 16     def __init__(self,args,timeout=0.5,retry=0):
 17         self.targets = parse_target(args)
 18         self.timeout = timeout
 19         self.retry = retry
 20 
 21     def arp_scan(self,pdst):
 22         #ARP发现扫描
 23         ans = sr1(ARP(pdst=pdst),timeout=self.timeout,retry=self.retry,verbose=False)
 24         if ans:
 25             if ans[ARP].op == 2:    #操作码为2是is-at,是ARP响应
 26                 print [+]IP: %s => MAC: %s % (pdst,ans[ARP].hwsrc)
 27 
 28     def icmp_scan(self,dst):
 29         #ICMP发现扫描
 30         ans = sr1(IP(dst=dst)/ICMP(),timeout=self.timeout,retry=self.retry,verbose=False)
 31         if ans:
 32             if ans[ICMP].type == 0: #ICMP type为0表示是ICMP echo-reply
 33                 print [+]IP:主机%s echo-reply. % dst
 34 
 35     tcp_info = {}
 36     def tcp_scan(self,dst,port):
 37         #TCP SYN,发送TCP SYN包,有响应表示端口开放
 38         ans,unans = sr(IP(dst=dst)/TCP(sport=RandShort(),dport=port,flags=S),
 39                        timeout=self.timeout,retry=self.retry,verbose=False)
 40         if ans.res:
 41             if ans.res[0][0][IP].dst not in Discovery_Scan.tcp_info:
 42                 Discovery_Scan.tcp_info[ans.res[0][0][IP].dst] = True
 43 
 44     udp_info = {}
 45     def udp_scan(self,dst,port):
 46         #UDP,发送UDP包,有响应表示端口开放
 47         ans,uans = sr(IP(dst=dst)/UDP(sport=RandShort(),dport=port),
 48                       timeout=self.timeout,retry=self.retry,verbose=False)
 49         if ans.res:
 50             if ans.res[0][0][IP].dst not in Discovery_Scan.udp_info:
 51                 Discovery_Scan.udp_info[ans.res[0][0][IP].dst] = True
 52 
 53 class Port_Scan(object):
 54     ‘‘‘
 55     说明:用于进行端口扫描,判断端口是否开放
 56     ‘‘‘
 57     def __init__(self,args,timeout=0.5,retry=0):
 58         self.targets = parse_target(args)
 59         self.timeout = timeout
 60         self.retry = retry
 61 
 62     syn_port_dict = {}
 63     def syn_port_scan(self,dst,port):
 64         #TCP SYN端口扫描,若SYN包返回携带SYN、ACK(即TCP.flags=18)标志的包,则表明此端口打开。
 65         ans,uans = sr(IP(dst=dst)/TCP(sport=RandShort(),dport=port,flags=S),
 66                       timeout=self.timeout,retry=self.retry,verbose=False)
 67         if ans:
 68             first_respons_pkt = ans.res[0][1]
 69             if first_respons_pkt[TCP] and first_respons_pkt[TCP].flags == 18:
 70                 if first_respons_pkt[IP].src not in Port_Scan.syn_port_dict:
 71                     Port_Scan.syn_port_dict[first_respons_pkt[IP].src] = [first_respons_pkt[TCP].sport]
 72                 else:
 73                     Port_Scan.syn_port_dict[first_respons_pkt[IP].src].append(first_respons_pkt[TCP].sport)
 74 
 75     udp_port_dict = {}
 76     def udp_port_scan(self,dst,port):
 77         #UDP端口扫描,若UDP端口返回ICMP port-unreachable,则表示端口打开。(排除某些主机对任何UDP端口的探测都响应为ICMP port-unrechable)
 78         ans,uans = sr(IP(dst=dst)/UDP(sport=RandShort(),dport=port),
 79                       timeout=self.timeout, retry=self.retry, verbose=False)
 80         if ans.res and ans.res[0][1].haslayer(UDPerror):
 81             first_respons_pkt = ans.res[0][1]
 82             if first_respons_pkt[IP].src not in Port_Scan.udp_port_dict:
 83                 Port_Scan.udp_port_dict[first_respons_pkt[IP].src] = [first_respons_pkt[UDPerror].dport]
 84             else:
 85                 Port_Scan.udp_port_dict[first_respons_pkt[IP].src].append(first_respons_pkt[UDPerror].dport)
 86 
 87 def parse_opt():
 88     ‘‘‘
 89     @说明:通过argparse模块解析程序传入的参数
 90     @return:args
 91     ‘‘‘
 92     usage = python %(prog)s <-p ping扫描类型> <-s 端口发现类型> [-t target] [--port ports]
 93     description = 简单扫描工具,可以进行存活扫描及端口扫描.\n  94                   存活扫描包括:ARP扫描、ICMP扫描、TCP扫描、UDP扫描.\n  95                   端口扫描包括:TCP SYN扫描、TCP ACK扫描、TCP FIN扫描.
 96     epilog = 以上做为说明,祝好运!
 97     parser = argparse.ArgumentParser(usage=usage,description=description,epilog=epilog,version=v1.0)
 98 
 99     target_group = parser.add_argument_group(target group,description=用于设置IP、PORT参数)
100     target_group.add_argument(--target,dest=target,action=store,
101                               help=target为IP或IP段,如192.168.1.1,192.168.1.x,或192.168.1.1-254)
102     target_group.add_argument(--port,dest=port,action=store,
103                               help=port为待扫描的端口,如21,80,...或21-80)
104 
105     ping_group = parser.add_argument_group(ping group,description=用于开启存活扫描相关选项)
106     ping_group.add_argument(-p,dest=ping,action=store_true,help=开启存活扫描)
107     ping_group.add_argument(--ARP,dest=ARP,action=store_true,help=启动ARP扫描)
108     ping_group.add_argument(--ICMP,dest=ICMP,action=store_true,help=启动ICMP扫描)
109     ping_group.add_argument(--TCP,dest=TCP,action=store_true,help=启动TCP扫描)
110     ping_group.add_argument(--UDP,dest=UDP,action=store_true,help=启动UDP扫描)
111 
112     port_scan_group = parser.add_argument_group(port scan group,description=用于开启端口扫描相关选项)
113     port_scan_group.add_argument(-s,dest=scan,action=store_true,help=开启端口扫描)
114     port_scan_group.add_argument(--SYN,dest=SYN,action=store_true,help=开启SYN扫描)
115     port_scan_group.add_argument(--ACK,dest=ACK,action=store_true,help=开启ACK扫描)
116     port_scan_group.add_argument(--FIN,dest=FIN,action=store_true,help=开启FIN扫描)
117     port_scan_group.add_argument(--UPORT, dest=UPORT, action=store_true, help=开启UDP端口扫描)
118 
119     utils_group = parser.add_argument_group(utils group,description=用于开启扫描过程中的一些实用选项)
120     utils_group.add_argument(--timeout,dest=timeout,action=store,type=float,help=设置发包超时时间,默认0.5秒)
121     utils_group.add_argument(--retry,dest=retry,action=store,type=int,help=设置发包重试次数,默认不重试)
122 
123     args = parser.parse_args()
124     if not args.ping and not args.scan:
125         print [-]必须通过-p/-s选项开启一种扫描
126         print \n
127         parser.print_help()
128         exit(1)
129     elif not args.target:
130         print [-]必须通过--target选项指定扫描的对象
131         print \n
132         parser.print_help()
133         exit(1)
134     if args.ping:
135         if not args.ARP and not args.ICMP and not args.TCP and not args.UDP:
136             args.ICMP = True  #若没有指定任何ping扫描方式,则默认选择ICMP扫描
137             print [+]没有指定任何ping扫描方式,默认选择ICMP扫描
138     if args.scan:
139         if not args.SYN and not args.ACK and not args.FIN and not args.UPORT:
140             args.SYN = True   #若没有指定任何端口扫描方式,则默认选择SYN扫描
141             print [+]没有指定任何端口扫描方式,默认选择SYN扫描
142         if not args.port:
143             args.port = 1-1024    #若没有指定任何扫描端口,则默认扫描1-1024
144             print [+]没有指定任何扫描端口,默认扫描1-1024
145 
146     return args
147 
148 def parse_target(args):
149     ‘‘‘
150     @说明:用于解析如‘192.168.1.1,192.168.1.x,...或192.168.1.1-254‘格式的IP为单独的IP,用于解析如‘21,80,...或21-80‘格式的端口为单独的端口
151     @param: args,一个namespace对象
152     @return: (ip_list,port_list)
153     ‘‘‘
154     pattern1 = r\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$
155     pattern2 = r\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}-\d{1,3}$
156     pattern3 = r\d{1,5}$
157     pattern4 = r\d{1,5}-\d{1,5}$
158     ip_list,port_list = None,None
159     if args.target:
160         if re.search(pattern1,args.target):
161             ip_list = args.target.split(,)
162         elif re.match(pattern2,args.target):
163             _split = args.target.split(-)
164             first_ip = _split[0]
165             ip_split = first_ip.split(.)
166             ipdot4 = range(int(ip_split[3]), int(_split[1]) + 1)
167             ip_list = [ip_split[0] + . + ip_split[1] + . + ip_split[2] + . + str(p) for p in ipdot4]
168         else:
169             print [-]target格式输入有误,请查看帮助!
170             exit(1)
171     if args.port:
172         if re.match(pattern4,args.port):
173             _split = args.port.split(-)
174             port_list = range(int(_split[0]),int(_split[1])+1)
175         elif re.search(pattern3,args.port):
176             port_list = args.port.split(,)
177         else:
178             print [-]port格式输入有误,请查看帮助!
179             exit(1)
180     return ip_list,port_list
181 
182 
183 def main():
184     ‘‘‘
185     @说明:扫描的主程序,首先根据条件创建Ping扫描或端口扫描对象,然后调用相关的扫描方法进行扫描。
186     ‘‘‘
187     args = parse_opt()
188     if args.ping: #是否启动Ping扫描
189         if not args.timeout and not args.retry:
190             obj_ping = Discovery_Scan(args)
191         elif args.timeout and not args.retry:
192             obj_ping = Discovery_Scan(args,timeout=args.timeout)
193         elif not args.timeout and args.retry:
194             obj_ping = Discovery_Scan(args,retry=args.retry)
195         else:
196             obj_ping = Discovery_Scan(args,args.timeout,args.retry)
197         ip_list = obj_ping.targets[0]
198         if ip_list:
199             #ARP扫描
200             if args.ARP:
201                 for pdst in ip_list:
202                     t = threading.Thread(target=obj_ping.arp_scan,args=(pdst,))
203                     t.start()
204                 while threading.activeCount() != 1:     #避免线程还没有运行完就提前输出不全的结果
205                     time.sleep(1)
206             #ICMP扫描
207             elif args.ICMP:
208                 for dst in ip_list:
209                     t = threading.Thread(target=obj_ping.icmp_scan,args=(dst,))
210                     t.start()
211                 while threading.activeCount() != 1:     #避免线程还没有运行完就提前输出不全的结果
212                     time.sleep(1)
213             #TCP扫描
214             elif args.TCP:
215                 port_list = [80,443,21,22,23,25,53,135,139,137,445,1158,1433,1521,3306,3389,7001,8000,8080,9090]
216                 print [+]请稍等,时间较长!
217                 for dst in ip_list:
218                     print [!]扫描...,dst
219                     for port in port_list:
220                         t = threading.Thread(target=obj_ping.tcp_scan,args=(dst,port))
221                         t.start()
222 
223                 print [+]正在处理扫描信息.
224                 while threading.activeCount() != 1:     #避免线程还没有运行完就提前输出不全的结果
225                     time.sleep(1)
226 
227                 if not obj_ping.tcp_info:
228                     print \n
229                     print = * 20
230                     print [+]未发现在线主机.
231                 else:
232                     print \n
233                     print = * 20
234                     for ip_a in sorted(obj_ping.tcp_info.keys()):
235                         print [+]主机 %s 在线. % ip_a
236             #UDP扫描
237             elif args.UDP:
238                 port_list = [7,9.13,15,37,53,67,68,69,135,137,138,139,445,520]
239                 print [+]请稍等,时间较长!
240                 for dst in ip_list:
241                     print [!]扫描...,dst
242                     for port in port_list:
243                         t = threading.Thread(target=obj_ping.udp_scan,args=(dst,port))
244                         t.start()
245 
246                 print [+]正在处理扫描信息.
247                 while threading.activeCount() != 1:     #避免线程还没有运行完就提前输出不全的结果
248                     time.sleep(1)
249 
250                 if not obj_ping.udp_info:
251                     print \n
252                     print = * 20
253                     print [+]未发现在线主机.
254                 else:
255                     print \n
256                     print = * 20
257                     for ip_a in sorted(obj_ping.udp_info.keys()):
258                         print [+]主机 %s 在线. % ip_a
259     if args.scan:   #是否启动端口扫描
260         if not args.timeout and not args.retry:
261             obj_port = Port_Scan(args)
262         elif args.timeout and not args.retry:
263             obj_port = Port_Scan(args,timeout=args.timeout)
264         elif not args.timeout and args.retry:
265             obj_port = Port_Scan(args,retry=args.retry)
266         else:
267             obj_port = Port_Scan(args,args.timeout,args.retry)
268 
269         ip_list,port_list = obj_port.targets
270         if ip_list and port_list:
271             if args.SYN:
272                 for dst in ip_list:
273                     print [!]扫描...,dst
274                     for port in port_list:
275                         t = threading.Thread(target=obj_port.syn_port_scan,args=(dst,int(port)))
276                         t.start()
277 
278                 print [+]正在处理扫描信息.
279                 while threading.activeCount() != 1:     #避免线程还没有运行完就提前输出不全的结果
280                     time.sleep(1)
281 
282                 if not obj_port.syn_port_dict:
283                     print \n
284                     print = * 20
285                     print [+]未发现开放TCP端口.
286                 else:
287                     print \n
288                     print = * 20
289                     for k,v in obj_port.syn_port_dict.items():
290                         print [+]主机 %s 开放的TCP端口有:%s % (k,str(v))
291             elif args.ACK:
292                 pass    #基本不能使用
293             elif args.FIN:
294                 pass    #基本不能使用
295             elif args.UPORT:
296                 for dst in ip_list:
297                     print [!]扫描...,dst
298                     for port in port_list:
299                         t = threading.Thread(target=obj_port.udp_port_scan,args=(dst,int(port)))
300                         t.start()
301 
302                 print [+]正在处理扫描信息.
303                 while threading.activeCount() != 1:     #避免线程还没有运行完就提前输出不全的结果
304                     time.sleep(1)
305 
306                 if not obj_port.udp_port_dict:
307                     print \n
308                     print = * 20
309                     print [+]未发现开放UDP端口.
310                 else:
311                     print \n
312                     print = * 20
313                     for k,v in obj_port.udp_port_dict.items():
314                         print [+]主机 %s 开放的UDP端口有:%s % (k,str(v))
315 
316 if __name__ == __main__:
317     try:
318         start_time = time.time()
319         main()
320         stop_time = time.time()
321         print [+]总共耗时+str(stop_time-start_time)+秒.
322     except Exception,e:
323         print [-]执行出错,具体错误见下面信息.
324         print e

 

以上是关于python编写类似nmap的扫描工具的主要内容,如果未能解决你的问题,请参考以下文章

用python编写nmap扫描工具--采用协程的方式

使用 python nmap 模块扫描从先前扫描生成的主机

nmap基本命令使用

Python-通过调用Nmap来进行端口扫描

Python3小工具——结合nmap扫描

端口扫描器--利用python的nmap模块