小米浏览器地址栏欺骗漏洞原理与利用分析

0x00 概述

漏洞概述:通过构建URL使得用户地址栏显示正常的url地址,而实际访问的却是恶意网站

漏洞编号:CVE-2019-10875

测试环境: 小米Note 4

测试版本: v1.5.3

下载地址: apkmirror

影响版本: MI Browser (v10.5.6-g) and Mint Browser (v1.5.3)

0×01 漏洞原理

首先依旧是猜测一下漏洞挖掘的思路,这个实际上有点脑洞了,有可能是自己写的Fuzz脚本测试出来的,也有可能是凭借经验去测试出来。

但我们依旧可以总结最关键的点,那就是 可控数据流,我在我的文章中多次提到这个概念,只要有可控的数据流,那么就会有可能造成漏洞的地方。这里可控的入口点,自然是导航栏输入地址的地方。因此,我们先不管漏洞作者是如何挖掘,我们从最基本的入口去找即可。

我们可以使用UI Automator Viewer去查找导航栏的ID以及其调用的地方。
如下图所示,我们可以找到Resource-id,依次去找到调用的地方。

在这里插入图片描述

.field public static final url_bar:I = 0x7F0802A3
this.mUrlBar = this.findViewById(2131231395);

那么我们的任务就是搞清楚this.mUrlBar的数据调用过程,具体的同学们可以尝试着去逆向,顺着思路去学习一番。

这里给出调用链,可以供你们参考一下

at cn.tasfa.vulhookprj.HookMiBrowser$1.afterHookedMethod(HookMiBrowser.java:27)
at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:645)
at android.widget.TextView.setText(Native Method)
at com.miui.org.chromium.chrome.browser.omnibox.UrlBarViewBinder.bind(UrlBarViewBinder.java:60)
at com.miui.org.chromium.chrome.browser.omnibox.UrlBarCoordinator$1.bind(UrlBarCoordinator.java:49)
at com.miui.org.chromium.chrome.browser.omnibox.UrlBarCoordinator$1.bind(UrlBarCoordinator.java:46)
at com.miui.org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor.onPropertyChanged(PropertyModelChangeProcessor.java:75)
at com.miui.org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor.access$000(PropertyModelChangeProcessor.java:16)
at com.miui.org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor$1.onPropertyChanged(PropertyModelChangeProcessor.java:33)
at com.miui.org.chromium.chrome.browser.modelutil.PropertyObservable.notifyPropertyChanged(PropertyObservable.java:63)
at com.miui.org.chromium.chrome.browser.modelutil.PropertyModel.set(PropertyModel.java:177)
at com.miui.org.chromium.chrome.browser.omnibox.UrlBarMediator.pushTextToModel(UrlBarMediator.java:109)
at com.miui.org.chromium.chrome.browser.omnibox.UrlBarMediator.setUrlBarData(UrlBarMediator.java:97)
at com.miui.org.chromium.chrome.browser.omnibox.UrlBarCoordinator.setUrlBarData(UrlBarCoordinator.java:69)
at com.miui.org.chromium.chrome.browser.omnibox.LocationBarLayout.setOmniboxEditingText(LocationBarLayout.java:991)
at com.miui.org.chromium.chrome.browser.omnibox.NavigationBar.setDisplayTitle(NavigationBar.java:650)
at com.miui.org.chromium.chrome.browser.omnibox.NavigationBar.setUrlToPageUrl(NavigationBar.java:621)
at com.miui.org.chromium.chrome.browser.omnibox.LocationBarLayout.updateLoadingState(LocationBarLayout.java:1089)
at com.miui.org.chromium.chrome.browser.toolbar.ToolbarManager.updateTabLoadingState(ToolbarManager.java:1054)
at com.miui.org.chromium.chrome.browser.toolbar.ToolbarManager.updateCurrentTabDisplayStatus(ToolbarManager.java:1032)
at com.miui.org.chromium.chrome.browser.toolbar.ToolbarManager.refreshSelectedTab(ToolbarManager.java:987)
at com.miui.org.chromium.chrome.browser.toolbar.ToolbarManager.onNativeLibraryReady(ToolbarManager.java:745)
at com.miui.org.chromium.chrome.browser.toolbar.ToolbarManager.initializeWithNative(ToolbarManager.java:606)
at com.miui.org.chromium.chrome.browser.ChromeTabbedActivity.initializeUI(ChromeTabbedActivity.java:522)
at com.miui.org.chromium.chrome.browser.ChromeTabbedActivity.finishNativeInitialization(ChromeTabbedActivity.java:274)
at com.miui.org.chromium.chrome.browser.init.ChromeBrowserInitializer$7.initFunction(ChromeBrowserInitializer.java:243)
at com.miui.org.chromium.chrome.browser.init.ChromeBrowserInitializer$1NativeInitTask.run(ChromeBrowserInitializer.java:173)

