伪造IP与伪造referer

在http协议中伪造ip的可能性研究

 

些日子对自定义http协议的各个数据进行了研究,对于ip伪造的问题,我当时给的建议是使用代理服务器,不过后来发现,其实可以在http协议加入一个选项,来实现一个非伪造ip的伪造ip 。如何理解呢?理由如下:~

 
一、方法概述
在http协议数据头里面加入选项“x-forward-for”,例如:“x-forward-for:202.204.76.254”,这样发送出去 的包,就是一个特殊的包,在收包方看来,这个包的意思是,一个代理服务器发过来的数据包,而这个包的真是ip是“202.204.76.254”,其实还 是实现的是三次握手,但是只不过是在发包的同时,对收包方提到了一个第三者。
 
二、试用范围
因为现在的网站类的程序如果有IP限制的话,基本上都是会检测是不是代理服务器发送的数据的,如果是代理服务器发送的数据,那么他就把IP记为这个(透明)代理服务器发送的x-forward-for的IP。
以一段较为流行的php检测ip的代码为例:
function get_ip(){ if(getenv('HTTP_CLIENT_IP')) { $gb_ip = getenv('HTTP_CLIENT_IP'); } elseif(getenv('HTTP_X_FORWARDED_FOR')) { $gb_ip = getenv('HTTP_X_FORWARDED_FOR'); } elseif(getenv('REMOTE_ADDR')) { $gb_ip = getenv('REMOTE_ADDR'); } else { $gb_ip = $_SERVER['REMOTE_ADDR']; } return $gb_ip; }
那么大家可以看到这个IP是如何伪造的了。
 
三、应对方法
当然对于网站方面,这种伪造ip的情况虽然不是很多,但是如果在投票类的程序中,当然很需要这方面的检测了,呵呵。多多检测 HTTP_CLIENT_IP吧。貌似这个还没有办法伪造?.............................
 
四、总体看法
这个办法之所以称之为非伪造ip的伪造ip,主要就是利用了现在大多数网站程序检测ip的一个漏洞。所以如果网站程序能够重新审视一下自己的ip检测办法,这个方法就会慢慢失效的。呵呵。


-------------------------

伪造 referer

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

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

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

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

-------------- 评论

精彩的处理方式。是原创吗?
obj.Option(4) = 13056;
obj.Option(6) = false;
这两个难道是 WinHttp.WinHttpRequest.5.1 方法自带的吗 ?

WinHttpReque
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值