是否可以通过欺骗 IP 发送 HTTP 数据包?

信息安全 http tcp ip欺骗
2021-08-21 15:47:24

我有以下 PHP 代码,accepted仅当 IP 等于 127.0.0.1(环回)时才写入名为 text.txt 的文件。如果 IP 不匹配,它会写入denied.

<?php
$file = fopen('text.txt' , 'a');
if($_SERVER['REMOTE_ADDR'] === '127.0.0.1') {
$request = $_GET['output'];
if($request === '123') {
fwrite($file, "\x0D\x0A".'accepted - ' .$_SERVER['REMOTE_ADDR']);

}

}
else {  
    fwrite($file, "\x0D\x0A".'denied - ' .$_SERVER['REMOTE_ADDR']);
}
?>

我可以从欺骗 IP 为 127.0.0.1 的外部网络发送获取请求 (www.example.com/get.php?output=123) 吗?如果有可能,我该怎么做?如果不是,为什么?

3个回答

是否可以通过欺骗 IP 发送 HTTP 数据包?

不,你不能。

HTTP 是 TCP 之上的协议,由于协议的内部结构,使用 TCP 进行 IP 欺骗几乎是不可能的。您不仅需要像在 UDP 中那样发送单个欺骗数据包,而且您实际上需要使用匹配的序列号回复对等方的数据包,而无法查看包含您需要匹配的序列号的对等方数据包。并且这个回复必须发生在建立连接之前,即在发送你的 HTTP 有效负载之前。

除此之外,许多系统会简单地丢弃不符合路由的数据包,即声称来自 127.0.0.1 (localhost) 的数据包永远不应进入与本地网络连接的网卡。

if($_SERVER['REMOTE_ADDR'] === '127.0.0.1') {

但是考虑到您的代码,如果 in 的值$_SERVER['REMOTE_ADDR']可能被欺骗,您实际上可能会更感兴趣。虽然大多数人认为这是客户端的源 IP 地址,但它实际上可能与 HTTP 连接的真实源 IP 不同,甚至可能被攻击者操纵。

在 Web 服务器前面的反向代理(或负载均衡器)的情况下,Web 服务器不知道客户端的真实 IP,因为来自客户端的连接实际上终止于反向代理。因此,反向代理通过插入 HTTP 标头来传播原始客户端源 IP 的情况并不少见,通常是X-Forwarded-For. 一些 Web 服务器设置为将来自此标头的值放入$_SERVER['REMOTE_ADDR']而不是实际源 IP。在某些情况下,攻击者实际上可以利用它来绕过您的案例中使用的基于 IP 的访问控制。

有关这种绕过的具体示例,请参阅Anatomy of an Attack: How I Hacked StackOverflow

这不可能

欺骗性的 http 数据包必须通过 TCP 连接传输。

TCP 具有 3 次握手,可防止来自欺骗性 IP 地址的通信到达服务器的 PHP 代码。

在开始发送应用程序数据之前,会发生以下情况:

发送带有欺骗 IP 的 TCP SYN

SERVER以 SYN-ACK 响应该 IP 并等待从该 IP 返回的 ACK 数据包。

对话结束!

您的 TCP 堆栈只会发送 SYN 数据包,而远程系统会尝试将 SYN-ACK 数据包发送回您发送的欺骗 IP。即使它存在并接收到 SYN-ACK 数据包,它也永远不会从该欺骗 IP 获得对 SYN-ACK 的回复,因为它知道它从未发送过 SYN 数据包。

剧透:你不能。

聪明的裤子:如果您可以将请求放入单个 TCP 数据包中,则可以。或者,如果您控制到欺骗 IP 的路由。或者IP被欺骗的机器。

但是:你可能无法做到这一点。

问题是:虽然 HTTP 是无状态的,但它使用 TCP,而事实并非如此。特别是,在发送任何实际数据之前,会执行握手以建立通信的“基本规则”。

如果发送了带有欺骗 IP 的数据包,则来自服务器的答案将发送到该 IP,而不是您的 IP。

这意味着您无法完成握手,因此不发送 HTTP 请求。

更准确地说,如果你从 IP a 欺骗 TCP SYN 数据包,你只能看到发送到 IP b 的数据包,你不会看到服务器发送到 a 的 TCP ACK 数据包。因此,您无法制作另一个欺骗数据包来正确建立 TCP 连接。

为了进一步阅读,我建议您最喜欢的搜索引擎和“TCP”。