• 【JavaScript 逆向】拼多多 anti_content 参数逆向解析


    前言 

    现在一些网站对 JavaScript 代码采取了一定的保护措施,比如变量名混淆、执行逻辑混淆、反调试、核心逻辑加密等,有的还对数据接口进行了加密,这次案例是通过补环境过加密。

    声明

    本文章中所有内容仅供学习交流,相关链接做了脱敏处理,若有侵权,请联系我立即删除!

    案例分析

    目标网址:

    aHR0cHM6Ly9tb2JpbGUueWFuZ2tlZHVvLmNvbS8=

    数据接口:

    aHR0cHM6Ly9tb2JpbGUueWFuZ2tlZHVvLmNvbS9wcm94eS9hcGkvc2VhcmNoX3N1Z2dlc3Q=

    以上均做了脱敏处理,Base64 编码及解码方式:

    1. import base64
    2. # 编码
    3. # result = base64.b64encode('待编码字符串'.encode('utf-8'))
    4. # 解码
    5. result = base64.b64decode('待解码字符串'.encode('utf-8'))
    6. print(result)

    常规 JavaScript 逆向思路

    一般情况下,JavaScript 逆向分为三步:

    • 寻找入口:逆向在大部分情况下就是找一些加密参数到底是怎么来的,关键逻辑可能写在某个关键的方法或者隐藏在某个关键的变量里,一个网站可能加载了很多 JavaScript 文件,如何从这么多的 JavaScript 文件的代码行中找到关键的位置,很重要;
    • 调试分析:找到入口后,我们定位到某个参数可能是在某个方法中执行的了,那么里面的逻辑是怎么样的,调用了多少加密算法,经过了多少赋值变换,需要把整体思路整理清楚,以便于断点或反混淆工具等进行调试分析;
    • 模拟执行:经过调试分析后,差不多弄清了逻辑,就需要对加密过程进行逻辑复现,以拿到最后我们想要的数据

    接下来开始正式进行案例分析:

    寻找入口

    打开开发者人员工具,进行抓包,从响应预览中可以看到搜索内容的下拉列表的接口为 search_suggest?pdduid=XXX&query=XXX:

    负载中可以看到一些接口 url 的参数,query 就是搜索栏中输入的内容,很明显,anti_content 参数经过加密,接下来就需要对这个参数进行逆向分析:

    逆向分析

    anti_content 是接口 url 中的参数,且下拉数据是通过 ajax 加载的,所以通过 Hook 或者 XHR 断点的方式都能成功定位,不过大道至简,这里直接全局搜索 anti_content,因为只有一个 js 文件中包含这个关键字:

    点击 SearchViewUI.js 文件跟进去,然后通过左下角的 { } 对其进行格式化操作,ctrl + f 局部搜索 anti_content 关键字,只有一个结果,在第1949 行,在 第1939 行打下断点调试:

    可以看到 f 即 anti_content 参数的值,f 定义在第 1938 行,f = e.sent,此时加密后的参数已经生成了,所以需要向上跟栈,看看是哪加密的:

    跟到 vendors_xxx 文件的第 19158 行,这里就是个异步 Promise,在 19619 行打下断点会发现此时的 e 还是 undefined,没生成加密参数:

    XMLHttpRequest 这种异步的都很麻烦跳来跳去,类似如下几个地方,跟栈需要耐心:

    1. var l = p(e, t, n);
    2. return this._invoke(t, e)
    3. return e.apply(this, arguments)
    4. getAntiContent
    5. initRiskCntroller
    6. messagePackSync

    跟到后面会跳转到一个叫 react_anti_XXX 的文件,这个文件还记录了鼠标移动轨迹:

    在该文件的第 1791 行是 anti_content 参数的关键加密位置,这部分经过混淆,不过也没必要解混淆:

    控制台打印看看,Lt() 即返回这个值的函数: 

    滑到开头,会发现这是个通过 webpack 打包了的 js 文件,框出来的部分就是模块加载器,有个 webpack 很明显的标志:

    return t[e].call(o.exports, o, o.exports, r)

    webpack 相关推荐看看这篇文章:JavaScript 之 webpack 加密代码扣取

    这里为文件本身的加载器调用,删掉,后面调用加载器的时候再传值进去就行了:

    现在只需要把加载器导出为全局变量,然后将该函数改为自执行调用即可:

    1. !(function (t) {
    2. var n = {};
    3. function r(e) {
    4. if (n[e])
    5. return n[e].exports;
    6. var o = n[e] = {
    7. i: e,
    8. l: !1,
    9. exports: {}
    10. };
    11. return t[e].call(o.exports, o, o.exports, r),
    12. o.l = !0,
    13. o.exports
    14. };
    15. window.rose = r;
    16. })
    17. ...
    18. ...
    19. ...
    20. let anti_content = window.rose(4);
    21. result = new anti_content();

    将此时的 js 代码放到浏览器环境中运行,在 result 处打断点,断住后跟进到第 1830 行:

    会跳转到如下代码处:

    1. var Vt = new Bt;
    2. t[a(831, "C0uu")] = function() {
    3. var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}
    4. , n = a;
    5. return t[w] && X && Vt[n(548, "YD8i")](t[w]),
    6. Vt
    7. }

    Vt 继承了 Bt 的方法,返回值部分 t[w] 是一个时间戳,w 为 serverTime:

    跟到 Vt[n(548, "YD8i")] 中看看,这里是通过 now() 方法生成的时间戳:

     所以可以写成如下样式:

    1. let anti_content = window.rose(4);
    2. result = new anti_content({ serverTime: new Date().getTime() });

    Vt 原型下的 messagePack 函数调用了刚刚的加密函数 Lt():

    所以来试试 result 调用 messagePack 函数能否得到加密值:

    在控制台中成功打印出了加密结果,证明加密方法就是这样的,接下补环境即可,整理后的 js 文件如下:

    1. !(function (t) {
    2. var n = {};
    3. function r(e) {
    4. if (n[e])
    5. return n[e].exports;
    6. var o = n[e] = {
    7. i: e,
    8. l: !1,
    9. exports: {}
    10. };
    11. return t[e].call(o.exports, o, o.exports, r),
    12. o.l = !0,
    13. o.exports
    14. };
    15. window.rose = r;
    16. })([function (t, n, r) {
    17. // 此部分与原 js 文件一样, 在此省略
    18. ])
    19. let anti_content = window.rose(4);
    20. result = new anti_content({ serverTime: new Date().getTime() });

     补完环境后即可在 node 环境下成功得到加密结果:

    python 调用:

    欢迎提供更多需要 anti_content 参数的接口 ~ 

  • 相关阅读:
    云IDE介绍——CSDN开发云
    权威认可 | Smartbi为何屡获市场认可,多个权威报告给出答案
    JavaBean 和 Spring Bean的区别
    node12-node的 get请求
    【深入浅出设计模式--命令模式】
    解决vue ui无法远程访问的问题
    http请求方式及传参方式
    Permissions for ‘xxx.pem‘ are too open
    【思维构造】Find The Array—CF1463B
    Linux 安全 - Capabilities机制
  • 原文地址:https://blog.csdn.net/Yy_Rose/article/details/127508765