9.苹果ios逆向-FridaHook-ios中的算法(CCCrypt)

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!

内容参考于:图灵Python学院

工具下载:

链接:https://pan.baidu.com/s/1bb8NhJc9eTuLzQr39lF55Q?pwd=zy89

提取码:zy89

复制这段内容后打开百度网盘手机App,操作更方便哦

上一个内容:8.苹果ios逆向-安装frida

ios中的app很少有加密的,大厂的app会有加密

苹果系统(ios和macOS)中提供了CCCrypt函数,它是一个用来加解密的函数,它提供了AES、DES、3DES、RC4、MD5等算法,就提供了一个函数可以很方便的,让开发者使用

CCCrypt函数说明

CCCryptorStatus CCCrypt(
    CCOperation op,           // 操作类型:加密/解密
    CCAlgorithm alg,        // 加密算法(如 AES)
    CCOptions options,        // 加密选项(如填充模式、加密模式)
    const void *key,          // 密钥
    size_t keyLength,         // 密钥长度
    const void *iv,           // 初始化向量(IV)
    const void *dataIn,       // 输入数据(明文/密文)
    size_t dataInLength,      // 输入数据长度
    void *dataOut,            // 输出数据缓冲区(密文/明文)
    size_t dataOutAvailable,  // 输出缓冲区大小
    size_t *dataOutMoved      // 实际输出数据长度
);

首先使用Charles抓一个包,如下图它有一个sign参数,一般有sign参数和一个时间戳这样组合的sign都是加密的,查找加密参数的方式,再请求一次,对比两次请求不一样的参数,只要不一样然后数据还看不懂,看着像加密数据,那它就是加密数据,如下图红框就是它的值就看不懂,然后看着也想加密数据,然后每次请求它都会变化,这就符合加密参数的特征

然后复制一下curl

然后直接让ai大模型把curl转成Python代码,如下图

然后这里有一个加解密网址:

https://gchq.github.io/CyberChef/

然后复制一下sign的数据,对它进行Base64解密,有些数据加密完会进行base64加密,如下图红框base64解密后以十六进制展示

使用frida-trace指令 hook CCCrypt算法,它要使用app的进程id

查看进程id

frida-ps -Ua

下图红框是我们需要的进程id

然后使用 frida-trace -Up 24699 -i CCCrypt,拦截CCCrypt,指令执行后刷一下手机,让app执行加密操作也就是调用CCCrypt函数,如下图有CCCrypt的打印说明,注入成功

然后它还会给我创建一个文件,如下图红框,上图红框的内容也是由下图红框的文件进行打印的

CCCrypt文件默认内容,然后我们需要完善它的内容,来查看真实的算法内容,onEnter用来查看入参,onLeave用来查看加密之后的数据(结果)

下图红框里的就是CCCrypt的入参

也就是下图红框的十个数据,args[0] 一直到 args[9]

效果图:拦截加密入参、加密方式

最终的代码

