0x00 前言
1、算法逆向
分析android so的时候,总会遇到一些算法,掌握算法的识别特征对逆向工作效率提升很大,小伙伴给我发来一道android题,涉及几个算法,记录一下做题过程。
2、题目信息
DDCTF2020 Android reverse01
描述(提示)
re1:以此提示为准!!!
最后一次MD5前的输入为:
0x6b,0x93,0x9c,0xfa,0xeb,0x68,0x4b,0x25,0x85,0x54,0xf9,0x1a,0x30,0x84,0xbc,0x7b,0x2c,0xce,0xf3,0x92,0xfe,0x63,0xae,0x67,0xf3,0xe7,0xfb,0x18,0xa2,0xb3,0x32,0x93
涉及算法
1、aes
2、xxtea
3、md5
0x01 算法识别
1、aes
aes一种常见的分组加密算法,加密过程涉及4个操作
(1)字节替换
(2)行移动
(3)列混淆
(4)轮密钥加
识别特征:程序中有256位S盒或者动态生成S盒,可以确定为AES加密
2、tea
tea一种常见的分组加密算法,密钥为128比特位,明文为64比特位,主要做了32轮变换,每轮变换中都涉及移位和变换。
识别特征:固定常数 0x9e3779b9 0x61c88647
3、md5
md5是一种密码散列函数,可以产生一个128位(16字节)的散列值。
识别特征:固定常数 0x67452301 0xefcdab89 0x98badcfe 0x10325476
0x02 逻辑分析
1、java层

2、native层

无混淆,逐一对几个方法的入参和结果进行动态调试

输入 1234567890
sub_8DDC

参数1 1234567890123456参数2 0x10参数3 1234567890参数4 0xFFD08C20 加密串存放地址参数5 0x20

0xFFD08C20 执行的内存发生了变化
sub_8FF8


参数1 0xFFD08C20 加密串存放地址参数2 0x8参数3 固定值 02 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00

0xFFD08C20 指向的内存又发生了一次改变
sub_9168

参数1 0xFFD08BA8


sub_9904

sub_8FF8方法中0xFFD08C20指向的内存复制到了0xFFD08BC0
sub_9988

0xFFD08C00是最后的加密结果 和 0xE1D78988 进行比较
根据以上调试开始寻找flag
使用插件看看用了哪些算法
根据交叉引用提示sub_8FF8 使用了tea算法
根据参数情况可能使用了 xxtea
网上资料long btea(long* v, long n, long* k) v是要加密的组元的起始地址,以32bit为单位,这里用long来实现。n是要加密的组元个数,正数是加密,负数是解密。k是密钥的起始地址,长度为4个组元,4*32=128bit。
对称加密 可以在调试的时候使用提示的bytes进行替换得到加密前的bytes
修改0x8 为负0x8
修改内存
解密结果
C5 36 28 3D 5A 2C 84 87 90 D7 53 DC 46 87 CD 5E
E2 7C 5D 8F 33 BA 88 6D 86 A7 44 64 D8 90 E3 E1
往上推看sub_8DDC函数


有key 有256 s盒,可能使用了aes
from Crypto.Cipher import AESdata = [0xC5, 0x36, 0x28, 0x3D, 0x5A, 0x2C, 0x84, 0x87, 0x90, 0xD7, 0x53, 0xDC, 0x46, 0x87, 0xCD, 0x5E, 0xE2, 0x7C, 0x5D, 0x8F, 0x33, 0xBA, 0x88, 0x6D, 0x86, 0xA7, 0x44, 0x64, 0xD8, 0x90, 0xE3, 0xE1]new_data = ''for i in data: new_data += chr(i)key = '1234567890123456'cipher = AES.new(key) print(cipher.decrypt(new_data))
flag : DDCTF{wsxsdf0987!}
将flag输入,check提示错误
重复以上的调试过程

这里根据特征判断使用了MD5

ffd08bb0是flag最终加密的结果 由于对比的是一个md5加密的后的bytes 所以check永远不会正确
import hashlibdata = [0x6b,0x93,0x9c,0xfa,0xeb,0x68,0x4b,0x25, 0x85,0x54,0xf9,0x1a,0x30,0x84,0xbc,0x7b, 0x2c,0xce,0xf3,0x92,0xfe,0x63,0xae,0x67, 0xf3,0xe7,0xfb,0x18,0xa2,0xb3,0x32,0x93]new_data = ''for i in data: new_data += chr(i) md5 = hashlib.md5()md5.update(new_data)print(md5.hexdigest())
0b64853504806cecc97fd4c6740aba56 对比 ED59A38617059E4D10C3FD273EF4684E
0x03 总结
1、算法识别特征
2、动态调试技巧