APP测试中遇到的一些加密问题

2023-01-09 17,327

案例一:Java层存在硬编码密钥

反编译apk,在包com.xxx.xxxx.utils中泄露加密key,同时可知加密方式为AES/ECB/PKCS5Padding

1.png

对登录请求数据包中,使用加密key进行解密

2.png


也可以使用Wallbreaker 查看类以及对象属性(若app存在双进程守护需先解决双进程守护)

objection -g com.xxxx.xxx explore -P ~/.objection/plugins

3.png

搜索类,根据给的 pattern 对所有类名进行匹配,列出匹配到的所有类名

plugin wallbreaker classsearch <pattern>

4.png

ClassDump,输出类的结构,获取密钥

plugin wallbreaker classdump <classname> [--fullname]

5.png


案例二:Java层不存在硬编码密钥

通过关键词找到关键方法com.xxx.e.b.d,可以看到该方法没有中没有硬编码的key值,当前知道加密方式为DES,同时没有特殊指定的话默认为ECB模式,方法d传入字节bArr,最终指定秘钥为bArr2,而该方法的作用只是截取bArr的前8个字节(des加密秘钥固为8个字节),因此只需知道传入的bArr即可获取秘钥

6.png


使用objection hook打印d方法调用和返回值

android hooking watch class_method com.xxxx.e.b.d --dump-args --dump-backtraces --dump-return

转换为字符即可获取密钥

7.png


也可以编写frida hook脚本,执行脚本即可查看加解密信息

function hook() {
    Java.perform(function () {
    var b=Java.use("com.xxx.xxx");
    b.b.overload("java.lang.String").implementation= function(a){
        console.log(a);
        var ret=this.b(a)
        console.log(ret);
        return a;
    }
    });
}
setImmediate(hook);

执行查看结果

frida -U xxx.xxx.xxx.xxx -l test.js

使用spawn的模式启动Frida的一个好处是可以带着HOOK脚本重启应用程序,避免错过hook点

frida -U -f com.xxxx.xxx -l test.js   --no-pause


案例三:HMACSHA签名存在硬编码密钥

抓包发现数据包存在签名,正常请求如下

8.png


修改数据包内容再次请求提示签名不正确

9.png


对其脱壳后找到签名算法代码

10.png


使用objection hook打印c方法调用和返回值

android hooking watch class_method com.xxx.x.x.c --dump-args --dump-backtraces --dump-return

可以知道明文格式:请求方法+&+URI+body,和签名后的结果

image.png


Java 将参数构造好后传给native函数com.xxxx.x.x.c,带了native关键字的说明java的作用范围达不到了,会去调用底层C语言的库。在最终执行的时候,通过JNI(调用本地方法接口)加载本地方法库中的方法。com.xxxxx.x.x.c的实现位于libhw-s.so 中,因此使用ida逆向libhw-s.so,搜索相关签名算法的关键字符,找到密钥

image.png


案例四:app使用动态密钥

测试某APP发现请求包和返回包内容均进行了加密

11.png


使用密码自吐脚本发现每次加密的密钥都会改变,但是iv固定


12.png

13.png

对APP进行脱壳并分析代码,由于iv是固定的,尝试直接搜索iv找到加密的地方,跟踪m6560CL

14.png

发现加密处理在so层中

15.png


hook decrypt方法发现该方法只加解密了手机号并非完整的数据包内容,看来并非是这里

16.png

hook genRandomKey方法发现返回值就是AES对应的密钥

17.png

输出AES对应的密钥

18.png

使用密钥和iv对数据进行解密发现解密失败,复制出请求包内容发现该内容为三段字符

20.png

其中第二段才是需要的json请求包内容

image.png

编写frida脚本固定密钥,使用固定后的密钥和iv即可更方便的对数据进行操作

function main() {
	Java.perform(function(){
    	var AESCoder = Java.use("com.xxx.xxxx.xxxx.xxxx.CryptoUtil");
    	AESCoder["genRandomKey"].implementation = function (){
            let ret = this.genRandomKey();
            var abb="uo2etSg6XNlq4nEv";
            return abb;
    	}
    });
}
setImmediate(main)

经测试发现只需第二段加密字段即可正常执行且返回包内容为明文数据

22.png

案例五:加密在Native层实现

登录时看到数据包请求包被加密

23.png

脱壳后查看代码,通过登录接口跟进一下loginRequestTask方法

24.png

从该方法中可知baseBean3.getData()用于获取加密的返回包数据,使用AesUtil.decrypt对数据进行了解密并返回解密内容

25.png

跟进AesUtil类

26.png

发现该方法的实现在so层中

27.png

在so文件中通过关键词找到相应密钥和iv

28.png

解密成功

29.png






本文作者:晚上

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/194675.html

Tags:
评论  (0)
快来写下你的想法吧!

晚上

文章数:2 积分: 20

安全问答社区

安全问答社区

脉搏官方公众号

脉搏公众号