js逆向案例-obsfuscator混淆

目录

        • 一、obsfuscator混淆特点
        • 二、如何分析逆向obsfuscator混淆
        • 三、逆向ob混淆实战
          • 1、目标结果
          • 2、查找哪个请求有目标数据
          • 3、查找加密参数生成位置
          • 4、分析data参数生成逻辑
          • 5、python请求验证结果

一、obsfuscator混淆特点

  • 1、通过混淆工具Obfuscator混淆过的代码即obsfuscator混淆(简称ob混淆),点击Obsfucate即可混淆如下代码
    js逆向案例-obsfuscator混淆_第1张图片

  • 2、特点:代码变量形式大篇幅的已_0x为前缀进行命名,通过死代码花指令增加代码可读难度;通常死代码在程序中完全不会调用,而花指令可能将一个变量经过一系列操作又变回原形的值,其过程毫无意义

var _0x2f9b = ['Hello\x20World!']; (function(_0x3af67b, _0x2f9b76) {
    var _0x471fa6 = function(_0x578853) {
        while (--_0x578853) {
            _0x3af67b['push'](_0x3af67b['shift']());
        }
    };
    _0x471fa6(++_0x2f9b76);
} (_0x2f9b, 0xb2));
var _0x471f = function(_0x3af67b, _0x2f9b76) {
    _0x3af67b = _0x3af67b - 0x0;
    var _0x471fa6 = _0x2f9b[_0x3af67b];
    return _0x471fa6;
};
function hi() {
    var _0x2b0421 = _0x471f;
    console['log'](_0x2b0421('0x0'));
}
hi();

二、如何分析逆向obsfuscator混淆

  • 1、第一种(不推荐):正向找传参入口,通过首次传入的参数正向分析它被改变或者被赋值给哪些变量,一步步看函数逻辑,还原代码,耗时间,最终结果可能还是错误的;
  • 2、第二种(推荐):逆向分析,留头留尾,找到传入的参数的入口,找到返回的参数,然后通过返回的参数一步步倒推分析这个返回的参数是如何生成的,然后缺啥补啥;
  • 3、第三种(推荐):如果第二种无法解决的话,终极武器,通过分析AST抽象语法树的结构,还原整个代码处理逻辑

三、逆向ob混淆实战

1、目标结果
  • 获取音乐列表数据
    js逆向案例-obsfuscator混淆_第2张图片
2、查找哪个请求有目标数据
  • 观察请求响应,发现search这个请求结果里正好是我们的目标结果数据,而它的请求参数data是加密的,所以接下来是研究data是如何生成的
    js逆向案例-obsfuscator混淆_第3张图片
3、查找加密参数生成位置
  • 首先全局搜与data,通过全局搜索(ctr + F)data、var data、data:、data=这一系列,可以发现都不是我们所要的data参数
    js逆向案例-obsfuscator混淆_第4张图片
  • 然后,尝试调用栈寻找,打开该请求调用栈,发现有个ajax请求,我们点击f、ajax、send这三个蓝色的VM,发现在f这个VM里面有我们要的data字段
    js逆向案例-obsfuscator混淆_第5张图片
  • 打断点、刷新页面:f的VM点进去后,左下角{}格式化后如下图,成功找到data参数的生成位置,在这里打个断点,刷新页面,会发现成功的断在了data参数的位置,接下来是分析data生成的具体流程,点击右上角第三个向下箭头进入函数内部查看生成逻辑
    js逆向案例-obsfuscator混淆_第6张图片
4、分析data参数生成逻辑
  • 调试发现,encode这个方法就是生成data的关键方法,传入参数是这么一个格式"text=周杰伦&page=1&type=migu"
    js逆向案例-obsfuscator混淆_第7张图片

  • 我们将function encode这个方法全部复制下来,存到一个ZJL.js文件(先将该VM所有js代码复制下来保存为音乐2.js文件,搜索该函数encode并折叠复制)
    js逆向案例-obsfuscator混淆_第8张图片

  • 在ZJL.js里面最后一行添加console.log(encode("text=周杰伦&page=1&type=migu")),并运行该ZJL.js文件,发现缺少参数_0x5e84
    js逆向案例-obsfuscator混淆_第9张图片

  • 查找参数_0x5e84生成位置,在音乐2.js文件里搜索var _0x5e84即为该参数生成位置,折叠发现83行到175行为_0x5e84为参数生成的所有
    js逆向案例-obsfuscator混淆_第10张图片

  • 看_0x5e84内部生成逻辑,回到谷歌调试界面,逐步调试,_0x5e84这个我进行了代码简化处理,简单的还原的该参数生成代码如下(ps:这一部分_0x5e84参数生成可以好好研究一下,细节不做介绍,省略~)
    js逆向案例-obsfuscator混淆_第11张图片

  • 在ZJL.js文件里补上这个_0x5e84参数的生成代码,继续运行,发现少location参数,回到谷歌页面调试
    js逆向案例-obsfuscator混淆_第12张图片

  • 在谷歌VM页面搜索location[_0x5e84(,打上断点,调试跳到该断点处,在console界面输出location,嗯~有结果,然后copy(location),复制到ZJL.js文件
    js逆向案例-obsfuscator混淆_第13张图片
    js逆向案例-obsfuscator混淆_第14张图片

  • 保存再运行,发现少MD5参数(ReferenceError: md5 is not defined),npm install crypto-js ,从crypto-js文件里导入md5
    js逆向案例-obsfuscator混淆_第15张图片

  • 保存再运行,发现有可能会报如下错误_0x514ed7[_0x5e84(...)] is not a function,这个原因是 _0x5e84[‘EIMrEA’] 这个对象里面参数不全的原因,到谷歌里面调试
    js逆向案例-obsfuscator混淆_第16张图片

  • 在encode方法return这里打个断点,调试跳到这里,console界面输出_0x5e84[‘EIMrEA’]这个结果,并复制到ZJL.js文件里替换_0x5e84[‘EIMrEA’],这个_0x5e84['EIMrEA']的key很多,尽可能的运行到函数返回结果的时候,在复制这个参数,否则还会报错_0x514ed7[_0x5e84(...)] is not a functionjs逆向案例-obsfuscator混淆_第17张图片

  • 如果保存文件后运行还有类似_0x514ed7[_0x5e84(…)] is not a function报错,在console界面输出_0x514ed7[_0x5e84(…)]这个结果,然后将js文件里对应的替换掉就行
    js逆向案例-obsfuscator混淆_第18张图片

  • 运行,结果输出,加密完成。将md5这里在稍微改下,添加个.toString(),这样data参数前4位就会随时间戳md5值改变了,但是不加也没啥影响,data的前4个字符随意生成4个字符都没啥问题

 var _0x271eea = _0x514ed7[_0x5e84('139', '!rZ)')](md5, new Date()[_0x5e84('13a', '*OHJ')]().toString())

js逆向案例-obsfuscator混淆_第19张图片

  • 点击获取完整ZJL.js
5、python请求验证结果
  • 用上面的data参数python请求看下结果,运行正常没问题
import requests
url = "http://59.110.45.28/m/api/search"
headers = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36",
    "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
    "origin": "http://tool.liumingye.cn"
}
data = {
    "data": "7c02QNBLytVZbtF9mFfgD1dlXCFcC_oAP4r3MDsbkvy-zP-yky9cO3wePMzVl9KMZpX9IrZwPNfDFXzu",
    "v": 2
}
resp = requests.post(url, data=data, headers=headers)
print(resp.text)


你可能感兴趣的:(SpiderCrawl,javascript,python)