被动式Web扫描器的技术实现

标签: WEB安全 | 发表时间:2016-05-04 09:21 | 作者:q6e79d
出处:http://www.freebuf.com

scan.jpg

本文原创作者:q6e79d

使用场景

在特定的情况下对单个页面进行SQL注入,XSS等漏洞进行渗透检测。例如,需要验证 http://www.example.com/query.php?id=1&uname=7ym0n,中的GET参数和POST表单。HTML代码如下:

  <html>
    <head>
        <meta charset="utf-8">
        <title>我是一个测试</title>
        <base href="/">
        <meta name="description" content="测试被动式扫描">
    </head>
    <body>
        <form action="/" id="check_post" method="POST">
            <input type="text" value="" name="mobile" id="mobile">
            <input type="submit" value="提交" name="check_submit" id="check_submit">
        </form>
    </body>
</html>

另一种场景,就是对自己访问过的网站页面进行测试,这样的应用场景下,如果手工检测,工作量太大,而且可能遗忘某方式去测试验证(比如绕狗,畸形的参数变化多端),导致准确率低,效率低。如果只需人工编写好验证方式的规则,让程序自己去进行验证,就会方便很多。而且重用性高,准确率高,效率高。

当然,有很多自动化工具提供给安全研究员使用——比如Sqlmap,Openvas等强大工具,但是我这里主要是说明场景和自己实现被动扫描。

设计原理与思路

被动模式实现方式有很多种,比如使用代理(proxy),或者(wireshark/Fiddler)抓包分析,为了能简单描述流程,采用代理方式做被动扫描,这种在某些时候可能更方便,更好维护。

                      |------------------------|
                    |      请求提交数据      |← ← ← ← ←↑
                    |------------------------|         ↑
                                ↓                      ↑
                               / \                     ↑
                              /   \                    ↑
                             /     \                   ↑
                            / 数据  \                  ↑
                            \  转发 /                  ↑
                             \     /                   ↑
                              \   /                    ↑
                               \ /                     ↑
                                ↓                      ↑
                    |------------------------|         ↑
                    |     处理URL/Body数据   |         ↑
                    |------------------------|         ↑
                                ↓                      ↑
                    |------------------------|         ↑
                    | 对GET参数和POST表单数  |         ↑
                    |      据进行篡改        |         ↑
                    |------------------------|         ↑
                                ↓                      ↑
                    |------------------------|         ↑
                    |     建立socket通信     |         ↑
                    |------------------------|         ↑
                                ↓                      ↑
                                /\                     ↑
                               /  \                    ↑
                              /    \                   ↑
                             /      \                  ↑
                            /        \                 ↑ N
                           / 提交串改 \                ↑
                           \ 后的请求 /                ↑
                            \        /                 ↑
                             \      /                  ↑
                              \    /                   ↑
                               \  /                    ↑
                                \/                     ↑
                                ↓                      ↑
                    |-------------------------|        ↑
                    |       验证结果          |        ↑
                    |-------------------------|        ↑
                                ↓                      ↑
                               /\                      ↑
                              /  \             N       ↑
                             / Y/ \  → → → → → → → → → →
                             \  N /
                              \  /
                               \/
                               ↓
                    |-------------------------|
                    |        输出结果         |
                    |-------------------------|

                            图(1) 原理图

代理(Proxy)服务器介绍

一个既做服务器又做客户端的中介程序.其用途是代表其他客户发送请求.请求在内部得到服务,或者经过一定的翻译转至其他服务器.一个代理服务器必须能同时履行本说明中客户端和服务器要求.

“透明代理”(transparent proxy)是一种除了必需的验证和鉴定外不修改请求或相应的代理.

“非透明代理”(non-transparent proxy)是一种修改请求或应答以便为用户代理提供附加服务的代理,附加服务包括类注释服务,媒体类型转换,协议简化,或者匿名滤除等.除非经明确指出,HTTP代理要求对两种代理都适用.

代理(Proxy)服务器实现

首先实现代理服务,类似nc工具一样,在请求数据后,需要截获请求的URL和数据,分析数据后进行篡改。然后发送TCP数据包。代码实现采用的nodejs,可以自行使用熟悉的语言去实现,比如C、Java、Python或Ruby。

nodejs网络操作,所以需要使用 nodejs中的 net包, var net = require('net');

需要转发端口,定义 proxy端口 var local_port = 3000;

