Android 渗透测试基础入门

概述

自从毕业了之后就少了很多杂七杂八的事,可以好好的学习下Android以及Android渗透测试。

基本结构

Android

Android 架构

Android 是基于 Linux 平台的操作系统。Android的系统架构和其操作系统一样,采用了分层的架构。
从架构图看,Android分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和Linux内核层。

android-base-android.dex

Android使用Dalvik虚拟机的概念,可以高效的运行多个虚拟机。Android操作系统使用这些虚拟机将各个应用程序运行为自己的进程。

安装的应用程序会因各种目的保存到如下目录:

1
2
3
4
5
6
/system/app/应用名.apk // 保存系统应用程序
/data/app/应用名.apk // 保存已注册的用户应用程序
/data/app/应用名-1.apk // 保存用户下载的应用程序
/mnt/secure/asec/应用名-1.asec // 保存移动到SD卡的应用程序
/data/data/应用名 // 保存应用程序的重要信息
/mnt/sdcard // 保存应用程序的一般信息

其中/data/data/应用名保存的信息最为重要:

1
2
3
4
5
6
/data/data/应用名
├─files // 保存内部使用的文件(so、data、ini文件等)
├─lib // 保存应用程序请求的库文件(存在so文件)
├─databases // 保存设置文件、内容文件等的查询信息的SQLite数据库文件(存在db文件)
├─cache // 有读写权限,包括浏览器缓存和用户临时状态信息
└─shared_prefs // 保存为XML文件,是应用程序共享的设置文件

其中 shared_prefs 目录内的preferences.xml文件包含应用程序的设置文件。因为包括升级、版本信息等内容,所以恶意访问时,此处会包含API密钥的盗用、认证密钥值等信息。

Android 重要组件以及生命周期

Android 由Activity,Service(服务),Content Provider(内容提供者),BroadCastReceiver(广播接收器)四大基本组件组成。

Activity

Android 应用程序中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。

Activity的生命周期如下图所示:

android-base-activity-live

途中涉及到的各类方法:

android-base-activity-func

Service

Service 不会显示给用户,其运行过程与Activity相似。听音乐或者录音都在后台运行,与其他软件的运行是同时的,这些都属于Service的功能。 Activity与Service都以名为UI线程的相同应用线程执行。

Content Provider

Content Provider 是应用程序之间共享数据的界面。Android的每个应用程序都默认在Sandbox中运行,所以与系统中的其他应用程序相互分隔,不能直接访问数据。Content Provider遵守CURD(Create、Update、Read、Delete)原则。应用程序通过Inter共享小数据。Content Provider 适合共享音乐文件、图片文件等大容量文件。

BroadCastReceiver

你的应用可以使用它对外部事件进行过滤只对感兴趣的外部事件(如当电话呼入时,或者数据网络可用时)进行接收并做出响应。广播接收器没有用户界面。然而,它们可以启动一个activity或serice 来响应它们收到的信息,或者用NotificationManager 来通知用户。通知可以用很多种方式来吸引用户的注意力──闪动背灯、震动、播放声音等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。

四大组件的注册

四大基本组件都需要注册才能使用,每个Activity、service、Content Provider内容提供者都需要在AndroidManifest文件中进行配置,AndroidManifest文件中未进行声明的activity、服务以及内容提供者将不为系统所见,从而也就不可用,而BroadcastReceive广播接收者的注册分静态注册(在AndroidManifest文件中进行配置)和通过代码动态创建并以调用Context.registerReceiver()的方式注册至系统。需要注意的是在AndroidManifest文件中进行配置的广播接收者会随系统的启动而一直处于活跃状态,只要接收到感兴趣的广播就会触发(即使程序未运行)。

AndroidManifest文件中进行注册格式如下:

1
2
3
4
<activity> 元素的name 属性指定了实现了这个activity 的Activity 的子类。icon 和label 属性指向了包含展示给用户的此activity 的图标和标签的资源文件。
<service> 元素用于声明服务
<receiver> 元素用于声明广播接收器
<provider> 元素用于声明内容提供者

APK

