-
-
[原创]SM4加密算法密钥key定位(IOS_ARM64)
-
2021-7-11 16:04 65149
-
<a href="https://996.icu"><img src="https://img.shields.io/badge/link-996.icu-red.svg" alt="996.icu" /></a> <a href="https://github.com/996icu/996.ICU/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-Anti%20996-blue.svg" alt="LICENSE" /></a>
问题背景
需要定位某应用中的SM4算法用到的密钥。
解决方法
首先要知道什么是SM4算法,百度SM4.0即可看到相应解释,并且有提供了多种语言版本的实现。
对于该算法的底层数学原理,并不需要非常了解。对逆向工程师来说,只需了解算法特点即可:数据是如何参与运算,密钥是在哪一步使用。
参考这里,可以知道其特点是有固定的三组数据,即CK、FK和sbox。而密钥,是固定长度16字节,并且在整个算法中只使用到一次,即如下图(Python版):
从这一步也可以看到使用了CK数据,说明或许可以根据CK数据被使用的地方来定位key。
然后看下key是怎么被使用的。进入图中GET_UINT32_BE(key[0:4])看下,如下:
1 2 | def GET_UINT32_BE(key_data): return int ((key_data[ 0 ] << 24 ) | (key_data[ 1 ] << 16 ) | (key_data[ 2 ] << 8 ) | (key_data[ 3 ])) |
可以知道其特征是连续的 << 加上 | 操作。
根据上述信息,思路就出来了:
- 在程序二进制文件(或者内存)中定位到CK或者Sbox数据段(数据是固定的,因此可以用二进制搜索或者内存扫描特定数据)。
- 根据数据被引用的地方定位到SM4算法的代码段。
- 在CK被使用的地方附近查看代码特征:移位操作和或操作(如果有混淆需要考虑去除混淆,或者数据跟踪)。
最后定位到上面那段GET_UINT32_BE函数在应用中的ARM64代码如下:
其中LSL是<<操作,注意后面0x18就是十进制的24,而ORR是|操作,这里就和算法对应起来了。至于BFI,相当于是比特的手术刀,来移动比特的。
比如BFI X3, X4, #0x10, #8
,就是用X4寄存器LSB端(低位)的8个bits替换掉X3寄存器从bit 16到bit 23的位置。
而BFI X3, X4, #0x8, #8
,就是用X4寄存器LSB端(低位)的8个bits替换掉X3寄存器从bit 8到bit 15的位置。
因此这里的X1就是密钥key的地址,从该地址取出16字节的内容就是要找的密钥key。
总结
定位SM4算法密钥,只需要了解算法特点,进行定位即可:根据CK定位算法代码区域,根据代码操作特征定位key。
参考资料
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课