首页
社区
课程
招聘
[原创]【银行逆向百例】16Android逆向之算法助手 frida绕过环境检测分析加密算法
发表于: 2小时前 79

[原创]【银行逆向百例】16Android逆向之算法助手 frida绕过环境检测分析加密算法

2小时前
79

“ 你打算怎么活,今后,在我死之后,你打算过怎样的生活,托尔芬。——《冰海战记》S1E24 ”

01环境版本

环境:
电脑,Windows 11 专业版 23H2

69aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6v1K9h3q4G2f1%4g2u0L8X3k6G2f1$3g2U0i4K6u0r3d9X3W2S2L8#2y4#2d9h3&6X3L8#2y4W2j5#2)9#2k6W2b7H3x3r3I4K6i4K6g2X3g2$3W2F1x3e0p5`.

软件:
Mumu模拟器,5.3.4

https://mumu.163.com/download/

Kitsune Mask,27.2

5d2K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1j5I4M7e0t1K6L8s2W2U0y4o6g2Q4x3V1k6w2K9i4c8K6N6h3&6W2e0h3q4Y4K9i4y4C8i4K6u0r3M7X3g2D9k6h3q4K6k6i4x3`.

算法助手,1.0.9

https://www.123865.com/s/7G8aTd-bKH4H

LSPosed,1.9.2

03aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6x3f1#2m8G2M7$3g2V1i4K6u0r3e0q4y4b7L8%4y4W2k6q4)9J5c8Y4u0W2L8r3g2S2M7$3g2K6i4K6u0r3N6r3q4Y4i4K6u0r3N6U0p5`..9.2

brook,20230606.5

3cdK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6@1P5s2c8Z5K9h3&6C8K9h3&6Y4i4K6u0r3j5Y4u0G2L8$3D9`.

frida-server,16.1.8

ebdK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6X3M7X3W2V1j5g2)9J5c8X3k6J5K9h3c8S2i4K6u0r3M7X3g2D9k6h3q4K6k6i4y4Q4x3V1k6@1j5h3N6Q4x3V1j5`.16.1.8

burpsuite,2025.1

973K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3L8%4u0@1M7%4N6A6k6$3N6W2M7W2)9J5k6h3&6W2N6q4)9J5c8X3u0#2M7Y4m8Q4x3V1k6J5k6h3I4W2j5i4y4W2M7H3`.`.

Charles,5.0.2

01fK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2U0K9r3q4J5L8r3g2K6M7s2u0G2P5s2W2Q4x3X3g2U0L8$3#2Q4x3V1k6V1L8%4N6F1L8r3!0S2k6q4)9J5c8R3`.`.

02操作步骤

1、弹窗提示设备环境风险,点击确定自动退出APP
图片描述
2、可写系统盘

https://mumu.163.com/help/20240202/35044_1136675.html

图片描述
3、安装KitsuneMagisk

f12K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1j5I4M7e0t1K6L8s2W2U0y4o6g2Q4x3V1k6w2K9i4c8K6N6h3&6W2e0h3q4Y4K9i4y4C8i4K6u0r3M7X3g2D9k6h3q4K6k6i4x3`.

图片描述
4、安装算法助手

https://www.123865.com/s/7G8aTd-bKH4H

图片描述
5、下载LSPosed-v1.9.2-7024-zygisk-release

e3cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6x3f1#2m8G2M7$3g2V1i4K6u0r3e0q4y4b7L8%4y4W2k6q4)9J5c8Y4u0W2L8r3g2S2M7$3g2K6i4K6u0r3N6r3q4Y4i4K6u0r3N6U0p5`..9.2

图片描述
6、允许root权限
图片描述
7、安装
图片描述
8、直接安装
图片描述
9、开启Zygisk
图片描述
10、关闭模拟器
图片描述
11、模块安装LSPosed-v1.9.2-7024-zygisk-release
图片描述
12、关闭模拟器
图片描述
13、下拉进入LSPosed
图片描述
14、模块启用算法助手
图片描述
15、启用模块后关闭模拟器
图片描述
16、算法助手勾选目标APP
图片描述
17、弹窗定位,启动APP
图片描述
18、查看日志
图片描述
19、复制调用堆栈
图片描述
20、分析日志,最后调用了AlertMessageDialog.showIosAlert
图片描述
21、启动frida-server

67cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6X3M7X3W2V1j5g2)9J5c8X3k6J5K9h3c8S2i4K6u0r3M7X3g2D9k6h3q4K6k6i4y4Q4x3V1k6@1j5h3N6Q4x3V1j5`.16.1.8

图片描述

adb push .\frida-server-16.1.8-android-x86_64 /data/local/tmp
adb shell
su
cd /data/local/tmp
chmod +x frida-server-16.1.8-android-x86_64
./frida-server-16.1.8-android-x86_64

22、获取包名

frida-ps -Uai

图片描述
23、hook弹窗通用方法Dialog.show,如果调用堆栈包含AlertMessageDialog关键字就返回空,成功绕过弹窗
图片描述

Java.perform(function() {
    var Dialog = Java.use("android.app.Dialog");
    Dialog.show.implementation = function() {
        if (Java.use("java.lang.Thread").currentThread().getStackTrace().toString().indexOf("AlertMessageDialog") !== -1) {
            console.log("[+] 拦截环境检测弹窗");
            return;
        }
        return this.show();
    };
});

24、网络环境勾选
图片描述
25、抓包请求加密

d48K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6^5P5W2)9J5k6h3q4D9K9i4W2#2L8W2)9J5k6h3y4G2L8g2)9J5c8X3&6W2N6%4y4Q4x3V1j5`.11263

