发表于IMC '20的,关于GFW检测和拦截Shadowsocks的文章,主要涉及主动探测攻击。
GFW Reporter | 中国如何检测和阻止Shadowsocks
原文标题:How China Detects and Blocks Shadowsocks 原文作者:Alice, Bob, Carol, Jan Beznazwy and Amir Houmansadr 原文链接:https://dl.acm.org/doi/abs/10.1145/3419394.3423644 发表会议:IMC'201、引言与基于机器学习的被动加密流量分析不同,本文侧重于主动探测攻击。
Shadowsocks早于2019年就被大范围封禁,目前已很少有人继续使用Shadowsocks,但其检测与封禁原理值得学习与借鉴,以用来思考如何进行暗网协议的检测与封禁。本文贡献如下:
揭示并系统研究了GFW应对Shadowsocks的方法。识别并指纹化不同类型的主动探测攻击,并推测其背后的意图。得出更真实的重放攻击对抗模型。提出了一种暂时但有效的规避策略,并提供了防御主动探测攻击的建议。与不同Shadowsocks版本的开发者合作,提高Shadowsocks对主动检测攻击的抵抗力。2、Shadowsocks原理Shadowsocks是一种加密代理协议,旨在通过加密流量来避免被审查机构封禁,而不是通过模仿其他协议。与传统VPN不同,Shadowsocks等代理协议重点在于代理,而传统VPN侧重于利用公网提供局域网服务。现如今许多VPN厂商也将规避策略应用于产品中,导致许多文献将代理协议与VPN混为一谈,我们暂不论其正误。
Shadowsocks有两个主要组成部分:客户端和服务端。通常,Shadowsocks服务端安装在审查控制之外的网络中。客户端将一个预访问的目标地址(例如,目标网站的IP和端口)加密发送给服务端,服务端连接到目标地址,并为客户端代理流量。客户端与服务端之间的所有流量都是加密的。
Shadowsocks使用两种加密方案:流密码(Stream Cipher) 和 AEAD密码(Authenticated Encryption with Associated Data Cipher)。
流密码(Stream Cipher):加密方式较弱,仅提供机密性,不提供完整性和认证,攻击者能够修改密文,而不被服务端发现,即服务端会尝试解密被修改的密文,并反馈给攻击者。因此单独使用流密码加密的方法被逐步弃用。AEAD密码(AEAD Cipher):AEAD(带有关联数据的身份验证加密)提供机密性、完整性和认证,是对流密码的改进,修复了流密码无法验证完整性与认证的缺陷,即攻击者修改密文后,服务端会发现密文被修改,并拒绝服务。Shadowsocks早期版本多用Stream Cipher,但由于其抵抗主动探测攻击的能力较弱,后续版本都已用AEAD Cipher替代。具体数据报格式可参考文献[1]。
3、探针的属性本节主要解决如下几个问题:
观察到哪些类型的探针?在什么条件下?这些探针来自哪里?探针是否具有指纹?包含哪些信息?代理连接建立之后,多久会出现探针?3.1 实验设计实验的目的是通过设置 Shadowsocks 服务器,诱使 GFW 主动探测并发送探针。实验使用了不同的Shadowsocks实现方式( Shadowsocks-libev 和 OutlineVPN),客户端通过 curl和浏览器向不同网站发送 HTTP 和 HTTPS 流量,实验捕获客户端和服务端的流量数据进行分析。实验为期四个月,涵盖了多个不同服务器和客户端配置,未使用任何混淆插件或特定防火墙规则。
3.2 探针类型本文将探针分为两大类:重放型探针(replay-based probes)和 随机型探针(seemingly random probes),并对其进行细分。
重放型探针(Replay-based probes):这些探针来源于先前记录的合法连接(即正常客户端代理请求)的首个数据包。其类型包括:
R1:完全相同的重放。R2:重放时,第0字节发生变化。R3:重放时,第0-7字节和第62-63字节发生变化。R4:重放时,第16字节发生变化。R5:重放时,第6字节和第16字节发生变化。其中,R3、R4 和 R5 类型的探针仅在 OutlineVPN 实验中出现,R5 探针在实验中只出现过2次。
随机型探针(Seemingly random probes):这些探针的长度变化较大,内容与任何已知的合法连接无关,属于“非重放”类型。其类型包括:
NR1:长度为 7-9、11-13、15-17、21-23、32-34、40-42 或 48-50 字节的探针。NR2:长度恰为 221 字节的探针。其中,NR1 类型探针的长度分布呈现以 8、12、16、22、33、41 和 49 字节为中心的三元组分布。
3.3 探针来源实验结果从 IP 地址 和 自治系统(AS) 两方面分析了探针来源。
实验中,共发现51837个探针,来自12300个不同的源 IP 地址,超过75%的 IP 地址发送了多个探针,且与前人研究得出的探测Tor网络等其它代理服务的IP重叠很小。发送探针的 IP 主要来源于 AS4837(联通骨干网) 和 AS4134(电信骨干网),此外还发现一些前人研究中未出现的自治系统(AS)。3.4 探针指纹本文通过分析数据包在IP层和TCP层的特征来对探针进行指纹识别。
IP层:研究人员IP ID字段没有明显特征,而 TTL 值在 46-50 之间。TCP层:约 90% 的探针使用了 32768-60999 范围内的源端口,这个范围是许多 Linux 内核的默认源端口范围;探针从未使用小于 1024 的源端口。探针的 TCP 时间戳(其增长速度因操作系统而异)显示,大量IP共享少数几个 TCP 时间戳序列,且有至少7个不同的物理系统或进程参与,并以其中一个为主。时间戳序列的线性增长速率大部分为 250 Hz,一小部分为 1000 Hz。3.5 重放攻击延迟根据实验所知,GFW 会记录正常代理客户端连接的第一个数据包,并在稍后作为主动探测的探针进行重放,还可能还会对其进行修改。
首次重放探测的延迟(橙色线)和所有重放探测的延迟(蓝色线)有所不同。20%以上的首次重放探测发生在 1 秒内,50%以上发生在 1 分钟内,75%以上发生在 15 分钟内。重放探测的延迟范围很广,最短为 0.28 秒,最长可达 570 小时。这表明 GFW 可能会立即发送探针,也可能将探针存储很长时间后再发送。
4、触发主动探测的原因本节主要解决如下几个问题:
触发主动探测需要多少流量?为什么 R3、R4 和 R5 类型的探针只发送到 OutlineVPN 服务端,而不发到 Shadowsocks-libev 服务端?GFW 是否考虑数据包的长度?GFW 是否考虑数据包负载的熵值?外部到内部连接(客户端在中国外,服务端在中国内)是否会像内部到外部连接那样引发大量主动探测?4.1 实验设计由于 Shadowsocks 数据流(加密后)是随机的,因此可以通过发送随机数据以代替真实客户端实现触发主动探测的功能。
该实验设计了一个发送随机数据的 TCP 客户端,连接到不同模式的服务器,以研究哪些特征能触发 GFW 的主动探测。实验使用两种服务器模式(sink 和 responding)并调整数据包的字节长度和熵值,通过在不同条件下观察 GFW 的响应,探索触发主动探测的关键特征。
sink 模式:服务端接收来自客户端的 TCP 连接请求,但不会返回任何数据。该模式主要用于观察没有响应的服务端是否会触发 GFW 的探测。responding 模式:服务端会向探测者返回随机数据,数据长度在 1 到 1000 字节之间。该模式用来测试 GFW 对带有实际响应的数据流的探测响应。4.2 实验结果分析小流触发探测:即使客户端向服务端仅发送一个数据包,也足以触发主动探测。这些探针类型与上节实验中观察到的7种类型相同。特定包长触发重放探测:触发重放探测的包长通常在160到700字节之间,且包长模16后的余数具有一定规律。高熵数据包更易触发重放探测:所有熵值的数据包都可能被重放,但高熵(7.2)包触发探测的概率几乎是低熵(3.0)包的四倍。R3和R4探针依赖于R1和R2探针:R3和R4类型的探针只有在服务端已经响应R1和R2类型探针后才会发送,这表明GFW的主动探测系统是分阶段进行的,只有在观察到特定条件时,才会进入下一个阶段。出现新类型探针:GFW发出了一些新类型的探针,包括重放型探针(16到32字节之间的变化)和非重放型探针,证明了GFW在进行主动探测时不断变化。GFW不区分流量方向:无论服务端在中国境内还是境外,都会触发GFW的主动探测。这与前人发现的自外而内的Tor连接不会触发主动探测不同,表明GFW在针对不同协议有不同对策。5、探针的意图作者开发了探测模拟器,以用来模拟GFW。通过对比Shadowsocks服务器与非Shadowsocks服务器在响应探针上的差异,来推测GFW识别Shadowsocks服务器的原理。
5.1 随机型探针的意图不同的Shadowsocks实现方式对不同长度的随机型探针有不同的响应(包括TIMEOUT、RST和FIN/ACK),具体与加密方法(流加密或AEAD加密)以及初始化向量(IV)或盐的大小有关。
流加密的Shadowsocks-libev v3.0.8–v3.2.5:在使用流加密的Shadowsocks-libev v3.0.8–v3.2.5版本时,当初始化向量(IV)为8字节时(其余长度类似),服务端对随机探针的响应取决于探针的长度。 (1)当探针长度为1-8字节时,服务端总是超时,因为它只接收到了部分IV,正在等待剩余目标规范。 (2)当探针长度为9-14字节时,服务端会立即发送RST,因为它收到了错误的不完整的目标规范。 (3)当探针长度为15字节或以上时,服务端会有三种响应:RST、TIMEOUT以及FIN/ACK,具体响应取决于探针是否恰好被解密为有效的目标规范。解密失败会响应RST。但若解密出有效的目标规范,服务器会尝试连接目标,但由于目标(一个随机的IP或主机名)通常是无效的,连接会失败,服务器会发送FIN/ACK;如果连接未立即失败,服务新尝试重新连接,从而出现TIMEOUT情况。AEAD加密的Shadowsocks-libev v3.0.8–v3.2.5:在使用AEAD加密的Shadowsocks-libev v3.0.8–v3.2.5版本时,盐长取16字节(其余盐长类似)。 (1)当探针长度小于或等于50字节时,服务端会超时等待剩余目标规范,因为它需要足够的数据来解析报文,即盐值(16字节)、加密长度前缀(2字节)、加密长度标签(16字节)和另一个标签(16字节),共50字节。 (2)当接收到51字节或更多数据时,服务端会尝试解密数据,但由于身份验证错误(与流密码不同,AEAD密码提供了完整性和认证机制,几乎不可能碰巧通过身份认证),服务器会立即发送RST。Shadowsocks-libev v3.3.1–v3.3.3的变化:在新版本中,为了抵抗部分主动探测攻击,服务端不再像旧版本那样在不满足目标范式(Stream)或认证错误(AEAD)时立即返回RST,而是返回TIMEOUT,以减少特征。OutlineVPN v1.0.6的响应:OutlineVPN仅使用AEAD加密,探测包小于50字节时会超时,50字节的包则立即发送FIN/ACK,而大于50字节的包会因认证错误触发RST。OutlineVPN v1.0.7–v1.0.8的变化:从v1.0.7开始,OutlineVPN的服务器会始终响应TIMEOUT,以减少特征。由此可知,攻击者通过对随机型探针响应的统计分析,可以识别Shadowsocks服务器,并可能推测出使用的加密方式、实现版本等信息。比如,通过观察RST或TIMEOUT的概率,攻击者可以推测出IV长度以及对应的加密算法。
5.2 重放型探针的意图在基于重放的探测中,服务器对重放型探针的响应取决于是否有重放防御机制。
没有重放防御机制:没有重放防御机制的服务器(如OutlineVPN v1.0.6–v1.0.8)对相同重放型探针响应一致,攻击者可以通过检查响应推测代理协议。例如,攻击者可以通过 R4 重放型探针枚举修改所有 255 个字节的值,精确地确定每种响应的概率,以确定是否为Shadowsocks协议。具有重放防御机制:即使有重放防御机制(如Shadowsocks-libev使用Bloom过滤器),使用AEAD加密时,服务器对相同字节修改的重放响应一致,而使用流加密时响应不一致,攻击者仍可以通过此特征得到一些信息。6、GFW封禁机制GFW根据某种规则,对IP或者端口进行封禁。GFW在封禁Shadowsocks服务器后不会定期检查其是否仍继续运行。GFW虽然探测到Shadowsocks服务器,但仅封禁其中少数。7、规避策略Shadowsocks的检测分为两个阶段:(1)被动识别可疑连接;(2)对服务器进行主动探测,因此可以通过规避被动检测或以不导致封禁的方式响应主动探测来避免被封禁。
7.1 流量分析防御通过改变客户端到服务器的数据包长度,例如使用Brdgrd,可以有效避免GFW的流量分析,从而减少主动探测。但Brdgrd自身存在指纹识别、TCP窗口不一致及可能导致连接失败的局限性,因此不能作为永久的解决方案。
7.2 主动探测防御添加认证机制:仅使用AEAD加密算法,以避免Shadowsocks流加密中的认证缺失问题,从而防止利用密文可篡改性进行探测攻击。基于随机数和时间的重放过滤:通过结合时间戳和随机数来防止重放攻击,从而避免仅依靠随机数的防御机制带来的不对称问题。一致的服务器响应:为避免服务器被识别,Shadowsocks等代理协议应确保在正常操作和错误发生时响应一致,从而防止通过TCP标志和时序元数据触发指纹识别。总结本文主要探讨了GFW如何通过主动探测技术识别并封禁Shadowsocks代理服务。通过实验,分析了GFW对Shadowsocks的探测方式,包括重放型探针和随机型探针,揭示了探针的来源、指纹特征及其背后的探测意图。文章还探讨了如何通过优化Shadowsocks协议的防御机制,如采用AEAD加密、重放过滤机制和一致的服务器响应策略,来提高对主动探测攻击的抵抗力。最后,提出了流量分析和主动探测的规避策略。
References[1] Shadowsocks: A secure SOCKS5 proxy. https://github.com/shadowsocks/shadowsocks-org/blob/master/whitepaper/whitepaper.md, 2019-01-04.