吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 12021|回复: 80
收起左侧

[Android 原创] 猿人学安卓逆向对抗比赛(1-5题)

  [复制链接]
漁滒 发表于 2022-5-20 19:25

@TOC

题目大纲

题号 题目
java层加密
so层加密
so层加密带混淆
grpc
双向认证
设备指纹加密
quic
upx
tcp
tls

第一题:java层加密

不管三七二十一,上来先抓个包看看
在这里插入图片描述

这是一个post请求,并且附带三个参数,其中一个是sign,那么第一题要分析的应该就是这个sign了,用jadx反编译apk,尝试搜索一下请求地址【/app1】

在这里插入图片描述

只有一个结果,就是你了。选中对应的调用方法,右键选择【查找用例】

在这里插入图片描述
在这里插入图片描述
这次有两个结果,随便点其中一个

在这里插入图片描述

这里看到了sign的关键词,猜测这个就是生成sign的函数,尝试使用frida hook一下对比结果

        var Sign = Java.use("com.yuanrenxue.match2022.security.Sign");
        Sign.sign.implementation = function(a){
            console.log('on sign');
            send('a');
            send(a);
            var sign = this.sign(a);
            send('sign');
            send(sign);
            console.log('le sign');
            return sign;
        };

抓包结果

page=1

sign=e17b4693d730d180b6f6c523a427c08e

t=1652709242

hook结果

on sign
a
长  度:16
字节集:[112, 97, 103, 101, 61, 49, 49, 54, 53, 50, 55, 48, 57, 50, 52, 50]
字符串:b'page=11652709242'
Base64:cGFnZT0xMTY1MjcwOTI0Mg==
HEX   :706167653d3131363532373039323432
sign
e17b4693d730d180b6f6c523a427c08e
le sign

可以看到sign的结果是对的上的,入参就是页数加上时间戳,与请求的参数也是可以对上的,那么sign的计算就是这个函数。

如果把这个函数改成python,那是比较麻烦的,那这了就直接用java运行了,把代码复制到新的文件,复制后【OooO00o.OooO00o(-592855683721616730L)】这个地方会报错,hook一下很容易就知道是【"%02x%02x%02x%02x"】,后面这个相关的就都跳过了。

然后编写一个测试的main方法

在这里插入图片描述

运行的结果是【b94231f3390145e577ab667354a2395d】,神了个奇了,居然与hook的结果不一样。代码里面都是正常的运算代码,也没有设置到时间和随机数这些变量,怎么会不一样呢?

这里就要考虑有没有可能是反编译出了问题,那这里函数不多,那就以函数为单位测试一下哪里出错了

在这里插入图片描述
第一步运行的是padding函数,那么就hook一下看看

        Sign.padding.implementation = function(bArr){
            console.log('on padding');
            let ret = this.padding(bArr);
            console.log(ret);
            console.log('le padding');
            return ret;
        };

可以得到

on sign
a
长  度:16
字节集:[112, 97, 103, 101, 61, 49, 49, 54, 53, 50, 55, 56, 56, 52, 48, 50]
字符串:b'page=11652788402'
Base64:cGFnZT0xMTY1Mjc4ODQwMg==
HEX   :706167653d3131363532373838343032
on padding
[112, 97, 103, 101, 61, 49, 49, 54, 53, 50, 55, 56, 56, 52, 48, 50, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0]
le padding
sign
8fd84d9c105338c8b4872a67b2cca259
le sign

然后在java中也打印一下这个结果

在这里插入图片描述
发现结果已经不一致了

在这里插入图片描述
这个函数看名字应该是一个填充的函数,在整个函数体下来看应该是一个哈希算法的填充

在这里插入图片描述
这里的最后8个字节就是来自于这个循环,实际就是内容长度的序列化数据,但是java代码这里指定的数据类型是int,但是8个字节的应该是long类型,所以这里序列化的时候用了两个int来填充,导致数据不一样,所以把【length】的类型从int修改为long

再次运行后发现,运行结果就与hook结果一致了。代码就扣出来,那么要怎么给python进行调用呢?

某帮m3u8解密算法分析这篇文章的回复中,我提到了如何在python中使用jpype库调用java代码,所以这里也用相同的方法调用

import java.util.ArrayList;

public class Sign {
    public static void main(String[] args) {
        System.out.println(new Sign().sign("page=11652788402".getBytes()));
    }

    private static final int A = 1732584193;
    private static final int B = -271733879;
    private static final int C = -1732584194;
    private static final int D = 271733878;

    private static int f(int i, int i2, int i3) {
        return ((~i) & i3) | (i2 & i);
    }

    private static int ff(int i, int i2, int i3, int i4, int i5, int i6) {
        return rotateLeft(i + f(i2, i3, i4) + i5, i6);
    }

    private static int g(int i, int i2, int i3) {
        return (i & i3) | (i & i2) | (i2 & i3);
    }

    private static int gg(int i, int i2, int i3, int i4, int i5, int i6) {
        return rotateLeft(i + g(i2, i3, i4) + i5 + 1518565785, i6);
    }

    private static int h(int i, int i2, int i3) {
        return (i ^ i2) ^ i3;
    }

    private static int hh(int i, int i2, int i3, int i4, int i5, int i6) {
        return rotateLeft(i + h(i2, i3, i4) + i5 + 1859775393, i6);
    }

    private ArrayList<Integer> padding(byte[] bArr) {
        long length = bArr.length * 8;
        ArrayList<Integer> arrayList = new ArrayList<>();
        for (byte b : bArr) {
            arrayList.add(Integer.valueOf(b));
        }
        arrayList.add(128);
        while (((arrayList.size() * 8) + 64) % 512 != 0) {
            arrayList.add(0);
        }
        for (int i = 0; i < 8; i++) {
            arrayList.add(Integer.valueOf((int) ((length >>> (i * 8)) & 255)));
        }
        return arrayList;
    }

    private static int rotateLeft(int i, int i2) {
        return (i >>> (32 - i2)) | (i << i2);
    }

    public String sign(byte[] bArr) {
        ArrayList<Integer> padding = padding(bArr);
        int i = A;
        int i2 = B;
        int i3 = C;
        int i4 = D;
        for (int i5 = 0; i5 < padding.size() / 64; i5++) {
            int[] iArr = new int[16];
            for (int i6 = 0; i6 < 16; i6++) {
                int i7 = (i5 * 64) + (i6 * 4);
                iArr[i6] = (padding.get(i7 + 3).intValue() << 24) | padding.get(i7).intValue() | (padding.get(i7 + 1).intValue() << 8) | (padding.get(i7 + 2).intValue() << 16);
            }
            int[] iArr2 = {0, 4, 8, 12};
            int i8 = i;
            int i9 = i2;
            int i10 = i3;
            int i11 = i4;
            int i12 = 0;
            while (i12 < 4) {
                int i13 = iArr2[i12];
                i8 = ff(i8, i9, i10, i11, iArr[i13], 3);
                int ff = ff(i11, i8, i9, i10, iArr[i13 + 1], 7);
                i10 = ff(i10, ff, i8, i9, iArr[i13 + 2], 11);
                i9 = ff(i9, i10, ff, i8, iArr[i13 + 3], 19);
                i12++;
                i11 = ff;
            }
            int[] iArr3 = {0, 1, 2, 3};
            int i14 = i8;
            int i15 = i11;
            for (int i16 = 0; i16 < 4; i16++) {
                int i17 = iArr3[i16];
                i14 = gg(i14, i9, i10, i15, iArr[i17], 3);
                i15 = gg(i15, i14, i9, i10, iArr[i17 + 4], 5);
                i10 = gg(i10, i15, i14, i9, iArr[i17 + 8], 9);
                i9 = gg(i9, i10, i15, i14, iArr[i17 + 12], 13);
            }
            int[] iArr4 = {0, 2, 1, 3};
            int i18 = i14;
            int i19 = 0;
            while (i19 < 4) {
                int i20 = iArr4[i19];
                int hh = hh(i18, i9, i10, i15, iArr[i20], 3);
                i15 = hh(i15, hh, i9, i10, iArr[i20 + 8], 9);
                i10 = hh(i10, i15, hh, i9, iArr[i20 + 4], 11);
                i9 = hh(i9, i10, i15, hh, iArr[i20 + 12], 15);
                i19++;
                i18 = hh;
            }
            i += i18;
            i2 += i9;
            i3 += i10;
            i4 += i15;
        }
        return String.format("%02x%02x%02x%02x", Integer.valueOf(i), Integer.valueOf(i2), Integer.valueOf(i3), Integer.valueOf(i4));
    }
}

