タグアーカイブ 管理者アカウント

WordPressの__GA_INJ_START__マルウェア感染を完全駆除する手順

WordPressの__GA_INJ_START__マルウェア感染を完全駆除する手順

WordPress のテーマファイル functions.php に「__GA_INJ_START__」というコメント記述を見つけたら、Google Analytics を装ったマルウェア感染の可能性が高い。完全に駆除するには、functions.php を元に戻すだけでは不十分で、データベースに潜む隠し管理者アカウントの削除と侵入経路の遮断まで行う必要がある。

__GA_INJ_START__マルウェアとは何か

__GA_INJ_START__マルウェアとは何か

このマルウェアは、テーマの functions.php 内に不正なコードを注入する際、開始位置の目印としてコメント文「__GA_INJ_START__」を書き込む。Google Analytics の計測タグに似せた外見のため、コードをざっと見ただけでは正規のトラッキングコードと勘違いしやすい。

実際に注入されるコードは、Google Analytics とは無関係の永続的なバックドアとして働く。具体的には、不正な管理者アカウントを定期的に生成したり、攻撃者が自由にサイトへ再侵入するための隠し経路を維持する機能を持つ。コード自体が自己修復的に動くこともあり、単に該当部分を削除しても再び書き戻されるケースがある。

感染の典型的な流れは、まず正規の WordPress 管理者アカウントへ何らかの方法でログインし、管理画面内のファイル編集機能やコードスニペット系プラグインを経由して functions.php に到達する。その段階で不正な管理者アカウントを追加し、数日から数週間かけて隠しアカウントを増やした後、最終段階として __GA_INJ_START__ 付きのコードがテーマに注入される。

典型的な感染の進行フロー
正規のWP管理者ログイン ファイル編集系プラグイン操作 functions.phpへアクセス 不正な管理者アカウント作成 GA_INJテーマ注入
侵入段階  攻撃準備段階  最終的な感染完了

このデモは侵入から感染完了までの典型的な進行パターンを示している。攻撃者は一度管理者権限を得ると、すぐに目立つ改ざんを行うのではなく、まず隠しアカウントを作って持続的なアクセスを確保するのが特徴だ。

隠し管理者アカウントをどうやって見つけるか

隠し管理者アカウントをどうやって見つけるか

このマルウェアに感染したサイトでは、データベース内に通常では一覧に表示されない形で不正な管理者アカウントが追加されている。管理画面のユーザー一覧に表示されない場合もあるため、phpMyAdmin などでデータベースを直接確認するのが確実だ。

まず wp_users テーブルを開き、ユーザー名に不審な接頭辞が付いていないかを確認する。具体的には sync_agent、cdn_worker、seo_service の後にランダムな英数字が続く形式のアカウントが典型的だ。テーブルプレフィックスが wp_ 以外の場合は、その文字列に読み替えて探す。

次に wp_usermeta テーブルで、該当ユーザー ID に administrator 権限を付与するエントリが存在するかを調べる。さらに wp_options テーブルには __ga_hidden_users、_theme_inject_status、__ga_r_cache という見慣れないキーが保存されていることがある。これらのキーはマルウェアが隠し管理者の一覧を管理するために使う。

サーバーに SSH でログインできる環境なら、ファイルシステム全体を横断検索するのが最も早い。以下のコマンドでマルウェア特有の文字列を探せる。

grep -RniE '__GA_INJ|__ga_hidden_users|__ga_r_cache|_theme_inject_status|sync_agent|cdn_worker|seo_service' .

SSH が使えない場合は、FTP でファイルをダウンロードしてエディタの検索機能を使うか、運営中のレンタルサーバーが提供するファイルマネージャの検索機能を活用する。また、WordPress 管理画面から有効化されているプラグイン一覧を確認し、心当たりのないプラグインが増えていないかも必ず調べる。

マルウェアを完全に駆除するにはどうすればいいか

マルウェアを完全に駆除するにはどうすればいいか

重要なのは、functions.php を置き換えるだけでは駆除できないという点だ。隠し管理者アカウントとバックドアをすべて取り除くまで、攻撃者は何度でも再侵入できる。以下に駆除の全体フローを示す。

STEP 1 サイト全体のバックアップを取得する
STEP 2 データベースで隠し管理者アカウントを特定して削除する
STEP 3 functions.php から不正コードを除去する
STEP 4 全ファイルをバックドアの兆候がないか走査する
STEP 5 全管理者パスワードを変更しセッションをリセットする
STEP 6 WordPress本体、テーマ、プラグインを全て更新する

このデモは駆除作業の全体像を示している。以下、各ステップの具体的な進め方を詳しく解説する。

バックアップを必ず先に取得する

