使用 WinHttpRequest 伪造 Referer (附实战代码)

首先说明,伪造访问来路不是什么光明正大的事情,目的就是为了欺骗服务器。本来觉得给 XMLHTTP 对象增长一个 Referer 的header 就能够,结果却没有任何做用,改用 ServerXMLHTTP 也如此。json

无心间发现公司内部项目使用的 paypal 扣款程序里面有 WinHttp.WinHttpRequest.5.1 对象,它负责把客户的信用卡信息提交到 paypal 的服务器,看来是一个核心的远程访问方法,google一下发现它竟然用能够成功伪造全部 http 请求的 header 信息!下面的代码经过伪造 referer 的值,伪装从百度首页提交一个表单到指定的 url 去:浏览器

var url = "http://www.aspxhome.com"; 
var param = "name=david&age=30"; 
var obj = new ActiveXObject("WinHttp.WinHttpRequest.5.1"); 
obj.Open("POST", url, false); 
obj.Option(4) = 13056; 
obj.Option(6) = false; //false能够不自动跳转,截取服务端返回的302状态。 
obj.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); 
obj.setRequestHeader("Referer", "http://www.baidu.com"); 
obj.Send(param); 
WScript.Echo(obj.responseText);

保存为 xxx.js 文件,在命令行中运行 cscript.exe xxx.js。安全

 

从msdn得知,WinHttp.WinHttpRequest.5.1 是 msxml 4.0 的底层对象,也就是说 XMLHTTP/ServerXMLHTTP 也是在它的基础上封装而来。用 WinHttpRequest 发的请求,连 Fiddler 也监测不到,看来确实是比较底层的东西。服务器

---------------------------邪恶的分割线------------------------cookie

既然能够用它来伪造全部 http 请求的 header,那 Cookies、Sessionid 天然也就能够获得并传递了。下面是实战代码,用命令行登陆博客园,共三次请求,第一次请求获取表单的 VIEWSTATE 和 EVENTVALIDATION,第二次带帐户登陆,第三次带Cookie访问其首页:app

//封装成远程访问的函数 
function RemoteCall(method, url, param, header){ 
    var obj = new ActiveXObject("WinHttp.WinHttpRequest.5.1"); 
    obj.Open(method||"GET", url, false); 
    obj.Option(4) = 13056; 
    obj.Option(6) = false; 
    if(method=="POST"){ 
        obj.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); 
    } 
    if(header){ 
        for(var key in header){ 
            if(key=="Cookie"){//根据 MSDN 的建议,设置Cookie前,先设置一个无用的值 
                obj.setRequestHeader("Set-Cookie", "string"); 
            } 
            obj.setRequestHeader(key, header[key]); 
        } 
    } 
    obj.Send(param); 
    return obj; 
} 
//第一次远程访问博客园的登陆入口 
var url = "http://passport.cnblogs.com/login.aspx"; 
var objFirst = RemoteCall("GET", url, null); 
  
//取得 viewstate 与 eventvalidation 
var viewstate = objFirst.responseText.match(/id="__VIEWSTATE" value="(.*?)" \/>/)[1]; 
var eventvalidation = objFirst.responseText.match(/id="__EVENTVALIDATION" value="(.*?)" \/>/)[1]; 
  
//输入本身的帐户与密码 
var username = ""; 
var password = ""; 
var param = "" 
+ "__VIEWSTATE="+encodeURIComponent(viewstate)  
+ "&__EVENTVALIDATION="+encodeURIComponent(eventvalidation)  
+ "&tbUserName="+username 
+ "&tbPassword="+password 
+ "&btnLogin="+encodeURIComponent("登  录"); 
  
var objSecond = RemoteCall("POST", url, param); 
  
//登陆成功后服务器执行 Response.Redirect 跳转,即向客户端发送了 302 状态代码 
WScript.Echo(objSecond.status); //302即登陆成功, 若是是200,则登陆失败,页面没有跳转 
  
//带上登陆成功后的cookie,再次访问其首页 
var json = {"Cookie": objSecond.getResponseHeader("Set-Cookie")}; 
var objThird = RemoteCall("GET", "http://www.cnblogs.com", null, json); 
WScript.Echo(objThird.responseText);

 

上面的代码其实已经有必定恶意,我只为证实使用 WinHttpRequest 确实能够模拟浏览器发送请求,服务端也没法区别是从浏览器来的,仍是从命令行来的。这证实到一点,从客户端提交来的任何数据都不可信,由于发送的 http 数据包不但表单值能够修改,连数据包的header均可以随意修改。同时也说明,使用 VIEWSTATE 对表单的安全性无任何用处。函数

引用一张著名的漫画,在互联网上,没有人知道你是一条狗。在服务端,没有人知道你是从命令行发送出来的。 google

相关文章
相关标签/搜索