视频地址:Day1初识JS逆向 混淆与无混淆数据加密方案解析实战-36Kr数据加密解析 (AES数据逆向)_哔哩哔哩_bilibili
未完待续
一、排错
1.1) 目的:抓页面借口,简单请求会被拦截
1.2) 网址:乌海市公共资源交易中心 的http://www.whggzy.com/front/search/category
1.3) 视频位置:9:30~29:30
1.4) 问题重现:用request.post方法,直接请求会得到“系统出错,请稍后重试”,说明服务端有过滤
1.5) 解决:找到post的data数据真实格式、header真实需要。
(1) 开发者模式中找到“source”(chrome第三个,Firefox第三个叫调试器), 右侧XHR断点,添加“/front/search/category”, 刷新页面,中间区域js会断点,此时点击下方的{} 可以美化js代码
刷新页面可能会比较卡。
找到headers,即为请求头所需的变量参数。找到data, 即为请求内容
1.6) 思考:能否直接使用network上看到的信息? requestHeaders可以,但是请求payload是一个json串,直接把它当做字典传入data参数就会失败,而在options.data里明确显示成一个字符串。
二、加密解密
1.1) 目的:接口返回简单的密文,需要知道加密解密方法
1.2)网址:交易列表 - 福建省公共资源交易电子公共服务平台 的https://ggzyfw.fujian.gov.cn/FwPortalApi/Trade/TradeInfo
1.3) 视频位置:31:30~1:13:30
1.4) 问题解决: 解密
1.4.1) 搜索decrypt关键字,找到是哪个js文件执行了解密方法
1.4.2)对着app.js文件右键 在源码面板打开,搜索decrypt找到调用函数
1.4.3)简单调试确定函数功能是我们所需,函数保存下来并处理其中各变量(中间复杂过程略过)
1.5)工具插曲:Convert curl commands to code
可以用来将请求信息以curl格式(右键对准接口 复制 -> curl(bash) )转换为python代码
代码可以直接运行。
1.6)加密
1.6.1) 上一步的请求可以看出data结构
猜测ts应该是时间戳。通过js文件找到ts确实是通过new Date()生成的。
1.6.2) 如果改变ts的值,整个服务器会认为这是恶意请求,
因此猜测app.js对整个json_data进行了签名,通过headers中的portal-sign传给服务器校验
1.6.3)查找 portal-sign签名方法
同样是搜索“portal-sign” 确定只有app.js文件包含,并查找“portal-sign”字符串,发现这个值是通过方法生成的,可以看到getSign(e)的参数e正好是json_data(断点第三次的e才是)。
找到getSign函数是:
里面又包括r['d']常量、 l 函数和s函数... l 函数可以继续找,s函数最后是MD5
引入相应库、解决代码中的变量....
1.7)代码最后通过pyexecjs 把代码执行(需要本地有js解释引擎)可以参考下面的方法
Pyexecjs-使用python执行JavaScript_狄鸠的博客-CSDN博客_pyexecjs
小结:
逆向爬虫很大程度工作就在重现服务器投放到浏览器的js的运行逻辑,一步步抠代码,如果想简单一点可以用无头浏览器,但是效率会低不少。