当前位置:首页 > 焦点

discuz34漏洞

2023年底,漏洞一个做论坛运维的漏洞朋友半夜给我发消息,说他的漏洞Discuz站点数据库里多了一张表,名字是漏洞一串乱码。他没装任何插件,漏洞后台日志也查不到登录记录。漏洞我当时第一反应是漏洞误报,但看了他导出的漏洞SQL文件后,基本确定——这是漏洞Discuz X3.4的一个已知漏洞被人扫到了。

Discuz X3.4在国内论坛系统里的漏洞装机量不用多说,从地方门户到高校BBS,漏洞再到各种资源站,漏洞存量站点保守估计还有几十万个。漏洞这个版本官方早已停止主力维护,漏洞但大量站长因为插件兼容性、漏洞模板改造成本等问题,一直没升级到X3.5或更高版本。漏洞就藏在这种“用着还行就不动”的惯性里。

漏洞到底出在哪

问题集中在source/class/helper/helper_seccheck.php这个文件。X3.4的验证码校验逻辑在处理某些特定请求参数时,没有对数组类型的输入做严格过滤。攻击者可以通过构造畸形的seccode参数,绕过验证码检查,进而利用前台某些接口的SQL查询拼接缺陷,实现注入。

听起来有点绕。换个说法:正常情况下,你发帖或注册时系统会让你填验证码,填对了才放行。但这个漏洞允许攻击者把验证码校验那一步直接“短路”掉,然后在前台某个不设防的入口塞入恶意SQL语句。整个链条不需要后台权限,也不需要知道管理员密码。

我后来在本地搭了一个X3.4的环境复现,从发送构造请求到数据库返回异常数据,整个过程不到三秒。用sqlmap的话,一条命令就能跑出当前数据库名和用户表前缀。

真实攻击是什么样的

朋友那台服务器被入侵的时间点大概在凌晨两点到四点之间。攻击者没有直接拖库,而是先插入了一张乱码表,里面存了一个webshell的十六进制编码。第二天上午,服务器开始对外发送大量垃圾邮件——说明webshell已经被激活,机器变成了肉鸡。

这种手法在Discuz漏洞利用里很常见。直接拖库动静太大,数据库日志容易暴露;先拿shell再慢慢渗透,隐蔽性高得多。我看了下他服务器上的访问日志,攻击IP来自三个不同的境外VPS,请求路径伪装成了正常的member.php和forum.php,User-Agent是常见的浏览器标识。如果不是数据库里多了那张表,可能再过一周都不会发现。

修复没想象中那么难

官方在X3.4的后续补丁里其实已经修了这个问题,但补丁包没有单独发公告,很多站长根本不知道。如果你还在跑X3.4,最直接的办法是去GitHub上找Discuz的官方仓库,对比helper_seccheck.php的提交记录,手动把那段校验逻辑替换掉。改动量不大,核心就是加一个is_array()判断,再把参数强制转成字符串。

不想动手改代码的话,还有个土办法:在Nginx或Apache层面加一条规则,拦截所有seccode参数里包含方括号或特殊字符的请求。这不能根治,但能挡住大部分自动化扫描工具。我朋友后来就是先用这条规则顶了三天,等周末才做的代码替换。

另外说一句,别指望WAF能百分百拦住。我测试时用的几个免费WAF规则库,对这个漏洞的检出率不到四成。真正靠谱的还是把代码补丁打上,然后改掉数据库前缀,删掉install/目录,后台管理入口加IP白名单。这些老生常谈的操作,在X3.4这种老系统上反而最有效。

一个容易被忽略的细节

很多站长在修复后只检查了data/和config/目录,忘了看数据库里的common_member表。攻击者如果通过漏洞注册了隐藏管理员账号,光改代码是清不掉的。我朋友那台机器上就多了一个uid=8888的用户,用户名是一串正常汉字,但groupid被设成了1。这个账号在后台用户列表里不显示,只有直接查数据库才能看到。

所以修复步骤里应该加一条:核对common_member和common_member_field_home表,把不在你记忆里的管理员账号全部清掉。别嫌麻烦,这一步省了,前面补丁白打。

Discuz X3.4是个好系统,稳定、插件多、社区生态成熟。但好系统不等于没漏洞,尤其是停止维护之后。你不动它,不代表别人也不动它。

分享到: