某某网站 JS 逆向及 tls 指纹绕过分析
这是「进击的Coder」的第 749 篇技术分享
作者:TheWeiJun
来源:逆向与爬虫的故事
“
阅读本文大概需要 12 分钟。
”
特别声明:本公众号文章只用于学术研究,不作为其它不法用途;如有侵权请联系作者删除。
目录
一、前言介绍
二、参数分析
三、断点调试
四、算法分析
五、指纹绕过
六、学习展望
趣味模块
Robbers 是一名 spider 工程师,最近 Robbers 遇到了一个棘手的问题:Robbers 在访问某某网站时,遇到了 JS 加密参数。Robbers 凭借自己超高的专业技能对该加密参数逆向还原后,用 requests、httpx、aiohttp 等包去发包,居然认证不通过,提示身份授权失败。这篇文章,我们将和 Robbers 一起并肩作战,去解决这个问题!
一、前言介绍
我们在以往的文章中都是提到了如何从 params、data、headers、cookies、response 中去还原加密参数,通过还原加密参数的方式即可实现数据采集。而今天我们要分享的文章中,和提到的这几个类型完全没有任何关联,遇到这样的问题,该如何解决这类型的问题?带着这些疑问耐心看完本篇文章,你就豁然开朗了!
二、参数分析
1、首先打开我们今天要模拟的网站,刷新当前页面,截图如下:
2、打开开发者工具 DevTools, 选择 Network 栏目,刷新当前页面,截图如下:
3、经过分析可以确定该接口即为我们要获取数据的地址,接下来我们进行参数分析:
Request 参数分析:
总结:该接口都是明文,不需要进行任何还原。
Headers 参数分析:
总结:u-sign 目测为 md5 算法加密参数。
通过分析,我们可以确定 u-sign 参数是被加密处理了。经过重放请求包,不能够缺少 u-sign 参数,接下来我们需要进入JS段点调试分析加密参数环节一探究竟了。
三、断点调试
1、使用 XHR/fetch 打上断点,当该请求发包的时候,捕获断点如下:
2、在 Call Stack 栏目中追溯 headers 参数堆栈,截图如下所示:
3、在 u-sign 参数下面一行打上断点,查看 u-sign 对应的 value 的值,截图如下:
4、确定加密函数为 i 后,我们进入该函数,查看加密逻辑,截图如下:
5、确定 n(a) 为 u-sign 参数的值后,我们在 console 输出 a 参数,copy(a) 用前面提到的 md5 去校验看是否等于该参数的值,截图如下:
总结:确定参数算法及整个流程贯通后,接下来,我们只需要对 js 代码加密算法进行还原即可。
四、算法还原
1、Python 版本算法还原代码如下:
# -*- coding: utf-8 -*-
# --------------------------------------
# @author : 逆向与爬虫故事公众号
# --------------------------------------
import json
import hashlibdef get_sign(data: dict) -> str:data_str = json.dumps(data, separators=(',', ':'))text = f"{data_str.lower()}&9sasji5owng41irkisvtjhlxhmrysrp1"hash_md5 = hashlib.md5()hash_md5.update(text.encode())sign = hash_md5.hexdigest()return signif __name__ == '__main__':headers = {"Accept-Encoding": "gzip, deflate, br","Connection": "keep-alive",'Accept': '*/*','Accept-Language': 'zh-CN,zh;q=0.9','Cache-Control': 'no-cache',"Content-Length": "132",'Pragma': 'no-cache','Sec-Fetch-Dest': 'empty','Sec-Fetch-Mode': 'cors','Sec-Fetch-Site': 'same-site','sec-ch-ua': '"Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"','sec-ch-ua-mobile': '?0','sec-ch-ua-platform': '"macOS"','u-sign': '37635b63e0f1973c61b1444983eab1be','u-token': '',}json_data = {'keyword': '','provinceNames': [],'natureTypes': [],'eduLevel': '','categories': [],'features': [],'pageIndex': 5,'pageSize': 20,'sort': 11,}sign = get_sign(json_data)print(sign)print(headers['u-sign'])
2、代码运行后,Pycharm 打印结果如下:
3、算法还原后,使用 Python 发送请求包,截图如下:
总结:参数完全一致的情况无法通过认证,接下来我们进入新的环节解决这个问题吧!
五、指纹绕过
1、在我们参数算法完全还原的情况,请求该网站却提示身份认证失败,我们重新梳理下可能存在的情况如下:
cookies
http2.0
tls指纹
总结:经过分析,我们可以确认该网站不需要 cookies,故第一种怀疑排除掉;接下来进行 http2.0 验证。
2、可能比较傻,我确实用 httpx 验证了下该网站,截图如下:
with httpx.Client(http2=True) as req:response = req.post('https://xxxxxxxx.cn/xxxxx.basiclib.api.college.query',headers=headers, json=json_data)print(response.text)
Pycharm 代码运行后,截图如下:
总结:结局总是那么不理想,此刻怀疑的方案只剩下最后一种:该网站对 tls 请求指纹进行验证;接下来我们继续分析。
可能到这里会有人问,什么是tls指纹?
TLS 指纹,也有人叫 JA3 指纹。在创建 TLS 连接时,根据 TLS 协议在 Client Hello 阶段发送的数据包就是就是 TLS 指纹。不同浏览器、不同版本(不同框架)因为对协议的理解和应用不一样,所以发送的数据包内容也就不一样,所以就形成了 TLS 指纹。
3、使用 Postman 进行发包测试,不再使用 Python 第三方包,截图如下所示:
总结:看到此处后一下豁然开朗了,可以肯定对方服务端会对请求指纹进行校验,如果是我们刚刚使用的第三方包,都会被服务端给识别到,最后返回身份授权失败错误。那么我们如何过 TLS 指纹呢?
怎么过 TLS 指纹?这是一个黑客大佬总结的几种方法:
代理中转请求
使用 Go 语言爬虫库
魔改 requests
访问 ip 指定 host 绕过 waf
4、接下来,我们使用 Golang 编写代码及还原算法如下:
// Package main -----------------------------
// @author : 逆向与爬虫的故事
// -------------------------------------------
package mainimport ("crypto/md5""fmt""io/ioutil""log""net/http""strings""time"
)func main() {client := &http.Client{}dataStr := `{"keyword":"","provinceNames":[],"natureTypes":[],"eduLevel":"","categories":[],"features":[],"pageIndex":2,"pageSize":20,"sort":11}`var data = strings.NewReader(dataStr)req, err := http.NewRequest("POST", "https://xxxxxx/xxxxx.query", data)if err != nil {log.Fatal(err)}sign := fmt.Sprintf("%x", md5.Sum([]byte(strings.ToLower(dataStr)+"&9sasji5owng41irkisvtjhlxhmrysrp1")))fmt.Println(sign)req.Header.Set("Accept", "*/*")req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9")req.Header.Set("Connection", "keep-alive")req.Header.Set("Content-Type", "application/json")req.Header.Set("Origin", "https://xxxxx.cn")req.Header.Set("Referer", "https://xxxxxx.cn/")req.Header.Set("Sec-Fetch-Dest", "empty")req.Header.Set("Sec-Fetch-Mode", "cors")req.Header.Set("Sec-Fetch-Site", "same-site")req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36")req.Header.Set("sec-ch-ua", `"Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24"`)req.Header.Set("sec-ch-ua-mobile", "?0")req.Header.Set("sec-ch-ua-platform", `"Windows"`)req.Header.Set("u-sign", sign)req.Header.Set("u-token", "")resp, err := client.Do(req)if err != nil {log.Fatal(err)}defer resp.Body.Close()bodyText, err := ioutil.ReadAll(resp.Body)if err != nil {log.Fatal(err)}fmt.Printf("%s\n", bodyText)fmt.Println(string(time.Now().Weekday()))
}
5、执行编辑好的代码,GoLand 打印如下:
总结:到此我们已经能够解决 Robbers 粉丝遇到的问题了,这也让我意识到随着反爬策略的升级,服务端可能会对爬虫最常用的第三方包进行请求指纹检测。同时也说明了,爬虫除了 Python,用 Go 其实也是一个不错的选择。
六、学习展望
笔者对 GoLang、Python 代码分别设置代理后,用 charles 抓包分析如下:
GoLang 设置代理发包
Python 设置代理发包
我们对 GoLang、Python 两次发包后的请求参数对比分析,截图如下所示:
GoLang 版本
Python 版本
总结:本来想使用 charles 拦截请求包查看数据包有哪些区别,但是感觉使用 charles 查看不够直观,charles 应用中我们也得到了一些有用信息(标红部分),提取服务器的 ip+port 使用 Wireshark 打开查看,看看有没有更直观的信息吧。
使用 Wireshark 抓包,再次使用 go、Python 去发包,发包后根据 charles 获取的 ip 信息筛选 tls 指纹相关数据包,截图如下所示:
紧接着我们点击如下按钮进行参数定位:
将鼠标拉到最后,可以看到 tls 也就是 JA3 指纹如下所示:
整理 go、python 发包后的指纹文本对比如下:
总结:从上图可以看出两个请求包的 JA3 指纹加密算法不一致;如果我们还要继续使用 Python requests 去实现代码,可以尝试使用魔改 requests 修改 TLS 握手特征的代码去实现,也可以去阅读下 tls 指纹相关的文档。简单的网站是可以通过使用魔改 requests 修改 TLS 捂手特征代码通过,难度较大的就不能通过了,还需要新的方案去替代哦。这里突出一点,学无止境啊^_^⛽️
本篇分享到这里就结束了,欢迎大家关注下一期,我们不见不散☀️☀️
某某网站 JS 逆向及 tls 指纹绕过分析相关推荐
- 某某网站JS逆向及tls指纹绕过分析
大家好,我是TheWeiJun:光阴似箭.日月如梭,突然发现又有好长时间没有更新了.还好总有粉丝朋友找我提问,今天更新一篇粉丝Robbers提到的网站问题,主要涉及js逆向和tls指纹绕过.欢迎各位读 ...
- 国家税务总局全国增值税发票查验平台网站js逆向分析及全逆向算法还原
本文教程针对的是2021年7月2日时国税查验平台的js分析,其中版本号为V2.0.06_009.主要分析内容为key9和flwq39以及fplx这3个参数的算法,其中key9分为获取验证码阶段和查验阶 ...
- 超详细 某代刷网站js逆向
1.背景及简单分析 插播恰饭广告:可以加我qq 2967615343随便打赏点,我把js代码和post服务器可用脚本,一起发你 这几天想用Django写一个接口,但不知道写啥,写每天天气推送太俗,烂大 ...
- js逆向知识-Ja3指纹学习
目录 一.ja3指纹介绍 二.ja3指纹解决方案 一.ja3指纹介绍 1.指纹:通过一些算法将一些特征加密得到的值,这些值往往能够区分你是谁.每个客户端会生成特定的ja3指纹,并不会随ip和usera ...
- 某壁纸网站JS逆向+混淆代码扣取AST修复+Python批量下载教程+完整代码
由于内容相对较多,无限debugger.JS逆向.混淆代码扣取修复.Python爬虫,篇幅较长,文字教程就不提供了, 完整python代码 # -*- coding: utf-8 -*- # @Aut ...
- 《封号码罗》python爬虫之企某科技网站js逆向(十四)
首先查看ajax加载,可以发现,其所有的数据都是加密方式到前端页面,由前端页面js解密之后再渲染到网页中 根据其关键字 encrypt_data进行全局搜索,寻找js的解密代码 这个地方就是解密代码, ...
- 某我音乐网站JS逆向扣代码+Python一键下载
1.PC web端api,获取低品质音乐 2.自建api,获取高品质无损音质 getReqid.js function getReqid() {var t, e, nvar r = [55, 72, ...
- 【ja3 指纹算法】JS逆向之ja3指纹算法
ja3 官方:https://ja3er.com 访问这个网站:https://ja3er.com/json 你会看到类似如下的返回json字段结果,这就是著名的ja3算法加密后的结果.那么这个ja3 ...
- 签到网站js逆向与python实现
登陆分析 数据分析 Chrome浏览器进入填报系统,选择对应学校,来到登陆界面. 打开Chrome开发者工具(快捷键F12),模拟手机端. 111111 222222 333333 点击登陆,分析网络 ...
最新文章
- MIT自动驾驶船下水!可乘坐5人,阿姆斯特丹运河航行3小时误差不到0.17米
- 8.3 直接插入排序
- 土耳其电影公司选择Infortrend建立PB级数据存储基础设施
- POJ 计算几何(3)
- Python中的相对文件路径的调用
- TortoiseSVN使用指南
- Java 实现区块链中的区块,BLOCK的实现
- (第六周)团队项目6
- 软件测试工作职责,软件测试经理岗位职责
- 年会抽奖小游戏java_抽奖小游戏
- 光耦p621引脚图_p421光耦引脚图和代换
- java七牛云工具类_您应该知道的7个Java工具
- [Z] 通天塔导游:各种编程语言的优缺点
- 记录:2018年CCF优秀博士学位论文奖信息
- android 载入svg动画,Android 加载SVG动画
- MYSQL 递归树表函数
- zabbix5部署+Grafana大屏展示
- JAVA 枚举类型 根据代码得到中文
- 用stitching_detailed拼接图片失败,原因分析(待补充)
- 程序员接私活经验总结,来自csdn论坛语录
热门文章
- MATLAB delaunay函数使用
- jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=truecharacterEncoding=UTF-8
- R语言:用FMSB包做出漂亮雷达图
- IDEA选中一列数据
- 对抗噪音,一键清晰,HMS Core音频编辑服务给你“录音棚”般的体验
- 记录 |探究一次嗅到坏代码后封装再封装
- simulink命令集及常用模块说明
- matlab 1.封装LPF 巴特沃斯低通滤波器
- asp毕业设计——基于asp+access的房产信息管理系统设计与实现(毕业论文+程序源码)——房产信息管理系统
- UnityEditor查找引用和批量替换资源工具