駆除作業ではデータベースのレコード削除やファイルの書き換えを行うため、操作を誤るとサイトが壊れる恐れがある。作業前にデータベースとファイルの両方を丸ごとバックアップしておく。レンタルサーバーにバックアップ機能が付属している場合も、念のため別の場所にもコピーを保存する。

隠し管理者アカウントをデータベースから削除する

phpMyAdmin などで wp_users テーブルを開き、不審なユーザー名のレコードを特定する。sync_agent、cdn_worker、seo_service にランダムな英数字が付いた形式が典型だが、まったく別の名前で偽装している可能性もある。新規登録した覚えのない管理者権限ユーザーはすべて削除対象だ。

ユーザーを削除する際、wp_usermeta テーブルに残った関連エントリも忘れずに削除する。SQL を直接実行する場合は、該当ユーザー ID を指定して両テーブルからレコードを消す。操作前に必ずバックアップを取り、プレビュー画面で対象レコードを確認してから実行する。

functions.php の不正コードを除去する

テーマの functions.php をエディタで開き、__GA_INJ_START__ から始まるコメントと、それに続くコードブロックを特定する。__GA_INJ_END__ または類似の終了マーカーがある場合は、その範囲全体を削除する。マーカーが無い場合は、不審な関数定義や管理者アカウントを操作するコードを丁寧に確認しながら取り除く。

該当テーマが親テーマなら、修正がテーマ更新で失われないよう子テーマ化を検討する。また、他のテーマファイルや wp-content 直下の PHP ファイルにも同じマーカーが仕込まれている可能性があるため、前述の grep コマンドで全ファイルを横断検索してから作業するのが安全だ。

セッションとパスワードをリセットする

攻撃者が既存のセッションを保持していると、アカウントを消してもアクセスが続く。WordPress の管理画面からユーザー一覧を開き、すべての管理者ユーザーに対して「全てのセッションを破棄」を実行する。さらに全管理者のパスワードを新しいものへ変更する。可能ならメールアドレスも再確認し、見覚えのない転送設定が無いか調べる。

アクセスログから感染時期を特定するにはどうするか

アクセスログから感染時期を特定するにはどうするか

__GA_INJ_START__ が functions.php に現れた日が感染開始日とは限らない。実際には、その数日前から数週間前にかけて攻撃者が隠し管理者アカウントを作り、段階的に足場を固めていたケースが多い。駆除後に再発を防ぐには、感染の起点となった脆弱性や認証情報を特定することが欠かせない。

まずデータベースの wp_users テーブルで、不正な管理者の登録日時を確認する。WordPress はユーザー作成日時を user_registered カラムに記録している。次にサーバーのアクセスログを同じ期間分さかのぼり、wp-login.php へのログイン試行や、admin-ajax.php、theme-editor.php などへの不審なアクセスが無いかを照合する。

攻撃者が最初に正規の管理者アカウントでログインしていた場合、ログには正常なログインとして記録されているため見落としやすい。ログイン元 IP アドレスの突発的な変化、深夜帯のログイン、短時間での連続したファイル編集操作などを手がかりにする。ログの保存期間が短いレンタルサーバーでは、可能な範囲でログ保管期間を延ばしておくと今後の調査に役立つ。

再感染を防ぐには何をすればいいか

再感染を防ぐには何をすればいいか

駆除が完了しても、侵入経路が残っていれば同じ手口で再び感染する。再発防止には、まず WordPress 本体、テーマ、プラグインを最新版へ更新する。侵入経路として悪用された可能性のあるファイル編集系プラグインやコードスニペット系プラグインは、使用していないなら削除する。

管理者アカウントに対しては二段階認証を有効にし、パスワードは推測されにくい長いものへ変える。管理画面へのアクセスを IP アドレス制限で絞るのも効果的だ。さらに wp-config.php にファイル編集機能を無効化する定数 DISALLOW_FILE_EDIT を追加すると、管理画面からテーマやプラグインのコードを書き換えられる経路を塞げる。

定期的な点検も重要になる。ユーザー一覧に知らない管理者が増えていないか、wp_options に見覚えのないキーが無いか、functions.php などのテーマファイルに不審なコメントが追加されていないかを毎月確認する。可能ならセキュリティプラグインによる定期スキャンを導入し、変更検知の通知を受け取れるようにしておく。

Before 感染状態

functions.php に __GA_INJ_START__ が注入され、データベースには sync_agent や cdn_worker などの隠し管理者が存在する。攻撃者はいつでも再侵入できる状態。

After 駆除完了

不正コードが除去され、隠し管理者はデータベースから完全に削除済み。パスワードとセッションもリセットされ、更新も適用されている。

感染状態  駆除完了

