Reverse Engineering of Snell
Snell Server
本文是对 snell 协议版本 1.1 的初步逆向,项目地址在 GitHub.
Overview
Encryption Schema
Schema 同 shadowsocks aead 模式,分组密码选用了 chacha20-poly1305-ietf,详见 Aead Schema
会话密钥生成方式为
1 | crypto_pwhash(__out key, 32, psk, psk_len, salt, 3ULL, 0x2000ULL, crypto_pwhash_ALG_ARGON2ID13); |
参数意义详见 libsodium documentation
The Snell Protocol
C to S
1 | [1-byte version][1-byte command][1-byte client_id length][variable-length client_id][1-byte host length][variable-length host][2-byte port][application data...] |
其中
FIELD | OPTIONAL VALUE | COMMENT |
---|---|---|
version | 0x01 | |
command | 0x00 | PING |
0x01 | CONNECT | |
client_id length | zero currently | reserved for multi-user |
- 本 repo 给出的 demo 没有实现 obfs 功能
- host 总是字符串格式的,即使是 ip 地址
- port 为网络字节序
S to C
1 | [1-byte command][content...] |
其中
FIELD | OPTIONAL VALUE | COMMENT |
---|---|---|
command | 0x00 | TUNNEL |
0x02 | ERROR |
当 command=0x00 时,content 即是应用层数据,正常建立隧道将远端数据原封不动传递
当 command=0x02 时,content 具有如下模式
1 | [1-byte error code][1-byte error msg length][variable-length error message] |
Obfuscating Algorithm
HTTP
目前的 http 就是 simple-obfs 的 http mode,不想实现 demo 了,但可作如下验证
1 | ./snell-server -c ./snell-server.conf & |
假定 snell-server.conf 内容如下:
1 | $ cat ./snell-server.conf |
现在 surge 中添加代理test_snell = snell, [SERVER ADDRESS], 8787, psk=zzz, obfs=http
可成功访问网络
TLS
TLS 也就是 simple-obfs 的 tls mode,验证方式同上
Build Demo
macOS
1 | brew update && brew install boost libsodium glog gflags cmake |
debian
1 | apt update && apt install build-essential libboost-dev libsodium-dev libgoogle-glog-dev libgflags-dev cmake |