目录
前文
之前无聊看到ja3,就顺手倒腾了一遍,用php实现了一遍,虽然很绕,但勉强能用。上传github后,也就获得几个收藏。甚是激动。之后有个网友和我做了一点交流,还告诉了今天这个项目,大开眼界。简单记录下。果然懂得少,每天都可以有惊喜。
原理
利用不同系统在tcp默认配置得不同,从tcp的一次握手的SYN包中提取特征,与数据库对比进行打分,匹配出可能的系统。
特征[抄]
来自IP的熵
- IP.ttl (8 bits)
IP 标头的初始生存时间 (TTL) 值。TTL 表示允许 IP 数据包在 Internet 中循环的时间。每跳(例如路由器)将 TTL 字段减一。最大 TTL 值为 255,单个八位字节(8 位)的最大值。推荐的初始值为 64,但某些操作系统会自定义此值。因此,它与 TCP/IP 指纹识别相关。
项目中参数名为:ip_ttl
- IP.flags (3 bits)
不要分段 (DF) 和更多分段 (MF) 标志。在 IPv4 标头的标志字段中,有 3 位用于控制标志。“不分段”(DF)位在路径最大传输单元发现(PMTUD)中起着核心作用,因为它确定是否允许对数据包进行分段。有些操作系统在 IP 标头中设置了 DF 标志,有些则没有。
项目中参数名为:ip_df 和 ip_mf
来自TCP的熵
- TCP.data_offset (4 bits)
这是 32 位字中 TCP 标头的大小,最小为 5 个字,最大为 15 个字。因此,最大 TCP 标头大小为 60 字节(带有 40 字节的选项数据)。因此,TCP 标头大小取决于标头末尾存在多少选项。
项目中用的参数名是:tcp_header_length
- TCP.window_size (16 bits)
初始窗口大小。这个想法是不同的操作系统在初始 TCP SYN 数据包中使用不同的初始窗口大小。
项目中用的参数名是:tcp_window_size
- TCP.flags (9 bits)
该头域包含 9 个用于 TCP 协议控制目的的一位标志。初始 SYN 数据包的标志值大部分为 2(这意味着仅设置了 SYN 标志)。但是,我还观察到标志值为 194 (2^1 + 2^6 + 2^7),这意味着 SYN、ECE 和 CWR 标志设置为 1。如果设置了 SYN 标志,ECE 意味着客户端支持 ECN。拥塞窗口减少 (CWR) 意味着发送主机收到了一个设置了 ECE 标志的 TCP 段,并在拥塞控制机制中做出了响应。
项目中用的参数名是:tcp_flags
- TCP.acknowledgment_number (32 bits)
如果设置了 ACK 标志,则该字段的值是 ACK 的发送者期望的下一个序列号。如果在第一个数据包上设置了 SYN 标志,则应为零。
项目中用的参数名是:tcp_ack,目前(2022年6月21日),没参与评分
- TCP.sequence_number (32 bits)
如果 SYN 标志设置为 (1),则这是初始序列号。推测不同的操作系统使用不同的初始序列号,但初始序列号很可能是随机选择的。因此,该字段很可能对指纹识别没有特别的帮助。
项目中用的参数名是:tcp_seq,目前(2022年6月21日),没参与评分
- TCP.urgent_pointer (16 bits)
如果设置了 URG 标志,那么这个 16 位字段是与指示最后一个紧急数据字节的序列号的偏移量。在初始 SYN 数据包中它应该为零。
项目中用的参数名是:tcp_urp,目前(2022年6月21日),没参与评分
- TCP.options (Variable 0-320 bits)
所有 TCP 选项。该字段的长度由数据偏移字段决定。包含很多信息,但最重要的是:Maximum Segment Size (MSS),Window scale 值。因为 TCP 选项数据的大小是可变的,所以它是区分操作系统的最重要的熵来源。TCP 选项的顺序也被考虑在内。
项目中用的参数名是:tcp_options ,tcp_window_scaling,tcp_mss
评分
见识比较少,所以这个模块的每个部分我都学习了很多。
基础数据库
评分的基础数据库,按照项目作者的说法来自他自己的链接,仅收集人类数据。
>NikolaiT :i have a blog where I record sessions on https://bot.incolumitas.com/.
I disregard sessions that don’t appear to be human.
各项分值和示例值
Entropy |
score |
example value |
ip_ttl |
1.5 |
45 |
ip_df |
1 |
1 |
ip_mf |
1 |
0 |
tcp_window_size |
1.5 |
8 |
tcp_flags |
1 |
2 |
tcp_header_length |
1 |
128 |
tcp_mss |
1.5 |
1460 |
tcp_options |
3 |
M1460,N,W8,N,N,S, |
tcp_options_order |
2 |
M,N,W,N,N,S, |
猜法
- 与数据库内每项进行对比打分
- 按高分到低排序,取最高的N个
- 计算系统平均得分
- 以最高分为第一参考,系统平均分为第二参考,判断系统。
用途
这几个都是项目中已经罗列的。
-
检测系统
这是该指纹主要功能,不解释
-
检测代理
客户端的系统和指纹所反馈的系统不一致,大概率是个代理。
如很常见搭配,很容易被检测出来
window + chrome + http_proxy(linux)
-
检测vpn
这个原理就完全不懂了,但是,代码如下:
res['vpn_detected'] = res['fp']['tcp_mss'] in [1240, 1361, 1289]
如果该条件成立,也就是说这几个mss值就是VPN的特征,那么。。。。好吧到此为止。
优势
- 罕见而不容易发现
通ja3一样,有可能大部分人都不知道这回事,自然谈不上破解伪装,至少在今天之前我是这样的。
- 底层而不容易修改
TCP?SYN?TCP_OPS除了课本上,正经人谁平时关注这些啊,一个http用到底,不够就加个TLS。有些参数可能难以修改,增加伪装的难度。
突破
先想着,后续有测试的会回来更新
- 代理服务器系统
既然基本的判断是按照系统,那和客户端保持一致就可以了嘛。没做尝试,但目测可以。
- 客户端系统
相反,你能测出我的系统,我客户端直接伪装成对应系统不就可以了吗。当然,这只在这个项目内管用,多种指纹同时招呼,伪装成功与否就另说,不在这个项目范围。
- 修改代理服务器的配置
这和优势2对立,目前只知道ip_ttl能在window和linux被修改。
学到什么
-
值得学习评分系统
我之前有很多类似的想法,但效果都不好。这次是遇到了一个确实可以运行的系统。项目作者是如果选取熵和设计分值的,这个过程值得思考。当然这可能就是自己做的项目少,别打我。
-
tcp_option的评分
将一个多项部分带值得熵进行处理,分为完全匹配得3和顺序匹配得2。反正是学到了。
-
加深TCP/IP协议认识
一回生二回熟,看多几次就认识了。
-
pcapy看生态
python实现的抓包工具,在评论里还发现了别人提到的Go版本。只能说,php是最好的的语言。
参考
https://incolumitas.com/2021/03/13/tcp-ip-fingerprinting-for-vpn-and-proxy-detection/