Challenge Description
Welcome to the Android Insecure WebView Challenge! This challenge is designed to delve into the complexities of Android’s WebView component, exploiting a Cross-Site Scripting (XSS) vulnerability to achieve Remote Code Execution (RCE). It’s an immersive opportunity for participants to engage with Android application security, particularly focusing on WebView security issues.
Solution
As usual, I started by performing static analysis to get some understanding of the application.
Static Analysis
I started out by reading the AndroidManifest.xml
code after decompiling using jadx-gui
.
|
|
There is only MainActivity
activity which is exported and it has this intent filter where it accept URI data postboard://postmessage
.
|
|
Moving on to the main activity code, there’s a function for setting up WebView and it has JavaScript enabled. As for the handleIntent
function, it basically accept intent and use the data as message after base64 decode and the message will be used in WebView while executing the JavaScript function WebAppInterface.postMarkdownMessage
. If there’s an error, it will instead execute the JavaScript function WebAppInterface.postCowsayMessage
.
|
|
Looking at both the JavaScript function, the postMarkdownMessage
function has a set of rules where it only allows specific HTML tag to be rendered in the WebView. The HTML that might be useful is <img>
and <a>
as this 2 could potentially trigger XSS. Moving on to postCowsayMessage
, it will run CowsayUtil.INSTANCE.runCowsay
function.
|
|
Looking into the runCowsay
function, it basically interacting with shell command which I could inject my command easily since it is not sanitized. Now that I have some basic understanding, I tried to perform dynamic analysis to check if its correct.
Dynamic Analysis
Based on my previous information, I will need to provide a URI postboard://postmessage
and following with the message. The message will need to be base64 encoded. I started off by create a simple xss payload <a href="javascript:alert(1)">yeeehar</a>
and inject to the application.
This method allows me to perform XSS but it will need me to click the hyperlink. I continue by crafting the payload to trigger the vulnerable function, <a href="javascript:WebAppInterface.postCowsayMessage('hi;id');location.reload();">yeehar</a>
I managed to perform RCE by triggering the function and perform simple command injection. I then proceed to write a simple POC app to perform the attack in Kotlin. Do note that it is also possible to use img
tag and it could trigger the function without performing any click.
|
|
Things I learned from this challenge
- Source code review to find potential RCE and XSS