首页
论坛
专栏
课程

[原创]非商业APP加壳分析实验

2019-3-9 20:08 2559

[原创]非商业APP加壳分析实验

2019-3-9 20:08
2559

0x01 背景

随着移动互联网的逐渐升温,移动安全的从业者群体不断壮大,在大牛们的研究与工程下,很多工具也日趋完善。

不过我们依然会问一个问题,仅仅会用工具就足够了吗?

不,不够的,对于一个有志于提高自己技术水平的移动安全从业者,原理与工具同样重要。

因为只有深入了解了原理,我们才会不为名词所惑,明白为什么这样安全,那样不安全。

本次教程将简单快速地讲一讲,什么是加固和脱壳,顺带的实验将帮助你收获一个 “手工脱壳” 的小小成就。

入门向,老鸟勿喷。

加固的历史与对抗

如今的应用加固,已经相当普遍。小型开发者会使用私有化加固保护自己的版权防范抄袭,而大型机构则特别注意用商业加固来保护客户端核心业务逻辑免于破解。而各家厂商也在加固中增加了反调试、反Hook、混淆、白盒加密等攻防对抗技术,这往往让许多测试人员十分头疼。

不过说白了,加固的核心原理,其实就是把运行逻辑隐藏起来,或者说,把真实Dex隐藏起来。

早期加固

其实许多人会发现,把真实Dex从APK文件中隐藏起来,其实并不是一件太难的事情。

安卓提供了动态加载DEX文件的API,只要把Dex文件一加密,在运行的时候解密加载,APK中就看不到原始DEX的文件了。

没错,这就是早期加固的技术,只要找到了API,手写一个玩具也并不困难。

进阶加固

其实早期加固的问题是很大的,因为攻击者很快发现了,不管你再怎么加密,在动态加载的这一刻,内存中总是要出现原始DEX文件。找对时机,Dump一下内存,扣出DEX文件不就行了么?没错,这也就是本次实验的内容。

所以,相对专业的加固厂商为了对抗这一点,采取了类抽取,或者打散DEX内存结构的技术。通过在一定程度上嵌入安卓虚拟机,实现了字节码现用现加载,内存中不再出现完整可Dump的DEX文件了,就算Dump出来,也是一个几乎什么都没有的空壳DEX。

这个,就是市面上常见的免费加固的技术了。

其脱壳方法,在大佬面前也不是秘密,无非是强迫壳回填,或者是遍历内存结构重建DEX文件了。

商业加固

其实,当谈论到商业级别的加固,其核心技术就不再是DEX的结构和解析了,那并不能满足商业上的要求。

商业加固的核心是编译,将字节码重新编译,并通过编译阶段的混淆和防护,用全新的难以理解的字节码重构应用本身。这不但使得分析变得十分困难,其过程往往还是单向的,从而保证了DEX文件的不可还原。

当然,商业加固还集成了多种攻防对抗技术,单是反调试,就有多种方式在同时检测,想破解就不是单纯某一项技术的对抗了。

0x02 实验

实验:手工Dump脱壳

实验样本:一个无保护的早期加固技术样本,正好适合本次实验。

APP名称:记账城市(某繁体语言APP,你们懂的)

实验目标:通过内存Dump方式获取其原始Dex文件。

实验工具:IDA、开源工具ExtractDexFromOat、开源工具Jadx

实验准备:

1.        在手机中启动IDA远程调试服务器


2.        在电脑中转发调试端口


步骤一:DEX复原与定位

在正确的时机找到目标DEX文件,是Dump的第一步。当缺少时机时,有时还需要主动创造时机。

不过本样本缺少保护,也并未清理内存中的DEX文件,所以可以相对简单地定位。

1.        将IDA附加到APP对应的进程上。


2.        附加成功,可看到DEX在已加载模块中。


3.        在IDA的模块列表中,我们可以查看已经加载模块的地址还有大小信息。


步骤二:内存Dump

由于样本内存中的DEX文件完整,并不需要重建或回填,我们直接使用IDA脚本进行dump。

1.        按Shift+F2在IDA自定义脚本窗口运行dump脚本,手动填写参数。注意参数来自模块信息。

             

2.        使用工具ExtractDexFromOat将OAT格式的DEX还原出来。


步骤三:修复与验证

接下来就是修复和验证DEX文件了。

1.        为了使还原出来的DEX文件适配性更好,可以使用baksmali重构dex文件。

 

2.        使用jadx分析重构的dex文件,可以看到逆向工具对dex文件以近乎源码的形式查看。


实验结果

成功使用IDA进行了一次简单的手工内存Dump脱壳。

如果小伙伴们希望学习事件,还有一个基于完全一样保护技术的应用Walkr,你们可以自己上手练习。

0x03 总结

内存Dump

我们进行了一次简单的脱壳,能够成功当然也因为样本技术简单,同时缺少保护。

不过虽然简单,内存Dump是各类脱壳的基础操作,因为我们最终需要提取DEX文件。

内存Dump的方式多样,用IDA脚本是一种方法,写文件是一种方法,通过Socket发出也是一种方法。方法多种多样,适合自己的,就是最好的。

反调试

样本缺少反调试是降低脱壳难度的原因之一。

脱壳并不仅仅是对于内存中DEX的分析,更多的也是有来有往的攻防对抗,这是检验大佬的标准。

商业加固的真正难度

实现一种加固技术不易,不仅仅是简单加固原理的工程化实现,而是如何构建一个从静态、动态、破解对抗的全方位加固体系,如果希望一个简单的DEX整体加密就可以保护APP的安全,还是比较学院派了。比如这次的实验对象,如果要对APP做二次修改,其实都不用借助任何的逆袭技巧,因为它本身就没有完整性保护,签名保护,或者必须的反调试保护。

其实真正的难度,在于适配和取舍。从安卓4到安卓9,在碎片化的安卓系统中,如何做到既稳定又快速又高强度还不出问题的保护呢?

这就要看一个厂商的积累和能力了。

0x04 附件与参考

ExtractDexFromOat(https://github.com/ManyFace/ExtractDexFromOat)

Jadx(https://github.com/skylot/jadx)



[推荐]看雪企服平台,提供安全分析、定制项目开发、APP等级保护、渗透测试等安全服务!

上一主题 下一主题
最新回复 (5)
无边 2019-3-10 02:26
2
0
起点很高,不过样本是16年以前的东西。
pxhb 2 2019-3-10 13:39
3
0
感谢分享
珍惜Any 2019-3-11 10:27
4
0
导出内存 还不如直接用GG 
DWwinter 2019-3-11 13:24
5
0
谢谢分享
cnlife 2019-3-12 10:27
6
0
楼主能否提供样本?网上下的样本,发现有AppGuard.dex模块。已经完全不一样了。
游客
登录 | 注册 方可回帖
返回