I haven’t had much luck with bug bounties. At the time of writing, all of my submissions except one have been duplicates, which can be really demotivating. But instead of giving up, I decided to shift my focus over to learning how to analyze mobile applications, particularly Android APKs. Since then, I’ve glanced through a number of APKs while looking for low hanging fruit. With only a minor understanding of the mobile world, I looked through previously disclosed bounties in order to see what kind of things I should be looking for. This sent me down a spiral of activities, intents, providers, services and other things I quickly began to grasp. After going through a majority of the APKs listed on HackerOne with little success, I decided to go do what most guys do when they’re bored: go look at porn.
The Setup
Phone: Samsung Galaxy Tab A (SM-T350) OS: Android Marshmallow (6.0.1) IDE: Android Studio 3.4
The Target
The initial target was intended to be the PornHub mobile application. However, what I came across was malware posing as Pornhub, and as a result, I ended up performing some malware analysis as opposed to looking for vulnerabilities to exploit. While I have access to the Play Store on my device, I was looking through a lot of APKs that could not be found there (like banking apps for other countries). For those apps, I was using APKPure to download a copy after ensuring the package name was correct and the version of the app was as recent as possible. For whatever reason, I didn’t originally validate the “PornHub” app when I downloaded and installed it on my device.
My bad.
Initial Analysis
In what I assume is an effort to maintain legitimacy, PornHub hosts their APK on their website. This is likely due to the history of trojan horse apps found on the Google Play Store. Here is a summary of what the official app looks like as opposed to the fake app according to the Mobile Security Framework:


The random package name and main activity name were pretty suspicious, as neither reference PornHub. A quick check on VirusTotal shows that at least AV vendor determined the APK to be malicious.

