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

作者:快乐笛子 来源:快乐笛子blog 时间:2010-08-24 18:28:00 

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

无意间发现公司内部项目使用的 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 也监测不到,看来确实是比较底层的东西。

--------------------------- * 的分割线------------------------

既然可以用它来伪造所有 http 请求的 header,那 Cookies、Sessionid 自然也就可以得到并传递了。下面是实战代码,用命令行登录博客园,共三次请求,第一次请求获取表单的 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("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 对表单的安全性无任何用处。

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

标签:WinHttp.WinHttpRequest,referer,伪造
0
投稿

猜你喜欢

  • 浅谈品牌的视觉识别

    2009-07-03 12:28:00
  • 用户研究角度看设计(1)“复制链接”的故事

    2008-12-26 17:48:00
  • 适合所有表的添加、删除、修改的函数

    2008-04-15 15:29:00
  • 网页的栅格系统设计

    2008-09-19 21:13:00
  • 动态生成的IFRAME设置SRC时的,不同位置带来的影响

    2008-03-06 13:56:00
  • css学习笔记: 重置默认样式 css reset

    2009-07-19 14:30:00
  • ASP检测服务器相关的一些代码

    2008-01-25 19:20:00
  • 新手入门:防范SQL注入攻击的新办法

    2009-03-11 15:14:00
  • sina和265天气预报调用代码

    2007-11-19 13:32:00
  • 移动网站开发:标记语言

    2010-06-08 13:42:00
  • JavaScript for: i++ vs i–

    2010-06-24 21:42:00
  • 如何使用图片精灵优化你的网站

    2009-07-21 11:35:00
  • 陌生网页交互行为分析(1)——奇怪的关闭按钮

    2009-01-08 12:22:00
  • asp如何阻止别人非法链接你网站的图片?

    2010-07-11 21:01:00
  • 成为一个顶级设计师的第二准则

    2008-04-01 09:41:00
  • SQL语句操作主从关系表

    2011-06-19 13:19:05
  • MYSQL数据库表设计与优化(一)

    2010-10-25 19:50:00
  • 分享我们的select控件设计过程

    2009-06-16 18:04:00
  • H1标签的定义

    2008-07-29 12:43:00
  • 归纳万恶IE6的HACK方法

    2010-02-04 17:17:00
  • asp之家 网络编程 m.aspxhome.com