本项目旨在实现HTTPS中间人拦截的精确检测以及健壮的TLS指纹识别。 该项目基于论文《The Security Impact of HTTPS Interception》,最初是将其处理脚本和指纹移植到Go语言。
关于MITMEngine的更多背景信息,请参阅这篇 Cloudflare博客文章。 快速链接:
wireshark -v 检查版本)详细文档随代码提供(先将包复制到 $(GOPATH)/src/github.com/cloudflare/mitmengine 目录下)。
godoc -http=:6060
http://localhost:6060/pkg/github.com/cloudflare/mitmengine
在本项目中,指纹映射到对象的具体实例,而签名可以表示多个对象。我们采用这种约定是因为指纹通常是对象的内在属性,而签名是可以选择的。同样,服务器接收到的实际客户端请求会具有指纹,而生成请求的软件可以选择自己的签名(例如,通过选择支持的密码套件)。
客户端请求指纹源自客户端向服务器发出的请求,包含TLS和HTTP特征。客户端请求签名表示软件可以生成的所有可能指纹的集合。目标是使每个签名足够具体,以便唯一标识一个软件。
用户代理签名表示浏览器生成的一组用户代理。浏览器的用户代理签名允许指定浏览器版本范围,并可以指定操作系统名称、操作系统平台、操作系统版本范围以及设备类型,以创建更细粒度的签名。
浏览器签名包含用户代理签名和客户端请求签名。例如,这允许一个签名表示Chrome 31-38在Windows 10上可能生成的所有指纹。
MITM签名包含客户端请求签名以及关于MITM软件的额外细节,包括安全等级。安全等级可能受到客户端请求之外因素的影响,例如软件是否验证证书。
当与用户代理标识的浏览器相对应的预期客户端请求签名与实际客户端请求指纹不匹配时,我们认为HTTPS连接被拦截。
如果给定客户端软件的签名不准确或过时,则签名可能错误地将连接标记为被拦截。
如果代理紧密模仿客户端请求,则可能不会检测到不匹配。如果浏览器签名过于宽泛,同样无法检测到拦截。
在MALCOLM中使用的参考浏览器和MITM软件指纹位于 reference_fingerprints/mitmengine/。
这组指纹是来自 reference_fingerprints/pcaps/ 中TLS Client Hello pcap数据,以及Cloudflare网络上观察到并标记为高信任度(即对应人类和友好爬虫活动的流量)的前500个用户代理+TLS Client Hello对的组合。
理想情况下,我们不需要依赖从Cloudflare网络采样的参考指纹;而是拥有一套全面的pcap来构建参考TLS Client Hello集。有兴趣帮助我们扩充数据集吗?请查看如何贡献!
首先,用户需要创建一个 mitmengine.Config 结构体,并将其传递给 mitmengine.NewProcessor。mitmengine.Config 结构体可以指定包含浏览器指纹、MITM指纹和MITM头部的文件名。或者,它也可以指定一个配置文件,用于从任何其他来源读取上述文件;目前,MITMEngine支持从Amazon S3客户端兼容的数据库(包括Amazon S3和Ceph)读取这些文件。其他数据库的文件读取器(我们称之为"加载器")可以在 loaders 包中定义,只要新的加载器实现了Loader接口,它们就应该能够与MITMEngine的其他部分无缝配合。
MITMEngine包的预期入口点是 Processor.Check 函数,它接受用户代理和客户端请求指纹,并返回MITM检测报告。将来会添加更多API函数,例如允许向运行中的进程添加新签名。
以下是API使用示例。更完整的应用程序在 cmd/demo/main.go,可以通过运行 make bin/demo 构建。
rawUa := "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36"
requestFingerprintString := "303:dada,1301,1302,1303,c02b,c02f,c02c,c030,cca9,cca8,c013,c014,9c,9d,2f,35,a:aaaa,0,17,ff01,a,b,23,10,5,d,12,33,2d,2b,1b,dada,15:9a9a,1d,17,18:0::"
uaFingerprintString := "1:72.0.3626:2:3:10.14.3:1:"
requestFingerprint, _ := fp.NewRequestFingerprint(requestFingerprintString)
uaFingerprint, _ := fp.NewUAFingerprint(uaFingerprintString)
report := mitmProcessor.Check(uaFingerprint, rawUa, requestFingerprint)
TLS requestFingerprintString 的格式如下:
<tls_version>:<cipher_suites>:<extension_names>:<curves>:<ec_point_fmts>:<http_headers>:<quirks>
uaFingerprint 的格式如下:
# <browser_name>:<browser_version>:<os_platform>:<os_name>:<os_version>:<device_type>:<quirks>
如何将用户代理解析成 uaFingerprint 格式的示例见 cmd/demo/main.go 文件。
使用 MITMEngine 时,请记得拉取依赖。在运行测试之前,可能需要运行 vendoring 或 gomod 逻辑。
要测试,运行 make test;要查看代码覆盖率,运行 make cover。
由于浏览器和MITM指纹很快会过时,我们积极寻求用新样本来更新指纹库。
贡献指纹样本(下称"样本"),即表示您(以个人名义或代表您所代表或赞助(如有)的组织)授予 Cloudflare, Inc. 及其子公司和关联公司永久、不可撤销、免费、全球范围内的许可,授权对样本中的所有知识产权进行以下操作:(1) 复制、发布、展示和分发样本;(2) 准备基于样本或作为样本一部分的衍生作品。
要贡献指纹样本,请遵循以下步骤:
(已在 macOS Mojave 10.14.3 上测试)
创建服务器RSA证书和密钥对:
openssl req -new -x509 -sha256 -out server.crt -nodes -keyout server.pem -subj /CN=localhost
在端口4433上启动服务器:
openssl s_server -www -cipher AES256-SHA -key server.pem -cert server.crt
启动 TShark 捕获以解密 HTTP 头部(TShark >= 3.0.0):
tshark -i loopback -o tls.keys_list:"127.0.0.1,4433,http,server.pem" -Tjson -e http.request.line -Y http > header.json
启动 TShark 捕获 TLS Client Hello:
tshark -i loopback -f "tcp port 4433" -w handshake.pcap
从您要指纹识别的 TLS 客户端访问 https://localhost:4433。例如,
echo -e "GET /test HTTP/1.1\r\nHost:example.com\r\n\r\n" | openssl s_client -connect localhost:4433
按上述说明生成指纹样本(header.json、handshake.pcap),并将其放置在目录 reference_fingerprints/pcaps/<desc> 中,其中 <desc> 是唯一的描述性名称。
在 reference_fingerprints/fingerprint_metadata.jsonl 中添加一行,包含以下字段。os、device、platform 和 browser 字段的可用选项由 uasurfer 包定义。mitm_fingerprint.type 的可用选项如下。参见 reference_fingerprints/fingerprint_metadata.jsonl 中的示例;未知字段可留空或省略。
{ "desc": "<样本的唯一描述性名称>", "comment": "<关于样本的补充信息>", "handshake_pcap": "<包含TLS Client Hello的pcap文件路径>", "header_json": "<(可选)包含客户端HTTP请求的文件路径>", "ua_fingerprint": {"raw_ua": "<原始用户代理字符串>", "os": "<WindowsPhone|Windows|MacOSX|iOS|Android|...>", "os_version": "<主版本>.<次版本>.<补丁>", "device": "<Windows|Mac|Linux|...>", "platform": "<Computer|Tablet|Phone|...>", "browser": "<Chrome|IE|Safari|Firefox|...>", "browser_version": "<主版本>.<次版本>.<补丁>"}, "mitm_fingerprint": { "name": "<MITM描述>", "type": "<Antivirus|FakeBrowser|Malware|Parental|Proxy>" }}
我们也欢迎其他PR和功能请求!
mergeDB(位于 cmd/mergedb)是一个用于合并多个相近版本的浏览器或MITM软件中相似的TLS ClientHello指纹的工具。
使用 mergeDB 来整合大型的用户代理/Client Hello指纹列表:
go run cmd/mergedb/main.go
默认情况下,mergeDB 将对 reference_fingerprints/mitmengine 目录中的指纹进行操作。
提交包含上述更改的拉取请求。