需要解析完整的URI资源定位路径,通用URI定义:

  scheme:[//[user:password@]host[:port]][/]path[?query][#fragment]

使用一个 request_options对象存放,URI的数据结构。

  var request_options = {
    hostname: 'www.example.com',
    port: 80,
    path: '',
    method: 'GET',
    version: 0,
    headers: [],
    query: [],
    fragment: '',
    data: [],
    https:false
}

POST数据是以两个 \r\nor 0x0d 0x0a区分HTTP头和传输数据的。所以以两个换行符分割传输数据和HTTP头。

定义一个 buffer_find_body:

  function buffer_find_body(b){
    for(var i=0,len=b.length-3;i < len;i++){
        if (b[i] == 0x0d && b[i+1] == 0x0a && b[i+2] == 0x0d && b[i+3] == 0x0a){
            return i+4;
        }
    }
    return -1;
}

通过 buffer_find_body找到HTTP头结束位置,开始解析HTTP头数据,每一个头属性定义都以一个 \r\nor 0x0d 0x0a区分,定义 parse_request以换行符分割,使用正则匹配 scheme://host:port/path?query等:

  function parse_request(buffer){
    var buf = buffer.toString('utf8');
    var method = buf.split('\n')[0].match(/^([A-Z]+)\s/)[1];
    if (method == 'CONNECT'){ //支持HTTPS
        var _bufArr = buf.match(/^([A-Z]+)\s([^:\s]+):(\d+)\sHTTP\/(\d.\d)/);
        if (_bufArr && _bufArr[1] && _bufArr[2] && _bufArr[3] && _bufArr[4]){
            request_options.method = _bufArr[1];
            request_options.hostname = _bufArr[2];
            request_options.port = _bufArr[3];
            request_options.version = _bufArr[4];
            request_options.https = _bufArr[2].indexOf("https")!=-1?true:false;
        }
        return request_options;
    }
    else
    {
        var _bufArr = buf.match(/^([A-Z]+)\s([^\s]+)\sHTTP\/(\d.\d)/);
        if (_bufArr && _bufArr[1] && _bufArr[2] && _bufArr[3]){
            var host = buf.match(/Host:\s+([^\n\s\r]+)/)[1];
            if (host){
                var _op = host.split(':',2);
                request_options.method = _bufArr[1];
                request_options.hostname = _op[0];
                request_options.port = _op[1]?_op[1]:80;
                request_options.path = _bufArr[2];
                request_options.version = _bufArr[3];
                request_options.https = _bufArr[0].indexOf("https")!=-1?true:false;
                return request_options;
            }
        }
    }
    return false;
}

使用 netcreateServer方法创建服务,使用刚定义的几个函数进行数据解析:

  net.createServer(function (client){
    client.on("data",function(req){
        buf = new Buffer(data.length);
        data.copy(buf);
        var req = parse_request(buf);
        client.removeAllListeners('data');
        //建立socket发送数据,返回数据。
        //if(req)
        //  http_req(req);
    });
});

创建socket连接,请求并返回数据,修改请求头 Connection: Keep-AliveConnection: close

  function http_req(req){
    console.log(req.method+' '+req.hostname+':'+req.port);
    if (req.method != 'CONNECT'){
        var _body_pos = buffer_find_body(buf);
        if (_body_pos < 0) _body_pos = buf.length;
        var _header = buf.slice(0,_body_pos).toString('utf8');
        _header = _header.replace(/(proxy-)?connection:.+\r\n/ig,'')
                .replace(/Keep-Alive:.+\r\n/i,'')
                .replace("\r\n",'\r\nConnection: close\r\n');
        if (req.httpVersion == '1.1'){
            var url = req.path.replace(/http[s?]:\/\/[^/]+/,'');
            if (url.path != url) _header = _header.replace(req.path,url);
        }
        var _buf_1 = new Buffer(_header,'utf8');
        var _buf_2 = buf.slice(_body_pos);
        var re = new Buffer(_buf_1.length + _buf_2.length);
        _buf_1.copy(re);
        _buf_2.copy(re,_buf_1.length);
        buf = re;
        for(v in _buf_2.split('&')){
            req.data.push(v.split('='));
        }
    }
    var server = net.createConnection(req.port,req.hostname);
    server.on("data", function(data){ client.write(data); });
    if (req.method == 'CONNECT')
        client.write(new Buffer("HTTP/1.1 200 Connection established\r\nConnection: close\r\n\r\n"));
    else
        server.write(buf);

}

这样就完成了一个简单的代理服务器。现在能获取到GET和POST表单数据,剩下的需要做的就是拆分数据进行自动化渗透测试。

使用第三方渗透检测工具

使用SQLmap测试SQL注入。

使用 sqlmap需要用到系统命令行调用,加载 child_processvar exec = require('child_process').exec;http_req最后面加入

  //注意sqlmap在我系统中/usr/bin下所以直接调用。
var cmd = 'sqlmap -u "'+request_options.hostname+'" --data="'+buf.slice(buffer_find_body(buf))+'" --param-del="&" -f --banner --dbs --users';
exec(cmd, function (error, stdout, stderr) {
    console.log(stdout);
  });

需要什么策略,就加上即可,很方便的进行测试神马的,到此处基本就完成了图1中的被动扫描的整个流程,该代码没有优化,只是演示整个流程,当作生产环境需要优化。

附上 proxy代码地址,注意该源码没有实现被动扫描。

*本文作者:q6e79d,本文属FreeBuf原创奖励计划,转载须注明来自FreeBuf黑客与极客(FreeBuf.COM)

相关 [web 技术] 推荐:

Web技术整理

- Gabriel - 博客园-首页原创精华区
  Web技术或许是将来最为热门的技术之一. 这里略作一些总结,以及对各种Web技术作一些概要性介绍. (以下内容建立在我的粗略理解之上,欢迎指正).   推荐个学习Web技术比较好的网站,介绍的比较全面.   页面的展示使用超文本标记语言(HTML)来表示. 这是一种标签语言,本身不具有执行能力,只是结构化页面内容.

论Web Service 相关技术(转)

- - 互联网 - ITeye博客
摘要:随着Internet和weh技术的迅速发展,传统的分布式计算技术已经不能 很好的适用于Web环境. 正是基于这种情况,Web Service技术应运而生. Web Service是一个新概念,它的系统架构、实现技术是现有应用的面向Internet的一个延伸. Web是为了程序到用户的交互,而Web Service是为程序到程序的交互作准备,web Service已成为IT产业近几年来探索的热点课题之一.

当前最火的web开发技术

- - 博客园_新闻
2014 年 10 月 29 日,万维网联盟泪流满面地宣布,经过几乎 8 年的艰辛努力,HTML5 标准规范终于最终制定完成了,并已公开发布. HTML5 提供了一些新的元素和属性,例如 nav(网站导航块)和 footer. 这种标签将有利于搜索引擎的索引整理,同时更好的帮助小屏幕装置和视障人士使用,除此之外,还为其他浏览要素提供了新的功能,如 audio 和 video 标记.

高并发web服务技术选型

- - 崔永键的博客
主要问题集中在单个GB级数据使用何种DFS的问题上,目前还没有得到可靠的结论. 采用:nginx或 lvs: https://github.com/alibaba/LVS. 实施自己的调度策略:学习配置lvs或改造lvs或自己重写. 调研下采用hdfs还是fastdfs还是其他的:Fastdfs,ZFS,Lustre,HadoopHDFS,GlusterFS.

2010 Web前端技术趋势及总结

- bluesnail - 博客园-首页原创精华区
经过这段时间国内(百度,淘宝,新浪)及国外(Facebook,Youtube,Yahoo)各大公司的集中自曝,我们可以从中总结出2010 Web前端技术的一些趋势. 总的来说,随着后端技术(存储,并发,分布式)的成熟,各大公司已经把重点从后端架构调整/建设转移至前端(TTI时间,快速发布,带宽利用率).

2011年 5 大 Web 前端技术展望

- King - cnBeta.COM
感谢鸟人网BirdUser的投递. 刚刚过去的2010年里,我们看到了 HTML5技术的崛起,以及 CSS3的日渐成熟,经历了 Rails 3.0 新版本的推出,以及全球范围内采用的@font-face selector 技术等等一些更多的新技术和新鲜事情. 2011年将会有什么web前端技术出现或者成熟.

7 项 Web 开发者需要了解的新技术

- TONY - 博客园新闻频道
  Web 开发者需要经常更新他们的知识,学习新的技术,如果他们还想继续在 Web 开发领域混并混得还不错的话. 下面将为你展示 7 项新的 Web 开发技术,作为一个 Web 开发人员,你需要了解、熟悉并学会的技术.   目前,大量智能手机设备的涌现,同时各种不同尺寸屏幕的设备,如平板电脑之类的出现,对 Web 开发带来了前所未有的挑战,如何让 Web 页面能适应各种尺寸的屏幕让很多 Web 开发人员相当的纠结.

(转帖) 新的技术产业:Web Performance Optimization

- - kernelchina
【Appleleaf:在很多领域,无论对于中间设备还是服务器,high performance都是最大的Kill App,我们这些C工程,练好本领还有的饭碗端】. 在 O'Reilly Velocity China 2010 大会上,业界最有影响里的 Web 性能技术专家 Steve Souders 宣告 Web Performance Optimization (WPO) 时代已经到来.