Shadowsocks协议重定向攻击
Shadowsocks是一个基于SOCKS5的代理软件,其主要用途就不用解释了, 其协议存在漏洞,可以通过重定向攻击解密shadowsocks数据包密文。以下总结参考自Zhiniang Peng的研究成果
Shadowsocks工作原理
sslocal运行于本地,并监听某端口(默认1080)提供代理服务,ssserver运行于远程服务器,并监听某端口(默认8388)接收来自sslocal的数据
浏览器设置代理,所有请求首先发给sslocal,sslocal将数据进行加密后发给ssserver,ssserver解密数据包,并转发浏览器的请求,然后将结果加密返回,sslocal解密并返回给浏览器
client <—> ss-local <–[encrypted]–> ss-remote <—> target
可以通过pip安装python版Shadowsocks,在包存放路径下找到源码
python3 -m pip install shadowsocks
请求流程
sslocal通过发送以目标地址开头,后跟请求数据的包的密文来启动与ssserver的TCP连接
message=[target address][payload]
ciphertext=Stream_encrypt(key,IV,message)
最后发送的其实就是随机生成的16字节的IV+ciphertext
ssserver接收数据并解密
message=Stream_decrypt(key,IV,ciphertext)
并解析出[target address]
。 然后与[target address]
建立新的TCP连接,并向目标转发请求。ssserver接收到来自[target address]
的回复,进行加密并将其转发回sslocal,直到sslocal断开连接
sslocal收到的数据也是
随机生成的16字节的IV+response的密文
Address 格式
第一个字节用以说明地址类型
0x01:host是4字节的IPv4地址
0x03:host是可变长度的字符串,以1个字节开头作为长度,后跟最多255个字节的域名
0x04:host是一个16字节的IPv6地址
端口号是一个2字节无符号整数
[1-byte type][variable-length host][2-byte port]
AES-256-CFB
以AES-256-CFB加密方式为例
这种加密方式,明文和密文是等长的,解密过程如上。如果将密文的第一个块从c1修改为c1’,那么第一个明文块将从p1变为p1’,第二个分组的数据将会错误解密
他们的关系如下
c1’=xor(c1,r)
p1’=xor(p1,r)
请求重定向攻击
再回顾一下sslocal发送给ssserver的数据
IV+encrypt([target address][payload])
其中[payload]
是加密的无法得知,但如果能控制[target address]
并将其改为自己可控的服务器端[evil address]
再将修改后的包发送给ssserver,那么ssserver岂不是帮我们解密了[payload]
并且将请求转发到了[evil address]
假设使用的是IPv4地址,那么要构造一个[target address]
,就需要控制p1’的前7个字节,需要控制p1’的前7个字节就需要知道p1的前7个字节
而HTTP的响应包前7个字节是固定的,即HTTP/1.
攻击演示
服务端运行ssserver
客户端我用python版的时候有点小问题,所以就直接用这个了
用wireshark开始抓包,并使用curl通过代理请求百度,保存抓包结果p.pcapng
攻击代码
1 | from scapy.all import rdpcap |
在target_ip监听相应端口即可收到解密后的HTTP响应包