/**
 * 完整的十六进制+文本显示的CCCrypt监控脚本
 * 数据同时展示十六进制和可打印文本,不包含二进制格式
 */
{
    onEnter(log, args, state) {
        // 解析基础参数
        const op = args[0].toInt32();
        const alg = args[1].toInt32();
        const options = args[2].toInt32();
        const keyAddr = args[3];
        const keyLen = args[4].toInt32();
        const ivAddr = args[5];
        const dataInAddr = args[6];
        const dataInLen = args[7].toInt32();

        // 解析算法名称
        let algorithmName;
        switch (alg) {
            case 0: algorithmName = 'AES(kCCAlgorithmAES)'; break;
            case 1: algorithmName = 'DES(kCCAlgorithmDES)'; break;
            case 2: algorithmName = '3DES(kCCAlgorithm3DES)'; break;
            case 3: algorithmName = 'CAST(kCCAlgorithmCAST)'; break;
            case 4: algorithmName = 'RC4(kCCAlgorithmRC4)'; break;
            case 5: algorithmName = 'RC2(kCCAlgorithmRC2)'; break;
            default: algorithmName = `未知算法(${alg})`;
        }

        // 解析选项参数
        const mode = options & 0x0F;
        let modeName;
        switch (mode) {
            case 1: modeName = 'CBC(kCCOptionModeCBC)'; break;
            case 2: modeName = 'ECB(kCCOptionModeECB)'; break;
            case 3: modeName = 'CFB(kCCOptionModeCFB)'; break;
            case 4: modeName = 'OFB(kCCOptionModeOFB)'; break;
            case 5: modeName = 'CTR(kCCOptionModeCTR)'; break;
            case 6: modeName = 'GCM(kCCOptionModeGCM)'; break;
            default: modeName = `未知模式(0x${mode.toString(16)})`;
        }

        const padding = options & 0xF0;
        const paddingName = padding === 0x10 
            ? 'PKCS7填充(kCCPaddingPKCS7)' 
            : padding === 0x00 
                ? '无填充(kCCPaddingNone)' 
                : `未知填充(0x${padding.toString(16)})`;

        // 打印函数调用基本信息
        log('=== CCCrypt 调用开始 ===');
        log(`操作类型: ${op === 0 ? '加密(kCCEncrypt)' : '解密(kCCDecrypt)'}`);
        log(`算法类型: ${algorithmName}`);
        log(`选项参数: 0x${options.toString(16)}`);
        log(`  加密模式: ${modeName}`);
        log(`  填充方式: ${paddingName}`);
        log(`密钥长度: ${keyLen}字节`);
        log(`输入长度: ${dataInLen}字节`);

        // 打印密钥(十六进制+文本)
        if (keyAddr && !keyAddr.isNull() && keyLen > 0) {
            log('\n[密钥数据] (十六进制+可打印文本)');
            log(hexdump(keyAddr, {
                length: keyLen,
                header: false,
                ansi: true,
                format: 'hex+ascii' // 同时显示十六进制和ASCII文本
            }));
        }

        // 打印IV(十六进制+文本)
        if (ivAddr && !ivAddr.isNull()) {
            log('\n[IV数据] (十六进制+可打印文本)');
            log(hexdump(ivAddr, {
                length: 16,
                header: false,
                ansi: true,
                format: 'hex+ascii'
            }));
        }

        // 打印输入数据(十六进制+文本)
        if (dataInAddr && !dataInAddr.isNull() && dataInLen > 0) {
            const showLen = Math.min(dataInLen, 256);
            log(`\n[输入数据] (共${dataInLen}字节,显示前${showLen}字节)`);
            log(hexdump(dataInAddr, {
                length: showLen,
                header: false,
                ansi: true,
                format: 'hex+ascii'
            }));
        }

        // 保存输出参数引用
        this.dataOutAddr = args[8];
        this.dataOutLenPtr = args[10];
    },

    onLeave(log, retval, state) {
        // 打印执行结果
        const status = retval.toInt32();
        log(`\n[执行结果] 状态码: ${status} (${status === 0 ? '成功' : '失败'})`);

        // 打印输出数据(十六进制+文本)
        if (this.dataOutAddr && !this.dataOutAddr.isNull() && this.dataOutLenPtr) {
            const outLen = this.dataOutLenPtr.readUInt();
            if (outLen > 0) {
                const showLen = Math.min(outLen, 256);
                log(`\n[输出数据] (共${outLen}字节,显示前${showLen}字节)`);
                log(hexdump(this.dataOutAddr, {
                    length: showLen,
                    header: false,
                    ansi: true,
                    format: 'hex+ascii'
                }));
                log(`输出长度: ${outLen}字节`);
            }
        }

        log('=== CCCrypt 调用结束 ===\n');
    }
}


img

03-26
### 逆向工程与反编译概述 逆向工程是一种通过对软件的目标代码进行分析,将其转化为更高级别的表示形式的过程。这一过程通常用于研究现有系统的内部结构、功能以及实现细节。在Java和Android领域,反编译工具被广泛应用于逆向工程中。 #### Java逆向工程中的Jad反编译工具 Jad是一款经典的Java反编译工具,能够将`.class`字节码文件转换为可读的`.java`源代码[^1]。虽然它可能无法完全恢复原始源代码,但它提供了足够的信息来帮助开发者理解已编译的Java程序逻辑。Jad支持多种反编译模式,并允许用户自定义规则以适应不同的需求。此外,其命令行接口和图形界面使得复杂代码的分析变得更加便捷。 #### Android逆向工程中的JEB反编译工具 针对Android应用的逆向工程,JEB是由PNF Software开发的一款专业级工具[^2]。相较于其他同类产品,JEB不仅具备强大的APK文件反编译能力,还能对Dalvik字节码执行高效而精准的操作。它的核心优势在于以下几个方面: - **广泛的平台兼容性**:除Android外,还支持ARM、MIPS等多种架构的二进制文件反汇编。 - **混淆代码解析**:内置模块能有效应对高度混淆的代码,提供分层重构机制以便于深入分析。 - **API集成支持**:允许通过编写Python或Java脚本来扩展功能并完成特定任务。 #### APK反编译流程及其意义 当涉及到具体的APK包时,可以通过一系列步骤提取其中的信息来进行全面的安全评估或者学习目的的研究工作[^3]。这些步骤一般包括但不限于获取资产目录(`assets`)内的资源数据;解密XML配置文档如`AndroidManifest.xml`定位应用程序启动点;最后利用上述提到的各种专用软件重现整个项目框架供进一步探讨。 ```bash # 使用apktool反编译APK示例 apktool d your_app.apk -o output_directory/ ``` 以上命令展示了如何借助开源工具ApkTool轻松拆卸目标安卓档案至易于探索的状态下。 ### 结论 无论是传统的桌面端还是现代移动端环境里头,恰当运用合适的反编译解决方案都是达成逆向工程项目成功不可或缺的一环。每种工具有各自专精之处,在实际应用场景当中应当依据具体需求做出明智的选择。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值