首页
社区
课程
招聘
[分享]某短视频平台最新sig3字段算法分析(二)
发表于: 2025-1-13 21:51 37288

[分享]某短视频平台最新sig3字段算法分析(二)

2025-1-13 21:51
37288
  • 算法分析

紧接着上一篇,我们看下正常运行的结果

trace一下 call_doCommandNative_sig3

private void trace2file() {
    String traceFile = "unidbg-android/src/test/resources/app/trace/trace.txt";
    PrintStream traceStream = null;
    try{
        traceStream = new PrintStream(new FileOutputStream(traceFile), true);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    emulator.traceCode(module.base, module.base + module.size).setRedirect(traceStream);
}

在tace.txt中搜索f1e7,e7f1发现没有匹配数据,改搜索e7,从匹配的trace文件从最底部往最前查找可疑点会发现

从w1=0xa6接着往上分析

接着双击x21往上找

双击x0往上找

双击0xbffff470往上找

IDA定位也可以看到代码

就一个简单算法,求和,取反,异或对照着直接译出来即可。算法输入参数就是v374,结合trace文件,我们可以打印下v374的0至23位,并找到对应的赋值点并编上号便于后面进行分析

0x41   "str w11, [sp, #0x170]" w11=0x5141 sp=0xbffff470 => w11=0x5141 ①
0x51   "str w11, [sp, #0x170]" w11=0x5141 sp=0xbffff470 => w11=0x5141    
0x27   "strh w8, [sp, #0x172]" w8=0x27 sp=0xbffff470 => w8=0x27 ②
0x0    "strh w8, [sp, #0x172]" w8=0x27 sp=0xbffff470 => w8=0x27
0x60   "str w8, [sp, #0x174]" w8=0x4dfa1c60 sp=0xbffff470 => w8=0x4dfa1c60  ③
0x1c   "str w8, [sp, #0x174]" w8=0x4dfa1c60 sp=0xbffff470 => w8=0x4dfa1c60
0xfa   "str w8, [sp, #0x174]" w8=0x4dfa1c60 sp=0xbffff470 => w8=0x4dfa1c60 
0x4d   "str w8, [sp, #0x174]" w8=0x4dfa1c60 sp=0xbffff470 => w8=0x4dfa1c60 
0x1    "str w10, [sp, #0x178]" w10=0x1 sp=0xbffff470 => w10=0x1 ④
0x0    "str w10, [sp, #0x178]" w10=0x1 sp=0xbffff470 => w10=0x1 
0x0    "str w10, [sp, #0x178]" w10=0x1 sp=0xbffff470 => w10=0x1 
0x0    "str w10, [sp, #0x178]" w10=0x1 sp=0xbffff470 => w10=0x1 
0x61   "str w0, [sp, #0x17c]" w0=0xb03a661 sp=0xbffff470 => w0=0xb03a661 ⑤
0xa6   "str w0, [sp, #0x17c]" w0=0xb03a661 sp=0xbffff470 => w0=0xb03a661  
0x03   "str w0, [sp, #0x17c]" w0=0xb03a661 sp=0xbffff470 => w0=0xb03a661
0x0b   "str w0, [sp, #0x17c]" w0=0xb03a661 sp=0xbffff470 => w0=0xb03a661
0xac   "str w8, [sp, #0x180]" w8=0x676007ac sp=0xbffff470 => w8=0x676007ac ⑥
0x7    "str w8, [sp, #0x180]" w8=0x676007ac sp=0xbffff470 => w8=0x676007ac
0x60   "str w8, [sp, #0x180]" w8=0x676007ac sp=0xbffff470 => w8=0x676007ac
0x67   "str w8, [sp, #0x180]" w8=0x676007ac sp=0xbffff470 => w8=0x676007ac 
0x0    "str w8, [sp, #0x184]" w8=0xe7000d00 sp=0xbffff470 => w8=0xe7000d00 ⑦
0xd    "str w8, [sp, #0x184]" w8=0xe7000d00 sp=0xbffff470 => w8=0xe7000d00
0x0    "str w8, [sp, #0x184]" w8=0xe7000d00 sp=0xbffff470 => w8=0xe7000d00
0xe7   "str w8, [sp, #0x184]" w8=0xe7000d00 sp=0xbffff470 => w8=0xe7000d00

①比较明显就是设置的固定值,我们从②开始分析

可以比较明显的发现和0x404d8220地址有关系,直接trace一下

emulator.traceWrite(0x404d8228,0x404d8228 + 4);

定位到的位置是callJNI_OnLoad的时候操作的,所以也是固定值。

同样的追查流程找下③④也都是固定值,不想追流程其实也可以直接修改入参,这几个标注段基本都不会改变与入参无关。现在我们看下⑤直接定位到IDA赋值位置看一下

点进函数sub_120d8内部没有发现明显特征,转回来看下入参就会发现unk_56188有crc32的明显特征

百度或谷歌搜一下0x04c11db7

确定是CRC32之后我们在看一下另外两个入参


大概率能猜出是数据跟长度,拿出去试算一下

试算结果符合我们的猜测是标准的CRC32,在回过头来看下算法,分析trace会发现

[09:34:01 131][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x4c11db7 w11=0x0 => w8=0x1
[09:34:01 132][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x2608edb w11=0x1 => w8=0x3
[09:34:01 132][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x130476d w11=0x3 => w8=0x7
[09:34:01 132][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x9823b6 w11=0x7 => w8=0xe
[09:34:01 132][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x4c11db w11=0xe => w8=0x1d
[09:34:01 132][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x2608ed w11=0x1d => w8=0x3b
[09:34:01 132][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x130476 w11=0x3b => w8=0x76
[09:34:01 133][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x9823b w11=0x76 => w8=0xed
[09:34:01 133][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x4c11d w11=0xed => w8=0x1db
[09:34:01 133][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x2608e w11=0x1db => w8=0x3b6
[09:34:01 133][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x13047 w11=0x3b6 => w8=0x76d
[09:34:01 133][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x9823 w11=0x76d => w8=0xedb
[09:34:01 133][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x4c11 w11=0xedb => w8=0x1db7
[09:34:01 133][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x2608 w11=0x1db7 => w8=0x3b6e
[09:34:01 133][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x1304 w11=0x3b6e => w8=0x76dc
[09:34:01 133][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x982 w11=0x76dc => w8=0xedb8
[09:34:01 133][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x4c1 w11=0xedb8 => w8=0x1db71
[09:34:01 133][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x260 w11=0x1db71 => w8=0x3b6e2
[09:34:01 133][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x130 w11=0x3b6e2 => w8=0x76dc4
[09:34:01 134][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x98 w11=0x76dc4 => w8=0xedb88
[09:34:01 134][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x4c w11=0xedb88 => w8=0x1db710
[09:34:01 134][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x26 w11=0x1db710 => w8=0x3b6e20
[09:34:01 134][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x13 w11=0x3b6e20 => w8=0x76dc41
[09:34:01 134][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x9 w11=0x76dc41 => w8=0xedb883
[09:34:01 134][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x4 w11=0xedb883 => w8=0x1db7106
[09:34:01 134][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x2 w11=0x1db7106 => w8=0x3b6e20c
[09:34:01 134][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x1 w11=0x3b6e20c => w8=0x76dc419
[09:34:01 134][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x0 w11=0x76dc419 => w8=0xedb8832
[09:34:01 134][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x0 w11=0xedb8832 => w8=0x1db71064
[09:34:01 134][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x0 w11=0x1db71064 => w8=0x3b6e20c8
[09:34:01 134][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x0 w11=0x3b6e20c8 => w8=0x76dc4190
[09:34:01 135][libkwsgmain.so 0x0120f8] [68791f33] 0x400120f8: "bfi w8, w11, #1, #0x1f" w8=0x0 w11=0x76dc4190 => w8=0xedb88320

通过0x4c11db7 算出0xedb88320,然后采用直接计算法计算CRC32值,下面是直接计算法部分的截图

分析完第一个算法我们接着往后,trace一下入参地址0x404ff000

emulator.traceWrite(0x404ff000,0x404ff000 + 0x30);

结合trace文件定位一下发现是memcpy

我们继续trace地址 0x404d3330

emulator.traceWrite(0x404d3330, 0x404d3330 + 0x30);

根据地址可以定位到函数

再看一下函数体,找到可以看一下的数据可疑点byte_59080

打个断点看一下

debugger.addBreakPoint(module.base+0x25ad0);

大小端切换搜一下,最后搜0x05040706

搜到的项中有这么一项,应该不是明显的特征值,暂且先记录一下。我们在看一下函数输入参数

debugger.addBreakPoint(module.base + 0x262e8);

pkcs7填充,简单调试下会发现总共调用sub_25980三次,每次16个字节,一般这么玩的也就aes和sm4,sm4在app参数加密中用的比较少,结合前面的搜索结论大概率是aes,如果是aes还需要判断是ecb还是cbc,从入参看并没有看到类似的iv向量之类的,但是我们还是做一个试验看看,输入三组16字节数据

debugger.addBreakPoint(module.base + 0x262e4, new BreakPointCallback() {
    int count = 0;
    @Override
    public boolean onHit(Emulator emulator, long address) {
        byte[] data = {(byte)0xA8, 0x0D, (byte)0xAA, 0x37, (byte)0xD0, 0x3E, (byte)0xD5, (byte)0xAB, (byte)0xF0, (byte)0x86, (byte)0xA5, 0x65, 0x3F, 0x74, (byte)0xB8, 0x7F,
                (byte)0xA8, 0x0D, (byte)0xAA, 0x37, (byte)0xD0, 0x3E, (byte)0xD5, (byte)0xAB, (byte)0xF0, (byte)0x86, (byte)0xA5, 0x65, 0x3F, 0x74, (byte)0xB8, 0x7F,
                (byte)0xA8, 0x0D, (byte)0xAA, 0x37, (byte)0xD0, 0x3E, (byte)0xD5, (byte)0xAB, (byte)0xF0, (byte)0x86, (byte)0xA5, 0x65, 0x3F, 0x74, (byte)0xB8, 0x7F};
        if (count == 0)
            emulator.getBackend().mem_write(0x404d32d0, data);
        count++;
        return true;
    }
});

判断是ecb应该没错了,看了下其他几个入参并没有类似key的参数,怀疑是白盒aes,如果是白盒aes我们就需要找state块了。我们看一下函数部分代码,主要逻辑部分也就下面两个块

第一部分执行10次,第2部分执行9次,有点类似查表法的逻辑(字节转换 行移位 列混合),第一部分中sub24f48函数内容像是在变动赋值

我们在这个函数执行前后设置断点打印下,就能明显的看到移位特征了
debugger.addBreakPoint(module.base+0x24f90);
debugger.addBreakPoint(module.base+0x25e24);

a8 d0 f0 3f
0d 3e 86 74
aa d5 a5 b8
37 ab 65 7f

a8 d0 f0 3f
3e 86 74 0d
a5 b8 aa d5
7f 37 ab 65

找到了state接下来就是dfa攻击了,先修改一位试一下

debugger.addBreakPoint(module.base + 0x24fa4, new BreakPointCallback() {
    int count = 1;
    int count2 = 0;
    @Override
    public boolean onHit(Emulator emulator, long address) {
        byte[] data= {0x1};
        if (count % 9 == 0) {
            data[0] = (byte) getRandomNumber(0, 255);
            emulator.getBackend().mem_write(0x404d32d0 + count2 * 0x10 + getRandomNumber(0, 15), data);
        }
        count++;
        if (count == 11) {
            count = 1;
            count2++;
        }
        return true;
    }
});

debugger.addBreakPoint(module.base + 0x2601c, new BreakPointCallback() {
    int count = 0;
    @Override
    public boolean onHit(Emulator emulator, long address) {
        byte[] data = emulator.getBackend().mem_read(0x404d32d0 + count * 16, 16);
        printByteArray(data);
        System.out.print("\n");
        count++;
        return true;
    }
});

前后数据对比,很明显第1,8 ,11, 14个字节不同,符合注入特征

现在修改为批量随机注入

debugger.addBreakPoint(module.base + 0x24fa4, new BreakPointCallback() {
    int count = 1;
    int count2 = 0;
    @Override
    public boolean onHit(Emulator emulator, long address) {
        byte[] data= {0x1};
        if (count % 9 == 0) {
            data[0] = (byte) getRandomNumber(0, 255);
            emulator.getBackend().mem_write(0x404d32d0 + count2 * 0x10 + getRandomNumber(0, 15), data);
        }
        count++;
        if (count == 11) {
            count = 1;
            count2++;
        }
        return true;
    }
});

批量跑完后,将存在文件中的数据用phoenixAES和aes_keyschedule处理下,具体可以网上搜索下用法,这里就不介绍了


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 3
支持
分享
最新回复 (6)
雪    币: 1577
活跃值: (2237)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
优秀文章, 感谢分享
2025-1-14 00:15
0
雪    币: 90
活跃值: (340)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
666
2025-1-14 11:22
0
雪    币: 226
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
学习一下
2025-1-14 12:11
0
雪    币: 0
活跃值: (1172)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5

mark

最后于 2025-1-17 15:07 被冷瞳编辑 ,原因:
2025-1-15 10:27
0
雪    币: 212
活跃值: (365)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
我想要,大佬
2025-2-23 15:13
1
雪    币: 26
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
学习
3天前
0
游客
登录 | 注册 方可回帖
返回