前言

题目网址: http://www.shiyanbar.com/ctf/32

需要用到的工具: burpsuite

理解

实验吧WEB CTF 貌似有点难 全网最简单易懂的解题方法

函数分析

代码中包含了两个部分,一个是得到IP地址的GetIP函数,一个是通过GetIP函数获得的IP验证是否为1.1.1.1的主函数部分。

那么这题的思路应该非常的清晰,我们需要想方法使得代码中的GetIP函数获得的IP地址为1.1.1.1,我们就能得到flag。

好,那么现在我们再来查看这个函数,在这个函数中我们可以这样去进行理解,首先查看是否存在$_SERVER["HTTP_CLIENT_IP"],如果存在IP就是它,否则接下来看$_SERVER["HTTP_X_FORWARDED_FOR"],最后看$_SERVER["REMOTE_ADDR"],如果以上三个变量都不存在的话则返回0.0.0.0。

变量分析

了解完整个过程之后我们来讲讲这三个变量的含义,首先是$_SERVER["HTTP_CLIENT_IP"],这个变量表示的是代理服务器发送的HTTP头,$_SERVER["REMOTE_ADDR"]代表的是你的客户端和服务器握手时候的IP。

那么分析这两个变量,首先是$_SERVER["HTTP_CLIENT_IP"]变量,

曾经12年有个豆瓣的帖子激烈的讨论过这个东西的存在性:https://www.douban.com/group/topic/27482290/

有网友甚至实际操作一万次都没有找到过结果23333,但是其实头是有这个信息的,但是并未达成标准,并不是所有的服务器都实现了的,HTTP_CLIENT_IP在头信息中对应的是client-ip,是可以进行伪造的。我们再看看$_SERVER["REMOTE_ADDR"]这个变量,这个变量代表的是你的客户端和服务器握手时候的IP,什么意思呢?假如我们的客户端使用了代理服务器时,这个结果就不会是我们的客户端的IP,而是代理的ip。只有服务器直接暴露在我们的客户端前面的时候,得到的值才为客户端的IP。

介绍完这两个我们再来看看刚刚一直没有提到的$_SERVER["HTTP_X_FORWARDED_FOR"]。先来看看百度的结果:

X-Forwarded-For:简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP,只有在通过了HTTP 代理或者负载均衡服务器时才会添加该项。它不是RFC中定义的标准请求头信息,在squid缓存代理服务器开发文档中可以找到该项的详细介绍。标准格式如下:X-Forwarded-For: client1, proxy1, proxy2。

这个变量在实际应用中的意义我们这里先不谈,先来理解一下这个过程:当我们用代理服务器的时候,X-Forwarded-For这个值记录的是我们客户端原本的IP地址,而非代理服务的IP,简言之就是用来识别经过HTTP代理后的客户端IP地址。X-Forwarded-For在头信息中对应的就是X-Forwarded-For,是可以进行伪造的。

做题

我们可以伪造的信息有X-Forwarded-For和client-ip,分别对应的是X-Forwarded-For和HTTP_CLIENT_IP

操作还是先将浏览器代理和Burp代理监听调成一致,然后拦截请求发送到Repeater,编辑请求头信息,并发送。

实验吧WEB CTF 貌似有点难 全网最简单易懂的解题方法

更多

IP伪造

在阅读本文前,大家要有一个概念,由于TCP需要三次握手连接,在实现正常的TCP/IP 双方通信情况下,是无法伪造来源 IP 的,也就是说,在 TCP/IP 协议中,可以伪造数据包来源 IP ,但这会让发送出去的数据包有去无回,无法实现正常的通信。

一些DDoS 攻击,它们只需要不断发送数据包,而不需要正常通信,它们就会采取这种“发射出去就不管”的行为来进行攻击。

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

先搞明白后端应用IP获取来源

1.’REMOTE_ADDR’是远端IP,默认来自tcp连接客户端的Ip。可以说,它最准确,确定是,只会得到直接连服务器客户端IP。如果对方通过代理服务器上网,就发现。获取到的是代理服务器IP了。
如:a→b(proxy)→c ,如果c 通过’REMOTE_ADDR’ ,只能获取到b的IP,获取不到a的IP了。
这个值是无法修改的。

2.’HTTP_X_FORWARDED_FOR’,’HTTP_CLIENT_IP’ 为了能在大型网络中,获取到最原始用户IP,或者代理IP地址。对HTTp协议进行扩展。定义了实体头。
HTTP_X_FORWARDED_FOR = clientip,proxy1,proxy2其中的值通过一个 逗号+空格 把多个IP地址区分开, 最左边(client1)是最原始客户端的IP地址, 代理服务器每成功收到一个请求,就把请求来源IP地址添加到右边。
HTTP_CLIENT_IP 在高级匿名代理中,这个代表了代理服务器IP。
其实这些变量,来自http请求的:X-Forwarded-For字段,以及client-ip字段。 正常代理服务器,当然会按rfc规范来传入这些值。
但是,攻击者也可以直接构造该x-forword-for值来“伪造源IP”,并且可以传入任意格式IP.
这样结果会带来2大问题,其一,如果你设置某个页面,做IP限制。 对方可以容易修改IP不断请求该页面。 其二,这类数据你如果直接使用,将带来SQL注册,跨站攻击等漏洞。

这类问题,其实很容易出现,比如很多时候利用这个骗取大量伪装投票。那么该如何修复呢?

防范修复

在代理转发及反向代理中经常使用X-Forwarded-For 字段。

X-Forwarded-For(XFF)的有效性依赖于代理服务器提供的连接原始IP地址的真实性,因此, XFF的有效使用应该保证代理服务器是可信的.

比如Nginx代理服务器,我们可以在其转发/反向代理的时候主动配置X-Forwarded-For为正确的值。

location / {
    proxy_pass  ....;
    proxy_set_header X-Forwarded-For $remote_addr ;
}

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

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

location ~ \.php$ {
fastcgi_pass localhost:9000;
fastcgi_param  HTTP_X_FORWARD_FOR  $remote_addr;
}

但是更常用的配置如下:

proxy_set_header   Host             $host;
proxy_set_header   X-Real-IP        $remote_addr;
proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

后台代码,通过X-Real-IP头来获取客户真实IP


转载:
决斗场 - 实验吧 WEB 貌似有点难
IP伪造与防范