首先抓包请出今天的受害者
直接base64解密下,发现能解开,得到如下结果
可以看到里面一个字段ab是加密的,咱们今天就分析下这个ab参数是怎么生成的,使用jadx-gui打开app反编译后搜"ab"找到如下
查看引用找到如下
发现是native导出的函数,并且传的参数是个对象,接着找到导出的so文件
用ida打开so文件找到JNI_OnLoad导出的函数
点进去函数
一共3个参数,第三个参数a3就是我们java传的context对象,再看他调用了1DA0C函数多传了0函数,顺着追进去,代码有250+行没有混淆,还算清晰
通过静态分析,可以看出代码分为三部分。
第一部分、通过命令行获取安卓设备的指纹信息
第二部分、初始化秘钥,对获取的参数拼接好进行加密
第三部分、加密完成转换成base64返回java层
目前我们还不知道是什么加密方式呢,我们找到他获取完设备信息,准备加密的地方,有两个写死的字符串,我们跟踪进去,
追进去这个函数,发现sbox盒子的出现
发现sbox是标准的,没有魔改,初步可以定义为aes加密了,了解aes加密的都知道aes加密的特征
(1)密钥扩展函数里字节替换后会进行异或操作。
(2)明文经过字节替换后会进行行移位操作。
上图就是进行了字节替换,在往下分析到了行移位
追进去2AE38函数,跟踪到如下代码
发现了列混合特征: 某两个字节异或后会判断字节的最高bit位,如果最高bit位为1,则与0x1B异或。
再往下看
进行了大循环,当v67==144时跳出循环。每次v67加16字节,用144除以16
=9,这个9轮循环可以看出这是aes128的加密轮数,因为他是10轮,如果是256他的轮数应该是14轮 在循环之前已经处理一轮了,我们根据这个aes特征,找到定位到秘钥和iv生成的地方
经过分析大概猜测为这个两个参数就是秘钥和iv,直接上frida,hook下这两个值
打印结果如下
有了key,iv在线解密下吧,
发现成功解密,都是获取的设备信息,然后混淆了key名,既然知道key,iv的所在,我们看看他是怎么扩展秘钥的,找到iv生成的地方
代码很简单,进行了一些位移异或操作,这个我发现key是动态的,测试发现这个iv是不变的,那么这个直接写死即可,在回头看看key生成的方式
有个v43的判断,查看引用发现a43
就是a3,刚进入函数的时候传的是0,那么走的肯定就是else了,直接hook打印2C4C4参数的值
参数1是app包名+版本号+设备的指纹,参数2是长度,参数3是写死的key值,返回值就是我们打印计算后参数3的key值,这个key值和设备的指纹有关系,我们就把代码抠出来,分析下key值的变化
代码不是很长,直接复制出来c代码运行下,算下key值是否正确,执行下,发现始终不正确
后来定位到是参数类型的问题,将a3类型强转成unsigned char类型,再次运行下,问题解决
成功算出key值,由于在python中调用c代码比较麻烦,反正代码也不长,直接对照c代码重写了下改成python,运行结果如下
完工。
最后经常点外卖的可以关注下这个小程序,每天都能领取大额外卖优惠券红包,
文章仅供学习交流,请勿用于非法用途,如有侵犯到贵公司隐私或者利益,请联系我立马删除。
原文始发于微信公众号(逆向客栈):某APP设备指纹AES加密算法分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论