这是「进击的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 指纹绕过分析相关推荐

  1. 某某网站JS逆向及tls指纹绕过分析

    大家好,我是TheWeiJun:光阴似箭.日月如梭,突然发现又有好长时间没有更新了.还好总有粉丝朋友找我提问,今天更新一篇粉丝Robbers提到的网站问题,主要涉及js逆向和tls指纹绕过.欢迎各位读 ...

  2. 国家税务总局全国增值税发票查验平台网站js逆向分析及全逆向算法还原

    本文教程针对的是2021年7月2日时国税查验平台的js分析,其中版本号为V2.0.06_009.主要分析内容为key9和flwq39以及fplx这3个参数的算法,其中key9分为获取验证码阶段和查验阶 ...

  3. 超详细 某代刷网站js逆向

    1.背景及简单分析 插播恰饭广告:可以加我qq 2967615343随便打赏点,我把js代码和post服务器可用脚本,一起发你 这几天想用Django写一个接口,但不知道写啥,写每天天气推送太俗,烂大 ...

  4. js逆向知识-Ja3指纹学习

    目录 一.ja3指纹介绍 二.ja3指纹解决方案 一.ja3指纹介绍 1.指纹:通过一些算法将一些特征加密得到的值,这些值往往能够区分你是谁.每个客户端会生成特定的ja3指纹,并不会随ip和usera ...

  5. 某壁纸网站JS逆向+混淆代码扣取AST修复+Python批量下载教程+完整代码

    由于内容相对较多,无限debugger.JS逆向.混淆代码扣取修复.Python爬虫,篇幅较长,文字教程就不提供了, 完整python代码 # -*- coding: utf-8 -*- # @Aut ...

  6. 《封号码罗》python爬虫之企某科技网站js逆向(十四)

    首先查看ajax加载,可以发现,其所有的数据都是加密方式到前端页面,由前端页面js解密之后再渲染到网页中 根据其关键字 encrypt_data进行全局搜索,寻找js的解密代码 这个地方就是解密代码, ...

  7. 某我音乐网站JS逆向扣代码+Python一键下载

    1.PC web端api,获取低品质音乐 2.自建api,获取高品质无损音质 getReqid.js function getReqid() {var t, e, nvar r = [55, 72, ...

  8. 【ja3 指纹算法】JS逆向之ja3指纹算法

    ja3 官方:https://ja3er.com 访问这个网站:https://ja3er.com/json 你会看到类似如下的返回json字段结果,这就是著名的ja3算法加密后的结果.那么这个ja3 ...

  9. 签到网站js逆向与python实现

    登陆分析 数据分析 Chrome浏览器进入填报系统,选择对应学校,来到登陆界面. 打开Chrome开发者工具(快捷键F12),模拟手机端. 111111 222222 333333 点击登陆,分析网络 ...

最新文章

  1. MIT自动驾驶船下水!可乘坐5人,阿姆斯特丹运河航行3小时误差不到0.17米
  2. 8.3 直接插入排序
  3. 土耳其电影公司选择Infortrend建立PB级数据存储基础设施
  4. POJ 计算几何(3)
  5. Python中的相对文件路径的调用
  6. TortoiseSVN使用指南
  7. Java 实现区块链中的区块,BLOCK的实现
  8. (第六周)团队项目6
  9. 软件测试工作职责,软件测试经理岗位职责
  10. 年会抽奖小游戏java_抽奖小游戏
  11. 光耦p621引脚图_p421光耦引脚图和代换
  12. java七牛云工具类_您应该知道的7个Java工具
  13. [Z] 通天塔导游:各种编程语言的优缺点
  14. 记录:2018年CCF优秀博士学位论文奖信息
  15. android 载入svg动画,Android 加载SVG动画
  16. MYSQL 递归树表函数
  17. zabbix5部署+Grafana大屏展示
  18. JAVA 枚举类型 根据代码得到中文
  19. 用stitching_detailed拼接图片失败,原因分析(待补充)
  20. 程序员接私活经验总结,来自csdn论坛语录

热门文章

  1. MATLAB delaunay函数使用
  2. jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=truecharacterEncoding=UTF-8
  3. R语言:用FMSB包做出漂亮雷达图
  4. IDEA选中一列数据
  5. 对抗噪音,一键清晰,HMS Core音频编辑服务给你“录音棚”般的体验
  6. 记录 |探究一次嗅到坏代码后封装再封装
  7. simulink命令集及常用模块说明
  8. matlab 1.封装LPF 巴特沃斯低通滤波器
  9. asp毕业设计——基于asp+access的房产信息管理系统设计与实现(毕业论文+程序源码)——房产信息管理系统
  10. UnityEditor查找引用和批量替换资源工具