实际上,我们找到关键的函数setDisplayTitle(Tab arg3)

void setDisplayTitle(Tab mTab) {
    int id;
    Resources mResource;
    if(mTab == null) {
        this.setUrlBarTextEmpty();
        return;
    }

    if(!this.isUrlBarFocused()) {
        if(this.mState != State.STATE_NORMAL) {
        }
        else {
            String url = mTab.getUrl();
            this.mUrlBar.setTag(url);
            if(mTab.isHome()) {
                this.setUrlBarTextEmpty();
                EditText editText = this.mUrlBar;
                if(this.mIsNightMode) {
                    mResource = this.getResources();
                    id = 2131034889;
                }
                else {
                    mResource = this.getResources();
                    id = 2131034886;
                }

                int color = mResource.getColor(id);
                editText.setHintTextColor(color);
            }
            else {
                if(TextUtils.isEmpty(((CharSequence)url))) {
                    this.setOmniboxEditingText(mTab.getTitle());
                    goto label_39;
                }

                String searchKeyWords = this.pickSearchKeyWords(url);  // 关键点就是这里,也是造成漏洞的关键原因
                if(this.isOnSearchResultPage(searchKeyWords)) {
                    this.setOmniboxEditingText(searchKeyWords);
                    goto label_39;
                }

                this.setOmniboxEditingText(this.stripUrl(url));
            }

        label_39:
            this.mUrlBar.setSelection(0);
            return;
        }
    }
}

接下来我们查看下函数pickSearchKeyWords

private String pickSearchKeyWords(String url) {
    String searchKeyword = null;
    if(url != null) {
        if(this.getCurrentTab() == null) {
        }
        else {
            url = this.getCurrentTab().getUrl();
            if(TextUtils.isEmpty(((CharSequence)url))) {
                return searchKeyword;
            }
            else {
                Uri uri = Uri.parse(url);
                String host = uri.getHost();
                if(TextUtils.isEmpty(((CharSequence)host))) {
                    return searchKeyword;
                }
                else {
                    searchKeyword = "";
                    String[] engineLabels = this.getSearchEngineLabels();
                    if(engineLabels != null && engineLabels.length > 0) {
                        int length = engineLabels.length;
                        int i;
                        for(i = 0; i < length; ++i) {
                            String searchEngine = engineLabels[i];
                            if(TextUtils.isEmpty(((CharSequence)searchEngine))) {
                            }
                            else if(host.contains(searchEngine.trim().toLowerCase())) {
                                searchKeyword = SearchEngineSwitchUtil.getInstance(this.mContext).getQueryParameterNameForSearchTermsMap(searchEngine);
                            }
                        }
                    }

                    if(searchKeyword == null) {
                        searchKeyword = "";
                    }

                    String keyWord = uri.getQueryParameter(searchKeyword);
                    if((TextUtils.isEmpty(((CharSequence)searchKeyword))) || (TextUtils.isEmpty(((CharSequence)keyWord)))) {
                        if(host.contains("yahoo.com")) {
                            keyWord = uri.getQueryParameter("p");
                        }
                        else if(host.contains("yandex.ru")) {
                            keyWord = uri.getQueryParameter("text");
                        }
                        else {
                            keyWord = uri.getQueryParameter("q");  // 也就是这里导致了漏洞
                        }
                    }

                    return keyWord;
                }
            }
        }
    }

    return searchKeyword;
}

0×02 漏洞利用

通过构造如下PoC:

http://www.tasfa.cn/?q=www.baidu.com

关键点 /?q=

地址栏显示的是www.baidu.com的地址,实际上访问的是www.tasfa.cn的地址,从而造成了地址栏地址欺骗的效果。

效果如下:

在这里插入图片描述

0×03 漏洞防御

  1. 作为个人用户,对于来历不明的链接,尽量不要进行点击操作
  2. 当进行一些敏感操作时,尽量手动输入地址,如手动输入银行地址,不要点击或复制他人提供的链接
  3. 作为开发者,应该在关键的地方点,进行代码审计,防止出现类似的漏洞。

0×04 参考

Unpatched Flaw in Xiaomi’s Built-in Browser App Lets Hackers Spoof URLs

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值