このデモは駆除前後の状態を対比したものだ。感染状態ではマルウェアの目印と隠し管理者が残っているが、駆除後は不正な要素がすべて取り除かれている。

よくある質問

__GA_INJ_START__はGoogle Analyticsの正規コードではないのか

正規の Google Analytics 計測コードにこのようなマーカーは存在しない。__GA_INJ_START__ は不正なコードの開始位置を示す目印で、マルウェアが後からコードを書き戻す際の識別子として使われる。テーマファイルにこの文字列を見つけたら感染を強く疑うべきだ。

隠し管理者アカウントはデータベースのどこを確認すれば見つかるか

wp_users テーブルと wp_usermeta テーブルの両方を確認する。ユーザー名が sync_agent、cdn_worker、seo_service にランダムな英数字が付いた形式なら要注意だ。さらに wp_options テーブルに __ga_hidden_users や _theme_inject_status などの見慣れないキーが無いかも調べる。

セキュリティプラグインを導入しているのに感染したのはなぜか

プラグインが検出できるシグネチャを持たない新種や変種だった、定義が古かった、正規の管理者としてログインしてから活動したため不正ログインと判定されなかった、などの理由が考えられる。プラグインに頼るだけでなく、定期的なユーザー一覧やファイルの目視確認も併用する。

感染後、サイトを公開したまま駆除作業はできるか

推奨されない。攻撃者がバックドアを持っている間、サイトを公開し続けると訪問者の情報が窃取されたり、別の攻撃の踏み台にされたりする恐れがある。可能ならメンテナンスモードに切り替え、バックアップを取ってから作業するのが安全だ。

駆除後にサイトが真っ白になった場合の対処方法は?

デバッグモードを有効にしてエラー内容を特定し、テーマやプラグインを一つずつ有効化して切り分ける。テーマの functions.php を編集した際に記述ミスがあると画面が真っ白になることが多い。感染前のバックアップがあれば、その時点から修復する方が確実な場合もある。

この記事のポイント

  • __GA_INJ_START__はGoogle Analyticsを装ったマルウェアの目印
  • 隠し管理者アカウントはデータベースを直接確認しないと見落とす
  • functions.phpの置き換えだけでは再感染する
  • アクセスログを数日〜数週間さかのぼって感染起点を探す
  • 駆除後は全パスワード変更とセッションリセットが必須
OptinMonsterやTrustPulseが原因でWordPressが乗っ取られた時の対処

OptinMonsterやTrustPulseが原因でWordPressが乗っ取られた時の対処

特定のプラグインをインストールしていた WordPress サイトで、管理者アカウントが勝手に作られたり、マルウェアを仕込まれる被害が広がっている。無効化した状態でも影響を受けるため、すぐにユーザー一覧とプラグインフォルダを確認しなければならない。

なぜ無効化したプラグインで侵入されたのか

なぜ無効化したプラグインで侵入されたのか

被害報告が相次いでいるのは、OptinMonster、TrustPulse、PushEngage という 3 つのプラグインだ。いずれも単体で配布されているほか、MonsterInsights Pro にバンドル(同梱)されて提供されている。注目すべきは、有効化していなくてもプラグインとして存在するだけで攻撃対象になった点だ。WordPress はプラグインを無効化しても、ファイル自体はサーバー上に残る。攻撃者はそのファイルに含まれる脆弱性を利用して外部からコードを実行し、管理者アカウントの新規作成や Cloudflare/ClearFake マルウェアの設置を行った。

無料版の Wordfence では検知できなかったケースが確認されている。シグネチャ(攻撃パターン)が更新されるまでの時間差や、攻撃手法が亜種に変化していたことが原因とみられる。そのため、目視での確認が不可欠だ。

侵入前 プラグインが無効で放置、ファイルはサーバー上に存在
侵入後 不明な管理者アカウントが追加され、不正な PHP ファイルが設置される
侵入前(ファイルはあるが無害に見える)  侵入後(管理者アカウントやマルウェアが追加される)

このデモは、プラグインファイルが放置された状態から攻撃者が侵入し、追加の不正な要素を仕込む流れを示している。

自分のサイトが影響を受けているか確認する手順

自分のサイトが影響を受けているか確認する手順

管理者アカウントの一覧を調べる

WordPress 管理画面の「ユーザー」→「すべてのユーザー」を開き、覚えのない管理者権限のアカウントが追加されていないかを確認する。アカウント名やメールアドレスに覚えがないもの、登録日時が直近のものがあれば要注意だ。

プラグインフォルダに不審な PHP ファイルがないか調べる

FTP ソフトやレンタルサーバーのファイルマネージャーで /wp-content/plugins/ 以下を開く。特に OptinMonster、TrustPulse、PushEngage のフォルダ内に、本来あるはずのない名前の PHP ファイルや、暗号化されたような文字列が書かれたファイルがないかを確認する。

