为防止App被篡改,这届安全工程师付出太多努力
在山寨这个领域,没有人比黑灰产更懂模仿。
据安全从业者介绍,一般而言,对于成熟的山寨开发者来说,几天时间内就可以做出一套前端框架。服务器、源代码、域名、服务商这些内容的创建,通过网上租赁的方式就可以解决。
比如,一款苹果应用商城里上线的App,黑灰产能达到1:1级别的复制,报价高达近三万元,20天就能完工。
如果想要让这些仿冒App成功上线苹果或者安卓的应用商店,只需要在完工后支付相应的费用即可。
而山寨开发者之所以能如此快速复刻出App,其实是对App 进行了反编译或篡改工作。
防篡改重要性
防篡改顾名思义就是通过技术手段让逆向工程师们不能篡改某个App 中的关键信息,进而起到App 加固的作用。
如果没有APP加固实现防篡改,那么攻击者插入恶意代码就可以达成两方面的攻击向量:
1、对于App用户而言,插入恶意代码的App传播出去可以进行钓鱼、电信诈骗等操作,用户会有资产或其他损失;
2、对于App 服务端而言,攻击者就可以利用客户端与服务端的一些接口对服务端进行攻击,对App造成相应的舆论和名誉损失。
App 加固中的防篡改原理
那么,App 加固中的防篡改究竟是如何实现的呢?
我们不妨从App 的开发讲起。
一个App 大致由开发者、App、包名、证书、签名组成。如果把开发者比作父母,那么App就是孩子,包名则是孩子(App)的姓名,证书则是孩子(App)的出生证明,签名则是身份证号码。
与新生婴儿类似,当开发者完成App 的开发时,App 只有姓名这一个可以证明其身份的东西,此时也很容易会发生“狸猫换太子”的情况。为了保证孩子的安全,父母就需要给孩子准备出生证明,然后再使用出生证明给孩子生成一个身份证号码,证明孩子的身份。
对于攻击者而言,要想拐走这个“孩子”,有两种方式:
一是通过盗取证书进行信息篡改,即对App 的证书进行攻击,包括证书文件本身、证书私钥、证书私钥别名,一旦攻击成功,他就可以以开发者的身份对App 进行篡改,但一般而言证书不会轻易泄露。
二是绕过签名与包名校验,直接对App 本身进行修改。这就相当于人贩子拐走了小孩,怎样对待被拐走的孩子是人贩子的事情。
了解了这个原理后,我们就比较好理解如何防篡改了。
要想保证App 不被篡改,我们要做的就是保证App 的包名、签名、证书等信息的安全。
一般做法是提前收集应用的包名、证书、签名并记录在册,当攻击者使用伪造的证书生成了伪造的签名,我们就可以快速识别出你的身份信息与记录在册的信息是不符的,这样我们的加固程序就可以拒绝使用这个App。
当App 出现闪退、崩溃等操作时,我们就可以考虑是不是我们使用的是假冒的App了。
App加固中的防篡改手段有哪些?
总的来说,防篡改可以通过加壳、资源加密 代码混淆、虚拟执行等手段来实现。
1、加壳即通过对 DEX 文件进行加壳防护可以选择整体 DEX 加固或者拆分 DEX 加固的方式,隐藏源码防止直接性的反编译。拆分 DEX 加固需要注意 DEX 文件的数据结构,选取 classdata 和 classcode 这两部分,即使拆分出来也不会泄露 class 数据和字节码数据,反编译出来也不完整,安全性较高。
2、资源加密即对软件包中的图片、音频、视频等资源文件进行加密,防止被攻击者替换或篡改。
3、代码混淆即对编译好的class文件进行混淆处理,处理后的代码与处理前代码能够完成相同的功能,但混淆后的代码很难被反编译,即使反编译成功也很难得出程序的真正语义。
4、虚拟执行即将原始化代码编译为动态的DX-VM虚拟机指令,运行在DX虚拟机之上,无法被反编译回可读的源代码。
但正如我们在上篇代码混淆的科普文章中提到的,仅靠代码混淆、防篡改是无法防住黑灰产的,在利益面前,他们总有办法找到漏洞。
因此,对于App 加固而言,最好的办法是多管齐下,对App 加固进行多重防护。比如字符串加密、控制流平坦化、指令替换、符号混淆、混淆多样化、不透明谓词、防动态调试、防动态注入、HOOK检测、代码段检验、完整性校验等等多种技术手段。
只有这样,才能防患于未然。