如何伪造 $_SERVER['REMOTE_ADDR'] 变量?

How to fake $_SERVER['REMOTE_ADDR'] variable?

提问人:Richard Knop 提问时间:2/23/2011 最后编辑:samayoRichard Knop 更新时间:5/15/2020 访问量:87819

问:

是否有可能伪造或劫持变量的内容?$_SERVER['REMOTE_ADDR']

我想用以下方式伪造请求:

$_SERVER['REMOTE_ADDR']='127.0.0.1';

我怎样才能用PHP做到这一点?CURL能以某种方式做到这一点吗?

PHP 安全

评论


答:

3赞 hsz 2/23/2011 #1

REMOTE_ADDR

用户查看当前页面的 IP 地址。

您可以使用代理等请求脚本来更改 IP 地址,但您不能在那里设置任何您想要的文本。

18赞 Michael Borgwardt 2/23/2011 #2

远程地址不是出于礼貌而添加的,它在 IP 协议中用于路由包,因此如果您发送带有虚假地址的包,您将不会收到响应,并且由于您谈论的是 HTTP 请求,该请求是通过 TCP 连接传递的,这需要多个 IP 数据包(和匹配的响应)来设置:

不,这是不可能的(当然,除非通过环回接口从同一主机实际发送请求)。

评论

0赞 Álvaro González 2/23/2011
此外,它看起来像是需要在您的 TCP 堆栈和网卡驱动程序中进行一些调整。
3赞 Quamis 2/23/2011 #3

这是由 apache 或您正在使用的任何服务器设置的变量。你不能欺骗它。 您可能会在脚本的开头运行,但我怀疑这就是您要做的事情$_SERVER['REMOTE_ADDR']='127.0.0.1';

6赞 Álvaro González 2/23/2011 #4

您可以在服务器中覆盖数组中的任何项目,包括您提到的项目;当然,不是别人的。$_SERVER

但是,它不会更改计算机的 IP 地址。

9赞 Spudley 2/23/2011 #5

如果通过代理浏览,则可以设置为代理的 IP 地址,而不是最终用户的 IP 地址。$_SERVER['REMOTE_ADDR']

在这种情况下,您可以使用其他标头来代替: 此页面提供了一个函数,用于检查所有可能性并提供最有可能是最终用户的地址:

http://roshanbh.com.np/2007/12/getting-real-ip-address-in-php.html

但是,如果用户使用配置不当的代理、恶意代理或旨在匿名化最终用户的代理进行代理,则您将无法保证除(这只会将您引导到代理之外)以外的任何标头。REMOTE_ADDR

如果您的最终用户通过 HTTPS 浏览,那么将始终是他的 IP 地址;您不能通过 HTTPS 使用代理转发。因此,绝对确定他的地址的一种方法是让他在HTTPS中打开您的网站。REMOTE_ADDR

评论

2赞 Jonathan 1/14/2016
5 年后,这仍然是一个可靠的解决方案吗?
117赞 ircmaxell 2/23/2011 #6

我假设你的意思是远程伪造它。简短的回答是肯定的,你可以。关于它有多容易的长答案取决于你想如何伪造它。

如果您不关心接收响应,这就像打开一个原始套接字到目的地并伪造源 IP 地址一样微不足道。我不确定这在 PHP 中是否真的容易做到,因为所有 PHP 的套接字实现都处于或高于 TCP 级别。但我相信这是可能的。现在,由于您无法控制网络,因此响应不会返回给您。因此,这意味着您不能(无论如何都可靠地)通过简单的伪造 TCP 标头创建 TCP 连接(因为 syn-ack 确实通过要求双向通信来防止这种情况)。

但是,如果您可以破坏 IP 关闭的网关,则可以做任何您想做的事。因此,如果您破坏了计算机所连接的 wifi 路由器,您可以假装是那台计算机,服务器不会分辨出区别。如果你破坏了ISP的出站路由器,你可以(至少在理论上)假装是计算机,服务器不会分辨出区别。

有关详细信息,请参阅以下链接:

但是,只有当您实际破坏本地计算机/服务器时,您才能在 TCP 下伪造环回地址。在这一点上,这真的重要吗?127.0.0.1

重要

如果您使用框架来访问此信息,请绝对确保它不会检查标头!否则,伪造 IP 地址是微不足道的。例如,如果你使用的是 Zend Framework 的 Zend_Controller_Request_Http::getClientIp 方法,请绝对确保你作为参数传递!否则,有人只需要发送一个 HTTP 标头:它们现在看起来是本地的!在这种情况下,在不了解框架在后端如何工作的情况下使用框架真的很糟糕......X-HTTP-FORWARDED-FORfalseX-Http-Forwarded-For: 127.0.0.1

编辑:相关

我最近写了一篇博文,讲述了我是如何偶然发现 StackOverflow 应用程序中的一个漏洞的。它在这里非常相关,因为它利用了与这个问题所寻找的非常相似的机制(尽管它周围的情况有些狭窄):

我是如何破解 StackOverflow 的

13赞 rook 2/24/2011 #7

Apache 从用于与浏览器通信的 TCP 套接字进行填充。由于三向握手,不可能在开放的互联网上影响这个变量。如果客户端和服务器在广播网络上,例如 wifi,那么您可以嗅探电线并完成握手。$_SERVER['REMOTE_ADDR']