V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
whoami9894
V2EX  ›  程序员

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

  •  
  •   whoami9894 · 2020-03-18 18:01:11 +08:00 · 2474 次点击
    这是一个创建于 1745 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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


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

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