DownOL 软件仓库– 软件下载,字节世界与新知

从一款被篡改的软件谈 Android App 的安全之路

发表于:2024-04-27 作者:创始人
编辑最后更新 2024年04月27日,【原创】2017-12-18 龚沛华 高效运维作者简介龚沛华WiFi 万能钥匙信息安全部,Android 安全研究员,主要从事 Android app的逆向分析与安全保护。我来自 WiFi万能钥匙,主

【原创】2017-12-18 龚沛华 高效运维

作者简介

龚沛华

WiFi 万能钥匙信息安全部,Android 安全研究员,主要从事 Android app的逆向分析与安全保护。

我来自 WiFi万能钥匙,主要负责安卓立项和保护这块的工作。本文要分享的有七大块:

  1. Android 平台安全现状

  2. Android 安全模型

  3. 程序安全

  4. 数据安全

  5. 系统安全

  6. 一款被篡改的 APK

  7. APK 保护措施

1. Android 平台安全现状

左上角这张图是安卓端的恶意程序新增量和感染量。

右下角这张图是恶意程序类型的分布也占了很大的比例。

这些情况对一般用户都是比较敏感的行为,在安卓这块恶意程序的出现,也是应该引起我们一些注意。

移动终端特性:

  • 攻击入口广

    • 浏览器、恶意 app、网络劫持、usb

  • 碎片化

    • 安卓手机厂商多、安卓系统碎片化

  • 用户隐私

    • 通话、简讯、应用数据

安卓出现这么多恶意程序,是由于移动终端的特性决定的。

攻击入口比较广,比如安卓上的一些浏览器,一些恶意 APP,网络界面和USB。浏览器很多时候在用户不知道的情况下可能会点击一些恶意网站的链接,打开以后可能会有一些浏览器的漏洞,导致恶意下载一些APP,后台可能会有一些静态的 ROOT 这些行为。另外网络劫持也是比较常见的,往往这些劫持的 APP下载下来都是充满着各种恶意行为。

另外像碎片化,这个在国内更加的普遍,因为在国内安卓厂商比较多,并且系统也是各个厂商定制的比较多,各种各样的厂商不同的入口会导致不同的问题。

还有就是安卓系统,现在8.0版本出来可能稍微好一点。之前安卓系统漏洞是比较多的,像用户的隐私,如通话、简讯和应用数据,只要申请一些许可权就可以获取这些数据。

2. Android 安全模型

  • Linux内核安全特性

    • 保留对应版本 Linux 内核的常规安全特性

    • 基于 UID、GID 隔离的访问控制

    • 单用户系统,Android 使用UID、GID 区分不同的 App

  • 沙盒

    • 每一个 App 在/data/data 下拥有一个私有目录

    • 每一个 App 或服务对应单独的 UID,系统级 UID 从1000开始,第三方 App 从10000开始,以此进行 UID级的资源隔离

  • 许可权

    • App 需要许可权来访问各种系统资源

    • App 可以通过 AndroidManifest.xml 来申请许可权

    • 许可权分级

    • 由用户在安装时决定是否允许该许可权

    • 4.3之后可以动态管理

  • IPC 进程间访问控制

    • IPC 用于不同进程之间的数据通信

    • IPC 在上层有多种体现方式

  • Intent/Messenger/AIDL

  • APK完整性

    • Apk签名

  • SELinux

    • 内核级的强制访问控制

    • 4.3开始引入 Android

    • 保护系统关键资源

其实安卓做了一些安全的东西,上图左边是安卓的安全架构,第一个是 Applications,第二层是 Androidframework,代码签名,系统签名等等,还有多用户访问控制,加密,许可权保护等等,但是这些机制并不是完全的够用。

像 Linux 的安全特性,是常规在 Linux 进行修改变化过来的,所以跟我们常见的 PC 上的 Linux不一样。比如它是基于 UID 和 GID 的访问控制,另外在 APP 端是单独的控制,每个 APP 安装上去都会给你分配一个UID。这个是安全上的一个沙盒,系统级的 UID 都是从1000开始,第三方 APP是从10000开始的,以此进行UID级别上的资源隔离。此外,每一个 APP在系统的/data/data下拥有一个私有的目录,在这些目录下面的隐私数据其他的 APP 也是可以获取到的。

许可权这块其实现在对安卓来说是可以做到管理的,可以更好的进行一些控制。以前系统安装的时候直接申请所有许可权,要么全部给,要么全部不给。

另外安卓上的一些签名,这在我们平时工作中也会遇到很多挑战或者威胁,因为安卓它本来 APP是有相应的签名的,但是很容易被绕过,因为现在市场上有很多二次打包的APP,有一定的加护,可以进行系统校验。我们平时也会遇到这样的问题,即使做了校验,还可以通过系统进行反射绕过的。

3.程序安全

程序安全比较常规的像防止反编译,篡改,代码注入等等。

反编译本来原代码里面是没有这块的,在代码里面加入一些获取插件的代码,往往这些攻击是注重自我的保护,下载这些插件以后过了几秒钟就删掉了,然后在五秒之内会启动自己的插件和服务。

加密算法是比较关键的地方,我们在分析 APP 的时候分析加密算法是比较脆弱的,java层加密算法其实是没有什么用处的,我们建议在 SO 里面进行加密算法。

另外就是 HTTP 和 HTTPS 这块了,裸奔的 HTTP 是不安全,HTTPS 加密通道安全性依赖于对证书的认证。

4.数据安全

  • 敏感数据

    • 本地数据库

    • Shared_prefs

    • 网络数据传输

    • Sdcard

    • Log

    • ……

APP 上比较常见的本地数据库、Shared_prefs、网络传输。网络传输是比较关键的地方,往往我们在做 APP的测试的时候对网络和传输这块看的比较多一点,因为网络传输比较容易被劫持。另外像 SD 卡、日志等等。

5. 系统安全

  • 系统环境安全

    • 界面劫持

    • 组件暴露

    • 键盘记录

  • 系统库安全

    • WebView 不合理导出

    • targetSdkVersion<= 16、addJavascriptInterface

    • 运行 js 代码调用本地代码

系统安全比如界面劫持,这个对于金融类的 APP可能会比较多一点,它会直接弹出一个跟你界面一样的界面,诱导你输入账号、密码等等。

上面图片就是 WebView 的漏洞。

6. 一款被篡改的 apk

  • 工作原理

  • 篡改程序入口

  • 初始化支付

  • 下载病毒母体

  • 准备提权

  • 下载篡改系统工具包

  • 其它恶意行为

恶意 APP 分析

上面例子就是恶意的被篡改的 APP 大概的运行过程。

首先是打包一个 APP,在运行中会下载恶意的母体,并且有一些简讯拦截和提权等等恶意操作。我们通过反编译能够看到是把这个 APP的初始化函数加入了一段自己的初始化的代码,然后我们在这个 APP的一个注册文件里面可以看到上面图中加入的内容,就是如果发生了这样的信号,就可以把自己的相应组件给隐藏起来。

另外还可以看到在代码里面直接写入了支付的代码,并且进行了初始化,这个一旦成功了就可以直接进行支付了。

这只是其一,下面还会从服务器端下载一个恶意的病毒母体,从代码上可看出攻击者有一定的安全意识,他把自己的服务器等等在代码里面都加密了。我们可以通过网络抓包可以看到相应的服务器地址,并且都是加密的。

下载一段eql,是一个压缩包并且是可执行文件,打开后并不是一个图片,而一个加密的文件,我们对它进行解密可以看到也是一个压缩文件,进一步解密后是ELF 的文件。

此外还会下载另一个工具包,也是经过加密的,通过解密里面包含了四个文件,第一个是可以篡改系统的脚本,第二个是需要把这个 APP写入系统目录,第三个是一个 SU 的可执行文件,第四个是命令监控与执行的文件,可以监听 SD上的文件,然后去执行写入这个文件的所有命令,图中可以看出它执行过程中会做哪些操作,如把系统比如360、QQ安全管家等等都会关掉,做一个篡改,一个系统的目录和其他的恶意行为,比如删除系统文件,篡改系统工具包等等。

图中就是篡改了系统下面的一个文件,这个文件其实是在系统里面执行的文件,他篡改了这个文件后,每次用户重启手机的时候,就会执行他这个恶意行为代码,可以从服务器下载非常多的APP 文件,在用户后台进行安装,还会定制各种服务,让用户手机进行扣费。

这个例子就是在我们 APP 没有进行很好保护的情况下,会产生很多被篡改,导致用户损失。

7. APK 保护措施

  • APK 加壳与混淆

    • 加大代码分析难度

    • 代码加密、隐藏、反调试、反逆向分析等

    • APK 加壳

    • APK 混淆

  • APK 完整性检验

    • 变数名混淆、字元串加密、垃圾指令、指令替换、native 扰乱控制流

    • 反调试:ptrace、/proc/self/status、……

    • 反内存 dump

    • 反一键脱壳器

    • 验证证书、校验文件 hash 值等

    • 静态完整性

    • 动态完整性

    • 混淆

  • 代码隐藏

    • llvm

    • 代码段加密

    • 自定义 so 格式

    • 伪造无效字段信息

    • 非法指令

    • Manifest 文件修改、资源加密、……

    • DEX 文件加壳,整体保护、类抽取

    • 防反编译工具,修改文件头、修改 debug 字段数据指针、……

    • SO 保护

通过上面的例子,我们需要对我们 APP 进行更好的保护。

APP的保护主要从两个方面入手,一个是加壳,另一个是混淆

加壳比如代码加密、隐藏、反调试、反逆向分析等等。

APK 混淆就是加上代码。

APK 的校验有静态完整性,像验证证书、校验文件的 Hash 值等。还有动态完整性,像反调试 ptrace 等、反内存dump、反一键脱壳器。现在网络上面有很多一键脱壳的神器,所以一般的加护并不能很好的保护,还是需要进行反一键脱壳的措施。

像保护方式不管是反调试还是验证证书等,更多还是希望在 SO 里面做,这样相对来说安全性会相对高一点,同时还要对 SO进行相应的保护,这样可以达到更好的保护效果。

还有混淆,像变数名的混淆、字元串的加密、通过垃圾指令、通过指令替换、native 来干扰扰乱控制流。

代码隐藏主要是通过修改 Manifest 文件、资源加密、DEX 文件的加壳、整体保护、类抽取等等。

其实我们应该更多的对 SO 进行保护,比如像 LLVM、对代码段的加密、自定义 SO 格式,这个可能比较好一点,因为常规的 SO格式,攻击者会知道,通过自定义的 SO格式在分析难度上会更加大一点。加入一些在调试的时候导致调试工具自动崩溃的反调试的工具。还可以加入一些非法指令来达到一些保护的目的。

2022-05-09 22:55:12
0