tqsheng

go.....
随笔 - 366, 文章 - 18, 评论 - 101, 引用 - 0
数据加载中……

js伪造Referer来路

js伪造Referer来路  

2014-06-30 21:33:23|  分类: 默认分类|举报|字号 订阅

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

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

1

2

3

4

5

6

7

8

9

10

var url = "http://www.yourtarget.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 也监测不到,看来确实是比较底层的东西。

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

既然可以用它来伪造所有 http 请求的 header,那 CookiesSessionid 自然也就可以得到并传递了。下面是实战代码,用命令行登录博客园,共三次请求,第一次请求获取表单的 VIEWSTATE  EVENTVALIDATION,第二次带账户登录,第三次带Cookie访问其首页:

//封装成远程访问的函数  

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("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 对表单的安全性无任何用处。

posted on 2015-02-20 17:23 tqsheng 阅读(2863) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理