声明:本文章中所有内容仅供学习交流使用,不用于其他任何目的,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请联系作者立即删除!介绍:随着越来越多的人都会白盒AES的DFA,现在一些厂商为了安全性开始使用白盒SM4,那就让我们来看看吧~包名:Y29tLmJ5ZC5kZW56YWRpbGluaw==版本号:3.1.8定位也比较简单,相信屏幕前的彦祖都可以找到,这里直接给出Frida的脚本了然后我们使用Unidbg去模拟执行,代码如下arg3其实很明显就是IV了,看不出来也没关系,So里面可以看得出来,这里要用readFile的形式来读取它这个白盒的表,表太大了不能直接定义为字符串所以我采用了这种方式然后运行,发现读取了maps,补一下,不补的话跑不起来然后继续跑,会发现报错了,bangcle crypto tool error code : -1,NullPointerException这个空指针异常是我们没跑完肯定没有结果,然后我们又去读取的结果(getValue)所以报错了现在来看看这个报错哪来的,因为这个样本没有什么混淆、字符串加密,所以字符串加密就可以直接搜索出来了大概意思就是v12有问题,不为0,导致的错误,我们进去看看sub_509C这个函数可以通过断点在几个可疑的地方下一下断点看看到底执行了没有,也可以使用traceCode,我这里就直接说了,其实是v17 = (*((*a1)->reserved0 + 168))(*a1, a6)这里出问题了,根据Unidbg这里是GetStringUTFLength,然后判断长度是不是奇数,是的话就直接-1,-1基本表示失败、有问题,这里读取到的表长度是0x40009,是奇数,这个表按理来说是偶数才对,并且我们看了一下表的长度应该是0x40008才对,不知道什么原因读错了,patch一下就好了,代码如下然后代码就跑通了,这里要注意如果我们将明文改成几个字节跑出来的结果是错的,所以我上面没有修改明文,估计是在哪里判断了长度,无伤大雅我们继续分析,根据之前的符号已知是CBC模式的,并且IV我们也猜到了可能是其中一个参数,接下来我们就点进伪代码分析一下最后会跟到这个函数然后就没办法跟下去了,没办法直接根据伪代码来找到白盒SM4的具体位置,造成这个原因是因为IDA的反编译出问题了,其实就在这个函数里面,但是伪代码没翻译出来,对应如下我是怎么发现的呢一开始?我一开始直接偷懒了,搜索SM4直接定位到了bangcle_WB_QSM4_encryptHook了一下发现确实是这个函数并且代码的实现也确实是查表的实现,并且找不到Key,那就是白盒SM4了那如果符号搜索不到呢我们又要怎么定位?我们还可以使用traceCode和traceFunctionCall来进行定位,traceCode我们都比较熟悉,但是在这个样本里面不是很好用,因为粒度太细了要trace很久,感兴趣的可以试试看,也可以只trace一会然后停下来,然后聚焦bangcle_internal_crypto这个函数内部的一个控制流走向,因为我们前面就是跟到这里跟不下去了然后我们还可以使用Unidbg封装好的一个traceFunctionCall,粒度稍微粗糙一些但是够用了,这里就不多介绍了,因为我们的明文分组是刚好19个,根据标准的填充还会再填充一个分组,所以应该是20,但是这个traceFunctionCall还是有点问题的,有的时候trace不全,即次数会出现遗漏,这里仅提供一个思路~最后一个0x30ec就是我们刚刚字符串定位到的函数了接下来我们先来简单介绍一下白盒SM4的DFA差分故障攻击,详细的数学原理感兴趣的可以参考:浅析SM4中的DFA attack-安全KER - 安全资讯平台,这里就不多赘述了工具准备:SideChannelMarvels/JeanGrey: Tools to perform differential fault analysis attacks (DFA).SideChannelMarvels/Stark: Repository of small utilities related to key recovery我们可以先来看一份SM4的DFA攻击代码(参考:guojuntang/sm4_dfa: differential fault analysis attacks (DFA) against SM4)然后来总结一下注入故障的位置与时机涉及的数学原理其实是比较复杂的,这里我就直接总结一下:注入攻击的轮次时机:29-30-31-32,分别拿到对应的轮密钥注入攻击的故障要求:第29轮>13个字节的差分(基本16个字节的差分),第30轮129个字节的差分,第32轮5个字节的差分,这些是质量最高的差分范围当然这些也只是理论,实战的时候你会发现其实会有些变化简单介绍完方案以后我们来开始注入攻击吧,从最后一组分组的最后一轮开始,这里输出了前后的value确保注入故障成功正确的结果是3764c30d86577eab5ad61cc1cc7355f7,注入故障以后是47d601cf86577eab5ad61cc1cc7355f7,观察了一下故障字节是四个字节,不符合差分要求,那就先继续往上一轮注入看看,只需要修改一下偏移,我选择的是0x3764,故障密文是74f4709ae76f27ca5ad61cc1cc7355f7,故障字节8个字节,符合要求,在这个位置继续注入一次,每轮拿到两个故障密文,新的故障密文是b3801e6bdc3a139c5ad61cc1cc7355f7,也是8个字节的故障符合要求然后继续往第30轮注入,我选择的是0x3734,故障密文分别是2a4da31a9398bd3977fb7b8bcc7355f7、f707f9ef53227db06aea10f1cc7355f7,故障密文都是12个字节,符合要求继续往第29轮注入,我选的是0x3704,故障密文分别是e1320d54029a01d0c67d533720cceaa4、6ff24e4cc64870f0f1ac2ba4011bf052,16个字节的故障,符合要求然后我们可以先放到phoenixSM4看看tracefile里面的内容如下结果如下还差了第29轮的轮密钥,那我们就继续往上一轮注入攻击吧,我选的是0x36D4,故障密文分别是9d2fe59c814b4115072182f8279b69a6、c12dc7f7e8527e8713d8f637b979447d,基本都是16个字节的差分,然后继续phoenixSM4看看,结果出来了至此我们拿到轮密钥了,接下来就是通过轮密钥还原主密钥,这里使用的是SM4_Keyschedule这个前面贴出的优秀工具密钥就是39B8EC81 9A4A5585 40AFD76E 142A2B9E,IV就是62636461313233666364346432303139,放到CyberChef里面解密会发现报错:Invalid PKCS#7 padding.看起来像是填充出现了问题,难道是魔改了填充吗?我当
...(已截断)
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-285292.htm