PHP 使用 cURL 伪造客户端 IP 和 Referer 详解
在 PHP 开发中,有时需要向外部服务发起包含特定身份信息的请求。通过配置 cURL 的 CURLOPT_HTTPHEADER 参数,开发者可以插入如 X-FORWARDED-FOR 或 CLIENT-IP 等标头,尝试影响目标服务器的日志记录或 IP 识别逻辑,并结合 CURLOPT_REFERER 伪装跳转来源。
核心原理与准备条件
Web 服务器通常依据环境变量 $_SERVER['REMOTE_ADDR'] 记录物理连接的远端地址,这是无法被纯应用层请求伪造的。然而,许多应用代码为了获取“真实”用户 IP,会优先检查 HTTP_CLIENT_IP(由代理或网关设置)和 HTTP_X_FORWARDED_FOR(常用于 CDN/负载均衡透传)。此外,HTTP_REFERER 用于标识页面跳转来源。
cURL 允许我们在客户端层面直接向 HTTP 协议栈注入这些 Header。操作前需确保目标文件位于可访问路径(如本地测试环境),且理解此类操作的用途主要用于调试、自动化测试或特定业务场景下的来源伪装。
第一步:构建带有自定义头部的请求脚本 (fake_ip.php)
此步骤的目的是创建一个发出请求的主体,其中包含我们希望目标服务器接收到的伪造信息。
- 入口:
curl_init()初始化句柄。 - 动作:设置
CURLOPT_URL指向目标,利用CURLOPT_HTTPHEADER传递数组格式的 Header。 - 重要参数:
'CLIENT-IP:58.68.44.61':模拟来自该代理层的 IP。'X-FORWARDED-FOR:58.68.44.61':模拟经过一层转发后的 IP。array('X-FORWARDED-FOR:8.8.8.8', 'CLIENT-IP:8.8.8.8'):也可组合多个值。CURLOPT_REFERER:指定来源页 URL。- 完成状态:执行
curl_exec后返回目标页面的内容。
<?php
// 初始化 cURL
$ch = curl_init();
$url = "http://localhost/target_ip.php";
// 定义伪造的 IP 头部
$header = array(
'CLIENT-IP:58.68.44.61',
'X-FORWARDED-FOR:58.68.44.61',
);
// 设置其他必要选项
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 执行请求并获取结果
$page_content = curl_exec($ch);
curl_close($ch);
// 输出目标返回的内容
echo $page_content;
?>
第二步:创建用于解析和输出 Header 的目标脚本 (target_ip.php)
目标脚本的作用是打印当前 PHP 环境中读取到的各种 IP 变量和 Referer,以便对比查看哪些字段成功被伪造。
- 入口:直接调用
getenv()读取环境变量,或使用$_SERVER全局数组。 - 动作:按常见开源系统的读取顺序依次输出三个变量。
- 观察要点:
HTTP_CLIENT_IP应显示为设置的伪造 IP。HTTP_X_FORWARDED_FOR应显示为设置的伪造 IP。REMOTE_ADDR仍显示为 cURL 发出的实际连接地址(通常是 localhost 或 127.0.0.1)。
<?php
// 方法一:通过 getenv 读取环境变量
echo getenv('HTTP_CLIENT_IP') . '
'; // 对应 HEADER 中的 CLIENT-IP
echo getenv('HTTP_X_FORWARDED_FOR') . '
'; // 对应 HEADER 中的 X-FORWARDED-FOR
echo getenv('REMOTE_ADDR'); // 物理真实 IP
echo '
';
// 方法二:通过 $_SERVER 读取 (更常用的 PHP 方式)
function getClientIp() {
if (!empty($_SERVER["HTTP_CLIENT_IP"])) {
return $_SERVER["HTTP_CLIENT_IP"];
} else if (!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) {
return $_SERVER["HTTP_X_FORWARDED_FOR"];
} else if (!empty($_SERVER["REMOTE_ADDR"])) {
return $_SERVER["REMOTE_ADDR"];
} else {
return "err";
}
}
echo "Parsed IP: " . getClientIp();
echo "Referer: " . $_SERVER["HTTP_REFERER"] ?? "No Referer";
?>
第三步:完整测试流程与结果分析
在实际操作中,可以将上述两个文件分别保存为 1.php 和 2.php 放置于同一 Web 目录中进行测试。
// 1.php (发起方)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost/2.php");
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'X-FORWARDED-FOR:8.8.8.8',
'CLIENT-IP:8.8.8.8'
));
curl_setopt($ch, CURLOPT_REFERER, "https://www.example.com/"); // 伪造来路
curl_setopt($ch, CURLOPT_HEADER, 1); // 可选:若需查看响应头
$out = curl_exec($ch);
curl_close($ch);
?>
当访问 1.php 时,2.php 的输出结果通常如下所示:
- 前两项(
CLIENT-IP和X-FORWARDED-FOR)会正确显示为8.8.8.8。 REMOTE_ADDR会显示为请求源的本地 IP(如127.0.0.1)。Referer会被正确设置为https://www.example.com/。
这证实了只要服务端代码存在先检查伪造 Header 再检查物理 IP 的逻辑缺陷,客户端即可通过 cURL 轻易欺骗应用层关于“来源”的判断。
注意事项与安全性提醒
虽然技术上行得通,但在生产环境中依赖这些 Header 判断用户 IP 是高风险行为。恶意用户只需修改 HTTP 请求头即可绕过基于 IP 的频率限制或地域封锁。建议在生产环境结合服务端反向代理(如 Nginx)进行可信 IP 校验,或者直接使用 $_SERVER['REMOTE_ADDR'] 作为最可靠的信任源。
以上就是 PHP cURL 伪造 IP 来源与 Referer 的详细内容,更多关于 PHP cURL 网络编程技巧的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













