爬虫逆向学习(十):记录某省焦煤电子招采平台响应结果加密破解过程(绕过混淆)

var code = “37fef010-e1b9-4d58-a95d-1b35284a7b7a”
此分享只用于学习用途,不作商业用途,若有冒犯,请联系处理

Hook定位快捷命令

反爬前置信息

站点:aHR0cHM6Ly93d3cuc3hjY2R6emNwdC5jbi9ob21lL3RyYWRl
接口:/api/portal/v1/announcement/index
加密点:
在这里插入图片描述
在这里插入图片描述

逆向研究

文本混淆极大影响逆向研究,特别是这种用一堆无用的代码来遮掩关键代码的混淆更加让人头疼。对混淆大家第一反应是AST解混晓,不过这个实现起来比较麻烦(有工具会快点,但是得保证工具有用),下面我提供下多种破解思路

请求调用堆栈定位法

首先我们要清楚这个接口是xhr请求,而且是响应结果加密,明确这两个后我们看一下请求调用堆栈
在这里插入图片描述
我们可以看到调用堆栈有Promise.then,有经验的人就会知道这是ES6的语法,是ES6引入的一种用于处理异步操作的模式,xhr请求会用它来接收回调值。这里我们进去红框标识的堆栈

大家仔细看看这张图:
1处就是构建xhr请求处,这时还没发起请求
2是我们通过堆栈进来的代码位置,它会在这里进行1的请求操作
3就是请求拿到的响应结果了,我们直接在这个位置下断点,看看是啥情况
在这里插入图片描述

看,这里就拿到响应结果了,至于哪里进行的解密,我们继续跟下去
在这里插入图片描述

只要点两次这个按钮就进入下面的代码,这是响应拦截器,解密就是在这里进行的。
在这里插入图片描述
在这里插入图片描述

跟进去就可以看到解密代码了,实际上就是原生的AES解密
在这里插入图片描述

请求调用堆栈定位法大概就是这种分析流程了。

decrypt / encrypt关键词搜索法

这种方法有两个前提:

  1. 反爬使用的是常见的加解密算法,或者参考常见加解密算法实现的自研算法
  2. 代码未完全混淆

这个站点便适合这种方法,它使用的是原生的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)
posted @ 2024-10-11 10:19  七夜魔手  阅读(6)  评论(0编辑  收藏  举报  来源