爬虫逆向学习(十):记录某省焦煤电子招采平台响应结果加密破解过程(绕过混淆)
var code = “37fef010-e1b9-4d58-a95d-1b35284a7b7a”
此分享只用于学习用途,不作商业用途,若有冒犯,请联系处理
反爬前置信息
站点:aHR0cHM6Ly93d3cuc3hjY2R6emNwdC5jbi9ob21lL3RyYWRl
接口:/api/portal/v1/announcement/index
加密点:
逆向研究
文本混淆极大影响逆向研究,特别是这种用一堆无用的代码来遮掩关键代码的混淆更加让人头疼。对混淆大家第一反应是AST解混晓,不过这个实现起来比较麻烦(有工具会快点,但是得保证工具有用),下面我提供下多种破解思路
请求调用堆栈定位法
首先我们要清楚这个接口是xhr
请求,而且是响应结果加密
,明确这两个后我们看一下请求调用堆栈
我们可以看到调用堆栈有Promise.then
,有经验的人就会知道这是ES6
的语法,是ES6
引入的一种用于处理异步操作的模式,xhr
请求会用它来接收回调值。这里我们进去红框标识的堆栈
大家仔细看看这张图:
1
处就是构建xhr
请求处,这时还没发起请求
2
是我们通过堆栈进来的代码位置,它会在这里进行1
的请求操作
3
就是请求拿到的响应结果了,我们直接在这个位置下断点,看看是啥情况
看,这里就拿到响应结果了,至于哪里进行的解密,我们继续跟下去
只要点两次这个按钮就进入下面的代码,这是响应拦截器
,解密就是在这里进行的。
跟进去就可以看到解密代码了,实际上就是原生的AES
解密
请求调用堆栈定位法
大概就是这种分析流程了。
decrypt / encrypt关键词搜索法
这种方法有两个前提:
- 反爬使用的是常见的加解密算法,或者参考常见加解密算法实现的自研算法
- 代码未完全混淆
这个站点便适合这种方法,它使用的是原生的AES
算法,且decrypt
没有完全混淆
大家可能会问,得出这个结论是基于请求调用堆栈定位法
得出的。这样看确实是,但是以我的经验与习惯,当看到这种加密时是会优先使用关键词定位法的,这种定位不到再去使用其它定位方式。(搜一搜不费事)
HOOK JSON. stringify / JSON.parse
JSON. stringify
:字典转字符串,效果与python的json.dumps()一样
JSON.parse
:字符串转字典,效果与python的json.loads()一样
先睹为快,看到没,打印出来的数据是不是响应结果呵响应结果解密数据
一般情况下,加解密是对字符串进行操作的,那么它必然会使用到JSON. stringify / JSON.parse
,毕竟解密得到的数据字符串,正常使用需要转成字符串
我们加个debugger就能在断住了,然后跳出去函数就能到达关键代码位置了
(function() {
var parse = JSON.parse;
JSON.parse = function(params) {
console.log("Hook JSON.parse ——> ", params);
debugger;
return parse(params);
}
})();
AST解混淆
站点混淆使用的是OB混淆
,直接使用市面上提供的工具就可以解混淆,但是解混淆是没法把代码完全人性化的,下面是我解混淆后的结果
就解混淆只是帮我们优化和精简代码,一般情况并不能直接得到关键代码位置,后续还是要拿解混淆后的结果去替换原始代码,然后再去跟流程看看关键代码位置
算法破解
import json
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
def decrypt_aes(self, ciphertext):
key = '1234567890123456'.encode('utf-8')
iv = '1234567890123456'.encode('utf-8')
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted_data = cipher.decrypt(self.bs4_decrypt(ciphertext.encode()))
decrypted_text = unpad(decrypted_data, AES.block_size).decode()
return json.loads(decrypted_text)
本文来自博客园,作者:七夜魔手,转载请注明原文链接:https://www.cnblogs.com/ranbox/p/18461023