找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 71|回复: 0

某多多anti_content参数逆向(补环境)

[复制链接]

2万

主题

137

回帖

13万

积分

管理员

积分
139366
发表于 2024-8-17 20:52:51 | 显示全部楼层 |阅读模式 IP:山东省临沂市 联通

登录后更精彩...O(∩_∩)O...

您需要 登录 才可以下载或查看,没有账号?立即注册

×
资源来自网络分享,侵权请告知删除。
如失效,请联系管理

某多多anti_content参数逆向(补环境)

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

目标网址:https://dinduoduo.com/home/3c

加密参数:anti_content

请求带anti_content字段,结果正常,不带则异常

1.png

29.png

参数定位

anti_content 全局搜索

29.png

只有一处,定位到js文件中该位置,下断点

1.png

当t.next = 10 ,anti_content还未产生值

t.t1 = t.sent ,anti_content值已经产生

加密位置显而易见,Object(l.a)()是加密方法体,下断点,跳转到v函数

1.png

r.messagePackSync();产生我们需要结果,方法继续下断点

1.png

跳转到de函数,函数返回值下断点

1.png

加密函数的值是从 n[r("0x1bb", "A3e0")](ue)得到,n[r("0x1bb", "A3e0")]方法,参数传入一个参数,然后执行该参数,即执行ue()函数,即可得到anti_content加密值

拉到文件顶部,发现是一个典型的webpack

1.png

而n[r("0x1bb", "A3e0")](ue)是在fbeZ函数内部,而fbeZ又封装一个webpack,ue()函数在第四个模块(角标从0开始)

1.png


我们目标函数是在第二层webpack fbeZ内部,我们直接来扣代码,扣之前注意:找到fbeZ调用者,调用时是否传入参数。

文件全局搜索发现只有一处调用

1.png

显而易见n是外层的导出器函数,进入函数内部看看,验证正确

1.png

在n("fbez")函数内部

1.png

跟栈,可以发现调用fbez函数传入的参数:{

serverTime: e

}

返回值为r

1.png

anti_content的加密值已经出来了

1.png


扣webpack

接下来我们扣webpack 代码,webpack打包的代码有明显的特征,很容易识别出来,webpack推荐

1.png

运行成功,运行fbez模块用到8oxB,YuTi模块,浏览器找到这两个模块放入pdd_webpack文件中。本地运行发现没有出结果(缺少浏览器环境),去浏览器浏览器运行,成功生成加密参数并可用

1.png

1.png


补环境

为了更好的体验调试,本次我们不用补环境框架


vm2沙箱介绍

本地js环境联条配置可参考

准备环境做好了,F5运行vm.js

报错

定位到浏览器W("0x3f", "LZ%H")该处位置,浏览器环境rt[z]值为document,vm2沙箱环境值为undefined,缺少document导致环境报错

在enviroment.js文件中把window,document,navigator ,history ,localStorage常检测的环境先补上,再挂上代理

rename,savefunction方法作用

没有使用rename,savefunction方法之前

使用rename,savefunction方法之后,使其和浏览器结果一致

运行vm.js,日志报错,输出日志信息

我们将属性值为undefined对照浏览器补齐,如果浏览器的属性值为也为null可直接忽略

补完之后出结果,可用

代码提供
[JavaScript] 纯文本查看 复制代码
// vm.js代码
var vm= require("vm2")
var fs = require('fs')
const {VM,VMScript} = vm
var vm = new VM()
 
var code = fs.readFileSync('./enviroment.js')
code += fs.readFileSync('./pdd.js')
 
const script = new VMScript(code, `sy_debugging.js`);
vm.run(script)
 
debugger;;
 
// function get_encrypt(){
//     var res = vm.run(code)
//     return res
// }
// debugger;
// console.log(get_encrypt());




[JavaScript] 纯文本查看 复制代码
//enviroment.js 补环境代码
debugger;;
catvm = {}
catvm.memory = {log:[]};
// 保护伪造函数toString
;(() => {
    const $toString = Function.toString
    const myFunction_toString_symbol = Symbol('('.concat('', ')_', (Math.random()) + '').toString(36))
    const myToString = function (){
        return typeof this === 'function' && this[myFunction_toString_symbol] || $toString.call(this)
    }
    function set_native(func, key, value){
        Object.defineProperty(func, key, {
            enumerable: false,
            configurable: true,
            writable: true,
            value: value
        })
    }
    delete Function.prototype.toString
    set_native(Function.prototype, "toString", myToString)
    set_native(Function.prototype.toString, myFunction_toString_symbol, "function toString() { [native code] }")
    this.catvm.savefunction = (func, funcname) => {
        //todo 系统函数没名字 native code
        set_native(func, myFunction_toString_symbol, `function ${func.name || funcname || ''}() { [native code] }`)
    }
}).call(this)
 
