`
月影无痕
  • 浏览: 1009613 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

构造HTTP请求Header实现“伪造来源IP”

 
阅读更多

构造 HTTP请求 Header 实现“伪造来源 IP

 

在阅读本文前,大家要有一个概念,在实现正常的TCP/IP 双方通信情况下,是无法伪造来源 IP 的,也就是说,在 TCP/IP 协议中,可以伪造数据包来源 IP ,但这会让发送出去的数据包有去无回,无法实现正常的通信。这就像我们给对方写信时,如果写出错误的发信人地址,而收信人按信封上的发信人地址回信时,原发信人是无法收到回信的。

 

一些DDoS 攻击,如 SYN flood,  就是利用了 TCP/ip 的此缺陷而实现攻击的。《计算机网络》教材一书上,对这种行为定义为“发射出去就不管”。

 

因此,本文标题中的伪造来源IP 是带引号的。并非是所有 HTTP 应用程序中存在此漏洞。

 

那么在HTTP 中, " 伪造来源 IP",  又是如何造成的?如何防御之?

在理解这个原理之前,读者有必要对HTTP 协议有所了解。 HTTP 是一个应用层协议,基于请求 / 响应模型。客户端(往往是浏览器)请求与服务器端响应一一对应。

 

请求信息由请求头和请求正文构成(在GET 请求时,可视请求正文为空)。请求头类似我们写信时信封上的基本信息,对于描述本次请求的一些双方约定。而请求正文就类似于信件的正文。服务器的响应格式,也是类似的,由响应头信息和响应正文构成。

 

为了解这个原理,可使用Firefox Firebug,  IE 浏览器插件 HTTPwatch 来跟踪 HTTP 请求 / 响应数据。

 

本文中,以HTTPwatch 为例说明之。安装 httpwatch 并重启 IE 浏览器后, IE 的工具栏上出现其图标,点击并运行 Httpwatch,  就会在浏览器下方显示出 HTTPWatch 的主界面。

 


点击左下角红色的“Record ”按钮,并在地址栏输入 www.baidu.com,  等页面打开后,选中一个请求,并在下方的 tab 按钮中选择“ Stream ”,如图:

 


左边即是请求数据,右边即是服务器响应数据。左边的请求头均以回车换行结束,即“\r\n 最后是一个空行(内容为 \r\n , 表示请求 header 结束。而请求 header 中除第一行外,其它行均由 header 名称, header 值组成,如  Accept-Encoding: gzip, deflate header 名称与值之间有冒号相隔,之间的空格是可有可无的。

 

那么,在HTTP 应用程序中,如何取得指定的请求 header 信息呢?这里使用 PHP 语言为例说明。对所有客户端请求 header, PHP 程序中取得其值的方式如下:
$_SERVER['HTTP_ HEADER_NAME '] 

HEADER_NAME应该以换成对应的 header 名称,此项的规律是:全大写,连接线变成下划线。比如要取得客户端的 User-Agent 请求头,则使用 $_SERVER['HTTP_USER_AGENT'],  掌握这个规律,即可达到举一反三的效果。如要取得 COOKIE 信息,则使用 $_SERVER['HTTP_COOKIE'] 即可。也就是说, $_SERVER 数组中,以 HTTP 开头的项均属于客户端发出的信息。

 

回归到HTTP 应用程序层,来源 IP 的重要性不言而语,例如表单提交限制,频率等等均需要客户端 IP 信息。使用流行的 Discuz X2.5  的文件 source/class/discuz/discuz_application.php 中的代码片断:

private function _get_client_ip() {

$ip = $_SERVER['REMOTE_ADDR'];

if (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {

$ip = $_SERVER['HTTP_CLIENT_IP'];

 

如以下的JSP代码片段:
public String getIpAddr(HttpServletRequest request) {
       String ip = request.getHeader("x-forwarded-for");
       if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          ip = request.getHeader("Proxy-Client-IP");
       }
       if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          ip = request.getHeader("WL-Proxy-Client-IP");
       }
       if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          ip = request.getRemoteAddr();
       }
       return ip;
}

 

以上代码片段即是获取客户端IP ,这段程序会尝试检查 HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR,  根据之前的原理说明,以 HTTP_ 开头的 header,  均属于客户端发送的内容。那么,如果客户端伪造 Client-Ip, X-Forward-For ,不就可以欺骗此程序,达到“伪造 IP ”之目的?

 

那么如何伪造这项值?如果你会写程序,并了解HTTP 协议,直接伪造请求 header 即可。或者使用 Firefox Moify Headers 插件即可。  



按图示顺序号输入或点击相应按钮。Start 按钮这里变为红色 Stop ,说明设置成功。

这时,如果我们使用Firefox 访问其它网站,网站服务器就针接收到我们伪造的 X-Forward-For,  值为 1.1.1.1

 

严格意义上讲,这并不是程序中的漏洞。Discuz 为了保持较好的环境兼容性 ( 包含有反向代理的 web 服务器环境,如 nginx 作为 php fastcgi 的前端代理 ) ,如此处理是可以理解的。那么如何处理,才能杜绝这个问题呢?

 

服务器重新配置X-Forward-For 为正确的值。

 

如对典型的nginx + php fastcgi 环境( nginx php fastcgi 是否位于同一机器,并不妨碍此问题的产生) , nginx php fastcig 进程直接通信:



 

切记,$_SERVER['REMOTE_ADDR']  是由 nginx 传递给 php 的参数,就代表了与当前 nginx 直接通信的客户端的 IP (是不能伪造的)。

 

再比如,存在中间层代理服务器的环境:

 

 

这种情况下,后端的HTTP 文件服务器上获取取的 REMOTE_ADDR 永远是前端的 squid/varnish cache 服务器的通信 IP

 

服务器集群之间的通信,是可以信任的。我们要做的就是在离用户最近的前端代理上,强制设定X-Forward-For 的值,后端所有机器不作任何设置,直接信任并使用前端机器传递过来的 X-Forward-For 值即可。

 

即在最前端的Nginx 上设置:

location  ~  ^/static {

proxy_pass  ....;

proxy_set_header X-Forward-For $remote_addr ;

}

 

如果最前端(与用户直接通信)代理服务器是与php fastcgi 直接通信,则需要在其上设定:

location ~ "\.+\.php$" {

fastcgi_pass localhost:9000;

fastcgi_param  HTTP_X_FORWARD_FOR  $remote_addr;

}

记住,$remote_addr nginx 的内置变量,代表了客户端真实(网络传输层) IP 。通过此项措施,强行将 X-Forward-For 设置为客户端 ip,  使客户端无法通过本文所述方式“伪造 IP ”。

 

LVS转发环境下,是否存在此问题?

LVS工作在网络层,不改变来源及目标 IP ,更不可能更改应用层信息,故不存在此问题。如果有任何疑惑或需要帮助,请联系笔者信箱 zhangxugg@163.com。

 

存在此问题的程序:

所有版本的discuz, phpcms, phpwind, dedeCMS 。以及其它可能未知的程序。

 

例如使用Modify Headers 进行 IP 伪装之后再登录 bbs.phpchina.com ,我们查看自己的个人资料中的“上次访问 IP ”就发现就是我们伪装的数据。

 

可以说,互联网上存在此漏洞的网站实在是太多了。试试便知。那么对于存在此漏洞,并且使用IP 作限制的网站,一定要小心。

 

 

  • 大小: 60.4 KB
  • 大小: 90.1 KB
  • 大小: 45.6 KB
  • 大小: 38.5 KB
  • 大小: 39.7 KB
  • 大小: 28.8 KB
5
8
分享到:
评论
9 楼 w520hua 2012-08-28  
相当好了,亲自测试了下,不得不说有一套
8 楼 wxqhbw2008 2012-08-28  
7 楼 lenxen 2012-08-28  
写的不错,学习了
6 楼 greatwqs 2012-08-28  
构造Http 请求头来设置X-Forwarded-For
一般Nginx是通过这样的方式获得客户端IP.再用X-Forwarded-For参数传到PHP,java的后台,程序再获得X-Forwarded-For参数.

但是不知道nginx会不会把得到的IP 覆盖到 Http request Header中的X-Forwarded-For上面去, 没有测试过.

但是对于操作系统层面上的限制IP可能还是不能攻破.
如linux里面iptables屏蔽IP
5 楼 flashing 2012-08-27  
必须目标程序是跑在反向代理下吧
而且如果不是链式的反向代理,读X-Real-Ip也不可能出问题
不过如果真是链式的,倒是真有可能伪造一个,至少程序不好分辨。
4 楼 瓶鱼跃 2012-08-27  
我也想知道jsp怎么伪造··
3 楼 wasw100 2012-08-27  
应该是: X-Forwarded-For
2 楼 天之南极 2012-08-27  
jsp也是可以伪造的,原来跟这个差不多
1 楼 string2020 2012-08-27  
jsp怎么伪造。。。

相关推荐

    第二篇:Bypass X-WAF SQL注入防御(多姿势)1

    rules目录中的whiteip.rule的默认配置为[{"Id":74,"RuleType":"whiteip","RuleItem":"8.8.8.8"}],IP白名单规则默认IP为8.8.8.8,因此我们可以通过构造HTTP请求Header实现伪造IP来源为8.8.8.8,从而绕过x-waf的所有...

    PHP curl伪造IP地址和header信息代码实例

    本文将深入探讨如何使用PHP cURL来伪造IP地址和HTTP头信息,并解释其工作原理。 通常,服务器可以通过`$_SERVER`全局数组来获取客户端的IP地址和其他相关信息。有两个重要的变量用来获取IP地址:`$_SERVER['REMOTE_...

    PHP伪造来源HTTP_REFERER的方法实例详解

    通过PHP的fsockopen函数,可以创建一个到指定服务器的套接字连接,然后发送包含伪造HTTP_REFERER的HTTP请求,从而实现这个目的。 以下是一个简单的PHP代码示例,用于演示如何伪造HTTP_REFERER: ```php $host = '...

    syn flood 代码

    这里需要注意的是,为了模拟SYN Flood攻击,通常会使用伪造的源IP地址和端口,使得服务器无法正常响应这些半连接请求。 ### 其他注意事项 - 在实际环境中,实施SYN Flood攻击是非法的,并且可能会触犯相关法律法规...

    通过Python实现自动填写调查问卷.pdf

    5. **HTTP头部欺骗**:在这种情况下,作者发现通过修改HTTP头部的`X-Forwarded-For`字段可以伪造IP地址,从而绕过基于IP频率的反爬机制。在Python中,这可以通过设置requests库的headers参数来实现。 6. **IP地址...

    黑客安全编程之自己编程实现ARP欺骗工具(附详细代码).pdf

    ARP欺骗是一种常见的网络攻击手段,通过向局域网中发送伪造的ARP响应包,来篡改网络中的ARP缓存表,从而实现中间人攻击等恶意行为。值得注意的是,本文的目的是为了教育和安全研究,并不鼓励进行非法活动。 首先,...

    讲解ARP数据包很好的一篇文章

    在不安全的网络环境中,攻击者可以通过发送伪造的ARP响应包,将自己的MAC地址映射到其他主机的目标IP,造成数据包被错误地转发到攻击者,从而实现中间人攻击。 2. 监听原理: 基于ARP欺骗,攻击者可以拦截并查看...

    用c++实现的dos示例

    - `_IPHeader`和`_TCPHeader`:分别定义IP和TCP头部结构体,用于构造伪造的网络包。 - `_PSDHeader`:定义伪头部结构体,用于计算TCP校验和。 - `_AttackObj`:定义攻击目标结构体,包含目标IP和端口列表。 3. ...

    多线程DOS源码

    // 伪造IP地址 unsigned int destIP; // 攻击的IP地址 } IP_HEADER; ``` IP头部结构体同样为构建IP数据包提供了必要的框架。 ##### 4. 计算校验和函数 `checksum()` 校验和函数用于计算IP包和TCP包的校验和,...

    完美兼容各大浏览器获取HTTP_REFERER方法总结

    在这个例子中,cURL发起一个请求到目标URL,并在请求头中设置了伪造的IP和HTTP_REFERER。这种方式适用于服务器端操作,当需要从服务器向其他网站发送请求并携带特定的HTTP_REFERER时。 总的来说,由于不同浏览器的...

    PHP写的资源下载防盗链类分享

    在PHP中实现资源下载的防盗链功能,主要是通过验证HTTP请求头中的"Referer"字段来实现。"Referer"字段保存了请求资源的原始网页地址。通过检查这个字段是否来自授权的域名列表,来决定是否允许资源下载。 在提供的...

    php curl的深入解析

    3. 伪造IP和来路 ```php curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-FORWARDED-FOR:*.*.*.*', 'CLIENT-IP:*.*.*.*')); // 构造IP curl_setopt($ch, CURLOPT_REFERER, "***"); // 构造来路 ``` 最后,虽然PHP的...

Global site tag (gtag.js) - Google Analytics