漏洞扫描器之phantomJS获取ajax请求

程序自动化扫描漏洞,需要从页面中解析出有效url及其参数,然后加上payload进行漏洞验证

从页面中可以获得的有三类请求

1、a标签的href属性、iframe的src属性、form的action属性

2、js动态发出的ajax请求(前后端分离架构中,自动发出的ajax请求)

3、人机交互(onclick、onmouseover等)产生的请求

本篇关注第2类请求,借助phantomJS(一种无界面的模拟浏览器环境)的网络监听功能,获取页面自动发出的ajax请求


一、phantomJS环境搭建

wget下载http://phantomjs.org/download.html中对应版本

比如centos 64位:

wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2

解压tar xvf phantomjs-2.1.1-linux-x86_64.tar.bz2即可

随服务器环境而变,可能需要安装bzip2,fontconfig : yum -y install bzip2 fontconfig

然后切换目录 cd phantomjs, ,执行./bin/phantomjs -v输出版本信息,环境即搭建成功


二、编写js调用phantomJS的onResourceRequested功能

可以多参考phantomJS官方实例:http://phantomjs.org/examples

计划实现的功能:根据输入的url,获取页面中ajax请求,保存到相应文件

代码如下(get_ajax.js)//运行phantomjs get_ajax.js www.baidu.com baidu.txt

"use strict";
var page = require('webpage').create(),
    system = require('system'),
    fs = require('fs'),
    address;


if (system.args.length !== 3) {
    console.log('Usage: get_ajax.js www.douyu.com file');
    phantom.exit(1);
} else {
	if(system.args[1].indexOf('http') !=0){
		page.address = 'http://'+system.args[1];
	}else{
		page.address = system.args[1];
	}
    
    page.urls = '';
    page.onResourceRequested = function (req) {
        //console.log('requested: ' + JSON.stringify(req, undefined, 4));
        if (req.url.indexOf('.js') != -1 || req.url.indexOf('.png') != -1 ||
        	req.url.indexOf('.jpg') != -1 || req.url.indexOf('.gif') != -1 ||
        	req.url.indexOf('.woff') != -1 || req.url.indexOf('.css') != -1) return;


        if(req.method == 'POST'){
        	//其他格式json等 忽略
        	var page_url = req.url+'{postreq}?';
             if(req.postData){
                var q = req.postData.split('&');
                for(var i in q){
                    if(q[i].indexOf('=') != -1){
                        page_url += q[i].split('=')[0] + '=&';
                    }else{//json or other
                        page_url += btoa(req.postData) + '{json}&';
                    }
                }
            }
        	page_url = page_url.substring(0, page_url.length-1)
        	page.urls += page_url + "\n";
        	console.log(page_url)
        }else{
        	if(req.url.indexOf('?') != -1){
	        	var page_url = req.url.split('?')[0]+'?';
	        	var q = req.url.split('?')[1];
	        	q = q.split('&');
	        	Object.keys(q).forEach(function(key){
	        		page_url += q[key].split('=')[0] + '=&';
	        	});
	        	page_url = page_url.substring(0, page_url.length-1)
	        	page.urls += page_url + "\n";
	        	console.log(page_url)
	        }
        	
        }
    };


    page.onResourceReceived = function (res) {
        //console.log('received: ' + JSON.stringify(res, undefined, 4));
    };
    page.onLoadFinished = function(res) {
	    //console.log("page.onLoadFinished");
	};




    page.open(page.address, function (status) {
        if (status !== 'success') {
            console.log('FAIL to load the address');
        }
        setTimeout(function(){try {
        		fs.write(system.args[2], page.urls, 'a');
	        } catch(e) {
	        	console.log(e);
	        };
	        phantom.exit()},
        30000);
    });
}

有几点提示:

1、page.onLoadFinished事件发生之后,然后会有ajax请求发出。所以使用setTimeout等待一会儿再退出程序

2、这里可输入域名,url,去除掉图片、js、css、字体请求后,剩下的请求保存在”域名.txt“文件

3、参数值均已被清空(方便url去重)。post请求数据格式多变(json、xml、multiparty-form等),这里简单处理,非常规格式直接使用btoa转base64保存


ps:

1、人机交互产生的请求,自动化测试中有盲点击技术,待研究

2、是否监听websocket网络连接未知,漏洞扫描器不打算处理此类请求

3、使用代理抓请求包、获取测试服务器网络访问日志是两种更有效获取请求url的方式

猜你喜欢

转载自blog.csdn.net/haoren_xhf/article/details/80665663