So let’s get into what makes this malicious.
Exported Activities
An Android activity is basically any page that shows up on in an app. It could be a launch page, login page, some sort of webview, etc. Sometimes, activities are exported so that another application can interact with them. This is one of the first things I’ve learned to look at when analyzing APKs. The Mobile Security Framework (MobSF) reported 12 external activities:
com.xxconnect.mask.MainActivity.whatsapp
com.xxconnect.mask.MainActivity.twitter
com.xxconnect.mask.MainActivity.snapchat
com.xxconnect.mask.MainActivity.pinterest
com.xxconnect.mask.MainActivity.messenger
com.xxconnect.mask.MainActivity.instagram
com.xxconnect.mask.MainActivity.facebook
com.xxconnect.mask.MainActivity.chrome
com.xxconnect.mask.MainActivity.yonote
com.xxconnect.mask.MainActivity.bumail
com.xxconnect.mask.MainActivity.original
According to the AndroidManifest.xml, all of these activities were actually disabled and were just aliases
for
com.xxconnect.mask.MainActivity
. And while this particular activity was not
exported,
com.xxconnect.mask.MainActivity.original
was an exported activity meaning that ultimately, any application
could interact with com.xxconnect.mask.MainActivity
.
MainActivity
One of the first things to look for when checking an exported Activity is the onCreate
function which runs
when the Activity is created. Shout out to sensible naming.
|
|
This is a lot to look through, but the only thing that really matters is the highlighted line 65 initWebView()
which suggests that the main activity directly launches the WebView that is presented to the user. This turns
out to be the case (as indicated by this
) and we can just look at the WebView function to see what kind of
settings the WebView has.
|
|
Javascript Interfaces
The immediate standout is the initWebViewJavascriptInterface()
call. It turns out that there is a way for
Javascript to communicate with functions written in the java classes, and that is with a Javascript Interface. This means
that any webpage that is aware the application is calling it can interact directly with the code by the
interface name.
private final void initWebViewJavascriptInterface() {
this.addWebViewJavascriptAppInterface();
this.addWebViewJavascriptBrowserInterface();
this.addWebViewJavascriptTrackerInterface();
}
There’s three interfaces implemented but I focused on the what appeared to be the main one, offering the
most functionality. Within the MainActivity, a JS interface named app
is created. What does this interface do?
Luckily, the malware author didn’t obfuscate any of the function names so here are some important ones:
checkUpdate()
: Allows the attacker to update the app.downloadFile()
: Overloaded method. Allows the attacker to download files to the device. Optional arguments include opening file when download complete.downloadVideo()
: Allows the attacker to download videos to the device.installPackage()
: Allows the attacker to install additional packages.openFile()
: Allows the attacker to open a file.openPackage()
: Allows the attacker to open an application.openUri()
: Allows an attacker to open a URI on the device.openUriWithChromeCustomTabs()
: Allows an attacker to open up Chrome tabs.showLongToast()
: Allows the attacker to create an Android toast message that shows up at the bottom of the screen.showSnackbar()
: Allows the attacker to create a Snackbar popup.startActivityWithAction()
: Allows the attacker to open exported Activities of other applications.startActivityWithComponent()
: Allows the attacker to open exported Activities of other applications.uninstallPackage()
: Allows the attacker to uninstall packages.
There’s several other functions used for enumeration of the device, but these are the primary ones that enable malicious actions. Of course, since this Activity is exported, that means we can do this ourselves!
Exploiting the MainActivity
The terminology used to describe how one application talks to another is called an “intent”. Therefore, in order to manipulate this malware, we must create an intent of our own to send. Within the Main Activity code posted earlier, there’s some key information we need in order to manipulate the app.
@Override
protected void onCreate(@Nullable Bundle object) {
//.. (snipped for brevity)
object = this.getIntent().getStringExtra("url");
boolean bl = object == null || StringsKt.isBlank((CharSequence)object);
if (bl) {
object = this.getAppAdapter().getStartPageUrl();
}
this.isStartPage = this.isStartPage((String)object);
this.isVideoPage = this.getAppAdapter().isVideoPage((String)object);
this.setSupportActionBar((Toolbar)this._$_findCachedViewById(R.id.toolbar));
//.. (snipped for brevity)
this.initSearchEditText();
this.initWebView();
this.setCookies((String)object);
if (this.isStartPage) {
//.. (snipped for brevity)
((NestedWebView)this._$_findCachedViewById(R.id.webView)).loadUrl((String)object);
} else {
this.hideSplashView();
this.overridePendingTransition(2130771987, 2130771989);
((NestedWebView)this._$_findCachedViewById(R.id.webView)).loadUrl((String)object);
}
//.. (snipped for brevity)
}
We can see that the onCreate
function references the calling intent and grabs a string named url
, then later
calls loadUrl
with the URI as the parameter. This is the concept of an “Extra”. An Extra is simply a way to
provide additional information with the intent. In this case, we provide a string with an Extra designated as
url
.
I have an Android Studio APK project that I’ve been using to perform these kinds of tests. While setting up the
project is outside the scope of this post, it’s great that Android Studio does things like import classes for
you when you reference them. For example, if I make an Intent
object, Android Studio will automatically
import android.content.Intent
. So what does the exploit look like? It’s literally just an Intent object with
parameters set.
|
|
That’s all there is to it (in this case anyway). This is a good time to mention when the app normally opens, it
connects to the malicious domain with a redirect to PornHub in the URL parameters (i.e
https://MALICIOUS.COM/pages/ads/ad.html?r=https://www.pornhub.com
). However, since we passed in the URI extra,
it attempts to open the page specified instead. This is a very basic implementation of what appears to be a
common Android app vulnerability.
What the app normally looks like on launch:
Here’s what it looks like redirecting to my own URL. Unfortunately, the page does not render text for whatever reason but since it’s HTML and Javascript is enabled, I can perform some XSS with the following payload:
<html>
<head>
<title>Daddycocoaman's Test</title>
</head>
<body>
<script>
alert('This is XSS!');
</script>
</body>
</html>
Exploiting Javascript Interfaces
Exploiting the app
Javascript Interface is as simple as calling the object in Javascript. The functions that
are included in the app are the same functions that we can call via JS! This also appears to be a common
vulnerability in Android applications. Let’s add some of that functionality to the HTML page:
|
|
First, we determine if the app
interface exists. If it does, then we will show a Toast message with the
specified text. Next, we determine if the device has the Paypal Here app installed and if it does, we get an
alert. Since all of these conditions are true, we get the following result:
There’s a lot of actions the app allows through the Javascript Interface implementation but this should give a general idea of how easy it is to exploit them.
Conclusion
So there you have it: how my bug bounty hunt turned into malware analysis. There’s a lot more than this application does including dropping native ARM libraries, linking to additional malicious URLs, and even prompting the user to download additional malware.
The moral of the story is: If it’s not from the official website, it’s the wrong porn.
I’m gonna go set my Samsung tablet on fire now. Or maybe it’ll do it for me. Who knows?