seacms<=9.92前台getshell(已修复)
字数 1167 2025-08-27 12:33:49
SeaCMS <=9.92 前台GetShell漏洞分析教学文档
漏洞概述
SeaCMS内容管理系统在9.92及以下版本中存在一个严重的前台GetShell漏洞,攻击者无需登录即可利用该漏洞在服务器上执行任意代码。该漏洞源于代码逻辑缺陷和过滤不严导致的SQL注入,最终通过错误日志写入机制实现WebShell植入。
漏洞分析
1. 漏洞入口点
漏洞文件位于:comment/api/index.php
该文件开头包含:
require_once("../../include/common.php")
2. 全局变量注册问题
include/common.php会调用include/filter.inc.php进行全局变量注册,存在两个关键问题:
- 注册顺序错误:先注册变量,后检查变量名合法性
- 过滤不完整:漏过滤了
_SESSION、_FILES全局变量
3. 关键函数调用链
在comment/api/index.php第18行处调用了ReadData函数:
ReadData($rlist,$mlist,$id,$type);
$rlist变量可通过全局变量注册控制,该变量被传递到后续两个关键函数:
ReadmlistReadrlist
4. Readmlist函数分析
Readmlist函数对$rlist进行了过滤:
$rlist = str_replace(array("'","\"",")","("),"",$rlist);
过滤了单引号、双引号和括号,但未过滤其他SQL注入关键字符。
5. Readrlist函数漏洞点
Readrlist函数中存在直接拼接SQL语句的漏洞:
$query = "SELECT * FROM ".TABLE_PREFIX."comment WHERE id in ($ids) ORDER BY id DESC";
$ids即为可控的$rlist变量,且未使用引号包裹,导致SQL注入。
6. 错误处理机制导致GetShell
当SQL语句执行出错时,SeaCMS会将出错信息写入PHP文件(include/sql.class.php):
$error = date("Y-m-d H:i:s")." | ".getenv("REMOTE_ADDR")." | "."{$query}\n";
$error_file = CMSPATH."/data/errorlog.php";
file_put_contents($error_file,$error,FILE_APPEND);
由于错误信息中包含原始SQL查询,攻击者可以构造特殊SQL语句,将PHP代码写入错误日志文件。
漏洞利用步骤
- 构造恶意请求:通过GET/POST/COOKIE控制
$rlist变量 - 绕过过滤:使用未被过滤的SQL注入payload
- 触发SQL错误:构造会导致SQL语法错误的语句
- 注入PHP代码:通过错误信息将PHP代码写入日志文件
- 访问WebShell:访问
/data/errorlog.php执行任意代码
漏洞修复方案
- 修复顺序:应先检查变量名合法性再注册变量
- 完善过滤:增加对
_SESSION、_FILES的过滤 - 参数化查询:使用预处理语句替代SQL拼接
- 错误日志处理:对写入日志的内容进行严格过滤或禁用PHP代码执行
总结
该漏洞是典型的"多环节失效"安全漏洞,涉及:
- 全局变量注册逻辑缺陷
- SQL注入漏洞
- 不安全的错误处理机制
攻击者利用这些缺陷的连锁反应,最终实现了无需认证的前台GetShell。这反映了SeaCMS在安全编码实践上的严重不足,开发者应引以为戒,加强安全编码意识。