php 如何伪造 $_SERVER['REMOTE_ADDR'] 变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5092563/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to fake $_SERVER['REMOTE_ADDR'] variable?
提问by Richard Knop
Is it possible to fake or hiHyman a content of $_SERVER['REMOTE_ADDR']
variable?
是否有可能伪造或劫持$_SERVER['REMOTE_ADDR']
变量的内容?
I would like to fake a request with:
我想伪造一个请求:
$_SERVER['REMOTE_ADDR']='127.0.0.1';
How could I do that with PHP? Can CURL do that somehow?
我怎么能用 PHP 做到这一点?CURL 能以某种方式做到这一点吗?
回答by ircmaxell
I assume that you mean faking it remotely. The short answer is yes you can. The long answer about how easy it is depends on how you want to fake it.
我假设您的意思是远程伪造它。简短的回答是可以。关于它有多容易的长答案取决于你想如何伪造它。
If you don't care about receiving a response, it's as trivial as opening a raw socket to the destination and forging the source IP address. I'm not sure if it's really easy to do in PHP since all of PHP's socket implementations are at or above the TCP level. But I'm sure it's possible. Now, since you're not in control of the network, the response will not go back to you. So that means that you cannot (reliably anyway) create a TCP connection via a trivial forged TCP header (since the syn-ack does prevent this by requiring two-way communication).
如果您不关心接收响应,那么它就像打开一个到目的地的原始套接字并伪造源 IP 地址一样微不足道。我不确定在 PHP 中是否真的很容易做到,因为所有 PHP 的套接字实现都处于或高于 TCP 级别。但我确信这是可能的。现在,由于您无法控制网络,因此响应不会返回给您。所以这意味着你不能(无论如何可靠地)通过一个微不足道的伪造 TCP 标头创建一个 TCP 连接(因为 Syn-ack 确实通过需要双向通信来阻止这种情况)。
However, if you can compromise the gateway the IP is off of, you can do whatever you'd like. So if you compromise the wifi router a computer is connected to, you can pretend to be that computer, and the server won't tell the difference. If you compromise the ISP's outbound router, you can (in theory at least) pretend to be the computer and the server won't tell the difference.
但是,如果您可以破坏 IP 所在的网关,您就可以为所欲为。因此,如果您破坏了计算机所连接的 wifi 路由器,您可以假装是那台计算机,而服务器不会分辨出区别。如果您破坏了 ISP 的出站路由器,您可以(至少在理论上)假装是计算机,而服务器不会分辨出区别。
For some more info, see these following links:
有关更多信息,请参阅以下链接:
However, you will only be able to forge the 127.0.0.1
loopback address under TCP if you actually compromise the local machine/server. And at that point does it really matter?
但是,127.0.0.1
如果您真的危及本地机器/服务器,您将只能在 TCP 下伪造环回地址。在这一点上,这真的很重要吗?
Important
重要的
If you're using a framework to access this information, be absolutely surethat it does not check the X-HTTP-FORWARDED-FOR
header! Otherwise it's trivial to fake the IP address. For example, if you're using Zend Framework's Zend_Controller_Request_Http::getClientIp
method, be absolutely sure that you pass false
as the parameter! Otherwise someone just needs to send an HTTP header: X-Http-Forwarded-For: 127.0.0.1
and they now appear to be local! This is one case where using a framework without understanding how it works in the backend can really be bad...
如果您使用框架来访问此信息,请绝对确保它不会检查X-HTTP-FORWARDED-FOR
标题!否则,伪造 IP 地址是微不足道的。例如,如果您使用Zend Framework 的Zend_Controller_Request_Http::getClientIp
方法,请绝对确保您false
作为参数传递!否则有人只需要发送一个 HTTP 标头:X-Http-Forwarded-For: 127.0.0.1
它们现在看起来是本地的!这是一种情况,在不了解框架在后端如何工作的情况下使用框架真的很糟糕......
Edit: Relevant
编辑:相关
I wrote a blog post recently about how I stumbled across a vulnerability in StackOverflow's application. It's very relevant here, since it exploits a very similar mechanism to what this question is looking for (although the circumstances around it are somewhat narrow):
我最近写了一篇关于我如何偶然发现 StackOverflow 应用程序中的漏洞的博客文章。它在这里非常相关,因为它利用了与这个问题正在寻找的非常相似的机制(尽管它周围的情况有些狭窄):
回答by Michael Borgwardt
The remote address is not something added out of courtesy, it's used in the IP protocol to route packages, so if you send a package with a fake address, you will not receive a response, and since you're talking about a HTTP request, which is delivered over a TCP connection, which takes several IP packets (and the matching responses) to set up:
远程地址不是出于礼貌而添加的,它在 IP 协议中用于路由包,因此如果您发送带有假地址的包,您将不会收到响应,并且由于您在谈论 HTTP 请求,它通过 TCP 连接传送,它需要几个 IP 数据包(和匹配的响应)来设置:
No, that's impossible (except of course by actually sending the request from the same host via the loopback interface).
不,这是不可能的(当然,通过环回接口从同一主机实际发送请求除外)。
回答by rook
Apache populates $_SERVER['REMOTE_ADDR']
from a TCP socket that it uses to communicate with your browser. It is IMPOSSIBLEto influence this variable over the open internet because of the three-way-handshake. If the client and the server is on a broadcast network, like wifi, then you can sniff the wire and complete the handshake.
Apache$_SERVER['REMOTE_ADDR']
从它用来与浏览器通信的 TCP 套接字填充。由于三向握手,在开放的互联网上影响这个变量是不可能的。如果客户端和服务器在广播网络上,比如 wifi,那么你可以嗅探线路并完成握手。
回答by Spudley
If you browse via a proxy, $_SERVER['REMOTE_ADDR']
may be set to the proxy's IP address rather than the end user's.
如果您通过代理浏览,$_SERVER['REMOTE_ADDR']
可能会设置为代理的 IP 地址而不是最终用户的 IP 地址。
There are other headers which you can use instead in this case: This page gives a function which checks all the possibilities and provides the address most likely to be the end user's:
在这种情况下,您还可以使用其他标题:此页面提供了一个功能,可以检查所有可能性并提供最有可能是最终用户的地址:
http://roshanbh.com.np/2007/12/getting-real-ip-address-in-php.html
http://roshanbh.com.np/2007/12/getting-real-ip-address-in-php.html
However if the user is proxying using a badly configured proxy, or a malicious one, or one designed to anonymise the end user, then you won't be able to guarantee any of the headers other than REMOTE_ADDR
(which would only lead you as far as the proxy).
但是,如果用户使用配置不当的代理、恶意代理或旨在使最终用户匿名的代理进行代理,那么您将无法保证除REMOTE_ADDR
(这只会引导您到代理)。
If your end user is browsing via HTTPS, then REMOTE_ADDR
will always be his IP address; you can't use proxy forwarding via HTTPS. Therefore, the one way to be absolutely sure of his address is to get him to open your site in HTTPS.
如果您的最终用户通过 HTTPS 浏览,那么REMOTE_ADDR
将始终是他的 IP 地址;您不能通过 HTTPS 使用代理转发。因此,绝对确定他的地址的一种方法是让他在 HTTPS 中打开您的网站。
回答by álvaro González
You can overwrite any item in the $_SERVER
array, including the one you mention, in yourserver; of course, not in someone else's.
您可以将在覆盖任何物品$_SERVER
阵列,包括你提到的,在一个你的服务器; 当然,不是在别人的。
However, it won't change your computer's IP address.
但是,它不会更改您计算机的 IP 地址。
回答by Quamis
That is a variable set by apache or whatever server you're using. You cannot spoof it.
You may run $_SERVER['REMOTE_ADDR']='127.0.0.1';
at the beginning of the scripts, but i doubt thats what you're trying to do
这是由 apache 或您使用的任何服务器设置的变量。你不能欺骗它。您可能会$_SERVER['REMOTE_ADDR']='127.0.0.1';
在脚本的开头运行,但我怀疑这就是您想要做的
回答by hsz
REMOTE_ADDR
REMOTE_ADDR
The IP address from which the user is viewing the current page.
用户正在查看当前页面的 IP 地址。
You can request script using proxy, etc. to change IP address but you cannot set there any text you want.
您可以使用代理等请求脚本来更改 IP 地址,但您不能在那里设置任何您想要的文本。