cms逻辑问题-getshell
字数 1056 2025-08-06 18:08:14
CMS逻辑漏洞利用:绕过黑名单实现GETSHELL
漏洞概述
本文详细分析了一种CMS系统中存在的逻辑漏洞,该漏洞允许攻击者通过精心构造的payload绕过多重安全防护机制,最终实现代码执行和文件写入(GETSHELL)。漏洞核心在于exec函数拼接时的过滤不严,以及黑名单机制的绕过技巧。
漏洞环境
- 漏洞文件:
apps/home/controller/ParserController.php - 关键函数:
eval()执行用户可控输入 - 触发路径:通过CMS的模板解析机制最终到达漏洞点
三重防护机制分析
1. 第一重:黑名单过滤
系统维护了一个庞大的黑名单,拦截以下危险函数和关键字:
$_GET[ $_POST[ $_REQUEST[ $_COOKIE[ $_SESSION[
file_put_contents file_get_contents fwrite phpinfo base64
` shell_exec eval assert system exec passthru pcntl_exec popen proc_open
print_r print urldecode chr include request
__FILE__ __DIR__ copy call_user_ preg_replace
array_map array_reverse array_filter getallheaders get_headers
decode_string htmlspecialchars session_id strrev substr php.info
过滤逻辑:
if (preg_match('/上述黑名单正则/i', $matches[1][$i])) {
$danger = true;
}
if ($danger) {
continue; // 跳过解析
}
2. 第二重:函数名检测
系统检测括号前的字符串是否为函数名:
if (preg_match_all('/([\w]+)([\x00-\x1F\x7F\w\s\i', $matches[1][$i], $matches2)) {
foreach ($matches2[1] as $value) {
if (function_exists(trim($value)) && !in_array($value, $white_fun)) {
$danger = true;
break;
}
}
}
3. 第三重:模板语法限制
要求payload必须符合特定模板语法:
$pattern = '/\{pboot:if\s([\S]*?)\}\{\/pboot: if\}/';
if (preg_match_all($pattern, $content, $matches)) {
// 解析逻辑
}
关键限制:payload中不能包含$符号
绕过技巧
1. 绕过黑名单
虽然黑名单覆盖了大量函数,但仍有一些可用函数未被列入:
file()- 读取文件内容fputs()- 写入文件内容
2. 绕过函数名检测
使用注释符/*--*/可以阻断函数名检测:
/*--*/file();
3. 绕过$符号限制
由于payload中不能直接使用$符号,可以通过以下方法获取:
- 让CMS报错,从错误信息中获取绝对路径
- 使用
file()函数读取包含$符号的文件(如PHP文件本身) - 通过
fputs()写入文件时使用获取到的$符号
攻击链构建
-
触发路径:
- 访问首页触发
apps/home/controller/IndexController.php的_empty()方法 - 需要GET参数带有
tag进入判断 - 最终到达
apps/home/controller/ParserController.php的parserAfter()方法
- 访问首页触发
-
Payload构造:
- 使用
file()和fputs()组合 - 通过注释绕过函数检测
- 间接获取
$符号
- 使用
-
文件写入:
- 通过报错获取绝对路径
- 写入Webshell到可访问目录
防御建议
- 使用白名单而非黑名单机制
- 严格限制模板解析中的可执行代码范围
- 禁用
eval()等危险函数 - 对用户输入进行更严格的过滤和转义
- 实施代码审计,检查所有动态代码执行点
总结
该漏洞展示了黑名单防护机制的局限性,即使有多重过滤,仍可能被绕过。安全开发应遵循最小权限原则,避免不必要的动态代码执行,并采用更安全的替代方案处理用户输入。