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 漏洞防御
- 作为个人用户,对于来历不明的链接,尽量不要进行点击操作
- 当进行一些敏感操作时,尽量手动输入地址,如手动输入银行地址,不要点击或复制他人提供的链接
- 作为开发者,应该在关键的地方点,进行代码审计,防止出现类似的漏洞。
0×04 参考
Unpatched Flaw in Xiaomi’s Built-in Browser App Lets Hackers Spoof URLs