APK 文件其实是一个 Zip 的压缩包,解压了此文件可以看到如下目录:

1
2
3
4
5
6
7
8
9
10
APK
├─META-INF // 主要存放证书,没有证书无法安装程序
│ ├─CERT.RSA // 公钥证书
│ ├─CERT.SF // 包含APP的所用资源,负责对APP进行签名
│ └─MANIFEST.MF // 声明了资源,与CERT.SF相似
├─res // 存放资源文件的目录
├─lib // 如果存在的话,存放的是 ndk 编出来的 so 库
├─resources.arsc // 编译后的二进制资源文件
├─classes.dex // 最终生成的 dalvik 字节码
└─AndroidManifest.xml // 程序全局配置文件

classes.dex

Dex是Android系统中可以在Dalvik虚拟机上直接运行的文件格式。java源代码经过ADT的复杂编译后转换成Dex文件,这是一个逐步优化的过程。Dex文件的指令码就是Dalvik虚拟机专有的一套指令集,专门为嵌入式系统优化过,相比标准java的.class文件,它体积小,运行效率高。

classes.dex 文件头的格式如下:
android-base-classes.dex

androidManifest.xml

androidManifest.xml 是每个Android程序中必须的文件,它位于整个项目的根目录。我们每天都在使用这个文件,往里面配置程序运行所必要的组件,权限,以及一些相关信息。

AndroidManifest.xml是Android应用的入口文件,它描述了package中暴露的组件(activities, services, 等等),他们各自的实现类,各种能被处理的数据和启动位置。 除了能声明程序中的Activities, ContentProviders, Services, 和Intent Receivers,还能指定permissions和instrumentation(安全控制和测试)。

常用工具

ADB

adb的全称为Android Debug Bridge,就是起到调试桥的作用。通过adb我们可以在Eclipse中方面通过DDMS来调试Android程序,说白了就是debug工具。adb的工作方式比较特殊,采用监听Socket TCP 5554等端口的方式让IDE和Qemu通讯,默认情况下adb会daemon相关的网络端口,所以当我们运行Eclipse时adb进程就会自动运行。

借助adb工具,可以管理设备或手机模拟器的状态。还可以进行很多手机操作,如安装软件、系统升级、运行shell命令等等。其实简而言说,adb就是连接Android手机与PC端的桥梁,可以让用户在电脑上对手机进行全面的操作

命令介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 查看设备
$ adb devices
# 连接设备(夜神模拟器端口 62001)
$ adb connect ip:port
# 安装软件
$ adb install [apk文件路径]
# 卸载软件
$ adb uninstall [软件名]
$ adb uninstall -k [软件名] // 如果加 -k 参数,为卸载软件但是保留配置和缓存文件.
# 进入设备或模拟器的shell
$ adb shell
# 运行单条命令
$ adb shell [command]
# 端口转发
$ adb forward [PC] [设备]
$ adb forward tcp:6100 tcp:7100 // PC上所有6100端口通信数据将被重定向到手机端7100端口server上
$ adb forward tcp:6100 local:logd // PC上所有6100端口通信数据将被重定向到手机端UNIX类型socket上
$ adb forward tcp:62002 jdwp:17304 //在本地62002端口被重定向到手机17304进程上
# 从电脑上发送文件到设备
$ adb push [本地路径] [远程路径]
# 从设备上下载文件到电脑
$ adb pull [远程路径] [本地路径]
# 查看bug报告
$ adb bugreport
# 查看log
$ adb logcat

drozer

Drozer原名mercury,是一款不错的Android APP安全评估工具。现在有社区版/专业版两个版本。

安装

安装其实比较简单,这里不进行描述,只是记录下安装过程中遇到的问题以及解决方案。

一、修复连接时java路径找不到问题

解决方案:

1、创建如下文件并命名为:1.txt (如果为winXP,则可以直接命名为.drozer_config)
2、写入内容如下几行内容:此处为java.exe文件的安装位置,具体情况具体处理。

