安卓安全概述
- 1.Android系统概述
- 2.Android系统安全概述
- 3.Android系统的安全机制
- 应用程序框架安全机制
- 内核安全机制
- 运行环境安全机制
- 4.Android反编译工具
1.Android系统概述
Android采用层次化系统架构,Google官方公布的标准架构如图所示,自顶而下划分为5个主要功能层,分别是:
- 系统应用层(System Apps)
- 应用程序框架层(Java API Framework)
- 系统运行时库层(Native C/C++ Libraries和Android Runtime)
- 硬件抽象层(HAL)
- Linux内核层(Linux Kernel)
2.Android系统安全概述
Android系统是基于Linux内核的,通常使用Java语言编程。Android拥有一些安全特性来保护用户数据和资源。其中包括通过Linux内核的强大安全性、权限模型、应用程序签名以及所有应用程序的沙箱方法。这些特征是必要的,但不足以保证Android平台的安全。
正是由于Android系统本身的安全保护机制不足以保证Android平台的安全,以及当今Android的APP数量呈爆炸式增长,使得应用安全的需求被无限放大,推动了Android应用软件保护技术的产生和发展,APP加固技术逐渐涌现。
传统的软件保护技术根据所使用的方法,主要分为两类:第一类是基于硬件的保护技术,而第二类是基于软件的保护技术。前一种加密技术需要考虑到硬件设备等底层设备的运行原理,其开发难度大、成本高,但其破解难度大,主要由Google和厂家设计,而大部分文献涉及的Android保护机制主要基于是软件保护技术来涉及的,主要包括注册验证,代码混淆,防篡改,加壳技术等,较为灵活,成本较低,同时安全性有限。
3.Android系统的安全机制
应用程序框架安全机制
主要有应用程序的权限控制机制和数字签名机制。应用程序必须在权限内运行,程序安装时系统会对相关文件进行安全检查,通过后授予相应权限。从Android 6.0 (API 23)开始后采用运行时权限策略,普通权限在安装时一次授权完毕,而危险权限在应用运行时由应用自行申请、用户授权同意。
在Android 6.0及更高的版本( API >= 23 )是系统采用运行时权限模式,应用在安装时不会通知用户应用的权限,但是在应用需要使用危险的权限时,会提示用户手动进行授权,而普通权限在安装时一次授权完毕;而在Android 5.1.1级更低的 ( API <=22 )版本,用户需要在应用安装时授权所有的权限,才能正常安装,否则无法安装该应用程序。
应用申请的所有的权限都写在AndroidManifest的标签中,比如需要发送SMS消息的应用程序需要包含以下行:
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.snazzyapp">
<uses-permission android:name="android.permission.SEND_SMS"/>
<application ...>
...
</application>
</manifest>
Android的权限体系,一般是分为四种保护等级:正常、危险、签名和签名/特权,但是根据实际情况,往往有许多应用会申请一些不在这四种保护等级范围的权限,所以另外附加两种情况:不允许被第三方应用使用、已弃用。
权限的四个基本保护等级
- 正常(normal[N])权限的默认值。风险较低的权限,授权时会自动同意,无需用户手动同意。
- 危险(dangerous[D])一种风险较高的权限,可以使请求的应用程序访问私有用户数据或控制可能对用户产生负面影响的设备。
- 签名(signature[S])应用A有一个声明了signature等级的权限,则应用B必须具备应用A的相同的签名才行。若证书匹配,系统会自动授权,无需用户操作。
- 签名/特权(signature/privileged[S/P])API > 23后使用signatureOrSystem表示。一是放置在Android系统上专用文件夹中的应用程序才能获得授权;二是另外一个应用B需要有和有标记为signature的权限的应用A相同的签名。
附加的两种权限,针对不允许被第三方应用使用权限,这里有必要提及一下第三方应用的概念,Android系统自带的应用以外的,也就是我们开发者开发的Android应用,比如QQ、微博、微信、今日头条、抖音和王者荣耀等等,都是第三方应用,这些应用都是不能拥有NU标注的权限的。
对于带有已弃用标注的权限,有以下三种情况
- 从API级别高于某一值废弃。低于这个数值申请该权限属于正常,但是高于这个数值,再申请肯定是错误的,因为此权限被弃用。我们使用O-xxx来表示从API级别xxx以后废弃该权限。比如O-23表示从API Level为23以后弃用该权限。
- 该权限被某一权限替代。比如
BIND_CARRIER_MESSAGING_SERVICE
被BIND_CARRIER_SERVICES
取代。 - 该权限被永久废弃。我们用O-all来表示。
除了权限的概念外之外,Android系统中还有对权限的分组。权限分组为与设备功能或功能相关的组。在此系统下,权限请求会以组的形式进行提醒。例如,CONTACTS组(与此设备上的联系人和配置文件相关的权限),包括READ_CONTACTS、WRITE_CONTACTS和GET_ACCOUNT,当用户授权了READ_CONTACTS,则Android会自动授权另外两个权限,具体的权限是针对开发者,而对于用户而言是以组的形式展现。
内核安全机制
从技术架构角度来看,Android安全模型基于强健的Linux操作系统内核安全性,故Android的内核安全机制继承自Linux内核的安全机制。进程沙箱机制可以隔离隔离进程资源,限制资源间的自由度;低内存管理技术与新标准Binder IPC通信机制,适应嵌入式移动终端处理器的性能与内存容量的限制。还有完整的权限控制、管理和授权机制,加上签名的引入,能够对Android应用程序的行为进行规范化的管理,对应用之间的关系也进行了定义,包括信任关系和资源共享的授权。
运行环境安全机制
Android 4.4采用Dalvik虚拟机,每个应用都运行在独立的Dalvik虚拟机上,但虚拟机不作为隔离代码的安全边界,所以,在系统Android主要采用强制安全类型来进行加固。在Android 4.4以后Google引入了ART虚拟机,到5.5已经成为默认模式。Android 7.0 向 ART 中添加了一个 just-in-time(JIT)编译器,这样就可以在应用运行时持续的提高其性能。
4.Android反编译工具
为了达到反编译apk的最终目的,我们可以使用apktool、dex2jar、enjarify、jd-core( jd-gui )、cfr、procyon等工具。实际上,Apk可以看作是一个zip文件,其中的DEX是根据android系统中Dalvik或ART虚拟机优化后的Java字节码。在获取Java源代码之前,我们需要将DEX转换成等价的JAR。值得一提的是,我们可以认为Jar文件是封装一系列Java classes的包。最后,我们可以使用java反编译器:cfr、jd-core和procyon,三者中的任何一个都可以将JAR反编译成非常接近源项目的java文件。
由于反编译可能会出现错误,我们可以让三种java反编译器分别进行工作,结合三者的反编译结果来降低错误率。
不论如何我们也不能将APK文件完全恢复成java的源代码,还需要用我们的智慧手动地调整代码的细节,才能够完全恢复成原来项目的模样。更不要提,我们可能还会遇到混淆或者加固后的代码,这更加会增加我们恢复源码的难度。换句话说,这也是开发一个实用的反编译器的核心点和难点。
下图显示了Jar文件和Apk文件之间的区别。类文件本质上与dex文件相同,都是字节流的代码文件。换句话说,dex源自class文件,因为DVM或ART-VM是基于JVM开发的。我们可以使用JDK工具中的javap来反编译类文件,同样地,我们可以使用apktool来反编译dex文件:
1、从apk中获取资源文件和smali代码 - apktool
https://apktool.org/
一个用于逆向工程的第三方工具,可以用来逆向封闭的、二进制的Android应用程序。它可以将资源解码成几乎原始的形式,并在进行一些修改后重新构建它们。它还让应用程序使用起来变得更容易,因为APK项目本质上就是一个文件结构,我们可以将一些重复性的任务自动化,如构建apk等。
java -jar apktool.jar d yourapp.apk
2、从apk/dex中获取jar文件 - enjarify
https://github.com/google/enjarify
用于将Dalvik字节码转换为等价的Java字节码。
Enjarify是一个纯python 3应用程序,所以你可以直接运行它,你需要在命令行中进入到项目的根目录中,然后运行:
python -O -m enjarify.main yourapp.apk
3、从Jar中获取java代码
a. jd-core
https://github.com/nviennot/jd-core-java
JD-Core是jd-gui使用的java反编译器
java -jar jd-core.jar <compiled.jar> <out-dir>
b. cfr
https://www.benf.org/other/cfr/
CFR将对现代Java特性进行反编译——包括大部分Java 9、10和更高版本
java -jar cfr.jar <compiled.jar> --outputdir <dir>
c. procyon
https://bitbucket.org/mstrobel/procyon/wiki/Java%20Decompiler
Procyon是一套专注于代码生成和分析的Java元编程工具。
java -jar procyon.jar <compiled.jar> -o <dir>