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

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

目标网址:aHR0cHM6Ly9waW5kdW9kdW8uY29tL2hvbWUvM2M=

加密参数:anti_content

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

参数定位

anti_content 全局搜索

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

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

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

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

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

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

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

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

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

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

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

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

在n("fbez")函数内部

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

serverTime: e

}

返回值为r

anti_content的加密值已经出来了

扣webpack

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

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

补环境

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

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可直接忽略

补完之后出结果,可用

代码提供

// 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());
//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网站,可以搭建一个补环境框架逐步向框架里面添加浏览器环境,补的环境越多越完善,通杀的网站越多

  • 30
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的工作流程包括以下几个关键步骤: URL收集: 爬虫从一个或多个初始URL开始,递归或迭代地发现新的URL,构建一个URL队列。这些URL可以通过链接分析、站点地图、搜索引擎等方式获取。 请求网页: 爬虫使用HTTP或其他协议向目标URL发起请求,获取网页的HTML内容。这通常通过HTTP请求库实现,如Python中的Requests库。 解析内容: 爬虫对获取的HTML进行解析,提取有用的信息。常用的解析工具有正则表达式、XPath、Beautiful Soup等。这些工具帮助爬虫定位和提取目标数据,如文本、图片、链接等。 数据存储: 爬虫将提取的数据存储到数据库、文件或其他存储介质中,以备后续分析或展示。常用的存储形式包括关系型数据库、NoSQL数据库、JSON文件等。 遵守规则: 为避免对网站造成过大负担或触发反爬虫机制,爬虫需要遵守网站的robots.txt协议,限制访问频率和深度,并模拟人类访问行为,如设置User-Agent。 反爬虫应对: 由于爬虫的存在,一些网站采取了反爬虫措施,如验证码、IP封锁等。爬虫工程师需要设计相应的策略来应对这些挑战。 爬虫在各个领域都有广泛的应用,包括搜索引擎索引、数据挖掘、价格监测、新闻聚合等。然而,使用爬虫需要遵守法律和伦理规范,尊重网站的使用政策,并确保对被访问网站的服务器负责。
### 回答1: 拼多多是一家中国电商巨头,它的算法对于实现商品的高成交量起着重要的作用。Anti_content是拼多多的一款算法,它在国内电商市场中具有很高的知名度。在js购买方面,它的作用主要是通过“拆单”功能,提高拼购商品的成交率。 拼购商品的成功转化主要取决于两个关键因素,一是需求足够大,二是人数足够多。Anti_content算法针对这两个因素提供了优化和改进的方案。在js购买中,它通过降低拼购门槛,让更多的用户参与拼购,从而提高商品的成交率。 此外,通过反复试验和不断优化,Anti_content算法还实现了拆单功能。拆单功能将购物车中多个商品进行拆分,转换成多个订单,分别以独立的价格进行结算。这一功能对于降低拼购的门槛和提高成交率起到了非常重要的作用。 总之,在拼多多的算法中,Anti_content算法在js购买中具有非常重要的作用。它通过对拼购门槛的降低和拆单功能的实现,提高了拼多多商品的成交率和用户粘性,对于推动拼多多的快速发展起到了积极的作用。 ### 回答2: 拼多多算法是指拼多多购物平台上用于推荐商品的一种算法。在拼多多上,用户可以通过浏览商品、搜索等方式找到自己感兴趣的商品,而算法就是根据用户的行为和偏好,为用户推荐相似或相关的商品。 拼多多的算法主要采用了协同过滤、基于内容以及深度学习等多种技术。其中,anti_content是拼多多算法中的一种方法,它的主要作用是通过反向内容推荐,为用户推荐与其浏览记录中相反的商品。 具体而言,anti_content算法会根据用户的购买和浏览行为,分析出用户的兴趣爱好和偏好。然后,根据这些兴趣爱好和偏好的信息,系统会向用户推荐与其购买和浏览行为中相反的商品。例如,如果用户经常购买A类商品,那么系统就会向其推荐一些B类商品。这样做的目的是希望能够让用户能够多样化地体验不同类型的商品,从而提高用户的购物满意度和体验。 在实际应用中,anti_content算法通常会与其他算法相结合,综合考虑用户的行为、商品的特征和用户的个人喜好等因素,进行推荐。通过这些算法的运用,拼多多可以为用户提供个性化的、符合其兴趣爱好的购物推荐,提高用户的购物体验和满意度。 ### 回答3: 拼多多是一家中国的电商平台,而"anti_content"是指拼多多的算法对于用户购买过程中对内容进行反对的处理方式。拼多多的算法在用户购买过程中采用一些机制来反对一些内容。 首先,拼多多的算法会对商品的内容进行审核,确保商品内容不违反相关法律法规,并尽量避免用户购买到低质量或欺诈性的商品。 其次,拼多多根据用户的历史购买记录和个人兴趣偏好对商品进行推荐。通过分析用户的行为和偏好,算法会提供符合用户需求的相关商品,提高购买的满意度。 另外,拼多多的算法还会根据商品的评论、评分等信息来评估商品的质量和用户体验。通过对用户评价的分析,拼多多能够更加准确地反馈商品的优劣,帮助用户做出更加明智的购买决策。 最后,拼多多的算法还会根据商品的供应情况、促销活动等因素对购买过程进行调控。算法会推荐库存充足、价格合理的商品,同时会根据用户的购买行为和需求,提供一些促销活动来吸引用户购买。 总之,拼多多的算法通过对商品内容的审核、个性化推荐、用户评价分析以及购买过程调控等方式,提供给用户更加符合需求和优质的购买体验。同时,算法的反对内容机制也保证了用户购买中的安全和满意度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CgfFan

感谢看官老爷赏的咖啡钱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值