プラグインをすでに削除してしまった場合でも、/wp-content/ 直下や /wp-includes/、テーマフォルダ内に不審な PHP ファイルが残っていないか、更新日時が最近のものに心当たりがないかを見ておくとよい。

STEP 1 管理画面「ユーザー」で管理者アカウントを確認
STEP 2 FTP で /wp-content/plugins/ 以下の不審ファイルを調査
STEP 3 .htaccess や wp-config.php に追記がないかも確認

管理者アカウントとファイルの両面から、侵入の痕跡を短時間で洗い出す手順を示している。

不正アクセスが発覚した場合の緊急対応

不正アクセスが発覚した場合の緊急対応

不正な管理者アカウントを即座に削除する

覚えのない管理者アカウントを見つけたら、すぐにそのユーザーを削除する。削除時に「すべての投稿を帰属させる」選択肢が出るが、攻撃者が作成した投稿や固定ページがなければそのまま削除してよい。念のため、削除前にゴミ箱や下書きに不審なコンテンツがないかも確認しておく。

不正ファイルを削除し、該当プラグインを完全に除去する

不審な PHP ファイルは必ずバックアップを取った上で削除する。OptinMonster、TrustPulse、PushEngage のいずれかがインストールされているなら、今後も脆弱性が残る可能性を考え、プラグイン自体を完全に削除するのが安全だ。同梱元の MonsterInsights Pro を利用している場合も、これらのアドオンが自動でインストールされていないか確認する。

サイト全体のマルウェアスキャンを実施する

Wordfence や Sucuri などのセキュリティプラグインで手動の詳細スキャンを実行する。無料版の自動スキャンだけでは検知漏れが起こる可能性があるため、手動でフルスキャンをかける。Sucuri のサイトチェック(外部スキャナ)を併用すると、サーバー内部からは見えにくい改ざんも検出しやすくなる。

再発防止と今後のセキュリティ対策

再発防止と今後のセキュリティ対策

使用していないプラグインやテーマは「無効化」ではなく「削除」する

WordPress では、プラグインを無効化してもファイルはサーバー上に残り続ける。今回の事例が示すように、無効状態でもファイルが存在するだけで攻撃の足場になる。今後は使わないと判断したプラグインやテーマは、面倒でも完全に削除する習慣をつけるのが鉄則だ。

プラグインの更新を常に最新に保ち、導入元を精査する

公式リポジトリ外のプラグインや、長期間更新が止まっているものはリスクが高い。どうしても必要な場合を除き、信頼できる提供元のものだけを使う。自動更新を有効にしておくと、脆弱性が公表された直後の修正パッチを適用しやすくなる。

定期的な管理者アカウントとファイルの監査を組み込む

月に一度は「ユーザー一覧」を開き、見慣れないアカウントがないかを目視点検する。あわせて、サーバーのファイル更新日時を確認し、心当たりのないタイミングで変更されたファイルがないかをチェックする。人が目で見る作業は、自動ツールの検知漏れを補う最後の砦になる。

よくある質問

無効化していてもなぜハッキングされたのか

無効化はあくまでプラグインの動作を止めるだけで、ファイルはそのままサーバーに残る。今回の攻撃はファイルの存在を前提に外部から直接コードを実行する手法だったため、有効か無効かは関係なく被害が発生した。

Wordfence が入っていれば安心なのか

今回の事案では、無料版 Wordfence で検知できなかった例がある。セキュリティプラグインに過度な期待をせず、定期的な手動確認と不要なファイルの削除を組み合わせることが欠かせない。

MonsterInsights を使っているが該当プラグインは入れていない

MonsterInsights Pro の一部バージョンでは、これらのプラグインが同梱されて自動インストールされる場合がある。プラグイン一覧を開き、OptinMonster、TrustPulse、PushEngage が存在しないか今一度確認してほしい。

すでに削除したが、まだ不安が残る場合の最終確認方法は

レンタルサーバーの管理画面で最近のアクセスログを確認し、不審な IP アドレスや POST リクエストがないかを調べる。データベースの wp_users テーブルと wp_usermeta テーブルを直接 SQL で確認し、管理者権限(wp_capabilities に administrator を含む)のユーザーに不明なものがないかを調べる方法も有効だ。

この記事のポイント

  • OptinMonster、TrustPulse、PushEngage は無効化でも攻撃対象になる
  • 管理者一覧とプラグインフォルダをすぐに目視確認する
  • 不正アカウントと不審ファイルは即座に削除する
  • 今後は使わないプラグインを無効化で放置せず完全削除する
  • セキュリティプラグインだけに頼らず定期手動監査を組み込む