把上面代码保存到Sign.java

javac Sign.java
jar cvf Sign.jar Sign.class

运行上面两个命令行后,可以得到Sign.jar,复制到python同目录下,使用前需要先安装依赖

pip install JPype1
import jpype
import requests
import time

def main():
    jpype.startJVM(jpype.getDefaultJVMPath(), "-ea", "-Djava.class.path=Sign.jar")  # 启动java虚拟机
    jclass = jpype.JClass("Sign")  # 获取java类
    Sign = jclass()  # 实例化java对象
    url = 'https://appmatch.yuanrenxue.com/app1'
    for page in range(1, 6):
        data = {
            "page": page,
            "t": int(time.time())
        }
        data["sign"] = str(Sign.sign(f'page={data["page"]}{data["t"]}'.encode()))
        response = requests.post(url, data=data).json()
        print(response)
    jpype.shutdownJVM()

if __name__ == '__main__':
    main()

在这里插入图片描述

第二题:so层加密

通过第一题可以知道,大部分的题目窗口都在【com.yuanrenxue.match2022.fragment.challenge】这个类下面在这里插入图片描述
第二题中加载了so,并且只有一个sign函数是native函数,那么就hook这个函数,同时抓包查看

在这里插入图片描述
在这里插入图片描述

on sign 
str
1:1652965963
sign
IB/wL5GD01zlBS3MvRTLjw==
le sign

可以看到请求体与hook的数据是一致的,但是接着就不分析so了,直接上unidbg工具,从https://github.com/zhkl0228/unidbg拉取项目到本地,拉取完成后可以尝试运行一下看雪so的测试类【com.kanxue.test2.MainActivity】

在这里插入图片描述
没有出现报错,并且出现【Found: XuE】的字样,表示环境正常,开始编写我们自己的类【com.yuanrenxue.match2022.fragment.challenge.ChallengeTwoFragment】

package com.yuanrenxue.match2022.fragment.challenge;

import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Module;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.DalvikModule;
import com.github.unidbg.linux.android.dvm.DvmClass;
import com.github.unidbg.linux.android.dvm.StringObject;
import com.github.unidbg.linux.android.dvm.VM;
import com.github.unidbg.memory.Memory;

import java.io.File;
import java.io.IOException;

public class ChallengeTwoFragment {
    private final AndroidEmulator emulator;
    private final VM vm;
    private final Module module;
    private final DvmClass ChallengeTwoFragment;
    private final boolean logging;

    public ChallengeTwoFragment(boolean logging) {
        this.logging = logging;
        emulator = AndroidEmulatorBuilder.for64Bit().setProcessName("com.yuanrenxue.match2022").build();
        final Memory memory = emulator.getMemory();
        memory.setLibraryResolver(new AndroidResolver(23));
        vm = emulator.createDalvikVM(new File("../yuanrenxuem106.apk"));
        vm.setVerbose(logging);
        DalvikModule dm = vm.loadLibrary("match02", true);
        dm.callJNI_OnLoad(emulator);
        module = dm.getModule();
        ChallengeTwoFragment = vm.resolveClass("com/yuanrenxue/match2022/fragment/challenge/ChallengeTwoFragment");
    }

    public void destroy() throws IOException {
        emulator.close();
    }

    public static void main(String[] args) throws Exception {
        ChallengeTwoFragment challengeTwoFragment = new ChallengeTwoFragment(false);
        System.out.println(challengeTwoFragment.sign("1:1652965963"));
        challengeTwoFragment.destroy();
    }

    public String sign(String str) {
        StringObject sign = ChallengeTwoFragment.newObject(null).callJniMethodObject(
                emulator,
                "sign(Ljava/lang/String;)Ljava/lang/String;",
                vm.addLocalObject(new StringObject(vm, str))
        );
        return sign.getValue();
    }
}

在这里插入图片描述
测试结果与hook结果是一致的,大功告成,接下在就是怎么给到python调用了。一种是可以在java起一个本地服务端,然后通过http调用。另一种是像第一题一样,打包成jar给到python调用,那么我这里用的是后后面一种方法。

根据【JAVA】使用intellij IDEA将项目打包为jar包的提示,按照步骤把【unidbg-android】这整个项目打包成jar

在这里插入图片描述
打包后文件数量比较多,是正常现象,最后一个就是我们打包出来的jar,把全部文件都复制到python的目录

在这里插入图片描述
我的目录结构如上图,那么接着就是根据上一题一样,直接调用生成sign就可以,没有什么特别的

import jpype
import requests
import time

def main():
    jpype.startJVM(jpype.getDefaultJVMPath(), "-ea", "-Djava.class.path=../unidbg-android.jar")
    jclass = jpype.JPackage("com.yuanrenxue.match2022.fragment.challenge").ChallengeTwoFragment
    ChallengeTwoFragment = jclass(False)
    url = 'https://appmatch.yuanrenxue.com/app2'
    for page in range(1, 6):
        data = {
            "page": page,
            "ts": int(time.time())
        }
        data["sign"] = str(ChallengeTwoFragment.sign(f'{data["page"]}:{data["ts"]}'.encode()))
        response = requests.post(url, data=data).json()
        print(response)
    jpype.shutdownJVM()

if __name__ == '__main__':
    main()

在这里插入图片描述

第三题:so层加密带混淆

在这里插入图片描述

第三题和第二题基本相似,hook native方法,然后抓包

在这里插入图片描述

on crypto
str
0011652967032000
j
1652967032000
crypto
177f3b597937c04a0f4fccc208de9fce0ce39e5764c4115754b1cd643d528898
le crypto

hook结果与抓包结果也是对的上的,接下来一样是用unidbg生成签名

package com.yuanrenxue.match2022.fragment.challenge;

import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Module;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.DalvikModule;
import com.github.unidbg.linux.android.dvm.DvmClass;
import com.github.unidbg.linux.android.dvm.StringObject;
import com.github.unidbg.linux.android.dvm.VM;
import com.github.unidbg.memory.Memory;

import java.io.File;
import java.io.IOException;

public class ChallengeThreeFragment {
    private final AndroidEmulator emulator;
    private final VM vm;
    private final Module module;
    private final DvmClass ChallengeThreeFragment;
    private final boolean logging;

    public ChallengeThreeFragment(boolean logging) {
        this.logging = logging;
        emulator = AndroidEmulatorBuilder.for64Bit().setProcessName("com.yuanrenxue.match2022").build();
        final Memory memory = emulator.getMemory();
        memory.setLibraryResolver(new AndroidResolver(23));
        vm = emulator.createDalvikVM(new File("../yuanrenxuem106.apk"));
        vm.setVerbose(logging);
        DalvikModule dm = vm.loadLibrary("match03", true);
        dm.callJNI_OnLoad(emulator);
        module = dm.getModule();
        ChallengeThreeFragment = vm.resolveClass("com/yuanrenxue/match2022/fragment/challenge/ChallengeThreeFragment");
    }

    public void destroy() throws IOException {
        emulator.close();
    }

    public static void main(String[] args) throws Exception {
        ChallengeThreeFragment ChallengeThreeFragment = new ChallengeThreeFragment(true);
        System.out.println(ChallengeThreeFragment.sign("0011652967032000", "1652967032000"));;
        ChallengeThreeFragment.destroy();
    }

    public String sign(String str, String j) {
        StringObject sign = ChallengeThreeFragment.newObject(null).callJniMethodObject(
                emulator,
                "crypto(Ljava/lang/String;J)Ljava/lang/String;",
                vm.addLocalObject(new StringObject(vm, str)),
                Long.parseLong(j)
        );
        return sign.getValue();
    }
}

