深度剖析ja3 指纹及突破
本文由 简悦
SimpRead 转码, 原文地址 mp.weixin.qq.com
前言
是的,我重新发了,没想到一不小心就过了这么久了,发现这期间有天赋的大佬们现在对于
文章较之前有部分改动,对理解
之前发过
Official Account
到底什么是ja3
简介
git:https://github.com/salesforce/ja3
官方解释:
JA3 是一种创建SSL/TLS 客户端指纹的方法,它应该易于在任何平台上生成,并且可以轻松共享以用于威胁情报
更权威的介绍文章:https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967
浓缩一下大概意思就是:
JA3 是一种对传输层安全应用程序进行指纹识别的方法。它于2017 年6 月首次发布在GitHub 上,是Salesforce 研究人员John Althouse 、Jeff Atkinson 和Josh Atkins 的作品。创建的JA3 TLS/SSL 指纹可以在应用程序之间重叠,但仍然是一个很好的妥协指标(IoC) 。指纹识别是通过创建客户端问候消息的5 个十进制字段的哈希来实现的,该消息在TLS/SSL 会话的初始阶段发送。
这…..,
然后我猜,
ja3 的由来
其实,
对这个
TLS 客户端进行指纹识别的主要概念来自Lee Brotherston 2015 年的研究(https://blog.squarelemon.com/tls-fingerprinting/)和他的DerbyCon 演讲(https://www.youtube.com/watch?v=XX0FRAy2Mec) 。如果不是Lee ,就不会有JA3 的出现
ja3 如何工作的
原文解释的很好了,官方解释:
TLS 及其前身SSL 用于为常见应用程序和恶意软件加密通信,以确保数据安全,因此可以隐藏在噪音中。要启动TLS 会话,客户端将在TCP 3 次握手之后发送TLS 客户端Hello 数据包。此数据包及其生成方式取决于构建客户端应用程序时使用的包和方法。服务器如果接受TLS 连接,将使用基于服务器端库和配置以及Client Hello 中的详细信息制定的TLS Server Hello 数据包进行响应。由于TLS 协商以明文形式传输,因此可以使用TLS Client Hello 数据包中的详细信息来指纹和识别客户端应用程序
更多更专业的,如果很感兴趣,劳烦移步
https://engineering.salesforce.com/open-sourcing-ja3-92c9e53c3c41
感觉看了上面的话,是不是有点似懂非懂的感觉,没事,听我慢慢说,来个图吧,要来图的话,先来个三次握手的吧,老图了,相信各位朋友也都看烦了,我也看烦了,因为这图都传包浆了
详细的三次握手流程解释我就不说了,网上能查到的太多了,我就不献丑解释了,本篇文章的重点也不是它
那么按照
怎么说?画的很传神很易懂对吧?
更多原文解释,请看这里:https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967
识别原理
以下
1.JA3 不是简单地查看使用的证书,而是解析在SSL 握手期间发送的TLS 客户端hello 数据包中设置的多个字段。然后可以使用生成的指纹来识别、记录、警报和/ 或阻止特定流量。2.JA3 在SSL 握手中查看客户端hello 数据包以收集SSL 版本和支持的密码列表。如果客户端支持,它还将使用所有支持的SSL 扩展、所有支持的椭圆曲线,最后是椭圆曲线点格式。这些字段以逗号分隔,多个值用短划线分隔(例如,每个支持的密码将在它们之间用短划线列出)
JA3 方法用于收集Client Hello 数据包中以下字段的字节的十进制值:版本、接受的密码、扩展列表、椭圆曲线和椭圆曲线格式。然后按顺序将这些值连接在一起,使用 “,” 分隔每个字段,使用 “-” 分隔每个字段中的每个值
其中第一条,也解释了我前一篇请求时尝试提交一个
ja3 已收录指纹/ 黑名单
- https://sslbl.abuse.ch/blacklist/sslblacklist.csv
这个没有更新了只有上百条 - https://github.com/salesforce/ja3/blob/master/lists/osx-nix-ja3.csv
这个不是很全,只有上百条 - https://ja3er.com/getAllUasJson
这个一直在更新,十几万条 - https://ja3er.com/getAllHashesJson
同上,只是给定标注字段不同
我猜测,
案例解释
前面说了一堆理论概念,我们做开发的,如果只有概念没有实操或者例子解释是不够的,所以,来个案例,还是猿人学
这边
此时你会看到很多的数据数据包,过滤一下,直接在过滤器位置输入
全部的命令是啥意思这里就不多说了,更多的可以百度,只介绍几个这里会用到的命令:
ip.dst_host 就是目标地址,这里你可以理解为就是访问网站的服务端地址
ip.src_host 就是源地址,这里你可以理解为就是你正在操作的电脑的ip ,这个ip 大多是局域网ip
ip.host 跟上面一样,但是不会区分是src 还是dst ,只要有指定地址的都会过滤出来
给定过滤指令,回车,此时有可能你输入过滤命令之后,看不到有任何数据包,小问题,可能你打开
注意看,最开始的
有了这个,看看
展开
滑到最后,就能看到
然后,看
771,43690-4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,64250-0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-51914-21,51914-29-23-24,0
对应:
TLSVersion,Ciphers,Extensions,EllipticCurves,EllipticCurvePointFormats
以【,】分割,第一个数,771,根据官方解释,就是
后续的就不细说了,直接看
细心的你发现了,我截图这里是没有第四个数相关的套件,
其实不是没有的,是现在第四个参数由
注:
说到版本,纠正下我前一篇给的说明,
有关第三个数
实际的案例作为
如何突破ja3
终于到了大家都很感兴趣的环节,怎么破它了。
完全突破
python 半突破
在上一篇的解决方案里,修改
有关
也就是说,我们要想改,可以直接复制上面的套件覆盖下即可,例如:
urllib3.util.ssl_.DEFAULT_CIPHERS = 'EECDH+AESGCMEDH+AESGCM'
但是,相信对这个
如果你再配上
而浏览器的这个
所以,这很明显的差异好吗?是很容易被识别到的
而且根据我多方查阅,加上咨询了各位大佬之后,
但是其他的
也就是说这是
假如这种反爬手段满天飞的时候,
WTF?
那有朋友估计会想问
这么明显的特征,如果是一个实际的网站案例,你觉得他会放过你吗?
所以目前
说到这里,有朋友可能不信,口说无凭,这次来个实际的案例,一个大佬给我的某网站
浏览器打开(抱歉,我必须马赛克马到位
运行时发现程序卡住且一直没有响应的状态,测试得知原因是这个网站强制验证了
那换成
发现运行还是不行的。
怎么改都不成功的,这个就是实际例子说明了,这是
golang 之ja3transport 库突破ja3
之后在蔡老板朋友圈里,青南大佬评论中说了是可以替换
核心就是,代码里加了第三方库,ja3transport,这个库可以直接伪造
一执行,一看,就发现真的改变了
大概的看了下
ja3transport 简介
这个大佬给了一段解释:
JA3 的问题在于它仅比基于用户代理字符串的指纹识别客户端好一点。到目前为止,用户代理字符串比TLS ClientHello 数据包更容易更改。JA3 签名的参数仍由TLS 客户端控制,因此不能作为可信的信息来源。在Jeff 和John 的ShmooCon 谈话中,他们提到JA3 不是灵丹妙药。他们提出的颠覆JA3 检测的方法是使用操作系统的HTTPS 客户端绕过TLS 客户端特定的JA3 签名。我们提出了另一种通过制作与其他TLS 客户端(如浏览器)匹配的ClientHello 数据包来破坏JA3 检测的方法
ja3transport 突破原理
官方解释:
要想颠覆
JA3 ,需要修改5 个JA3 参数,可以在Refraction Networking 的utls 项目ClientHelloSpec 提供的struct 中修改。该包允许用户构建和执行ClientHello 握手。第一个参数,TLS 版本,可以用和成员修改。第二个参数,可用密码套件,可以通过更新成员来更改。第三个参数TLS 扩展可以通过更新成员来更改。参数的一个问题是所有参数都必须遵循TLSVersionMinTLSVersionMaxCipherSuitesExtensionsExtensionsTLSExtension 界面。第四个和第五个参数,椭圆曲线和椭圆曲线点格式,分别是TLS 扩展SupportedCurvesExtension 和 的一部分SupportedPointsExtension 我们不是根据
JA3 字符串创建客户端,而是可以生成与Web 浏览器等良性签名匹配的JA3 签名。有一些预设允许JA3 签名匹配Chrome 或Firefox ,甚至更多。我们仅限于屏蔽使用Go 可用的相同扩展的应用程序。例如,如果Chrome 使用Go 不支持的扩展程序,我们无法屏蔽它。屏蔽密码套件比较棘手,因为任何密码套件都可以进行广告,即使它没有实现。如果执行握手的服务器接受客户端通告但实际上并不支持的密码套件,则会出现问题。只要服务器接受实际支持的密码套件,虚假宣传比可用密码套件多的密码套件就不是问题
Go 的net/http 库有一个名为Transport. 传输结构负责编写如何将数据包发送到目标服务器。由于JA3 的签名是基于ClientHello 数据包的,我们可以进行TLS 握手,让Go 完成剩下的工作。该Transport 对象是一个参数http.Client 结构其中大部分进入开发人员都很熟悉。通过生成Transport 结构体,我们的库应该可以与任何现有的Go 项目无缝协作
浓缩下梗概,意思就是在
太牛逼了,他不是直接修改的
那么也就是说,其实
更多的解释请看原文:https://medium.com/cu-cyber/impersonating-ja3-fingerprints-b9f555880e42
ja3transport 后续问题
作者也说了,如果你随意地伪造
我们能想到的最简单的检测改进是将
JA3 签名与生成TLS ClientHello 数据包的进程映像配对。如果有客户端生成与Firefox 匹配的JA3 签名,但该进程不是Firefox ,则可能会发生一些奇怪的事情
ja3transport 缺陷
但是,用这个库
tls: server selected unsupported protocol version 304
一搜这个报错,就看到有个大佬说是因为不支持
对啊,这个网站上面它强制
golang 之CycleTLS 库http2.0+ja3 指纹突破
那只要能解决
7 May,那现在已经过去这么久了,大胆猜测一下,是不是这个大佬已经解决了呢?此时估计有朋友应该回想
哈哈哈,是啊,因为我个人觉得,爬虫跟前后端开发还是有点区别的,前后端开发,按照我的理解,讲究的逻辑严密,事先考虑各个层面的问题,尽量少
我开始尝试了这个库:
代码就不贴了,
所以,也就是说,之前用的库
这辈子没想到搞了几年爬虫逆向开发会为了解决
nodejs
还是用上面大佬
直接
验证python 指纹
既然已经可以随意改了对吧,那我改成
换接口验证
为了验证真的成功了,哈哈,该严谨的地方确实得严谨一点,还是用的
用wireshark 做最后的验证
那边
而之前我们看到的,比如猿人学
哪里不一样,以逗号作为分割,除了第一个数和最后一个数,其他的字段的开头一个数组都不一样(以【-】作为分割)
然后,此时此刻,我们先去
chrome 访问ja3 官网返回得到的:
771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-21,29-23-24,0
chrome 访问目标网站用wireshark 抓包得到:第一个:
771,43690-4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,60138-0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-51914-41,14906-29-23-24,0第二个:
771,10794-4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,14906-0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-2570-21,60138-29-23-24,0
仔细对比之后,也就刚好多了标记的
去掉上面标记出来的,其实第一个和第二个是一样的,仅仅是这个被我马赛克马死的平台是这样,我猜应该是这个平台自己多加了一层握手流程,所以会有
不过等等,突然有个疑问?为啥
这引出了一个新的问题,哪个才是对的
ja3 到底存在吗?
按理来说,应该信
为了进一步确认这个问题,根据青南大佬给文章的方案,可以伪造
首先澄清,没作弊哈,我用的第一个,跟我浏览器里的
这里我用的
再看
发现也是自定义的那个值,没有奇怪的数组了
相信有朋友会问,这就奇怪了,为啥这里又一样了?难道
那么,也就是说,
而且仔细看下面这个图,我鼠标放到
用微信好友
所以我跟
需要注意的点
-
有没有发现,其实
ja3 在2017 年就有了,据我了解,有很多公司的开发正在研究中。 -
有了一个
ja3 ,那我觉得后续肯定会出现升级版或者替代版了,红蓝对抗,反爬与反反爬,一直在对抗中进步,是好是坏,只能用时间来判定了。很多新东西靠自己一个人摸索是没法走到更远的,好比这个ja3 ,如果一开始没有Lee Brotherston 大佬在2015 公开讲解,也就不会有这么牛逼的ja3 指纹出现了,很喜欢微信好友Regionover 在一篇文章里的一句话: 【故事要留给过去,但成长要用于分享】 -
另外,希望国内外能有大神可以仿照这个
ja3transport 库或者CycleTLS 库写一个python 的库出来,唉,我自己也想写出来啊,过去这么久了,我也在看原理,还得花时间研究啊。
后续怎么继续学习tls 指纹
- 练习题:猿人学外部题
19 题,内部题22 ,29,32 题,32 题是app 版的tls 指纹校验,强的一批,网洛者练习平台第9 题(这个题正常的浏览器都会返回假数据,作者看了一会儿我的文章一晚上就搞了这道题出来,强的一批) ,只提示下,有几页假数据。 - 志远大佬的最新课程里有
tls 指纹的,感兴趣可以整一个。他的方法就是自编译openssl - 感兴趣可以读下
openssl 源码
之前说的tls 指纹研究怎么样了
说来惭愧,搞了这么久,也没搞出个所以然来,我越去了解,就越觉得这个东西不是那么容易的,资料太少,全靠摸索,只能慢慢来了,因为我想实现的是完全自定义
结语
-
真诚感谢一路下来认识的大佬们。以上都是个人见解,如果有误还望指正,有任何问题,我很乐意跟各位大佬们交流,我微信
id :**geekbyte,** 备注来意 -
另外应有些朋友的建议建了个群,里面很多大佬,安全渗透,爬虫,
web+app 逆向,前后端开发,ios 开发的大佬都有,已满200 人,想进群的可以加我微信 -
推荐下蔡老板的星球,
web 逆向必须学的ast 技术。他虽然不在爬虫圈,但是在爬虫圈一直有他的传说,我能有今天,能认识这么多大佬,很大一部分原因是因为他。真的很感谢蔡老板。