伪造来源IP欺骗

一,获取客户端IP目的

        一般对于访问比较频繁的接口,服务端都会根据IP做接口访问频率限制;例如,对于给定的IP,1分钟只能调用接口100次,频率过快服务端可以针对该IP进行特殊处理,比如接口直接调用失败或加入IP黑名单列表等操作。那么,对于服务端来说,能够获取客户端真实的IP信息,是至关重要的。

二,如何伪造来源IP,欺骗服务端

       

 

#获取客户端IP的方法(可能经过多个代理)
public String getIpAddr(HttpServletRequest request) {
       String ip = null;
       String ips = request.getHeader("X-Forwarded-For");//XFF头:client_ip,proxy1_ip,proxy2_ip...
       if(ips != null && ips.trim() != ""){ 
          ip = ips .split("\\s*,\\s*")[0];
       }
       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();//remoteAddr取自网络层IP地址,是不可能伪造的
       }
       return ip;
}

   X-Forwarded-For头是由代理自动设置的,如果代理不设置XXF请求头,服务器端是获取不到客户端真实IP信息的,getRemoteAddr()获取的是上一层代理的IP地址,如果客户端的访问没有经过代理,那么
getRemoteAddr()获取的才是用户的真实IP。XFF头格式:client_ip,proxy1_ip,proxy2_ip...(由代理自动设置)。

   了解了服务端代码获取客户端IP的原理后可知,客户端完全可以伪造X-Forwarded-For,Proxy-Client-IP,WL-Proxy-Client-IP请求头,从而对服务端进行欺骗。可以通过程序修改请求头,也可以使用代理软件拦截请求,动态修改请求头信息。

三,相关疑惑

//一个伪造的IP能否跟服务端建立TCP连接通信?
答案:是不可能的,因为TCP是面向连接的协议,每个连接都需要经过三次握手建立连接。
client发送syn报文给服务端,服务端响应syn+ack报文,由于IP是伪造的,伪造的IP是接收不到服务端响应的syn+ack报文并返回ack的,也就是说三次握手根本不能正常完成,TCP连接是不可能建立的。本文讲的伪造IP欺骗服务端是基于服务端获取IP的原理,修改http请求头,完成的欺骗。其底层建立TCP通信链路的IP,肯定是真实存在的,要不然没办法进行通信和交互。
如果攻击者使用大量伪造IP,发送syn报文给服务器,会导致服务器半连接队列堆满,正常用户无法和服务器建立TCP连接,也就是所谓的syn flood攻击(DDOS攻击中的一种)。

//一个伪造的IP能否跟服务器以UDP协议进行通信
答案:单向通信,client只能单向的发送数据给服务端,同样由于IP是伪造的,接收不到服务返回的UDP报文。UDP是一个面向非连接的协议,建立通信前不需要经过三次握手建立连接,也没有消息确认ack,超时重传等保障数据安全传输的机制。但是如果大量伪造的IP,发送垃圾数据给服务器,会造成服务瘫痪,影响正常用户使用,也就是所谓的udp flood攻击(DDOS攻击中的一种)。

猜你喜欢

转载自pandan-xyz.iteye.com/blog/2286087