Python Socket Scanner 笔记-企

当端口打开时,向端口发送 TCP SYN 请求,会返回一个 ACK 响应:www.njtw123.com

  

  当端口关闭,返回的是 RST响应:

  

  所以可以用 socket 编写一个小脚本来测试主机端口的开启情况,基本代码如下:

  

复制代码
 1 # coding: utf-8
 2 
 3 import socket
 4 from datetime import datetime
 5 
 6 # Set time-out to get the scanning fast
 7 socket.setdefaulttimeout(0.5)
 8 
 9 # Ask for input//http://www.njtw123.com/
10 remote_server = raw_input("Enter a remote host to scan:")
11 remote_server_ip = socket.gethostbyname(remote_server)
12 
13 # Print a nice banner with info on which host we are about to scan
14 print '-' * 60
15 print 'Please wait, scanning remote host ', remote_server_ip
16 print '-' * 60
17 
18 # Check what time the scan started
19 t1 = datetime.now()
20 
21 # Using the range function to specify ports(1 - 1024)
22 # We also put in some error handling for catching errors
23 try:
24     for port in range(1,1025):
25         sock = socket.socket(2,1) # 2:socket.AF_INET 1:socket.SOCK_STREAM
26         res = sock.connect_ex((remote_server_ip,port))
27         if res == 0:
28             print 'Port {}: OPEN'.format(port)
29         sock.close()
30 
31 except socket.gaierror:
32     print 'Hostname could not be resolved.Exiting'
33 
34 except socket.error:
35     print "Could't connect to the server"
36 
37 # Check the time now
38 t2 = datetime.now()
39 
40 # Calculates the difference of time //www.njtw123.com
41 total = t2 - t1
42 
43 # Print the info to screen
44 print 'Scanning Completed in: ', total
复制代码

参考:http://www.pythonforbeginners.com/code-snippets-source-code/port-scanner-in-python/

程序测试结果如下:

www.njtw123.com

看出来 在 socket 的超时时间设置为0.5的前提下 依然需要花费 8分27秒才能够把周知端口号扫完,有没有其他方式加快扫描速度?答案是有的。

******************** 该部分可以略过,一个小坑

打开 抓到的数据包列表,发现 timeout 包都会发送2个“伪重传”,发送这两个一般没什么用的数据包会占用 CPU的处理时间,自己分析连续两个端口的时间间隔就会发现

:间隔是0.5s(由 39号、46号、53号数据包分析得出),这恰好是在程序中设置的超时时间。

 

这样的话,1个端口0.5的超时等待,扫描一个主机的 1- 1024 号端口所用时间是可以大致估算下的:

1024 * 0.5 / 60 = 8.53 分钟左右。和上面程序实际扫描的时间(8分27秒)相符合。

 

所以对于这种时间主要花费在 socket 连接( 非 CPU 计算密集型 )的程序 可以使用 多线程来提升效率,

这里选择使用内建的库 multiprocessing.dummy 来实现多线程扫描:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# coding: utf-8
'''<br>  多线程 Socket TCP 端口扫描器  by: EvilCLAY<br>'''
import  socket
from  datetime  import  datetime
from  multiprocessing.dummy  import  Pool as ThreadPool
 
remote_server  =  raw_input ( "Enter a remote host to scan:" )
remote_server_ip  =  socket.gethostbyname(remote_server)
ports  =  []
 
print  '-'  *  60
print  'Please wait, scanning remote host ' , remote_server_ip
print  '-'  *  60
 
 
socket.setdefaulttimeout( 0.5 )
 
def  scan_port(port):
     try :
         =  socket.socket( 2 , 1 )
         res  =  s.connect_ex((remote_server_ip,port))
         if  res  = =  0 # 如果端口开启 发送 hello 获取banner
             print  'Port {}: OPEN' . format (port)
         s.close()
     except  Exception,e:
         print  str (e.message)
 
 
 
for  in  range ( 1 , 1025 ):
     ports.append(i)
 
# Check what time the scan started
t1  =  datetime.now()
 
 
pool  =  ThreadPool(processes  =  8 )
results  =  pool. map (scan_port,ports)
pool.close()
pool.join()
 
print  'Multiprocess Scanning Completed in  ' , datetime.now()  -  t1

扫描的结果如下:

可以发现 8 个线程并行发起请求,效率有很大的提升。
在被扫描主机未安装连接限制软件的前提下,测试了开启不同线程扫描所花费的时间 :

16 个线程 使用 32 秒扫完;www.njtw123.com
32个线程,使用 16 秒扫完;
64个线程,使用 8 秒扫完;
128个线程,使用 4 秒扫完;
256个线程,使用 2 秒扫完;
512个线程,使用 1.50 秒扫完;
1024个线程,使用 1.25 秒扫完;
在这里一共扫 1024 个端口,开更多的线程也没了意义。
www.njtw123.com
这和我早先接触到的一个概念 : " 多线程程序应该把线程个数 设置成 CPU 的核心数 * 2" 并不符合 。 我还是更相信实践, 查查相关资料后再说这个问题。

获取 Banner www.njtw123.com
把 函数修改成如下 即可:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def  scan_port(port):
     try :
         =  socket.socket( 2 , 1 )
         res  =  s.connect_ex((remote_server_ip,port))
         if  res  = =  0 # 如果端口开启 发送 hello 获取banner
 
             try :
                 s.send( 'hello' )
                 banner  =  s.recv( 1024 )
 
 
             except  Exception,e:
                 print  'Port {}: OPEN' . format (port)
                 print  str (e.message)
             else :
                 print  'Port {}: OPEN' . format (port)
                 print  'Banner {}' . format (banner)
 
         s.close()
     except  Exception,e:
         print  str (e.message)//http://www.njtw123.com/

  晚上研究下 Zmap 与 ZGrab 分析下 www.njtw123.com 这两款神器牛在什么地方 ~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值