1
2
3
[executables]
java =C:\rogram Files\Java\jdk1.7.0_40\bin\java.exe
javac =C:\Program Files\Java\jdk1.7.0_04\bin\javac.exe

3、把此文件放入个人目录下文件夹:

1
2
英文:C:\Users\<youruser name>\
中文:C:\用户\<你的用户名名称>\

4、通过cmd命令重命名此文件为:.drozer_config

1
rename C:\Users\d00218136\1.txt .drozer_config

运行

1
2
$ adb connect 127.0.0.1:62001 // 连接设备
$ adb forward tcp:31415 tcp:31415 // 开启端口转发

开启移动设备中的agent.apk

1
$ drozer console connect

用法

1
2
3
# 列出设备中安装的包
$ run app.package.list
$ run app.package.list -f 【app名称】 // 搜索包
1
2
3
4
# 获取安装的包的信息
$ run app.package.info
$ run app.package.info -a com.zjhcsoft.android.eip // 列举指定包的信息
$ run app.package.info -p android.permission.INTERNET // 根据权限来列举包

android-base-drozer-1

1
2
3
# 列举设备上所有的activity
$ run app.activity.info
$ run app.activity.info -f 【包名】 搜索包的activity

android-base-drozer-2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 列举设备上所有的provider
$ run app.provider.info
# 列举设备上所有的service
$ run app.service.info
# 列举设备上所有的broadcast
$ run app.broadcast.info
# 查看某包的受攻击面
$ run app.package.attacksurface com.zjhcsoft.android.eip
# 运行activity
$ run app.activity.info -a 【包】
$ run app.activity.start --action 【activity 设置的intent filter的action属性】 --category 【activity 设置的intent filter的category 属性】--component 【package 名字】 【component 属性】
$ run app.activity.start --action android.intent.action.MAIN --category android.intent.category.LAUNCHER --component com.android.browser com.android.browser.BrowserActivity
# 根据指定的intent action和intent category来查看activity
$ run app.activity.forintent --action 【intent action】 --category 【intent category】
$ run app.activity.forintent --action android.intent.action.VIEW --category android.intent.category.DEFAULT

其他用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
Dex是Android系统中可以在Dalvik虚拟机上直接运行的文件格式。java源代码经过ADT的复杂编译后转换成Dex文件,这是一个逐步优化的过程。Dex文件的指$ run 令码就是Dalvik虚拟机专有的一套指令集,专门为嵌入式系统优化过,相比标准jav// a的.class文件,它体积小,运行效率高。
$ run app.activity.forintent // Find activities that can handle the given intent
$ run app.activity.info // Gets information about exported activities.
$ run app.activity.start // Start an Activity
$ run app.broadcast.info // Get information about broadcast receivers
$ run app.broadcast.send // Send broadcast using an intent
$ run app.broadcast.sniff // Register a broadcast receiver that can sniff particular intents
$ run app.package.attacksurface // Get attack surface of package
$ run app.package.backup // Lists packages that use the backup API (returns true on FLAG_ALLOW_BACKUP)
$ run app.package.debuggable // Find debuggable packages
$ run app.package.info // Get information about installed packages
$ run app.package.launchintent // Get launch intent of package
$ run app.package.list // List Packages
$ run app.package.manifest // Get AndroidManifest.xml of package
$ run app.package.native // Find Native libraries embedded in the application.
$ run app.package.shareduid // Look for packages with shared UIDs
$ run app.provider.columns // List columns in content provider
$ run app.provider.delete // Delete from a content provider
$ run app.provider.download // Download a file from a content provider that supports files
$ run app.provider.finduri // Find referenced content URIs in a package
$ run app.provider.info // Get information about exported content providers
$ run app.provider.insert // Insert into a Content Provider
$ run app.provider.query // Query a content provider
$ run app.provider.read // Read from a content provider that supports files
$ run app.provider.update // Update a record in a content provider
$ run app.service.info // Get information about exported services
$ run app.service.send // Send a Message to a service, and display the reply
$ run app.service.start // Start Service
$ run app.service.stop // Stop Service
$ run auxiliary.webcontentresolver // Start a web service interface to content providers.
$ run exploit.jdwp.check // Open @jdwp-control and see which apps connect
$ run exploit.pilfer.general.apnprovider // Reads APN content provider
$ run exploit.pilfer.general.settingsprovider // Reads Settings content provider
$ run information.datetime // Print Date/Time
$ run information.deviceinfo // Get verbose device information
$ run information.permissions // Get a list of all permissions used by packages on the device
$ run scanner.activity.browsable // Get all BROWSABLE activities that can be invoked from the web browser
$ run scanner.misc.native // Find native components included in packages
$ run scanner.misc.readablefiles // Find world-readable files in the given folder
$ run scanner.misc.secretcodes // Search for secret codes that can be used from the dialer
$ run scanner.misc.sflagbinaries // Find suid/sgid binaries in the given folder (default is /system).
$ run scanner.misc.writablefiles // Find world-writable files in the given folder
$ run scanner.provider.finduris // Search for content providers that can be queried from our context.
$ run scanner.provider.injection // Test content providers for SQL injection vulnerabilities.
$ run scanner.provider.sqltables // Find tables accessible through SQL injection vulnerabilities.
$ run scanner.provider.traversal // Test content providers for basic directory traversal vulnerabilities.
$ run shell.exec // Execute a single Linux command.
$ run shell.send // Send an ASH shell to a remote listener.
$ run shell.start // Enter into an interactive Linux shell.
$ run tools.file.download // Download a File
$ run tools.file.md5sum // Get md5 Checksum of file
$ run tools.file.size // Get size of file
$ run tools.file.upload // Upload a File
$ run tools.setup.busybox // Install Busybox.
$ run tools.setup.minimalsu // Prepare 'minimal-su' binary installation on the device.