虽然每次运行的结果都不一样,可能是有随机数造成的。打包过去试试请求

import jpype
import requests
import time

def main():
    jpype.startJVM(jpype.getDefaultJVMPath(), "-ea", "-Djava.class.path=../unidbg-android.jar")
    jclass = jpype.JPackage("com.yuanrenxue.match2022.fragment.challenge").ChallengeThreeFragment
    ChallengeThreeFragment = jclass(False)
    url = 'https://appmatch.yuanrenxue.com/app3'
    for page in range(1, 6):
        tim = str(int(time.time() * 1000))
        data = {
            "page": page
        }
        data["m"] = str(ChallengeThreeFragment.sign(str(data['page']).zfill(3) + tim, tim))
        response = requests.post(url, data=data).json()
        print(response)
    jpype.shutdownJVM()

if __name__ == '__main__':
    main()

在这里插入图片描述
可以请求成功,说明也是没有问题的

第四题:grpc

第四题是grpc,那么grpc是什么呢?

更多人可能接触的更多的是基于REST的通信。我们已经看到,REST 是一种灵活的体系结构样式,它定义了对实体资源的基于CRUD的操作。 客户端使用请求/响应通信模型跨 HTTP 与资源进行交互。尽管 REST 是广泛实现的,但一种较新的通信技术gRPC已在各个生态中获得巨大的动力。

gRPC,其实就是RPC框架的一种,前面带了一个g,代表是RPC中的大哥,龙头老大的意思,另外g也有global的意思,意思是全球化比较fashion,是一个高性能、开源和通用的 RPC 框架,基于ProtoBuf(Protocol Buffers) 序列化协议开发,且支持众多开发语言。面向服务端和移动端,基于 HTTP/2 设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。

在 gRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来处理客户端调用。在客户端拥有一个存根能够像服务端一样的方法。

在这里插入图片描述
既然说到protobuf,就不得不说以前的一篇文章【JS逆向系列】某方数据获取,proto入门,我做了这道题才知道,原来这就是grpc呀,那么某方数据用的就是grpc,没有看前面文章的建议先看看再回来看这道题

在这里插入图片描述
接下来一样是抓包和hook

在这里插入图片描述

on sign
str
1:1652969194488
j
1652969194488
sign
8faf8d3081d431db
le sign

因为pbf是序列化后的数据,但是依稀能够看到最后一段签名的对的上的,首先第一步就是调用so生成sign

package com.yuanrenxue.match2022.fragment.challenge;

import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Module;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.DalvikModule;
import com.github.unidbg.linux.android.dvm.DvmClass;
import com.github.unidbg.linux.android.dvm.StringObject;
import com.github.unidbg.linux.android.dvm.VM;
import com.github.unidbg.memory.Memory;

import java.io.File;
import java.io.IOException;

public class ChallengeFourFragment {
    private final AndroidEmulator emulator;
    private final VM vm;
    private final Module module;
    private final DvmClass ChallengeFourFragment;
    private final boolean logging;

    public ChallengeFourFragment(boolean logging) {
        this.logging = logging;
        emulator = AndroidEmulatorBuilder.for64Bit().setProcessName("com.yuanrenxue.match2022").build();
        final Memory memory = emulator.getMemory();
        memory.setLibraryResolver(new AndroidResolver(23));
        vm = emulator.createDalvikVM(new File("../yuanrenxuem106.apk"));
        vm.setVerbose(logging);
        DalvikModule dm = vm.loadLibrary("match04", true);
        dm.callJNI_OnLoad(emulator);
        module = dm.getModule();
        ChallengeFourFragment = vm.resolveClass("com/yuanrenxue/match2022/fragment/challenge/ChallengeFourFragment");
    }

    public void destroy() throws IOException {
        emulator.close();
    }

    public static void main(String[] args) throws Exception {
        ChallengeFourFragment ChallengeFourFragment = new ChallengeFourFragment(true);
        System.out.println(ChallengeFourFragment.sign("1:1652969194488", "1652969194488"));;
        ChallengeFourFragment.destroy();
    }

