目录
关于指纹部分,Akami的文章写的很详细,具体可以移步Passive Fingerprinting of HTTP/2 Clients。
这里是我的笔记和一些实践过程。
HTTP2被动指纹
客户端在HTTP2 代码上的实现差异让指纹生成和识别成为可能。这里与TLS指纹(JA3)可以说是一模一样。而在我看来最大的区别是,TLS指纹实在明文中提取,而HTTP2指纹,更多是在TLS的加密数据包中,这让获取增加了一点难度。
格式
Akami 建议格式 S[;]|WU|P[,]#|PS[,]
,四部分的字段用"|“拼接5,而内部的[;]表示以”;"拼接,各字段对应的意义如下
|
SETTINGS Frame |
WINDOW_UPDATE Frame |
Priority Frames |
Request Pseudo-Header Fields Order |
字段 |
S[;] |
WU |
P[,]# |
PS[,] |
Firefox/113.0 |
1:65536;4:131072;5:16384 |
12517377 |
3:0:0:201,5:0:0:101,7:0:0:1,9:0:7:1,11:0:3:1,13:0:0:241 |
m,p,a,s |
-
SETTINGS Frame
以 Key:Value 形式的值。 多个设置帧根据它们出现的顺序使用分号 “;” 连接。
特别之处是:
- 选择性发送参数
- 不同参数顺序
- 不一样的参数值
-
WINDOW_UPDATE Frame
WINDOW_UPDATE 增量大小,如果帧不存在则为"00"。
特别之处:
- 总在SETTINGS Frame 后发送
- 不用客户端实现会导致值不同
-
Priority Frames
流优先信息的元组:StreamID:Exclusivity_Bit:Dependant_StreamID:Weight
。多个优先级帧由逗号",“连接,如果此功能不存在,则值应为"0”。
-
Request Pseudo-Header Fields Order
HTTP2 伪头部的顺序,用首字母表示,并用","连接
m (:method)
p (:path)
a (:authority)
s (:scheme)
捕获方式
这里指的是服务端,我能想到的思路大概有2种。
-
抓包解密
有时间再研究,暂时搞不懂。
-
魔改web服务器
HTTP2 的 web服务器一般会先完成2个部分的工作,TLS解密 + HTTP2解析,随后才会进行后续的动作。而HTTP2指纹,需要在HTTP2协议解析时提取。
NGINX 在解析 http2 连接后不会收集它们的帧详细信息,因此模块无法仅通过将自身注入请求生命周期的末尾来构建指纹
而phper怎么办呢,找个支持H2的php版本的web服务器魔改呗。而H2的php版本的web服务器,也只有(来源):
- swoole/swoole-src
swoole 的h2部分是C++,折腾它和折腾上面的nginx没差
- amphp/http-server
这是个纯php实现的H2 web 服务端。而H2部分的解析在另外的一个依赖中amphp/http
优点
- 与HTTP/1.1 相比,实现H2的服务端和客户端相当低
- 许多 HTTP/2 客户端不支持修改基本 HTTP/2 实现细节
不过已经有人早就开始行动了 特殊的curl版本 lwthiker/curl-impersonate ,win的curl-impersonate
- 已知浏览器只支持HTTP/2 over TLS,不支持 HTTP/2 over unencrypted connections,这意味着 TLS 指纹和HTTP2 指纹经常是一起出现的
demo
https://bjun.tech:9766/http2_fingerprint.php
源码
Xxx-Bin/php-http2-fingerprint
部分指纹
// Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/113.0
1:65536;4:131072;5:16384|12517377|3:0:0:201,5:0:0:101,7:0:0:1,9:0:7:1,11:0:3:1,13:0:0:241|m,p,a,s
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
1:65536;2:0;3:1000;4:6291456;6:262144|15663105|0|m,a,s,p
//Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.43
1:65536;2:0;3:1000;4:6291456;6:262144|15663105|0|m,a,s,p
// curl 7.58.0 (x86_64-pc-linux-gnu) libcurl/7.58.0 OpenSSL/1.1.1 zlib/1.2.11 libidn2/2.0.4 libpsl/0.19.1 (+libidn2/2.0.4) nghttp2/1.30.0 librtmp/2.3
3:100;4:1073741824;2:0|1073676289|0|m,p,s,a
// curl-impersonate-win curl_chrome110.bat
1:65536;2:0;3:1000;4:6291456;6:262144|15663105|0|m,a,s,p
//Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Mobile/15E148 Safari/604.1
4:2097152;3:100|10485760|0|m,s,p,a
//Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Safari/605.1.15
4:1048576;3:100|10485760|0|m,s,p,a
// Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15
4:4194304;3:100|10485760|0|m,s,p,a
参考
https://browserleaks.com/http2
http2-fingerprinting
https://httpwg.org/specs/rfc7540.html