androguard

androguard (Android guard) 是 Android 应用程序的逆向工程,提供恶意软件分析等等功能,androguard 主要由 Python 编写。

androguard 主要有以下功能:

1
2
3
4
5
6
7
androrisk.py // 该模块用于分析apk危险级别
androapkinfo.py // 该模块分析apk列出其中的文件类型、权限、4大组件、是否NDK反射等信息
androaxml.py // 该模块用于展示apk androidmanifest.xml
androgexf.py // 该模块生成函数调用图
apkviewer.py // 该模块生成指令级别的调用图
androlyze.py // 该模块为交互分析环境
androdiff.py // 分析2个apk的不同之处,检测app是否遭到修改

androapkinfo.py

该模块分析apk列出其中的文件类型、权限、4大组件、是否NDK反射等信息

1
$ python androapkinfo.py -i app-release.apk

android-base-tool-androapkinfo-1

androlyze.py

该模块为交互分析环境

1
$ python androlyze.py -i app-release.apk -x

android-base-tool-androlyze-1

1
2
3
$ python androlyze.py -s
$ a,d,dx = AnalyzeAPK("Desktop/app-release.apk")
$ print a,d,dx

android-base-tool-androlyze-2

1
2
$ d,dx = AnalyzeDex("Desktop/classes.dex")
$ print d,dx

android-base-tool-androlyze-3

等等,可以使用tab键

androdd.py

查看apk文件结构 按照指定格式显示androidapk的所有类和子方法的信息流

1
$ python androdd.py -i app-release.apk -o out -f png

androgexf.py

androgexf.py 将方法信息之间的连接状态转换成gexf格式

1
$ androgexf.py -i app-release.apk -o apk.gexf

androdiff.py

androdiff.py 分析2个apk的不同之处,检测app是否遭到修改

1
$ python androdiff.py -i app-release1.apk app-release2.apk

工具集

一、santoku 操作系统

santoku 实质是一款定制的 Ubuntu 12.04 系统镜像,类似于KALI,与其它Ubuntu系统相比,它具有如下特点:

1.集成了大量主流的Android程序分析工具,为分析人员节省分析环境配置所需的时间。
2.集成移动设备取证工具。支持Android、IPhone 等移动设备的取证工作。
3.集成渗透测试工具。
4.集成网络数据分析工具。在分析 Android病毒、木马等程序时,这些工具特别有用。
5.采用 LXDE 作为系统的桌面环境,界面与 Windows XP非常相似,符合中国人使用习惯。
6.正处于beta 阶段,但整个项目显得很有活力,相信将来的更新和维护也会不错。

