Socks5代理用户名密码批量认证爆破工具

前言:

Angel有1w个socks5代理的账号,要验证哪些还能用,哪些不能用,然后就有了这个工具.

在网上查了下相关的工具,基本上都是用curl设置代理,接着去请求一个公网上的一个脚本.也就是说你要批量验证,就得还有一个服务器.成本有些大.

于是就有了现在这篇文章和下面的这个工具了.

项目地址 https://coding.net/u/medicean/p/socks5validate/git

思路:

先说下我们验证的思路吧,就是把用户名和密码发送给server,然后根据返回的报文来看有没有验证成功.这个过程不需要第三方参与.

从协议开始:

老规矩,从协议开始.看协议的东西,RFC文档是最好的东西了.直接去查RFC文档了.

根据RFC1928文档: http://www.rfc-editor.org/rfc/rfc1928.txt

1.Client to Server

Client连接到Server,并发送一个版本,客户端支持的认证方式的一个报文,让服务器选择,格式如下:

1
2
3
4
5
+----+----------+----------+
|VER | NMETHODS | METHODS |
+----+----------+----------+
| 1 | 1 | 1 to 255 |
+----+----------+----------+

VER : socks协议版本号,这里就是x05.

NMETHODS: Client支持的认证的方式个数,我们本次只对用户名密码这种方式进行认证,所以个数就是x01

METHODS:认证方法.

下面是RFC文档中给出的已经有的取值

1
2
3
4
5
6
7
8
The values currently defined for METHOD are:

o X'00' NO AUTHENTICATION REQUIRED
o X'01' GSSAPI
o X'02' USERNAME/PASSWORD
o X'03' to X'7F' IANA ASSIGNED
o X'80' to X'FE' RESERVED FOR PRIVATE METHODS
o X'FF' NO ACCEPTABLE METHODS

于是我们这里就取x02就好.

so,可以想到第一步的payload就是:
payload1='\\x05\\x01\\x02'

2.Server To Client

Server在接收到Client的请求之后,Server会从Client支持的验证方式中选择一个合适的验证方法,告诉Client.格式如下:

1
2
3
4
5
+----+--------+
|VER | METHOD |
+----+--------+
| 1 | 1 |
+----+--------+

很简单的报文.就不分析了.

3.Client to Server

Client在收到Server返回的报文之后,提供相应的凭据给Server. RFC1929 是socks5用户名密码认证方式的说明.

客户端发送的报文格式如下:

1
2
3
4
5
+----+------+----------+------+----------+
|VER | ULEN | UNAME | PLEN | PASSWD |
+----+------+----------+------+----------+
| 1 | 1 | 1 to 255 | 1 | 1 to 255 |
+----+------+----------+------+----------+

VER:版本号

ULEN:用户名的长度

UNAME:用户名

PLEN:密码长度

PASSWD:密码

图中的数字代表该字段的字节数.

所以我们就可以构造第二步的payload了.

1
2
3
4
username='test'
password='testpass'

payload2=struct.pack('!BB'+str(len(username))+'sB'+str(len(password))+'s',1,len(username),username,len(password),password)

4.Server to Client

Client提供认证凭据给Server,Server返回认证结果.

报文格式也是简单粗暴:

1
2
3
4
5
+----+--------+
|VER | STATUS |
+----+--------+
| 1 | 1 |
+----+--------+

VER:版本号

STATUS:状态.

状态这里,如果认证成功就是x00 如果不成功,返回的就不是\\x00

值得注意的是,VER 包含了子版本号,所以会出现返回 \\x05\\x00\\x01\\x00 这种情况,我之前的代码就没考虑到这些

编码实现

分析到这里,已经可以编码了.代码如下:

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
debug=False
def validate(host,port,username,password):
try:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
socket.setdefaulttimeout(20)
s.connect((host,port))
payload1='\\x05\\x01\\x02'#socks 5 版本1 02采用用户名密码验证
s.send(payload1)
data1=s.recv(1024)
if data1!='\\x05\\x02': # Server response 05 02 use username/password validate
if debug:
print "Don't support user/pass auth"
s.close()
return False
#send validate data
#version len(username) username len(password) password
payload2=struct.pack('!BB'+str(len(username))+'sB'+str(len(password))+'s',1,len(username),username,len(password),password)
s.send(payload2)
data2=s.recv(1024)
if data2[1] =='\\x00': #success
if debug:
print 'username:%stPassword:%s---Success!'%(username,password)
Flag=True
else:
if debug:
print 'Auth Fail!'
Flag=False
s.close()
except:
if debug:
print 'validate host:%s with %s/%s occurred some exception.'
Flag=False
if s:
s.close()

return Flag

这样只是对一个主机进行认证,要做到批量,就写个for,加个外壳就好了,这里就不说这些了.要爆破什么的,都是在这个基础上搞了…

最后再贴上源码地址: https://coding.net/u/medicean/p/socks5validate/git