构造HTTP请求Header实现“伪造来源IP”(重在原理)

转载自:


1. 伪造原理

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

 

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

 

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

 

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

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

 

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

 

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



左边即是请求数据,右边即是服务器响应数据。

特点:

请求 header 中除第一行外,其它行均由 header 名称, header 值组成,如  Accept-Encoding: gzip, deflate  header 名称与值之间有冒号相隔,之间的空格是可有可无的。

那么,在HTTP 应用程序中,如何取得指定的请求 header 信息呢?

以下是js获取ip地址:

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;
}
由上可知: 服务器通过request中的  x-forwarded-for 和 client-ip 来获取 客户端的ip.

那么,如果客户端伪造 Client-Ip, X-Forward-For ,可以欺骗此程序,达到“伪造 IP ”之目的.


2. 那么如何伪造这项值(X-Forward-For)?

方法一: 如果你会写程序,并了解HTTP 协议,直接伪造请求 header 即可

方法二: 使用 Firefox Moify Headers 插件即可(推荐)



3. 如何避免伪造ip

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

服务器集群之间的通信,是可以信任的。我们要做的就是在离用户最近的前端代理上,强制设定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 ”。






已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页
实付 49.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值