ratched 是一个专门拦截 TLS 连接的中间人 (MitM) 代理。它旨在与 Linux 的 iptables REDIRECT 目标配合使用;所有需要被拦截的连接都可以重定向到本地 ratched 端口。通过 SO_ORIGINAL_DST 套接字选项,ratched 可以确定原始目标地址(在 iptables 数据包修改之前),并尝试与原始目标建立连接。
它与其他 MitM 软件的不同之处在于以下几点:
ratched 不会不加区分地拦截所有流量。具体来说,它首先等待 TLS 客户端发送 ClientHello 消息,以便 ratched 解析它并根据 TLS 服务器名称指示 (SNI) 扩展来决定是否拦截该目标。当您有虚拟主机托管,但只想拦截特定主机名的连接时,这尤其有用。
ratched 的目的不仅是嗅探密码,主要是将流量转储到 PCAPNG 文件中。选择 PCAPNG 文件格式是因为它允许用注释来标注连接(特别是,SNI 扩展中指示了哪个主机名),并且还允许将名称解析信息嵌入到捕获文件中(再次,将目标 IP 地址映射到 SNI 扩展的主机名)。
ratched 为每个被拦截的 SNI 提供单独的配置,包括支持的组(以前称为“支持的椭圆曲线”)、密码套件以及客户端和服务器端的特定 TLS 版本,并允许为不同的被拦截主机指定自定义证书/密钥。
ratched 提供对客户端证书的广泛支持,并且还提供自动伪造客户端证书的功能(类似于在另一个方向上伪造服务器证书)。
ratched 支持 OCSP 装订,并且可以在客户端发送状态请求 TLS 扩展时自动伪造正面的 OCSP 响应。
一旦 ratched 在路由机器上监听(在示例中,端口 9999),只需添加一个 iptables 条目来指定要捕获的流量。例如,要拦截从 192.168.1.7 发往端口 443 的所有流量,请使用:
# iptables -t nat -A PREROUTING -p tcp -s 192.168.1.7 --dport 443 -j REDIRECT --to-ports 9999
要拦截所有发往 443 的流量,只需执行:
# iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 9999
如果您充当路由器并想要拦截本地传入的流量,请使用 DNAT 目标而不是 REDIRECT,例如:
# iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 443 -j DNAT --to 192.168.123.1:9999
这里,eth1 是您拦截流量的接口,192.168.123.1 是本地接口 IP 地址。
帮助页面应该不言自明:
[//]: # (帮助页面开始 -- 自动生成,请勿编辑!)
usage: ratched [-c path] [-f hostname:port] [--single-shot] [--dump-certs]
[--keyspec keyspec] [--initial-read-timeout secs]
[--mark-forged-certificates] [--no-recalculate-keyids]
[--daemonize] [--logfile file] [--flush-logs] [--crl-uri uri]
[--ocsp-uri uri] [--write-memdumps-into-files]
[--use-ipv6-encapsulation] [-l hostname:port]
[-d key=value[,key=value,...]] [-i hostname[,key=value,...]]
[--pcap-comment comment] [-o filename] [-v]
ratched - 执行中间人攻击的 TLS 连接路由器
可选参数:
-c path, --config-dir path
配置目录,用于存储默认的根 CA 证书、CA 密钥对和服务器密钥对。
默认为 ~/.config/ratched
-f hostname:port, --local-fwd hostname:port
当建立到监听端口的本地连接时,默认情况下连接会被丢弃。指定此选项使 ratched 转发到给定的主机/端口组合。用于在没有 iptables REDIRECT 的情况下测试代理。
--single-shot 仅处理单个连接,然后立即终止。用于调试目的。
--dump-certs 在日志文件中打印每个被拦截连接所创建的证书。请注意,在许多情况下,您还需要将日志级别至少提高到 DEBUG 才能看到证书。
--keyspec keyspec 指定应使用的私钥规范。可以是 "rsa:bitlen" 或 "ecc:curvename" 形式。因此,有效的选择例如 "rsa:1024" 或 "ecc:secp256r1"。默认为 rsa:2048
--initial-read-timeout secs
指定 ratched 在放弃之前等待客户端提供其 ClientHello 的时间量(以秒为单位,浮点数)。默认为 1.0 秒。
--mark-forged-certificates
在创建的所有证书(包括动态伪造的客户端证书)的主题中包含一个 OU=ratched 条目,以便于调试。
--no-recalculate-keyids
在伪造客户端证书时,默认情况下会删除主题和颁发者密钥标识符并重新创建以匹配实际使用的密钥 ID。使用此选项,它们将按原样使用(即,密钥标识符元数据将不匹配实际使用的密钥)。此选项可能会暴露某些框架中的错误,这些框架将这些标识符视为可信信息。
--daemonize 不以前台模式运行,而是以后台守护进程方式运行。
--logfile file 不将日志记录到 stderr,而是重定向到给定文件。
--flush-logs 在每次调用 logmsg() 后刷新日志文件。降低性能,但提供行缓冲的日志。
--crl-uri uri 将给定的 URI 编码到服务器证书的 CRL 分发点 X.509 扩展中。
--ocsp-uri uri 将给定的 URI 编码到服务器证书的授权信息访问 X.509 扩展中,作为 OCSP 响应者 URI。
--write-memdumps-into-files
在日志中转储内存片段时,也将其二进制等价物输出到名为 hexdump_####.bin 的文件中,其中 #### 是递增的数字。用于调试内部数据结构。
--use-ipv6-encapsulation
对于写入 PCAPNG 文件格式,通常模拟 IPv4。这有一个缺点:当一个 IPv4 端点通过 TLS 服务器名称指示扩展服务多个服务器时,它们无法通过主机名区分。使用此参数,ratched 将数据包封装在 IPv4-in-IPv6 模拟中,并为不同的服务器名称分配不同的 IPv6 地址,从而实现准确的名称解析。
-l hostname:port, --listen hostname:port
指定 ratched 监听的地址和端口。默认为 127.0.0.1:9999。
-d key=value[,key=value,...], --defaults key=value[,key=value,...]
为所有未通过 --intercept 选项显式列出的主机指定服务器和客户端连接参数。参数以 key=value 形式给出;有效参数如下所示。
-i hostname[,key=value,...], --intercept hostname[,key=value,...]
仅拦截特定的主机名,由 ClientHello 中的服务器名称指示指示。可以多次指定以包含对多个主机的拦截。可以在 key=value 形式中指定附加参数,以进一步定义该特定主机的拦截参数。
--pcap-comment comment
将特定信息作为注释存储在 PCAPNG 头部内。
-o filename, --outfile filename
指定被拦截流量写入的 PCAPNG 文件。必要参数。
-v, --verbose 增加日志记录详细程度。
对于 --intercept 参数有效的参数如下:
intercept=[opportunistic|mandatory|forward|reject]
指定 ratched 对此特定连接应采取的模式。机会性 TLS 拦截是默认模式;这意味着首先尝试 TLS 拦截。如果失败(因为有人尝试发送非 TLS 流量),则回退到 'forward' 模式(即,原样转发所有数据)。强制性 TLS 拦截意味着如果无法进行 TLS 拦截,则连接终止。'forward' 模式,如前所述,简单地原样转发所有数据。'reject' 模式完全关闭连接,无论看到的流量类型如何。
s_tlsversions=versions
以冒号分隔的字符串,指定 ratched 服务器组件可接受的 TLS 版本。有效元素为 ssl2, ssl3, tls10, tls11, tls12, tls13。默认为 tls10:tls11:tls12。
s_reqclientcert=bool 要求所有连接到 TLS 代理服务器端的客户端提供客户端证书。如果没有给出替换证书(至少需要 certfile 和 keyfile),则伪造传入证书的所有元数据。如果给出了 certfile/keyfile,则隐含此选项。
s_send_rot=bool 默认情况下,ratched TLS 服务器不会在服务器证书列表中包含自己的信任根 (RoT) CA 证书。使用此选项,它会被添加到发送给对等方的证书中。
s_certfile=filename 指定公钥证书 (X.509) PEM 格式,应被 ratched 用作服务器证书。默认情况下,此证书是自动生成的。必须与 s_keyfile 一起使用。
s_keyfile=filename 指定给定服务器证书的私钥,PEM 格式。
s_chainfile=filename 指定要发送给客户端的 X.509 证书链,PEM 格式。
s_cacert=filename 颁发服务器证书的 X.509 CA 证书,PEM 格式。
s_cakey=filename 签署服务器证书的 X.509 CA 证书密钥,PEM 格式。
s_ciphers=ciphers ratched TLS 服务器使用的密码套件字符串。
s_groups=groups ratched TLS 服务器使用的密钥协商“支持的组”字符串(以前称为“椭圆曲线”)。
s_sigalgs=algs ratched TLS 服务器使用的密钥协商“签名算法”字符串。
s_ocsp=bool 通过发送 OCSP 票据作为响应来响应请求 OCSP 状态请求的客户端。默认启用。
c_tlsversions=versions
以冒号分隔的字符串,指定 ratched 客户端组件可接受的 TLS 版本。有效元素为 ssl2, ssl3, tls10, tls11, tls12, tls13。默认为 tls10:tls11:tls12。
c_certfile=filename 指定应被 ratched 用作客户端证书的 X.509 证书,PEM 格式。仅当连接的客户端也提供了客户端证书时才会使用。必须与 c_keyfile 一起使用。
c_keyfile=filename 给定客户端证书的私钥,PEM 格式。
c_chainfile=filename 要发送给服务器的 X.509 证书链,PEM 格式。
c_ciphers=ciphers ratched TLS 客户端使用的密码套件字符串。
c_groups=groups ratched TLS 客户端使用的密钥协商“支持的组”字符串(以前称为“椭圆曲线”)。
c_sigalgs=algs ratched TLS 客户端使用的密钥协商“签名算法”字符串。
示例:
$ ratched -o output.pcapng
在本地端口 9999 上打开并监听传入连接,拦截所有 TLS 流量并将输出写入给定的捕获文件。
$ ratched -f google.com:443 -o output.pcapng
与之前相同,但将所有无法确定目标的流量(例如,到本地端口 9999 的连接)重定向到 google.com 的 443 端口。
$ ratched -vvv --dump-certs -o output.pcapng
在拦截期间更加详细,并在日志中打印伪造的证书。
$ ratched --defaults intercept=forward -intercept --intercept www.johannes-bauer.com -o output.pcapng
通常不拦截连接(而是原样转发所有流量),除了具有服务器名称指示 www.johannes-bauer.com 的连接,对该连接执行拦截。
$ ratched --intercept www.johannes-bauer.com,s_reqclientcert=true -o output.pcapng
通常不向连接的对等方请求客户端证书,除了具有服务器名称指示 www.johannes-bauer.com 的连接,对于该连接,客户端会收到一个 CertificateRequest TLS 消息。如果客户端不提供客户端证书,则只使用常规 TLS 拦截。如果客户端提供了客户端证书,则伪造所有客户端证书元数据,并在与真实服务器的连接中使用伪造的客户端证书。
$ ratched --intercept www.johannes-bauer.com,c_certfile=joe.crt,c_keyfile=joe.key -o output.pcapng
与之前相同,但对于到 johannes-bauer.com 的连接,不伪造客户端证书,而是始终使用给定的客户端证书和密钥(joe.crt / joe.key)向服务器进行身份验证。
$ ratched --keyspec ecc:secp256r1 --ocsp-uri http://www.ocsp-server.com -o output.pcapng
为所有使用的证书选择 secp256r1 而不是 RSA-2048,并将 OCSP 响应者 URI 编码到这些伪造的证书中。
$ ratched --initial-read-timeout 5.0 --default intercept=mandatory -o output.pcapng
等待五秒钟让连接的客户端发送有效的 ClientHello 消息。如果五秒后没有收到任何内容,或者收到未知(非 TLS)流量,则终止连接,而不是执行原样转发。
[//]: # (帮助页面结束 -- 自动生成,请勿编辑!)
“ratched”这个名字暗指《飞越疯人院》中的护士长拉契特。如果你使用这个工具来监视别人,你就是一个彻头彻尾的混蛋,滥用你的权力。你应该看看这部电影。请负责任地使用 ratched 来增强我们基础设施的安全性,而不是破坏它。用于间谍目的的 TLS 拦截是可鄙且危险的。
ratched 至少需要 OpenSSL v1.1。
ratched 根据 GNU GPL-3 许可。