-
Notifications
You must be signed in to change notification settings - Fork 550
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
利用防重放机制自动对 Shadowsocks、VMess 等未知流量代理进行“隐蔽式拒绝服务攻击” #184
Comments
其实只会阻断这类协议:未知流量、0-RTT、有重放过滤器, |
——谁杀了我,而我又杀了谁? ——是我杀了我? |
“因噎废食”式攻击 |
墙变身为延迟复读机,你发什么他就发什么,你向梯子服务器建立一个连接他也建立一个连接。不同的是,他抢在你发的内容发出去之前就把你发的内容发出去了,而这个延迟是加给你的。 那么,当一个 IV 通过了后续的 AEAD 解密有效性检验并被加入反重放过滤器中时,来自客户端的、到达较晚的 IV 反而会触发重放检测,让客户端的整个连接变成无限读,直接实质上瘫痪代理。 这个由 rprx 提出的攻击的原理非常简单,部署起来可以说技术难度很小,虽然会有很大概率误伤正常服务,但不排除有在极端时期被墙针对性利用的可能。 |
如果在有实质有效数据转发后再将相应数据放进反重放过滤器,能否缓解该问题? |
能用是能用了,但如果里面是个无状态的服务,就很可能给对面回了一份一模一样的包,就把自己给卖了…… |
确实棘手,, |
正常的服务通常有握手鉴权机制,并且因此没有重放过滤器,即使某中间人无法识别给这么操作一波,基本上不会受影响。 而这些代理是不能有握手鉴权机制的,否则公开后会成为强特征。所以这是一个死局,还可以按比例干扰,非常恶心。 |
对了,防重放机制不一定都无限读, |
有意思,间歇性阻断就VANS了。 |
能否把客户端本身的ip也加入协议中作为一个特征?如果只是简单的重放的话ip肯定会变动,校验失败的直接丢掉? |
|
这确实是个很棘手的问题,可能需要移除过滤器并且重新设计协议才能彻底解决现在遇到的问题。 基本上我会赞成先移除过滤器,再考虑下一步协议要怎么改。
客户端本机是很大概率是没办法直接知道自身的外网IP的,所以做IP校验是不可行的。 |
可以通过访问某个外网特定的获取IP地址的接口来实现? |
这个是不现实的,外部接口如果设在国外GFW可以直接墙,设在国内可以直接找你麻烦。另外外部接口的做法无法应对多出口会变IP这种情况(比如某些运营商的透传或者小区黑宽带)。 |
可以用 Xray-core 的 TPROXY + sniffing + Freedom 改改代码来模拟出这种攻击。 |
Hi rprx, Great job discovering this attack! Blow are the description of the adversary, the proof of concept and our comments on this attack. AdversaryThis attack requires an in-path adversary to:
The attack is clever because the blocking will be connection-based, which potentially causes less collateral damage comparing to port-based or IP-based blocking. It can thus be especially useful when the GFW cannot accurately determine whether the server is for circumvention or not. Proof of conceptLet's get a traffic capture of the first packet sent from legitimate client to server. Note that it can be any Shadowsocks implementation and any encryption method. ss-server -s 127.0.0.1 -p 8388 -m aes-256-gcm -k "mypassword"
ss-local -s 127.0.0.1 -p 8388 -m aes-256-gcm -k "mypassword" -l 1080
curl -x socks5h://127.0.0.1:1080 -v http://example.com We then save the captured hex stream of the first legitimate packet to a file called echo "b0cee48154f678d86bb11ef35c4a069fedd6c7748ceca018702f104a6f52b22b9119ac97fb74c9de333a57fedcd71c604672e1a875f93ec46ae9fa1526459721638a7f3d042e96d34cab26ea4f61a9fe86b4efdc6b1f41edac458802b284bc339b7432f128256b3301b7e80460a2a0e5630b494cbd31a8532d8420c8e792be449f76100d862c2e60e12bc9d20fc706a6cc0bd522f785b6c3aadd1b5f24c2cf22b08cfeddc21918d28730ef800c48a6b2546d405562de1f11d74e5946e2a9" > payload We prepare a head -c 64 payload > salt Now, we start the server again using: ss-server -s 0.0.0.0 -p 8388 -m aes-256-gcm -k "mypassword" First we send the salt and close the connection: xxd -r -p salt | nc -vn 127.0.0.1 8388 As expected, Shadowsocks-rust server will complain, but no worry, our salt has been remembered: ERROR failed to decode Address, may be wrong method or key, from client 127.0.0.1:51930, error: timed out Now, we simulate the delayed legitimated connection: xxd -r -p payload | nc -vn 127.0.0.1 8388 The server will not respond to the delayed legitimate client because it detects repeated salt: ERROR failed to decode Address, may be wrong method or key, from client 127.0.0.1:51932, error: detected repeated iv/salt Affected Shadowsocks implementationsUsing the method above, we tested Shadowsocks-rust v1.8.23 and Shadowsocks-libev v3.3.3 on February 1, 2021. While apparently all Shadowsocks implementations with nonce-based replay filter will suffer from the replay of a complete legitimate payload, exclusively sending the salt is sufficient to block Shadowsocks-rust v1.8.23 connections. A simple salt replay will not block Shadowsocks-libev and Outline's connection because these two implementations will only remember the salts if the following length tag and payload tag are authenticated. Note that we did not test Outline ourselves, but we were told by Outline developer @fortuna that Outline server would authenticate before remembering the salt back to October 2020. CommentsBelow, we argue that additional effort is required for the GFW to deploy this seemingly easy attack. This is because this attack requires in-path capability, while evidence suggests that the GFW traffic analysis system has been designed to be on-path. We believe similar rationale applies to the other newly discovered vulnerability. The difference between an in-path and on-path system is clearly introduced by Wang et al. in section 2.1:
In this proposed attack, the adversary has to buffer and delay the legitimate packet for at least a large amount of time: That being said, we conjecture that the censor would use a hybrid approach to implement such attacks. The censor may first conduct on-path traffic analysis, and then capture and buffer only a few legitimate connection using in-path devices based on IP-port pair. In fact, if such a hybrid approach is implemented, the censor can identify Shadowsocks servers with many new attacks by blocking and/or modifying legitimate connections. For example, although we have not tested it against other protocol, it seems to be rare for a server that respond to a certain payload only for the first time, but not any other time. Finally, we realized that Shadowsocks community are proposing a potential upgrade to the Shadowsocks protocol. We thus encourage Shadowsocks community to read this post by us. You may find it helpful because that post contains our thoughts on how to make a more probe-resistant circumvention service based on our findings of the GFW. For example, the attack above could be mitigated as suggested in the post:
|
感谢 @gfw-report 进行详尽的测试,我的补充如下:
|
It appears that, at least for Shadowsocks-libev v3.3.5, it requires both the length tag and the payload tag to be properly authenticated before the replay filter remembers a nonce. Thus a 50-byte truncation may not be sufficient. We conduct the following test: We prepare a xxd -r -p payload | head -c 50 > salt_len_lentag.bin Now, we start the server again using: ss-server -s 0.0.0.0 -p 8388 -m aes-256-gcm -k "mypassword" We send the salt, length field and length tag; and then close the connection: nc -vn 127.0.0.1 8388 < salt_len_lentag.bin Now, we simulate the delayed legitimated connection: xxd -r -p payload | nc -vn 127.0.0.1 8388 It turned out that the server would still respond to the delayed legitimate client.
We agreed that the delay could possibly be short. As shown in Figure 7, the minimal observed delay of a replay was
We agreed that it requires a probing experiment to the real world network like what Frolov et al. did in Section 3.B. |
|
@fortuna I'm contacting you via Keybase |
如果server對每個連接都也生成一個新的IV(可能的話再加以長度干擾參數),應該可以避免回包一模一樣吧? |
如果將握手鑑權與Payload結合呢?當然我一直覺得完整鑑權的意義不是很大。重放只對第一個包有效,server也很容易察覺重放,改變對重放的處理方案(不應該直接取消,應用程式server不應該收到兩次包)以及解決樓上的問題(或許ECC前向安全原理可以做到相關機制?)就能解決很大部分的問題。 |
@RPRX If GFW is bothered enough to launch such attack, why doesn't it just blacklist the server IP? What assumptions do you hold about GFW for this attack to be realistic? |
It is difficult for GFW to determine whether a weakly-characterized encrypted connection carries the Shadowsocks service. Of course, if GFW knows that a server provides Shadowsocks, it will block that server. |
@QChWnd You're repeating me. Let me rephrase it: in what scenario would GFW choose to launch this hypothetical attack instead of just simply banning the suspected server IP address or dropping uncategorized traffic altogether? |
目前 Server 端回复已经是每个 Session 独立生成一个 IV (Salt) 的了(也就是Client和Server之间使用的收发IV是不一样的)。
I'm not sure if GFW can establish TCP connections by spoofing the IPs of other users in China. But if GFW can do this, then I'm afraid it will be difficult to block suspicious IPs. Because blocking such IPs will likely affect normal users. |
The current misjudgment rate of GFW does not seem to be high, perhaps it does not want to bring misjudgments. |
That's a completely different issue. See the quote above by @gfw-report about on-path vs in-path systems. For performance and reliability reasons it's relatively safe to assume GFW is on-path, so it has limited capabilities to establish TCP streams on behalf of real users. |
因为这种方式可以 精准过滤掉所有 符合“未知流量 + 0-RTT + 有重放过滤器”的协议,附带伤害相对最小,且不需要其它辅助手段。 高下立判。 |
如果不能做任何形式的鑑權(比如Server發現重放過多,向Client提出鑑權請求等),天衣無縫的抗包長分析確實幾乎不能實現(考慮效率,多餘長度一般不能太長,多次重放也可以察覺。拆成多包等手段當然也可以做,但效果估計不好)。但我個人認為多次重放包長度相似並不能夠作為強特徵。 |
@RPRX For this attack to be deployable, GFW needs to be in-path, which is unlikely. See the quote above by @gfw-report. Assuming an in-path GFW (a very big IF given the tradeoffs), injecting extra bytes into encrypted streams will result in disruption for most protocols in use today—the collateral damage would be way too high. Correct me if wrong, but I think that you're also implicitly assuming anti-replay defense would block attacking IP for this attack to be useful. But that's not the default behavior in all official SS implementations. I remain unconvinced this attack is realistic in production. |
首包重放為啥會沒有包含有效的Payload呢 XD |
SNI 阻断是怎么做到的? 并且这里不是 |
I believe that GFW has such strength. See GFW's experimental TLS MITM on GitHub. |
SNI 阻断、ESNI 封锁等已被证实且可被复现的攻击方式表明他们有能力进行 连接级的实时流量分析及进一步操作 并且这里的目标是未知流量,而不是所有流量,从而排除了绝大多数已知协议比如 TLS、HTTP,它们应该占 99% 综合下来,我没有看到明显的 |
我希望補充一點:ESNI的DPI&丟包的時代相比RST阻斷時代的實現成本可能已經不同了。並且兩套系統之無縫配合或許可以說明GFW具有某種強大的負載均衡機制。 |
From the perspective of the receiver there's no observable difference: If GFW is sending using the same source IP, it's effectively injecting bytes to the stream.
Still, why not just drop unknown traffic altogether? Additionally, one instance of this attack will only cause a single stream to be blackholed by the anti-replay defense (unless the server also blocks the attacking IP which will cause long-term damage). The collateral damage would be all the unknown traffic because no modern encrypted stream protocols can tolerate injection. |
very big difference. GFW initiates a new TCP connection for replay. |
@QChWnd My bad. Now I see the point of this attack 😂 I was misled by the in-path vs on-path discussion above. |
Well then the only recourse would be a handshake, in which case it's better to just use TLS with all its overhead :( |
我猜测gfw有这样做的能力,但是没有这样做的必要 |
不太理解是什么意思,ss的实现里,不是先检查密文的完整性再检测salt的唯一性吗? |
@Howard0o0 墙给你到服务器的包加一个大的延迟,然后自己另开一个连接复读你发的内容。 |
@DuckSoft 原来如此,明白了 |
在中国连上代理服务器再访问中国服务器的网站,很容易被分析出来吧。 国内用户 > 代理服务器 > 访问国内网站; 防火墙可以捕获记录: 例如: 模型为: 如果代理服务器接收了非常多中国用户主动连接的同时,又大量访问服务器中国的网站。有明显是代理行为。 两套关联分析可以比较容易识别出代理行为。 目前发现全局代理时,非常容易被临时全局阻断代理服务器的TCP数据。 |
不用改代理實現的解決方案比如加個海外中轉或者在Server上套Warp等。Client上鏈式代理也可以。改代理實現的解決方案也有如mux等。 |
偽造ip无法建立TCP会话, 只能发一发UDP。当然这个不是代理软件问题,可能得自己加一层代理。 |
是可以的,因為是一台牆內與一台牆外偽源機器一唱一和。為防止真正的牆外IP收到並回覆,可以把牆內機發包TTL改至正好能出牆。 |
由于 #183 ,我在研究“对服务端与客户端的逐字节重放”,并且取得了一些成果,此时又开了一下脑洞:
如果布隆过滤器被人恶意打满呢?不过可操作性不强,还有太多未知变量。接着就想到了如题:众所周知,某中间人一直在对未知流量进行重放,导致现在大多数实现都有防重放机制。
而利用服务端的防重放,中间人不需要破坏连接,只需提前发送未知流量的前 32 个字节(或更多),即可使这些代理实质性失效。
不需要封锁任何 IP 或端口,精准阻断未知流量类代理。 某种程度上还是无解的,允许重放又会存在问题。
这个机制简单可行,好消息是,它尚未被部署,坏消息是,一旦部署会很棘手。
The text was updated successfully, but these errors were encountered: