• 请不要在回答技术问题时复制粘贴 AI 生成的内容
whoami9894
V2EX  ›  程序员

5hadow5ocks 的 TCP 流处理是不是有缺陷啊

  •  
  •   whoami9894 · Mar 18, 2020 · 3253 views
  •   You need to sign in to view this topic
    This topic created in 2400 days ago, the information mentioned may be changed or developed.

    下午在看 5hadow5ocks AEAD 算法的重定向攻击,简单看了一下源码,版本号是 2.8.2

    发现它支持的加密算法都是流密码,猜测它内部是不是没做 TCP 的上层分包,发现果然是。大体 sslocal 和 ssserver 的通信逻辑:

    1. 客户端通过 sslocal 本地的 Socks5 客户端向 target 发请求,Socks5 握手结束后,sslocal 调用 Encryptor.encrypt(data)加密数据,在向 ssserver 建立 TCP 连接时会在数据头部附上固定长度的 IV。数据长度被扩展为 len(DATA) + len(IV)

    2. ssserver 端的 eventloop 在on_read事件触发时调用_on_local_read,注意到这里只是简单的data = self._remote_sock.recv(BUF_SIZE),接着就调用 ENcryptor.decrypt 解密。decrypt 的逻辑是:

      if self.decipher is None:
          decipher_iv_len = self._method_info[1]
          decipher_iv = buf[:decipher_iv_len]
          print('IV: ', decipher_iv.encode('hex'))
          self.decipher = self.get_cipher(self.key, self.method, 0,
                                          iv=decipher_iv)
          buf = buf[decipher_iv_len:]
          if len(buf) == 0:
              return buf
      return self.decipher.update(buf)
      

      看出该条 TCP 连接后续的解密都会用这第一个包发来的 IV。解密完成后直接往对端的 socket 写了

    那么问题来了,在没有做分包的情况下,按现在代码的逻辑,self._remote_sock.recv()如果分两次 read 才拿到完整的 IV,就直接把第一次小于 16bytes 的数据设置成当前 TCPRelay 的 IV (虽然概率不大,但考虑极端情况)这里应该考虑一下边界处理吧

    我担心是自己哪里思考错了,所以实验了一下,在上面代码中加了一行 print,结果确实存在问题,分两次发数据连接直接 closed 了

    IV:  6f
    2020-03-18 17:39:42 WARNING  unsupported addrtype 194, maybe wrong password or encryption method
    2020-03-18 17:39:42 ERROR    can not parse header when handling connection from 127.0.0.1:59824
    
    23 replies  •  2020-03-20 07:42:09 +08:00
    wweir
        1
    wweir  
       Mar 18, 2020 via Android
    ss 协议不坐混淆的话,特征太大,基本不能用
    有空还是研究下其它能用的协议吧
    exkernel
        2
    exkernel  
       Mar 18, 2020
    提个 PR 改善一下?
    wevsty
        3
    wevsty  
       Mar 18, 2020
    并没有觉得这样处理有什么问题。
    G2bN4dbX9J3ncp0r
        4
    G2bN4dbX9J3ncp0r  
       Mar 18, 2020
    @wweir trojan
    wweir
        5
    wweir  
       Mar 18, 2020 via Android
    @lidashuang 嗯,我自己也写了一个,规则更加智能点,使用方便点
    G2bN4dbX9J3ncp0r
        6
    G2bN4dbX9J3ncp0r  
       Mar 18, 2020
    @wweir 厉害, 规则方面我都用 surge
    love4taylor
        7
    love4taylor  
       Mar 18, 2020 via Android
    去提个 issue 不就完了。
    whoami9894
        8
    whoami9894  
    OP
       Mar 18, 2020
    @exkernel
    @Love4Taylor
    那倒没必要,这个问题现实中触发概率也不大;发帖只是记录一下而已
    whoami9894
        9
    whoami9894  
    OP
       Mar 18, 2020
    @wweir 确实,基本没什么人用了
    whoami9894
        10
    whoami9894  
    OP
       Mar 18, 2020
    @wevsty 只能说触发概率低而已,这么写肯定有问题
    toyassb
        11
    toyassb  
       Mar 18, 2020 via iPhone
    他现在版本号不都 3.2 了么
    kwlokip
        12
    kwlokip  
       Mar 18, 2020 via Android
    3.x 版本不是出来很久了??
    wevsty
        13
    wevsty  
       Mar 18, 2020
    @whoami9894
    这种问题无非就是 2 种处理办法。
    要不然死等 16 个字节,要不然就收到一次就处理。一直等着 16 字节的问题在于不能假定连接上的都是合法的客户端,要是只发送 1 个字节就不发了,那就只能等着连接超时了,可这不利于该类工具的使用目的。
    reus
        14
    reus  
       Mar 18, 2020   ❤️ 1
    这明显是实现的问题,不是协议的问题。如果协议写明是 16byte,那当然需要一直 read,直到读满 16byte。只用一次 read,就是有缺陷的实现。多次 read 之间,也会有超时处理的,例如读 16byte 过程中,超时可以用很短的,例如一秒。后面传输的时候再设大点。

    @wevsty 每一次 read 前设超时时间即可,握手时用短超时,传输时用长超时。任何协议实现都是要考虑超时的,本来就不应该依赖操作系统本身的 TCP 超时设置。
    whoami9894
        15
    whoami9894  
    OP
       Mar 18, 2020
    @wevsty 它本身就是用的异步 eventloop 的实现,简单点解决:在 TCPRelay 中设置一个 buffer,判断如果 IV 未设置 && len(data) + len(buffer) < 16 就把 data 放到 buffer 并 return,else 则设置 IV。
    你说的这种问题属于 slow connection 漏洞,现在的实现中一样避免不了这个问题,还是得靠类似心跳机制或 #14 的超时机制来处理


    @reus 是的,实现的问题
    whoami9894
        16
    whoami9894  
    OP
       Mar 18, 2020
    @toyassb
    @kwlokip
    不太了解,毕竟我很久没用了,我从 Github 搜索出最高 star 的几个备份都是 2.8 版本,新版本不清楚有没有改这里的逻辑;而且我发帖只是记录和讨论,并不是说 ss 有缺陷不要用或怎样
    tankren
        17
    tankren  
       Mar 18, 2020 via Android
    ss 早就能精确识别了 不要用了
    cigarzh
        18
    cigarzh  
       Mar 18, 2020
    早就不用 python 实现了,万年 libev
    ZRS
        19
    ZRS  
       Mar 18, 2020   ❤️ 1
    重定向攻击我记得是针对非 AEAD 算法的

    python 版应该已经停止开发很久了,因为不支持 AEAD 也早就不推荐使用,难免有实现问题
    whoami9894
        20
    whoami9894  
    OP
       Mar 19, 2020 via Android
    @ZRS 感谢指出,笔误了。是针对 OFB CFB CTR 等不带 MAC 的非 AEAD 算法的
    ps1aniuge
        21
    ps1aniuge  
       Mar 19, 2020
    现在土高了。大家的 ss 还好吗?都挂了把?
    qqpkat2
        22
    qqpkat2  
       Mar 19, 2020
    @ps1aniuge v2ray 还能再战
    bt7vip
        23
    bt7vip  
       Mar 20, 2020 via Android
    不知各位有没有看过一张网图,后台显示,除了 iplc 是未知之外,其他流行工具都显示在上面,发起 ip,目标 ip,网站地址,所属位置或单位。其他真假不论,单一个所属单位,各位也能想到喝茶为什么速度那么快了吧,iplc 基本都是国内做业务,根本没有任何抵抗力。不过好像没有 tor。各位使用的时候把握好分寸,希望新的工具赶快到来。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   5580 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 62ms · UTC 08:20 · PVG 16:20 · LAX 01:20 · JFK 04:20
    ♥ Do have faith in what you're doing.