文章目录
- [1 漏洞核心原理](#1 漏洞核心原理)
- [2 漏洞的2个关键限制](#2 漏洞的2个关键限制)
-
- [2.1 只能用在根路径/](#2.1 只能用在根路径/)
- [2.2 第一个斜杠前不能出现.(点)](#2.2 第一个斜杠前不能出现.(点))
- [3 限制绕过方法](#3 限制绕过方法)
-
- [3.1 工具快速生成](#3.1 工具快速生成)
- [4 实战案例复现](#4 实战案例复现)
-
- [4.1 环境准备](#4.1 环境准备)
- [4.2 漏洞利用步骤](#4.2 漏洞利用步骤)
- [4.3 关键疑问:URL中3个"127.0.0.1:8000"的区别](#4.3 关键疑问:URL中3个“127.0.0.1:8000”的区别)
- [4.4 国外公开案例补充](#4.4 国外公开案例补充)
- [5 漏洞防御方案](#5 漏洞防御方案)
-
- [5.1 核心防御](#5.1 核心防御)
- [5.2 版本升级](#5.2 版本升级)
- [5.3 代码层面防护](#5.3 代码层面防护)
- [6 总结](#6 总结)
⚠️本博文所涉安全渗透测试技术、方法及案例,仅用于网络安全技术研究与合规性交流,旨在提升读者的安全防护意识与技术能力。任何个人或组织在使用相关内容前,必须获得目标网络 / 系统所有者的明确且书面授权,严禁用于未经授权的网络探测、漏洞利用、数据获取等非法行为。
1 漏洞核心原理
PHP有个内置Web服务器,用php -S命令就能快速启动,方便本地开发,不用像平常那样装Nginx或Apache 。但它在解析请求路径时出了问题。它允许在路径的第一个斜杠之前、以及斜杠之间,用星号*当通配符,而且几乎所有ASCII字符都被当成合法路径。
正常时,服务器会把像/index.php这样的路径,对应到本地根目录的index.php文件执行。可攻击者利用*通配符的特性,构造特殊路径,骗服务器把路径解析成「远程URL请求」 ,让服务器主动向攻击者指定的目标发起请求,这就是SSRF(服务器端请求伪造)。简单讲,服务器本来只该处理本地文件,结果被攻击者骗去给别的地方发请求了。
核心要点总结:利用PHP内置服务器路径解析中*通配符的漏洞,诱导服务器发起非预期的远程请求,实现SSRF攻击。
2 漏洞的2个关键限制
这个漏洞不是想用就能用的,有两个必须同时满足的限制条件。
2.1 只能用在根路径/
漏洞只在访问网站根目录/的时候才会触发。这意味着,受影响的代码得写在根目录的index.php文件里,像/admin/、/api/这些其他路径都不行。
2.2 第一个斜杠前不能出现.(点)
路径的第一个/之前,绝对不能有.字符。我们平常写的IP(像127.0.0.1)、域名(像example.com)都带. ,直接写会被服务器拦截,触发不了漏洞。
3 限制绕过方法
要绕过「不能出现.」这个限制,关键是把目标IP转换成不带点的十六进制或十进制格式。
比如说,常见的目标是访问本地127.0.0.1(内网本地服务,SSRF常用目标)。
- 常规IP:
127.0.0.1(带.,不能用) - 无点转换:把32位IP拼成完整十六进制数是
0x7F000001,对应的十进制是2130706433 - 最终可用格式:
2130706433(没点,符合服务器限制)
3.1 工具快速生成
手动算容易出错,这里有个GitHub工具 ,能一键生成无点IP。输入目标IP,直接输出能用的编码格式,复制就能拿来利用漏洞。
4 实战案例复现
4.1 环境准备
- 先在本地安装存在该漏洞的PHP版本(PHP 7.0 - 7.4这些旧版本,新版本已经修复了)。
- 在本地创建根目录
test,新建index.php,写入下面简单的请求转发代码(模拟有SSRF风险的业务逻辑):
php
<?php
// 模拟业务:获取用户传入的URL,发起请求(存在SSRF风险)
$url = $_GET['url']?? 'https://www.baidu.com';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>
- 启动PHP内置服务器,在
test目录执行命令:php -S 127.0.0.1:8000。这时服务器监听本地8000端口,根路径对应index.php,满足漏洞触发条件。
4.2 漏洞利用步骤
- 生成无点目标IP :要是我们想访问本地
127.0.0.1:8000的服务,用工具生成无点IP :127.0.0.1→ 无点十进制:2130706433。 - 构造恶意请求 :结合
*通配符,构造请求URL :http://127.0.0.1:8000/*2130706433*8000*/*?url=http://127.0.0.1:8000。 - 发送请求验证 :在浏览器或者用
curl工具访问这个URL ,PHP内置服务器会错误解析路径,向127.0.0.1:8000发起请求,成功触发SSRF ,就能获取本地服务的响应内容。要是出现"invalid link"报错,可能是PHP版本已修复漏洞,或者路径构造错了,可以换旧版本PHP再试试。
4.3 关键疑问:URL中3个"127.0.0.1:8000"的区别
为啥同一个URL里有3个看起来一样的127.0.0.1:8000 ?其实它们作用完全不同,只是凑巧指向同一个本地地址。
先看完整URL :http://127.0.0.1:8000/*2130706433*8000*/*?url=http://127.0.0.1:8000
- 第一个127.0.0.1:8000 :这是你要攻击的目标服务器 ,对应URL开头的
http://127.0.0.1:8000/,就像你射箭要瞄准的靶子,明确了你要攻击哪台机器,所有后续操作都围绕它。 - 第二个"127.0.0.1:8000" :它是绕过滤的伪装路径 ,对应URL中间的
*2130706433*8000*,这里面2130706433是127.0.0.1的无点十进制格式,8000是端口号。它不是真要访问这个地址,而是用来绕过PHP内置服务器"第一个斜杠前不能有."的限制,让服务器正常解析路径不报错,就像是骗服务器开门的工具。 - 第三个127.0.0.1:8000 :这是真正让服务器去访问的地址 ,对应URL末尾的
?url=http://127.0.0.1:8000,是SSRF攻击的核心目标。它告诉有漏洞的服务器"你帮我去请求这个地址" ,服务器收到指令就会主动发起请求,实现SSRF攻击。比如这里让服务器访问自身,能查看本地服务响应内容;换成内网其他IP ,就能扫描内网服务、获取敏感信息。
总结来说:第一个是"打谁",第二个是"怎么骗着进门",第三个是"让它做什么",用途完全不一样,只是地址碰巧相同。
4.4 国外公开案例补充
这个漏洞最早是安全研究员mhmdiaa公开披露的,在GitHub Gist上提供了完整的利用工具和测试方法,海外安全社区都验证过。可以用来攻击那些误把PHP内置服务器部署在公网的开发环境,能实现内网端口扫描、本地服务访问、文件读取等操作。
5 漏洞防御方案
5.1 核心防御
千万别在生产环境用PHP内置服务器,它是给本地开发用的,本身在生产环境安全性不够。生产环境得用Nginx/Apache + PHP - FPM的架构。
5.2 版本升级
要是非得用PHP内置服务器,那就升级到PHP 8.0及以上的最新版本,官方已经修复了路径解析的这个缺陷。
5.3 代码层面防护
对用户能控制的URL/路径参数做严格的白名单校验,只允许访问指定的域名/IP ,不许随便转发请求。
6 总结
这个PHP内置服务器的漏洞,是因为*通配符路径解析错误导致能构造SSRF攻击。
- 触发条件:PHP内置服务器加上根路径的
index.php。 - 绕过关键:把IP转成无点编码。
- 防御核心:别在生产环境用PHP内置服务器。
本文是「Web安全基础」系列内容,点击专栏导航查看全部系列内容。