上海网站开发定制,手机膜+东莞网站建设,最近的电脑培训学校,网络建设原则文章目录 1. 写在前面2. 接口分析3. 断点分析4. RPC调用5. 算法还原 【#x1f3e0;作者主页】#xff1a;吴秋霖 【#x1f4bc;作者介绍】#xff1a;擅长爬虫与JS加密逆向分析#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长… 文章目录 1. 写在前面2. 接口分析3. 断点分析4. RPC调用5. 算法还原 【作者主页】吴秋霖 【作者介绍】擅长爬虫与JS加密逆向分析Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python与爬虫领域研究与开发工作 【作者推荐】对爬虫领域以及JS逆向分析感兴趣的朋友可以关注《爬虫JS逆向实战》《深耕爬虫领域》 未来作者会持续更新所用到、学到、看到的技术知识包括但不限于各类验证码突防、爬虫APP与JS逆向分析、RPA自动化、分布式爬虫、Python领域等相关文章 作者声明文章仅供学习交流与参考严禁用于任何商业与非法用途否则由此产生的一切后果均与作者无关如有侵权请联系作者本人进行删除 1. 写在前面 最近有点小忙又来到了周末熬夜更一篇逆向技术文章本期写的是之前做过的一个网站一个类似七麦数据的APP聚合类平台平台内榜单、搜索、评论、评分、下载量等接口在发送请求的时候需要携带一个加密参数K
往期同类文章回顾感兴趣的可阅读七麦analysis参数分析与Python算法实现
2. 接口分析
这个加密参数K的算法在所有的接口均是通用的加密手法跟很多网站相似也不相似相似的是API路径加请求参数参打包加密不相似的是在此之外又增加了动态参数参与加密这里我们以评论页面为例开始分析如下所示 随意点击一个切换评论天数触发请求查看一下接口发包情况。可以看到就一个加密参数K值其他字段的话都是固定的其中id字段是APP应用的唯标识也是密文这里我没有去深入研究按理说也是可以去分析找到生成算法的当然非必要应为在搜索的时候可以从上级接口中拿到每个APP对应的密文id如下所示 3. 断点分析
针对上面的加密参数首先需要定位加密参数生成的位置也是逆向分析的第一步有多种定位的方式其中包括XHR断点以及Hook直接搜索加密之后的K基本是无望一搜一大堆。这里我们下一个XHR断点 触发断点后往前跟栈可以看到JS文件没有一百也有大几十都是Webpack如下经过反复调试找到加密入口函数如下所示
h加密方法接受四个参数e是请求提交的参数path是接口的短路径r是请求方法n也是一串参数不知道是哪里来的话这里可以先不管。只需要知道它肯定也是参与了加密就行可以在控制台看了一下明文信息如下所示 把之前的断点释放在加密方法内下个断往下走可以看到最终加密参数生成的结果返回我们可以在控制台打印验证一下如下所示 4. RPC调用
这里借着这个案例分别说说RPC跟扣加密加密代码还原的两种解决方案。找到了加密方法后如果你不想再继续调试去扣加密代码的话就可以上RPC了RPC是什么即远程调用调用什么调用最终的JS加密方法我们可以不需要继续去了解这个方法下面的具体加密逻辑因为就算我们扣下来了可能还会面临环境问题
做爬虫JS逆向不需要去深入了解RPC技术只需要知道如何在逆向中巧妙运用即可
直接注入ws服务替换编辑后的JS文件如下所示 h加密方法最终的返回值就是密文K在其内部直接编写一个自执行函数接受加密所需参数再调用加密方法生成K参数值这里我们甚至不需要去分析参数n的来源
编写Python调用代码并在本地启动后刷新网页代码实现如下
import asyncio
import websocketsasync def receive_message(websocket):try:while True:send_text input(请输入要加密的字符串)if send_text exit:print(退出)await websocket.send(send_text)breakelse:await websocket.send(send_text)response_text await websocket.recv()print(加密结果, response_text)except Exception as e:print(发生异常:, e)finally:await websocket.close()async def main():async with websockets.connect(ws://127.0.0.1:8765) as websocket:await receive_message(websocket)asyncio.run(main())
可以看到ws服务接受到提交参数后调用加密方法成功拿到加密结果如下所示 上面RPC的方案在ws服务开启后可把Python调用稍微修改一下做成一个API服务提供远端调用这样爬虫可以直接并发调用加密
5. 算法还原
上面说到的RPC方案虽然可以绕过加密的这个问题但是性能肯定是不能跟算法相比。能还原算法的大部分是不会去使用RPC方案的一般场景都在短期内无法快速还原加密算法的情况下会采用RPC作为一个临时的数据抓取方案
接下来我们往下分析去扣JS代码并还原加密算法首先我们先找到n参数内d、k、l、num、s、sort是如何生成的断点继续往下走注意看在K进行base64编码返回密文前的一行JS代码如下所示
来就是这里我们总结分析一下上图几个参数的值跟n参数内的字段对应关系如下 n {“s”: s, “k”: d, “l”: f, “d”: 0, “sort”: “dd”, “num”: 10} 像上面三个动态生成的参数参与加密一般也有可能是其他算法生成的、但是也可能是在前面某些接口内生成的请求一次刷新一次最新的参数所以可以先用搜索大法去验证一下一般可能会有意想不到的结果如下所示 至此参与加密的动态参数n就搞定了每次请求之前请随便找个主页接口求一下把上面的动态参数拿出来即可
接着继续分析加密逻辑现在已经是周六的凌晨3点了一边回忆复盘加调试、一边记录到文章中
进入到Object(l.b)函数内部这里提示一下各位新手朋友像一些基本的调式技巧不熟悉的可以先学习一下多看看大佬的视频或者文章我觉得我一般都写的够细了还有人私信问怎么操作说看不懂如下所示 现在我们尝试将这个方法加上前面的加密函数h全部扣出来进行替换JS代码中写有注释如下所示
function m(e, n, o) {var d ;// t.from自己定义一下就一个编码方法n t.from(n, utf8),o t.from(o, utf8);//使用NodeJS中内置经典加解密模块替换//var c Object(r.createDecipheriv)(aes-128-cbc, n, o);//使用AES算法创建解密器var c crypto.createDecipheriv(aes-128-cbc, n, o);//将十六进制编码的密文进行解密return d c.update(e, hex, utf8),d c.final(utf8)
}function h(e, path, n, r) {var s n.s, d n.k, f n.l, v n.d, h n.sort, k n.num, y function(content, t, e) {for (var a Array.from(content), n Array.from(t), r a.length, o n.length, d String.fromCodePoint, i 0; i r; i)a[i] d(a[i].codePointAt(0) ^ n[(i e) % o].codePointAt(0));return a.join()}(function(s, t, path, e) {return [s, t, e, path].join(())}(function(t, e) {var n c()(t);if (!_()(n)) {var r [];for (var d in n)m()(n[d]) get e (n[d] n[d].join()),post e (m()(n[d]) || o()(n[d])) (n[d] JSON.stringify(n[d])),r.push(n[d]);return r.sort(),r.join()}// 这里我们先将Object(l.b)替换为上面的m函数}(e, r), parseInt((new Date).getTime() / 1e3) - 655876800 - v, path, h), m(s, d, f), k);//return t.from(y).toString(base64)//采用浏览原生函数编码方式return btoa(y)
}上面JS代码已经还原了90%只差最后一步t.from这个方法是干嘛的断点继续调式如下所示 from方法接受两个参数r默认空t需要编码的字符串e编码类型默认UTF-8来用调式环境的数据编写一个from函数测试一下跟浏览器一致如下所示
最后将浏览器环境请求参数跟动态参数n的数据丢给上面还原的加密算法测试如下
K加密结果与浏览器一致至此结束补环境的话代码量会更多这个网站加密结构还是很清晰的 测试运行一下抓取评论接口数据效果如下 最后互联网任何公开的数据源有获取数据的需求可以适当的利用工具与技术来助力。但切记不要滥用以免对任何第三份平台与网站造成压力与负担请使用合理、合法、合规、合情的方式去满足自己的需求
好了到这里又到了跟大家说晚安的时候了。创作不易帮忙点个赞再走吧。你的支持是我创作的动力希望能带给大家更多优质的文章