首先,我是新手,希望大佬勿喷,只是分享我的学习流程 本贴没出现任何关于真正业务相关的代码,只有学习流程,对包名进行打码 ,违规必删
首先frida -f 模式注入app
app启动后有强制退出弹框 可以看到有可能存在反root , 反调试 。 但是奇怪的是,frida连接并没有死,app也并没闪退 , 只是app出现弹框强制退出,意识到这比其他so层反注入可能要好很多,因为这代表so层没有进行强制终止app进程 ,尝试用frida动态找类以及查询进程信息进行基本连接测试发现完全可以操控app进程,那么就好办了,不过以防万一,还是先dlopen看看加载的so文件里有没有可以的风控so


dlopen脚本
Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"), { onEnter: function (args) { console.log("加载SO:" + args[0].readCString() ); } }); console.log("监控启动!操作APP看SO加载路径~");
|

hook clone函数,暗杀子线程
clone是 Android/Linux 创建线程的核心系统调用,所有子线程创建必走此函数;
PROT_NONE为内存权限标识,设为该权限后,对应地址无法读 / 写 / 执行,线程执行即崩溃;
Hook clone 捕获壳的防护子线程地址,打PROT_NONE直接废线程。
hook clone函数 实战代码
function hook_cer_test_and_offset() { const TARGET_SO = [ ]; var clone = Module.findExportByName('libc.so', 'clone'); if (!clone) { console.log("[-] 未找到clone函数"); return; } Interceptor.attach(clone, { onEnter: function (args) { if (args[3].isNull() || args[3] == 0) return; try { var addr = args[3].add(96).readPointer(); if (addr.isNull() || addr == 0) return; var mod = Process.findModuleByAddress(addr); if (mod && TARGET_SO.includes(mod.name)) { var so_base = mod.base; var offset = addr - so_base; console.log("【检测线程定位】"); console.log("SO名:", mod.name); console.log("入口地址:", addr); console.log("十进制偏移:", offset); console.log("十六进制偏移:", "0x" + offset.toString(16).toUpperCase()); console.log("====================================="); } } catch (e) { } }, onLeave: function (retval) { } }); console.log("[+] clone函数Hook完成,仅监控目标防护SO(含最新新增3个可疑SO + 日志所有出现SO)"); }
setImmediate(() => { hook_cer_test_and_offset(); }); |
可以看到,只有自研究的so文件 ,里面有一个so文件很可疑,这里用红圈标记,尝试hook clone函数,看看是否会出现clone线程的情况,有的话直接暗杀 。 这是clone函数的脚本,大家可以用这个来进行定位可疑so文件的子线程,因为就我目前对银行app过检测的经验来看,大部分是通过clone子线程来进行检测的,甚至有多个子线程互相检测的情况 ,我查过梆梆反调试的原理,也是通过clone线程来进行检测frida痕迹,不论行不行大家都可以先试试,就我个人来言,能过百分之60的银行类检测,但是本项目恰好是另外百分之40,哈哈,但是也有办法!接下来会演示


把挖到的地址patch 暗杀后,发现app还是有强制弹框,此时我又锁定了另外一个so,发现同样clone了子线程 ,同样的操作,发现app直接打不开了,app无响应,我此时有一个大胆的想法,这个可能是解密壳的so文件,先过完检测再来确定
那么暗杀方法不行,那么就抓住一切可以利用的痕迹,没用通杀的方法,只有灵活的人类 ,之前有提到,这里frida注入app后并没有死,可以操控frida hook进程,那么还说什么,抓住破绽弹框,直接hook弹框类 , 抓住调用栈,拦截调用 , 发现果然孵化再打开的时候就不再弹框了,


注意,这里我要分享一个细节 大家注意,可以通过hook 弹框类的java创造方法来检测弹窗,但是更好的是通过调用堆栈找到真正的方法调用类方法,可以更精准,更安全
接下来检测就这样过掉了,接下来就是本篇最过瘾的一集,脱壳
一开始,我用mt管理器查看加固信息,惊呆了,头部银行居然没有加固么??包结构如此清晰,没有出现加固的特征


打开业务包名,哈哈哈还是被加固了的,AndroidManifate.xml 也有加固特征

接下来我尝试使用opencommon脱壳,结果是脱到了的

也可以看清楚完整的包结构 但是做了函数抽取,也就是把class文件里面的函数指令直接打上nop导致只能看见空 ,这就是典型的特征 ,java层的反馈就是包的结构虽然一清二楚 但是函数全部都是return null

这里我做了一点分析,就是说,我们使用opencommonhook的时候 ,此时拿到的是被nop化的dex文件 ,很头疼怎么办呢, 我们等待回填又不能触发opencoomon ,所以此时我们可以考虑使用frida-dexdump ,在回填后深度扫描内存,也是一种好方法 注意,这里必须触发模块,或者主动调用函数来让app强制回填,不然同样抓不到
经过反复测试,找到加载点,因为这里是函数抽取,包的结构是完全明了的,完全可以进行主动调用函数来看看dex回填的时机,这里比较私密,不懂私信我,所以经过一番测试,找到了位置,于是,可以考虑使用frida-dexdump深度脱壳来dump maps里面的文件
值得注意的是,如果连frida-dexdump被检测的很严重,就是对内存分区做了强检测,导致应用闪退的话,这时候就真的只能采用so文件主动解密的方法了,分析壳的解密函数,手动解密,难度很高,但是这里很幸运,脱到了

此时就是真正的代码,脱壳成功

接下来就可以来分析登录接口的加密了,首先第一步,先抓包 ,小黄鸟安装证书后,连接电脑协同,必须安装证书,否则可能导致抓不到包
但是我们开启小黄鸟之后,可以发现,开启了ssl检测

我们需要hookTrustManagerImpl ,过掉检测
成功抓到包,我们筛选登录接口,触发登录模块,定位登录包 ,最终找到了登录包

根据参数静态搜索定位 ,打开jadx,搜索名称

此时通过frida动态分析 ,hook java的aes方法 和 crypti方法 找到加解密和密钥 也可以通过静态分析, 但是这里我推荐先动态hook ,定位到具体位置,再进行动态调试,主动调用函数,看函数用途
这一步份涉及实现细节,本文不展开,需要的话可以私信我
至此登录接口破解成功
因为是作者第一次发帖,本贴我不知道什么能写上去什么不能,所以后面会比较模糊,但是可以参考思路,谢谢大家,如果有帮助,麻烦关注一下,我们可以一起进步
传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 4天前
被reserve_zhou编辑
,原因: 有一些图片受损了,修复一下