首页
社区
课程
招聘
[原创] dex动态自修改demo题解
发表于: 2021-4-20 14:45 12133

[原创] dex动态自修改demo题解

2021-4-20 14:45
12133

题目来自看雪2w班9月第一题。题目主要考察AES+RC4算法,但是神奇的是用了一个dex中的一个stringID在动态运行时被修改成另一个值了,因此导致静态看到结果和动态观察不一致。

脱壳,脱壳后进行逆向,

一开始感觉so文件完全没啥用,反而有一个Utils的类十分可疑

很明显的test函数是入口,然后调用bbbbb函数进行加密得到的返回值作为aaaaa函数的参数进行加密,最后确认是否等于Utils.Cipher

一开始一看 不是很明显嘛直接CyberChef,然而。。

图片描述

很明显不对。。想到之前寒冰师傅出的题,一定是动态修改,那么那个so文件应该就做了这件事。。。

直接用Objection打印吧

图片描述

果然。。。

再来CyberChef

图片描述

还是不对,难道不是也不是AES嘛 。。

后来经过主动调用发现AES是对的,那么RC4魔改了????直接抠出来用Java工程跑一遍,确实和标准的RC4不一致。。

不过由于RC4这种是一个对称密码,那么我直接拿AES解密后的去再调用一次这个函数就行了。。

最终frida跑出来原来的正确的flag

图片描述

脚本关键函数如下

这里的c3bfc...是我用CyberChef逆出来的。

或者自己写一个java工程,把这个类的所有代码拷出来。。。写个反向的工程就行了。这里我贴出我为了印证RC4的Java工程的代码吧

最后验证索然无味

图片描述

永远要记得只有动态在内存中的才是真的,静态看到的可能只是一个谎言。

 
 
package com.kanxue.test;
 
import android.util.Base64;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
 
public class Utils {
    public static String cipher;
 
    static {
        Utils.cipher = "sGpdX0nDoRPWnonSt0SQQXOk/0wID0jvtAqb2QxJoW4=";
    }
 
    public Utils() {
        super();
    }
 
    public static String aaaaa(String arg7, String arg8) throws Exception {
        String v0 = null;
        if(arg8 == null) {
            return v0;
        }
 
        if(arg8.length() != 16) {
            return v0;
        }
 
        SecretKeySpec v2 = new SecretKeySpec(arg8.getBytes("utf-8"), "AES");
        Cipher v3 = Cipher.getInstance("AES/ECB/PKCS5Padding");
        v3.init(1, ((Key)v2));
        return new String(Base64.encode(v3.doFinal(arg7.getBytes("utf-8")), 0));
    }
 
    static String bbbbb(String arg14, String arg15) {
        int v0 = 0x100;
        char[] v1 = new char[v0];
        char[] v2 = new char[v0];
        int v3;
        for(v3 = 0; v3 < v0; ++v3) {
            v1[v3] = arg14.charAt(v3 % arg14.length());
            v2[v3] = ((char)v3);
        }
 
        v3 = 0;
        int v4;
        for(v4 = 0; v4 < v0; ++v4) {
            v3 = v2[v4] + v3 + v1[v4] & 0xFF;
            char v5 = v2[v4];
            v2[v4] = v2[v3];
            v2[v3] = v5;
        }
 
        v0 = 0;
        v3 = 0;
        String v4_1 = "";
        int v5_1;
        for(v5_1 = 0; v5_1 < arg15.length(); ++v5_1) {
            v0 = v0 + 1 & 0xFF;
            char v6 = v2[v0];
            v3 = v3 + v6 & 0xFF;
            char v7 = ((char)(v2[v3] + v6 & 0xFF));
            v2[v0] = v2[v3];
            v2[v3] = v6;
            try {
                v4_1 = v4_1 + new String(new char[]{((char)(arg15.charAt(v5_1) ^ v2[v7]))});
            }
            catch(Exception v8) {
                v8.printStackTrace();
            }
        }
 
        return v4_1;
    }
 
    public static boolean test(String arg6) {
        boolean v0 = false;
        new Utils();
        String v2 = Utils.bbbbb("kanxue", arg6);
        try {
            if(!Utils.aaaaa(v2, "0123456789abcdef").replace("\n", "").equals(Utils.cipher)) {
                return v0;
            }
        }
        catch(Exception v3) {
            v3.printStackTrace();
            return v0;
        }
 
        return true;
    }
}
package com.kanxue.test;
 
import android.util.Base64;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
 
public class Utils {
    public static String cipher;
 
    static {
        Utils.cipher = "sGpdX0nDoRPWnonSt0SQQXOk/0wID0jvtAqb2QxJoW4=";
    }
 
    public Utils() {
        super();
    }
 
    public static String aaaaa(String arg7, String arg8) throws Exception {
        String v0 = null;
        if(arg8 == null) {
            return v0;
        }
 
        if(arg8.length() != 16) {
            return v0;
        }
 
        SecretKeySpec v2 = new SecretKeySpec(arg8.getBytes("utf-8"), "AES");
        Cipher v3 = Cipher.getInstance("AES/ECB/PKCS5Padding");
        v3.init(1, ((Key)v2));
        return new String(Base64.encode(v3.doFinal(arg7.getBytes("utf-8")), 0));
    }
 
    static String bbbbb(String arg14, String arg15) {
        int v0 = 0x100;
        char[] v1 = new char[v0];
        char[] v2 = new char[v0];
        int v3;
        for(v3 = 0; v3 < v0; ++v3) {
            v1[v3] = arg14.charAt(v3 % arg14.length());
            v2[v3] = ((char)v3);
        }
 
        v3 = 0;
        int v4;
        for(v4 = 0; v4 < v0; ++v4) {
            v3 = v2[v4] + v3 + v1[v4] & 0xFF;
            char v5 = v2[v4];
            v2[v4] = v2[v3];
            v2[v3] = v5;
        }
 
        v0 = 0;
        v3 = 0;
        String v4_1 = "";
        int v5_1;
        for(v5_1 = 0; v5_1 < arg15.length(); ++v5_1) {
            v0 = v0 + 1 & 0xFF;
            char v6 = v2[v0];
            v3 = v3 + v6 & 0xFF;
            char v7 = ((char)(v2[v3] + v6 & 0xFF));
            v2[v0] = v2[v3];
            v2[v3] = v6;
            try {
                v4_1 = v4_1 + new String(new char[]{((char)(arg15.charAt(v5_1) ^ v2[v7]))});
            }
            catch(Exception v8) {
                v8.printStackTrace();
            }
        }
 
        return v4_1;
    }
 
    public static boolean test(String arg6) {
        boolean v0 = false;
        new Utils();
        String v2 = Utils.bbbbb("kanxue", arg6);
        try {
            if(!Utils.aaaaa(v2, "0123456789abcdef").replace("\n", "").equals(Utils.cipher)) {
                return v0;

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 3
支持
分享
最新回复 (3)
雪    币: 116
活跃值: (1012)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
支持一下
2021-4-26 00:59
0
雪    币: 334
活跃值: (392)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
支持一下
2021-4-29 08:42
0
雪    币: 548
活跃值: (60)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
感谢
2023-3-21 13:19
0
游客
登录 | 注册 方可回帖
返回
//