拼多多anti-token分析

前言:拼多多charles抓包分析发现跟商品相关的请求头里都带了一个anti-token的字段且每次都不一样,那么下面的操作就从分析anti-token开始了

1.jadx反编译直接搜索

选中跟http相关的类对这个方法进行打印堆栈

结合堆栈方法调用的情况找到具体anti-token是由拦截器类f.a方法调用的,在http.a.c()方法中生成并且http.p.e()方法中加入请求头

在http.a.c()方法中有个一个判断条件如果为true则走d.a().e()方法生成anti-token

如果为false则走j()方法生成anti-token

hook这个i()方法返回值可知获取商品详情接口返回值为false所以走的是j()方法进行计算anti-token。

SecureNative.deviceInfo3()方法生成,传入的str为pdd生成的固定id 一个字符串.

根据hook_libart 得到info3()方法是在libodd_secure.so中,那么ida打开看看这个so包

2.这部分我们采用unidbg+jnitrace+frida相结合的方式

unidbg前期准备的代码这里就不发了直接调用这个info3方法

这里提示调用gad()方法返回一个字符串那么frida hook这个方法拿到这个值 如下图 一个固定的字符串

16位长度看着像AES的密钥 

继续补环境 这里简单补环境就不发了

补完简单的环境代码后,再次运行报这个错误 看错误应该是缺少文件 ,那么看看日志需要补那个文件

继续运行,没有返回值报空指针。execve()函数执行的时候程序exit了这里我们返回对象本身.

execve()函数执行的时候程序exit了

execve filename=/system/bin/sh, args=[sh, -c, cat /proc/sys/kernel/random/boot_id]

这个函数相当于查看 boot_id这个文件信息

捋顺下逻辑应该就是先fork进程 然后在子进程中读取这个文件 然后把他写入pip中

那么自定义syscallhandler后 再次运行成功拿到结果

 

全部代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

package pdd;

import com.github.unidbg.AndroidEmulator;

import com.github.unidbg.Emulator;

import com.github.unidbg.Module;

import com.github.unidbg.file.FileResult;

import com.github.unidbg.file.IOResolver;

import com.github.unidbg.file.linux.AndroidFileIO;

import com.github.unidbg.linux.android.AndroidARMEmulator;

import com.github.unidbg.linux.android.AndroidEmulatorBuilder;

import com.github.unidbg.linux.android.AndroidResolver;

import com.github.unidbg.linux.android.dvm.*;

import com.github.unidbg.linux.file.ByteArrayFileIO;

import com.github.unidbg.memory.Memory;

import com.github.unidbg.memory.SvcMemory;

import com.github.unidbg.spi.SyscallHandler;

import com.github.unidbg.unix.UnixSyscallHandler;

import java.io.File;

import java.nio.charset.StandardCharsets;

import java.util.ArrayList;

import java.util.List;

import java.util.UUID;

public class Pddmain extends AbstractJni implements IOResolver<AndroidFileIO> {

    private AndroidEmulator androidEmulator;

    private static final String APK_PATH = "/Users/Downloads/com.xunmeng.pinduoduo_6.7.0_60700.apk";

    private static final String SO_PATH = "/Users/Downloads/com.xunmeng.pinduoduo_6.7.0_60700/lib/armeabi-v7a/libpdd_secure.so";

    private Module moduleModule;

    private VM dalvikVM;

    public static void main(String[] args) {

        Pddmain main = new Pddmain();

        main.create();

    }

    private void create() {

        AndroidEmulatorBuilder androidEmulatorBuilder = new AndroidEmulatorBuilder(false) {

            @Override

            public AndroidEmulator build() {

                return new AndroidARMEmulator("com.xunmeng.pinduoduo",rootDir,backendFactories) {

                    @Override

                    protected UnixSyscallHandler<AndroidFileIO> createSyscallHandler(SvcMemory svcMemory) {

                        return new PddArmSysCallHand(svcMemory);

                    }

                };

            }

        };

        androidEmulator = androidEmulatorBuilder.setProcessName("").build();

        androidEmulator.getSyscallHandler().addIOResolver(this);

        Memory androidEmulatorMemory = androidEmulator.getMemory();

        androidEmulatorMemory.setLibraryResolver(new AndroidResolver(23));

        dalvikVM = androidEmulator.createDalvikVM(new File(APK_PATH));

        DalvikModule module = dalvikVM.loadLibrary(new File(SO_PATH), true);

        moduleModule = module.getModule();

        dalvikVM.setJni(this);

        dalvikVM.setVerbose(true);

        dalvikVM.callJNI_OnLoad(androidEmulator, moduleModule);

        callInfo3();

    }