二、APKIDE

APKIDE这是一个大佬们集成的一个APK的测试工具集,包含了常用的大部分工具,例如adb、apktool等。

基础操作

签名

前面介绍过,META-INF这个文件主要与签名、证书有关。

对APP进行签名

一、删除apk中的META-INF文件夹,然后重新zip压缩成apk
二、创建密钥存储器(已经有的可以跳过)

1
$ keytool -genkey -v -keystore 【keystore名称】 -alias 【密钥别名】 -keyalg RSA -keysize 2048 -validity 【有效天数】

android-base-keytool-1

三、使用密钥存储器对app进行签名

1
$ jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore 【keystore名称】 【apk文件】 【密钥别名】

android-base-jarsigner-1

签名成功后会重新出现META-INF文件夹

查看APP的签名

解压APK文件,使用JDK的keytool来查看META-INF/CERT.RSA文件内容

1
$ keytool -printcert -file 【证书】

android-base-keytool-2

验证APP的签名

1
$ jarsigner -verify -verbose 【apk存放路径】

android-base-jarsigner-2

查看AndroidManifest.xml文件

1
$ java -jar apktool.jar d -f s 【APK地址】

android-base-apktool-1

静态调试

一、将apk文件转化为jar文件

1
$ dex-jar.bat 【apk】

二、jd-gui.exe 可反编译jar文件

android-base-jd-gui-1

动态调试

一、将apk转换成smali代码

1
$ java -jar apktool.jar d 【APK地址】 -o out

二、修改AndroidManifest.xml中的Android:debuggable=”true”

android-base-dong-AndroidManifest-1

三、在入口处添加waitForDebugger代码进行调试等待

这里说的入口处,就是程序启动的地方,就是我们一般的入口Activity,查找这个Activity的话,方法太多了,比如我们这里直接从上面得到的AndroidManifest.xml中找到,因为入口Activity的action和category是固定的。

android-base-dong-AndroidManifest-2

找到入口Activity之后,我们直接在他的onCreate方法的第一行加上waitForDebugger代码即可,找到对应的MainActivity的smali源码:
然后添加一行代码:

1
invoke-static {}, Landroid/os/Debug;->waitForDebugger()V // 相当于java的 android.os.Debug.waitForDebugger();

android-base-dong-smali-1

四、将smali 转换成apk

1
$ java -jar apktool.jar b 【路径】 【目标路径】

五、重新签名

1
$ jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore 【keystore名称】 【apk文件】 【密钥别名】

六、安装apk

1
$ adb install 【apk】

七、android studio 导入此项目,需要配置gradle,可参考文章

路径一般为 home\.gradle\wrapper\dists\gradle-x.x-all\xxxxxxxxxxxxx\gradle-x.x

八、配置android studio调试配置,Run->Edit configurations,点击+号,新建remote类型调试器,设置Name, 修改端口号,可以选择被占用的任意端口,本次设置为62002

九、运行指定的Activity

1
$ adb shell am start -D -n com.zjhcsoft.android.eip/.MainActivity

十、查找相应的apk进程

1
$ adb shell ps | findstr eip

android-base-dong-lookps-1

十一、设置端口转发

1
$ adb forward tcp:62002 jdwp:17304

这条命令的含义可以认为是在本地62002端口与手机17304进程之间建立一条通道,当开始调试时,AS连接本地的8800端口,通过这条通道控制程序的运行

十二、设置断点

android-base-dong-duan-1

十三、调试 run->debug选择刚才新增的调试器,此时程序会断在设置的断点的行,调试器解密如下

android-base-dong-duan-2

渗透测试中注意的点

废话不说,直接上图好了。

android-base-pentest-1

总结

毕竟还只是刚入门,学的时间也不是很久,就先总结到这,之后在进行渗透测试方面的练习以及案例的补充。