//代理
catvm.proxy = function (obj) {
    // Proxy 可以多层代理,即 a = new proxy(a); a = new proxy(a);第二次代理
    // 后代理的检测不到先代理的
    return new Proxy(obj, {
        set(target, property, value) {
            catvm.memory.log.push({"类型":"set-->","调用者":target,"调用属性":property,"设置值":value});
            console.table([{"类型":"set-->","调用者":target,"调用属性":property,"设置值":value}]);
            return Reflect.set(...arguments); //这是一种反射语句,这种不会产生死循环问题
        },
        get(target, property, receiver) {
            if(target.name!=='toString' && property !=='Math' && property !== 'isNaN' && property !=='undefined'){
                catvm.memory.log.push({"类型":"get<--","调用者":target,"调用属性":property,"获取值":target[property]});
                console.table([{"类型":"get<--","调用者":target,"调用属性":property,"获取值":target[property]}]);
            }
            return target[property];  // target中访问属性不会再被proxy拦截,所以不会死循环
        }
    });
};
 
//定义原型名称
catvm.rename = function rename(obj,proValue)
{
    //定义原型名称
    Object.defineProperties(obj,{
        [Symbol.toStringTag]:{
            value:proValue,
            configurable:true
        }
   });
}
 
delete global;
delete Buffer;
 
window = globalThis;
window.outerHeight = 1080;
window.chrome = catvm.proxy({}) 
setTimeout = function setTimeout(){console.log(arguments)}
var Window = function Window(){};
Object.setPrototypeOf(window,Window.prototype);
catvm.rename(Window.prototype,'Window');
catvm.savefunction(Window)
 
var HTMLDocument = function HTMLDocument(){};
document = {
    cookie:'_nano_fp=XpmaXqdaXqdbXqXJXo_ShM7Br8OTCzqBDo6OVbYc',
    referrer:'https://xxx.com/home/3c',
    getElementById:function getElementById(){
        console.log(arguments);
    },
    addEventListener:function addEventListener(){
        console.log(arguments);
    }
};
Object.setPrototypeOf(document,HTMLDocument.prototype);
catvm.rename(HTMLDocument.prototype,'HTMLDocument');
catvm.savefunction(HTMLDocument)
 
var Location = function Location(){};
location = {
    href:'https://xxx.com/home/3c',
    port:'',
};
Object.setPrototypeOf(location,Location.prototype);
catvm.rename(Location.prototype,'Location');
catvm.savefunction(Location)
 
var Navigator = function Navigator(){};
navigator = {
    plugins:[],//插件直接补为空列表就ok,有的浏览器可能就是没有插件
    languages:['zh-CN', 'zh'],
    userAgent:'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
};
Object.setPrototypeOf(navigator,Navigator.prototype);
catvm.rename(Navigator.prototype,'Navigator')
catvm.savefunction(Navigator)
 
var History = function History(){};
history = {
    back:function back(){
        console.log(arguments);
    }
};
Object.setPrototypeOf(history,History.prototype);
catvm.rename(History.prototype,'History')
catvm.savefunction(History)
 
var Storage = function Storage(){};
localStorage = {
    getItem:function getItem(){
        console.log(arguments)
    }
};
Object.setPrototypeOf(localStorage,Storage.prototype);
catvm.rename(Storage.prototype,'Storage')
catvm.savefunction(Storage)
 
var Screen = function Screen(){};
screen = {
    availHeight:1080,
 
};
Object.setPrototypeOf(screen,Screen.prototype);
catvm.rename(Screen.prototype,'Screen')
catvm.savefunction(Screen)
 
window = catvm.proxy(window)
document = catvm.proxy(document)
location = catvm.proxy(location)
navigator = catvm.proxy(navigator)
history = catvm.proxy(history)
localStorage = catvm.proxy(localStorage)
screen = catvm.proxy(screen)



结语

拼多多补环境比较简单,这样补的环境并不完善,仅仅是针对pdd网站,可以搭建一个补环境框架逐步向框架里面添加浏览器环境,补的环境越多越完善,通杀的网站越多


from: https://blog.csdn.net/m0_38098782/article/details/138271203


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|时间戳|加密|CTF WiKi|CTF平台汇总|CTF show|ctfhub|棱角安全|rutracker|攻防世界|php手册|peiqi文库|CyberChef|猫捉鱼铃|手机版|小黑屋|cn-sec|IOTsec-Zone|在线工具|分享屋 ( 鲁ICP备2021028754号 )

GMT+8, 2024-9-19 09:25

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表