图片描述
26、算法助手勾选算法分析
图片描述
27、复制调用堆栈日志
图片描述
28、分析调用堆栈
用户名,调用 RSAUtils.IdNoEncrypt() → 内部调用 RSAUtils.encrypt() 进行 RSA 加密

com.xxx.utils.keyboardutil.RSAUtils.encrypt
com.xxx.utils.keyboardutil.RSAUtils.IdNoEncrypt

密码,调用 RSAUtils.PwdRandomRsaEncrypt() → 内部先用 AESUtils.encrypt() 加密密码,再用 RSA 加密 AES 密钥

com.xxx.utils.keyboardutil.AESUtils.encrypt
com.xxx.utils.keyboardutil.AESUtils.encrypt
com.xxx.utils.keyboardutil.RSAUtils.PwdRandomRsaEncrypt

图片描述
29、hook.js
图片描述

Java.perform(function() {
    console.log("[*] Frida Hook已启动 - 延迟Hook策略");
    // 字节转Hex
    function bytesToHex(bytes) {
        if (!bytes) return "null";
        var result = "";
        for (var i = 0; i < bytes.length; i++) {
            result += ("0" + (bytes[i] & 0xFF).toString(16)).slice(-2);
        }
        return result;
    }
    // 打印调用堆栈
    function printStackTrace() {
        console.log("[调用堆栈]");
        var traces = Java.use("java.lang.Thread").currentThread().getStackTrace();
        for (var i = 0; i < traces.length && i < 10; i++) {
            var line = traces[i].toString();
            if (line.indexOf("cn.com.xxx") !== -1 || line.indexOf("xxx") !== -1) {
                console.log("  at " + line);
            }
        }
    }
    // ==================== 弹窗拦截 ====================
    try {
        var Dialog = Java.use("android.app.Dialog");
        Dialog.show.implementation = function() {
            try {
                if (Java.use("java.lang.Thread").currentThread().getStackTrace().toString().indexOf("AlertMessageDialog") !== -1) {
                    console.log("[+] 拦截环境检测弹窗");
                    return;
                }
            } catch(e) {}
            return this.show();
        };
        console.log("[+] 弹窗拦截已启用");
    } catch(e) {}
    // ==================== 延迟Hook目标类 ====================
    var rsaHooked = false;
    var aesHooked = false;
    var hookAttempts = 0;
    var maxAttempts = 30;
    function tryHookTargetClasses() {
        hookAttempts++;
        // 尝试Hook RSAUtils
        if (!rsaHooked) {
            try {
                var RSAUtils = Java.use("com.xxx.utils.keyboardutil.RSAUtils");
                console.log("[+] RSAUtils 类已加载,开始Hook...");
                // Hook encrypt (String, Key)
                try {
                    RSAUtils.encrypt.overload('java.lang.String', 'java.security.Key').implementation = function(data, key) {
                        console.log("\n================ RSAUtils.encrypt ================");
                        console.log("[输入] " + data);
                        var result = this.encrypt(data, key);
                        console.log("[输出Hex] " + bytesToHex(result));
                        printStackTrace();
                        console.log("==================================================");
                        return result;
                    };
                } catch(e) {}
                // Hook IdNoEncrypt
                try {
                    RSAUtils.IdNoEncrypt.implementation = function(idNo) {
                        console.log("\n================ RSAUtils.IdNoEncrypt ================");
                        console.log("[输入数据] " + idNo);
                        var result = this.IdNoEncrypt(idNo);
                        console.log("[加密结果] " + result);
                        printStackTrace();
                        console.log("======================================================");
                        return result;
                    };
                } catch(e) {}
                // Hook PwdRandomRsaEncrypt
                try {
                    RSAUtils.PwdRandomRsaEncrypt.implementation = function(pwd, randomKey) {
                        console.log("\n================ RSAUtils.PwdRandomRsaEncrypt ================");
                        console.log("[AES随机密钥] " + pwd);
                        console.log("[明文密码] " + randomKey);
                        var result = this.PwdRandomRsaEncrypt(pwd, randomKey);
                        console.log("[加密结果] " + result);
                        printStackTrace();
                        console.log("==============================================================");
                        return result;
                    };
                } catch(e) {}
                rsaHooked = true;
                console.log("[+] RSAUtils Hook完成");
            } catch(e) {}
        }
        // 尝试Hook AESUtils
        if (!aesHooked) {
            try {
                var AESUtils = Java.use("com.xxx.utils.keyboardutil.AESUtils");
                console.log("[+] AESUtils 类已加载,开始Hook...");
                try {
                    AESUtils.encrypt.overload('java.lang.String', 'java.lang.String').implementation = function(data, key) {
                        console.log("\n================ AESUtils.encrypt ================");
                        console.log("[随机密钥] " + data);
                        console.log("[用户输入] " + key);
                        var result = this.encrypt(data, key);
                        console.log("[AES密文] " + result);
                        printStackTrace();
                        console.log("==================================================");
                        return result;
                    };
                } catch(e) {}
                aesHooked = true;
                console.log("[+] AESUtils Hook完成");
            } catch(e) {}
        }
        // 如果还有类未Hook成功,继续尝试
        if ((!rsaHooked || !aesHooked) && hookAttempts < maxAttempts) {
            setTimeout(tryHookTargetClasses, 300);
        } else if (rsaHooked && aesHooked) {
            console.log("[*] 所有目标类Hook完成");
        }
    }
    // 开始尝试Hook
    setTimeout(tryHookTargetClasses, 1000);
    console.log("[*] Hook设置完成,请操作APP进行登录");
});

30、输出日志与数据包一致
图片描述

“ 最近在看新的机会,希望能去武汉、深圳或上海发展。个人主要深耕渗透测试方向,平时对逆向工程也有研究。如果有合适的团队或岗位,还望各位大佬多多帮忙留意和推荐,感激不尽!”


传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回