    @Override

    public void callStaticVoidMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {

        if ("com/tencent/mars/xlog/PLog->i(Ljava/lang/String;Ljava/lang/String;)V".equals(signature)) {

            return;

        }

        super.callStaticVoidMethodV(vm, dvmClass, signature, vaList);

    }

    private void callInfo3() {

        List<Object> argList = new ArrayList<>();

        argList.add(dalvikVM.getJNIEnv());

        argList.add(0);

        DvmObject<?> context = dalvikVM.resolveClass("android/content/Context").newObject(null);

        argList.add(dalvikVM.addLocalObject(context));

        argList.add(dalvikVM.addLocalObject(new StringObject(dalvikVM, "api/oak/integration/render")));

        argList.add(dalvikVM.addLocalObject(new StringObject(dalvikVM, "dIrjGpkC")));

        Number number = moduleModule.callFunction(androidEmulator, 0xb6f9, argList.toArray())[0];

        String toString = dalvikVM.getObject(number.intValue()).getValue().toString();

        System.out.println(toString);

    }

    @Override

    public DvmObject<?> callStaticObjectMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {

        if ("com/xunmeng/pinduoduo/secure/EU->gad()Ljava/lang/String;".equals(signature)) {

            return new StringObject(vm, "cb14a9e76b72a627");

        else if ("java/util/UUID->randomUUID()Ljava/util/UUID;".equals(signature)) {

            UUID uuid = UUID.randomUUID();

            DvmObject<?> dvmObject = vm.resolveClass("java/util/UUID").newObject(uuid);

            return dvmObject;

        }

        return super.callStaticObjectMethodV(vm, dvmClass, signature, vaList);

    }

    @Override

    public DvmObject<?> callObjectMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {

        if ("java/util/UUID->toString()Ljava/lang/String;".equals(signature)) {

            UUID uuid = (UUID) dvmObject.getValue();

            return new StringObject(vm, uuid.toString());

        else if ("java/lang/String->replaceAll(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;".equals(signature)) {

            String obj = dvmObject.getValue().toString();

            String arg0 = vaList.getObjectArg(0).toString();

            String arg1 = vaList.getObjectArg(1).toString();

            String replaceAll = obj.replaceAll(arg0, arg1);

            return new StringObject(vm, replaceAll);

        }

        return super.callObjectMethodV(vm, dvmObject, signature, vaList);

    }

    @Override

    public int callIntMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {

        if ("java/lang/String->hashCode()I".equals(signature)) {

            return dvmObject.getValue().toString().hashCode();

        }

        return super.callIntMethodV(vm, dvmObject, signature, vaList);

    }

    @Override

    public FileResult<AndroidFileIO> resolve(Emulator<AndroidFileIO> emulator, String pathname, int oflags) {

        if ("/proc/stat".equals(pathname)) {

            String info = "cpu  15884810 499865 12934024 24971554 59427 3231204 945931 0 0 0\n" +

                    "cpu0 6702550 170428 5497985 19277857 45380 1821584 529454 0 0 0\n" +

                    "cpu1 4438333 121907 3285784 1799772 3702 504395 255852 0 0 0\n" +

                    "cpu2 2735453 133666 2450712 1812564 4626 538114 93763 0 0 0\n" +

                    "cpu3 2008473 73862 1699542 2081360 5716 367109 66860 0 0 0\n" +

                    "intr 1022419954 0 0 0 159719900 0 16265892 4846825 5 5 5 6 0 0 497 24817167 17 176595 1352 0 28375276 0 0 0 0 5239 698 0 0 0 0 0 0 3212852 0 12195284 0 0 0 0 0 43 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12513 2743129 375 12477726 0 0 0 0 37 1351794 0 36 8 0 0 0 0 0 0 5846 0 0 0 0 0 0 0 0 0 141 32 0 55 0 0 0 0 0 0 0 0 18 0 18 0 0 0 0 0 0 66 0 0 0 0 0 0 0 77 0 166 0 0 0 0 0 394 0 0 0 0 0 1339137 0 0 0 0 0 0 313 0 0 0 55759 7 7 7 0 0 0 0 0 0 0 0 3066136 0 47 0 0 0 2 2 0 0 0 6 8 0 0 0 2 0 462 2952327 35420 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 495589 0 0 0 0 3 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 37662 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4760 0 0 97 0 0 0 0 0 0 0 0 0 243 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4649 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 22355451 0 0 0 14 0 24449357 96 49415 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17067 780222 3211 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 649346 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" +

                    "ctxt 1572087931\n" +

                    "btime 1649910663\n" +

                    "processes 230673\n" +

                    "procs_running 6\n" +

                    "procs_blocked 0\n" +

                    "softirq 374327567 12481657 139161248 204829 7276312 2275183 26796 12851725 80988196 1422751 117638870";

            return FileResult.success(new ByteArrayFileIO(oflags, pathname, info.getBytes(StandardCharsets.UTF_8)));

        }

        return null;

    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/111776.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言每日一练------Day(5)

本专栏为c语言练习专栏&#xff0c;适合刚刚学完c语言的初学者。本专栏每天会不定时更新&#xff0c;通过每天练习&#xff0c;进一步对c语言的重难点知识进行更深入的学习。 今日练习题关键字&#xff1a;错误的集合 密码检查 &#x1f493;博主csdn个人主页&#xff1a;小小u…

系统架构:软件工程

文章目录 资源知识点自顶向下与自底向上形式化方法结构化方法敏捷方法净室软件工程面向服务的方法面向对象的方法快速应用开发螺旋模型软件过程和活动开放式源码开发方法功用驱动开发方法统一过程模型RUP基于构件的软件开发UML 资源 信息系统开发方法 知识点 自顶向下与自底…

QtConcurrent和QFuture的使用

在Qt中&#xff0c;有时候我们会遇到这样一种情况&#xff0c;需要执行一个很长时间的操作&#xff0c;这时候我们的主界面就会卡住。我们的通常做法就是把这个很长时间的操作扔到线程里去处理&#xff0c;可以使用标准库中的线程也可以使用QThread。 如果我们要在这个很长时间…

ChatGPT 随机动态可视化图表分析

动态可视化图表分析实例如下图: 这样的动态可视化图表可以使用ChatGPT OpenAI 来实现。 给ChatGPT发送指令: 你现在是一个数据分析师,请使用HTML,JS,Echarts,来完成一个动态条形图,条形图方向横向,数据可以随机生成,并且随机生成10个不同的商品名称,每个类别分别用…

Nginx到底是什么,他能干什么?

目录 Ngnix是什么&#xff0c;它是用来做什么的呢&#xff1f; 一。Nginx简介 二&#xff0c;为什么要用Nginx呢&#xff1f; 二。Nginx应用 1.HTTP代理和反向代理 2.负载均衡 Ngnix是什么&#xff0c;它是用来做什么的呢&#xff1f; 一。Nginx简介 Nginx是enginex的简写&…

基于大语言模型知识问答应用落地实践 – 知识库构建(下)

上篇介绍了构建知识库的大体流程和一些优化经验细节&#xff0c;但并没有结合一个具体的场景给出更细节的实战经验以及相关的一些 benchmark 等&#xff0c;所以本文将会切入到一个具体场景进行讨论。 目标场景&#xff1a;对于 PubMed 医疗学术数据中的 1w 篇文章进行知识库构…

Mycat之前世今生

如果我有一个32核心的服务器&#xff0c;我就可以实现1个亿的数据分片&#xff0c;我有32核心的服务器么&#xff1f;没有&#xff0c;所以我至今无法实现1个亿的数据分片。——MyCAT ‘s Plan 话说“每一个成功的男人背后都有一个女人”&#xff0c;自然MyCAT也逃脱不了这个诅…

C语言每日一练------Day(6)

本专栏为c语言练习专栏&#xff0c;适合刚刚学完c语言的初学者。本专栏每天会不定时更新&#xff0c;通过每天练习&#xff0c;进一步对c语言的重难点知识进行更深入的学习。 今日练习题关键字&#xff1a;整数转换 异或 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn…

ChatGPT⼊门到精通(2):ChatGPT 能为我们做什么

⼀、雇佣免费的⼲活⼩弟 有了ChatGPT后&#xff0c;就好⽐你有了好⼏个帮你免费打⼯的「⼩弟」&#xff0c;他们可以帮你做很多 ⼯作。我简单总结⼀些我⽬前使⽤过的⽐较好的基于ChatGPT的服务和应⽤。 1、总结、分析 当我们在阅读⼀些⽂章和新闻的时候&#xff0c;有的⽂章写…

ARM-M0 + 24bit 高精度ADC,采样率4KSPS,国产新品,传感器首选

ARM-M0内核MCU 内置24bit ADC &#xff0c;采样率4KSPS flash 64KB&#xff0c;SRAM 32KB 适用于传感器&#xff0c;电子秤&#xff0c;体脂秤等等

同源策略与解决方法

同源策略与解决方法 1.浏览器的同源策略 1.1 同源策略 同源策略&#xff08;same origin policy&#xff09;&#xff0c;一种安全策略&#xff0c;用于限制一个源的文档或者它加载的脚本如何能与另一个源的资源进行交互。 浏览器默认两个不同的源之间是可以互相访问资源和…

集合框架-(Collection/Map)

1.单列集合 1.1基础概要 集合中存储的是对象的地址信息&#xff0c;想要输出对象的信息&#xff0c;需要在具体的类中重写toString&#xff08;&#xff09;方法 Collection代表单列集合&#xff0c;每个元素数据只包含一个值 List集合&#xff1a;添加的元素可以是有序、可…

【第1章 数据结构概述】

目录 一. 基本概念 1. 数据、数据元素、数据对象 2. 数据结构 二. 数据结构的分类 1. 数据的逻辑结构可分为两大类&#xff1a;a. 线性结构&#xff1b;b. 非线性结构 2. 数据的存储结构取决于四种基本的存储方法&#xff1a;顺序存储、链接存储、索引存储、散列存储 3. …

uni-app中使用iconfont彩色图标

uni-app中使用iconfont彩色图标 大家好&#xff0c;今天我们来学习一下uni-app中使用iconfont彩色图标&#xff0c;好好看&#xff0c;好好学&#xff0c;超详细的 第一步 首先&#xff0c;从iconfont官网&#xff08;iconfont-阿里巴巴矢量图标库&#xff09;选择自己需要的图…

从零构建深度学习推理框架-11 Resnet

op和layer结构 在runtime_ir.cpp中&#xff0c;我们上一节只构建了input和output&#xff0c;对于中间layer的具体实现一直没有完成&#xff1a; for (const auto& kOperator : this->operators_) {if (kOperator->type "pnnx.Input") {this->input_o…

Soul涉赌?元宇宙“皮囊”绷不住走样的“灵魂社交”

“软色情”、“杀猪盘”之后&#xff0c;陌生人社交平台Soul又多了一张“涉赌”标签。 8月初&#xff0c;视频媒体青蜂侠Bee报道称&#xff0c;Soul平台内游戏“星际庄园”名为“种地”&#xff0c;但用户充值种“水果”、平台发起概率抽奖、奖励转手可场外变现的玩法暗藏赌博…

DNS 协议都没听过?你配做开发?

一、什么是DNS协议&#xff1f; DNS协议是一种用于将域名转换为IP地址的分布式命名系统。它通过将用户提供的域名映射到相应的IP地址&#xff0c;实现了互联网上资源的定位和访问。DNS协议采用了层次化的域名结构&#xff0c;使得域名之间可以建立逻辑上的关联。 二、DNS解析过…

新建Spring Boot项目

使用IDEA 来创建: 文件-新建-项目 填写项目元数据 选择依赖项 此处可以先选 web-spring web 关于这些依赖项&#xff0c;更多可参考&#xff1a; IDEA创建Spring boot项目时各依赖的说明&#xff08;Developer Tools篇&#xff09;[1] 项目结构介绍 展开项目&#xff0c;此时…

跨站请求伪造(CSRF)

文章目录 渗透测试漏洞原理跨站请求伪造&#xff08;CSRF&#xff09;1. CSRF概述1.1 基本概念1.1.1 关键点1.1.2 目标 1.2 CSRF场景1.2.1 银行账户转账1.2.2 构造虚假网站1.2.3 场景建模1.2.4 实验 1.3 CSRF类别1.3.1 POST方式 1.4 CSRF验证1.4.1 CSRF Poc generator 1.5 XSS与…

Python爬虫(十六)_JSON模块与JsonPath

数据提取之JSON与JsonPATH JSON(JavaScript Object Notation)是一种轻量级的数据交换格式&#xff0c;它是的人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。适用于进行数据交互的场景&#xff0c;比如网站前台与后台之间的数据交互。 JSON和XML的比较可谓不相…