    public String sign(String str, String j) {
        StringObject sign = ChallengeFourFragment.newObject(null).callJniMethodObject(
                emulator,
                "sign(Ljava/lang/String;J)Ljava/lang/String;",
                vm.addLocalObject(new StringObject(vm, str)),
                Long.parseLong(j)
        );
        return sign.getValue();
    }
}

这次运行结果就是一致的,然后就可以打包给python使用了。第二步就是编写proto文件,因为java层的代码是被混淆的,不好找出原本的键名,不过proro对键名是不敏感的,那么就以简单为主,按照前面的参数来自定义键名,首先尝试编写请求体参数

需要先安装依赖

pip install grpcio
pip install protobuf
pip install grpcio-tools

根据抓包的链接【http://180.76.60.244:9901/challenge.Challenge/SayHello】创建proto文件

在这里插入图片描述
这三个地方需要注意,要与抓包的参数对应

syntax = "proto2";

// http://180.76.60.244:9901/challenge.Challenge/SayHello
// python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. app_proto2.proto

package challenge;

message RequestMessage {
    optional int32 page = 1;
    optional int64 t = 2;
    optional string sign = 3;
}

message ResponseMessage {
        repeated Item data = 1;
}

message Item {
    optional string value = 1;
}

service Challenge{
 rpc SayHello (RequestMessage) returns (ResponseMessage) {}
}

上面文件保存为【app_proto2.proto】,放到python文件同目录,然后执行下面指令

python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. app_proto2.proto

然后就可以得到【app_proto2_pb2.py】和【app_proto2_pb2_grpc.py】

在这里插入图片描述
根据其他的文章说明,新建Stub之前,需要先创建Channel

channel = grpc.insecure_channel('180.76.60.244:9901')

在这里插入图片描述
然后创建client用于真正的PRC请求

client = app_proto2_pb2_grpc.ChallengeStub(channel=channel)

测试发出请求


import app_proto2_pb2
import app_proto2_pb2_grpc
import jpype
import time
import grpc

def main():
    channel = grpc.insecure_channel('180.76.60.244:9901')
    client = app_proto2_pb2_grpc.ChallengeStub(channel=channel)
    jpype.startJVM(jpype.getDefaultJVMPath(), "-ea", "-Djava.class.path=../unidbg-android.jar")
    jclass = jpype.JPackage("com.yuanrenxue.match2022.fragment.challenge").ChallengeFourFragment
    ChallengeFourFragment = jclass(False)
    requests_data = app_proto2_pb2.RequestMessage()
    requests_data.page = 1
    requests_data.t = int(time.time() * 1000)
    requests_data.sign = str(ChallengeFourFragment.sign(str(requests_data.page) + ':' + str(requests_data.t), str(requests_data.t)))
    print(requests_data)
    response = client.SayHello(requests_data)
    print(response)
    jpype.shutdownJVM()

if __name__ == '__main__':
    main()

在这里插入图片描述
请求数据正常,完成

本题参考文献
1.【后台技术】gRPC 基础概念详解
2.gRPC传输协议使用(python教程)
3.猿人学-app逆向比赛第四题grpc题解

第五题:双向认证

既然题目已经告我我们是双向认证了,那么直接抓包肯定是不用想了,必然抓不到,这里我就直接用r0ysue的r0capture,这个frida脚本同时可以把客户端证书dump出来,项目地址:https://github.com/r0ysue/r0capture

在这里插入图片描述
这里项目拉取下来后,我修改了小小东西,我把证书dump出来的目录改到了对应app的目录下,避免一些权限问题

在这里插入图片描述
可以看到上面证书已经被dump出来,dump后的密码为【r0ysue】,同时也抓到包了,可以看到请求地址,请求头和请求体

把dump到手机的证书传到电脑上,我顺便改名为【yuanrenxue.p12】接着使用【OpenSSL】库来提取出key和cert

from OpenSSL import crypto

p12 = crypto.load_pkcs12(open("yuanrenxue.p12", 'rb').read(), b'r0ysue')
with open('client.key', 'wb') as f:
    f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, p12.get_privatekey()))
with open('client.cert', 'wb') as f:
    f.write(crypto.dump_certificate(crypto.FILETYPE_PEM, p12.get_certificate()))

然后可以获得【client.key】和【client.cert】,接着试试发送请求

from OpenSSL import crypto
import requests

def main():
    # p12 = crypto.load_pkcs12(open("yuanrenxue.p12", 'rb').read(), b'r0ysue')
    # with open('client.key', 'wb') as f:
    #     f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, p12.get_privatekey()))
    # with open('client.cert', 'wb') as f:
    #     f.write(crypto.dump_certificate(crypto.FILETYPE_PEM, p12.get_certificate()))

    url = 'https://180.76.60.244:18443/api/app5'
    for page in range(1, 6):
        data = {
            'page': page
        }
        response = requests.post(url, data=data, verify=False, cert=('client.cert', 'client.key'))
        print(response.text)

if __name__ == '__main__':
    main()

在这里插入图片描述
可以看到已经正确获取数据了,到这里就结束了。

前面不是说有十道题,怎么一半就没了呢?主要是因为菜,后面的做不出来

免费评分

参与人数 35吾爱币 +40 热心值 +27 收起 理由
notifier + 1 + 1 谢谢@Thanks!
yytkkn + 1 + 1 我很赞同!
longforus + 1 + 1 谢谢@Thanks!牛啊 学习了
xiaofanxiaoyu + 1 我很赞同!
zjw912555576 + 1 + 1 漁滒NP
technogoon + 1 + 1 热心回复!
YycAway + 1 + 1 我很赞同!
timewl + 1 + 1 热心回复!
coderyl + 1 用心讨论,共获提升!
lvhmst + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
rep3 + 1 + 1 用心讨论,共获提升!
HA? + 1 我很赞同!
努力加载中 + 1 + 1 热心回复!
cclong + 1 + 1 大佬呀,多谢分享
fsunmoon + 1 热心回复!
fengbolee + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
zj_tj + 1 + 1 热心回复!
1MajorTom1 + 1 我很赞同!
procurve + 1 + 1 谢谢@Thanks!
victos + 1 + 1 谢谢@Thanks!
福仔 + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
笙若 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
鹤舞九月天 + 1 + 1 我很赞同!
葬天月痕 + 1 我很赞同!
悦来客栈的老板 + 1 + 1 我很赞同!
#sky# + 1 + 1 热心回复!
notrack + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
gunxsword + 1 + 1 谢谢@Thanks!
天空宫阙 + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
ofo + 3 + 1 jadx右键这些功能真实用
xionghaizi + 1 + 1 我很赞同!
pdcba + 1 + 1 用心讨论,共获提升!
beyond1994 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
hecoter + 1 + 1 我很赞同!
Andrea + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 漁滒 发表于 2022-5-24 11:37
iamspiderman 发表于 2022-5-24 11:36
大佬,请问你用的什么抓包工具呀第一题

小黄鸟  HttpCanary
 楼主| 漁滒 发表于 2022-6-17 16:05
Eb0ny 发表于 2022-6-17 16:00
想问下大佬,第二题我做到unidbg的时候按照你的java脚本运行会什么返回的sign是null,是环境的原因还是啥

内存读写报错了,一般是代码有问题
foolboy 发表于 2022-5-20 19:27
kiopc 发表于 2022-5-20 19:30
先说一声牛beer
wasm2023 发表于 2022-5-20 20:02
渔滒太强了
秋澄 发表于 2022-5-20 20:32
别啊,渔总快更,等着看后面的呢
lovehfs 发表于 2022-5-20 20:51
好好学习一下
10086abc 发表于 2022-5-20 21:04
大佬大佬
taxuewuhen 发表于 2022-5-20 21:35
谢谢分享
BoBuo 发表于 2022-5-20 22:48
向渔滒学习
ZYZZMD 发表于 2022-5-21 07:06
太牛了。。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-19 14:40

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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