是否可以伪造或劫持$_SERVER['REMOTE_ADDR']
变量的内容?
我想伪造一个请求:
$_SERVER['REMOTE_ADDR']='127.0.0.1';
我怎么能用PHP做到这一点? CURL能以某种方式做到吗?
答案 0 :(得分:105)
我认为你的意思是远程伪造它。简短的回答是肯定的。关于它是多么容易的长期答案取决于你想要伪造它的方式。
如果您不关心接收响应,那么打开原始套接字到目的地并伪造源IP地址就像是微不足道的。我不确定在PHP中是否真的很容易,因为所有PHP的套接字实现都达到或高于TCP级别。但我相信这是可能的。现在,由于您无法控制网络,因此响应不会再回复给您。这意味着你无法(无论如何)通过一个简单的伪造TCP头创建一个TCP连接(因为syn-ack通过要求双向通信来防止这种情况)。
但是,如果你可以破坏IP关闭的网关,你可以做任何你想做的事情。因此,如果你破坏了计算机连接到的wifi路由器,你可以假装是那台计算机,而服务器将无法区分。如果你破坏ISP的出站路由器,你可以(理论上至少)假装是计算机而服务器不会分辨出来。
有关更多信息,请参阅以下链接:
但是,如果您实际危及本地计算机/服务器,则只能在TCP下伪造127.0.0.1
环回地址。那时真的很重要吗?
如果您使用框架来访问此信息,请绝对确定它不会检查X-HTTP-FORWARDED-FOR
标头!否则,伪造IP地址是微不足道的。例如,如果您使用的是Zend Framework's Zend_Controller_Request_Http::getClientIp
方法,请务必确保将false
作为参数传递!否则,有人只需要发送一个HTTP标头:X-Http-Forwarded-For: 127.0.0.1
,它们现在看起来是本地的!这是一个使用框架而不了解它在后端如何工作的情况可能真的很糟糕......
我最近写了一篇关于我如何偶然发现StackOverflow应用程序中的漏洞的博客文章。这里非常相关,因为它利用了一个与这个问题所寻求的非常相似的机制(虽然它周围的情况有点狭窄):
答案 1 :(得分:17)
远程地址不是出于礼貌而添加的,它在IP协议中用于路由包,所以如果你send a package with a fake address,你将不会收到响应,因为你在谈论HTTP请求,通过TCP连接传递,它需要几个IP数据包(和匹配的响应)来设置:
不,这是不可能的(当然,实际上通过环回接口从同一主机发送请求)。
答案 2 :(得分:12)
Apache从用于与浏览器通信的TCP套接字填充$_SERVER['REMOTE_ADDR']
。由于three-way-handshake,在开放式互联网上影响此变量是不可能。如果客户端和服务器在广播网络上,如wifi,那么你可以嗅探线路并完成握手。
答案 3 :(得分:8)
如果您通过代理浏览,$_SERVER['REMOTE_ADDR']
可能会设置为代理的IP地址而不是最终用户的。
在这种情况下,您可以使用其他标题:此页面提供了一个功能,可以检查所有可能性并提供最有可能是最终用户的地址:
http://roshanbh.com.np/2007/12/getting-real-ip-address-in-php.html
但是,如果用户使用配置错误的代理或恶意代理或代表匿名最终用户的代理进行代理,则您将无法保证REMOTE_ADDR
以外的任何标头(这只会引导你到代理人。)
如果您的最终用户通过HTTPS进行浏览,那么REMOTE_ADDR
将永远是他的IP地址;您无法通过HTTPS使用代理转发。因此,绝对确定他的地址的一种方法是让他用HTTPS打开你的网站。
答案 4 :(得分:7)
您可以在 服务器中覆盖$_SERVER
阵列中的任何项目,包括您提及的项目;当然,不是别人的。
但是,它不会更改计算机的IP地址。
答案 5 :(得分:3)
REMOTE_ADDR
用户正在查看当前页面的IP地址。
您可以使用代理等请求脚本来更改IP地址,但您无法设置任何所需的文本。
答案 6 :(得分:3)
这是由apache或您正在使用的任何服务器设置的变量。你无法欺骗它。
您可以在脚本的开头运行$_SERVER['REMOTE_ADDR']='127.0.0.1';
,但我怀疑您正在尝试做什么