「勝手に広告が表示される」——その正体、マルウェアとは限りません

「サイトに身に覚えのない広告が出ている」「プラグインが勝手に操作されている気がする」。こうした相談を受けたとき、多くの人がまずマルウェア感染や乗っ取りを疑います。今回ご相談をいただいたニュースメディアサイトも、まさにその疑いから調査が始まりました。

ところが、約15,000本のファイルとデータベースを精査した結論は「マルウェアは存在しない」。真相は、もっと気づきにくいものでした。セキュリティの甘さを突かれて第三者に不正ログインされ、管理画面から無断で広告タグを仕込まれて、広告収益を奪われていたのです。この記事では、その調査から完全除去までの記録を、同じ被害を防ぎたい運営者の方と、調査手法を知りたい技術者の方の両方に向けて残します。

なぜ、マルウェアがなくても被害に遭うのか?

答えは、攻撃者が「不正なコードを仕込む」代わりに、「管理画面に正規にログインして操作する」手口を使ったからです。今回のサイトはログインまわりのセキュリティが甘く、第三者に不正ログインを許してしまった可能性が高い状態でした。

いったん管理画面に入られてしまえば、攻撃者は正規の広告プラグインを使って広告を仕込むだけです。ファイルにはウイルスもバックドアも残らないため、ウイルススキャンをかけても何も出ません。だから、セキュリティ的には”異常なし”に見えてしまい、気づかないうちに収益を吸われ続けてしまいます。

放置するとどうなる? 収益の横取りだけでは済まない

結論から言うと、この被害には「収益を奪われる」以上の実害があります。今回のケースで確認できたリスクを整理します。

リスク 何が起きるか
広告収益の横取り 本来サイト所有者に入るはずの広告収益が、第三者のアカウントに支払われ続ける。
本人の広告アカウント停止 不適切な広告と同一ページに自社広告が出ることで、本人のAdSense等がポリシー違反で停止・BANされる恐れ
ブランド・信用の毀損 ニュースメディアに、脈絡のない広告や不適切な広告が表示される。
気づきにくさ マルウェアではないため通常の対策では検知されず、長期間放置されやすい。

とくに深刻なのが2番目です。今回、仕込まれていた広告にはアダルト・出会い系の広告が含まれていました(本記事には画像は掲載しません)。Google AdSenseは、アダルトコンテンツや広告と同じページに自社広告を出すことをポリシー違反として厳しく扱います。つまり第三者は、収益を吸い上げるだけでなく、サイト所有者本人のAdSense資産まで危険にさらしていたことになります。

いちばん巧妙だった「オトリ」の仕掛け

この件で最も悪質だったのが、本人のAdSenseを”オトリ”に使っていたことです。広告設定の一番目には、確かにサイト所有者本人のAdSenseタグが置かれていました。ところがそれは「表示オフ(無効)」に設定され、実際には1円も生んでいなかったのです。

管理画面をパッと見ると「本人のAdSenseが入っている」ので安心してしまう。しかし実際に稼働して収益を生んでいたのは、その裏に並んだ第三者名義の広告ネットワーク「AdStir」のタグでした。しかもそのタグは、目立つ場所だけでなく、休眠中の広告枠や、タイトルのない非公開の下書き投稿にまで分散して隠されていました。

下の画面は、そのタイトルのない下書き投稿の中身です。「広告①」「広告②」としてAdStirの広告コードが埋め込まれ、実際に配信されていたのはアダルト系の広告でした(広告画像は黒く塗りつぶしています)。

タイトルのない非公開の下書き投稿に、AdStirの広告コードが埋め込まれていた画面。配信されていたアダルト広告の画像は黒く塗りつぶしている

技術編に入る前に:運営者が今すぐ確認すべき3点

マルウェアが見つからなくても「無断マネタイズ」の可能性は残ります。専門知識がなくても、次の3点だけはまず確認してください。

  • ads.txt(=広告収益の支払先を宣言するファイル)に、身に覚えのないネットワークやアカウントIDが並んでいないか
  • コード挿入系のプラグイン(広告挿入・スニペット系)に、誰が入れたか分からない広告タグがないか
  • 広告タグやads.txtのアカウントIDが、本当に”自分のもの”か

ここから先は、実際にどう調査し、どう完全除去したかの技術記録です。

第一段階の調査:本当にマルウェアはいるのか?

まず「マルウェアがいる」という疑いを、潰し込みで検証しました。プラグイン配下のPHPファイル約15,000本を対象に、マルウェアの定番シグネチャを横断検索します。難読化・動的実行・Webシェル・権限昇格・不正なファイル書き込みなどを一括で洗い出しました。

結果は、いずれも正規プラグインの正当な用途のみで、第三者の不正コード・バックドアは検出ゼロ。あわせてWordPressコアや .htaccess、アップロードディレクトリも確認しましたが、改ざんの痕跡はありません。マルウェアが一括でファイルを書き換えたときに特有の「同一日時で大量のファイルが更新される」パターンも見られませんでした。

ファイルがクリーンでも、DBに保存されたコードが実行される経路が残るため、データベースも精査しました。管理者アカウントは本人1名のみ(不正な管理者の追加なし)、コードスニペット・WP-Cron・重要オプションにも不審な点はなし。第一段階の結論は「コードを仕込むタイプのマルウェア・バックドアの痕跡は一切なし」。ただし、これは”誰も侵入していない”という意味ではありませんでした。

第二段階:Base64に隠された「本当の問題」を解読する

コード上のマルウェアはいない。では「勝手に広告が表示される」の正体は何か。ここで所有者から決定的な証言が得られます。「これらの広告プラグインを、自分で入れた覚えがない」。つまり、第三者が不正ログインで管理画面に入り込み、正規のプラグインを使って広告を仕込んでいたという筋です。しかも攻撃者は、新しい管理者アカウントを作らず既存のアカウントに入り込んで操作していたため、「不正な管理者の追加」としては表に出ず、いっそう気づきにくくなっていました。

広告表示を担っていたのは、広く使われている正規の広告挿入プラグインでした。ただし設定は独自のBase64形式でDBに保存されており、素の検索では中身が見えません。全16ブロックをデコードして解析したところ、次の構造が判明しました。

  • 1番目のブロック:本人のAdSense。ただし「無効」に設定され表示されていない(=オトリ)
  • 残りの大半のブロック:第三者名義の広告ネットワーク「AdStir」のタグ(アカウントIDは2系統)
  • タグは、稼働中の枠・休眠中の枠・タイトルなしの下書き投稿4件・ads.txt に分散して隠蔽

なお、AdStir自体は正規の広告ネットワークです。問題はネットワーク側にあるのではなく、その仕組みが悪用され、第三者のアカウントに収益が流れる形で無断で仕込まれていたことにあります。下の画面は、実際に仕込まれていた広告ブロックの一つです(アカウントIDは伏せ字にしています)。上部のタブを見ると広告枠は16個あり、その多くにこうしたAdStirのタグが仕込まれていました。

広告挿入プラグインに仕込まれていたAdStirの広告タグ。アカウントID(app_id)は伏せ字。上部のタブから広告枠が16個あることが分かる

さらに ads.txt にも、AdStirの認可行が大量に書き込まれていました。ads.txt は「この広告枠の収益は、このアカウントに支払ってよい」と宣言するファイルです。身に覚えのないアカウントの DIRECT 宣言がある=その相手に収益が流れることを意味します。本来このサイトのads.txtは1行で十分なはずが、下の画面のように100行以上が不正に追記されていました(サイトを特定する情報は黒塗りにしています)。

ads.txt管理画面。本来は本人のAdSense1行だけのはずが、AdStir経由の提携ネットワークの行が100行以上も不正に追記されていた。サイトを特定する情報は黒塗り

除去対応:「配信されるHTMLに出ない」を最終ゴールに

対応の考え方はシンプルです。どこに保存されていようと、実際に配信されるHTMLに出なければ広告は動いていない。これを最終ゴールに、隠し場所を1つずつ潰しました。

  • 広告挿入プラグイン:稼働中の第三者ブロックを本人のAdSenseに差し替え、休眠中の第三者ブロックはすべて空に
  • 広告用の下書き投稿:タグ埋め込み用に作られていたタイトルなしの下書き4件を削除
  • ads.txt:AdStirの認可行を丸ごと削除し、本人のAdSense1行のみを残す
  • 履歴の掃除:削除した下書きはゴミ箱を空にして完全削除。文字列が残るリビジョン(編集履歴)もDBから削除

ads.txt は、除去前後でこれだけ変わりました(IDは伏せ字)。

検証:本当に消えたかを、多層で確認する

「対応した」で終わらせず、残存ゼロを多層で確認しました。まずキャッシュをパージし(古いキャッシュに広告が残るのを防ぐ)、次に公開ページのHTMLソースを表示して広告ネットワーク名・アカウントIDを検索。さらにデータベース全体もSQLで検索します。

配信HTML・データベースの両面で残存0件を確認して、対応完了です。あわせて、bot登録と思われるスパム会員の整理、不要な会員登録の受付停止、管理者パスワードの変更といった、最低限のセキュリティ対応も実施しました。

再発防止:不正ログインを防ぎ、広告を点検する

今回の根本原因は、ログインまわりのセキュリティが甘く、不正ログインを許してしまったことでした。対策は2方向です。まず「入られない」ための守りを固め、あわせて「入られても早く気づける」点検を習慣にしてください。

  • 強固なパスワード+二段階認証(2FA):推測されにくいパスワードにし、可能なら二段階認証を有効化する。これが最優先
  • ログイン試行の制限:総当たり攻撃を防ぐため、ログイン失敗回数の制限やログインURLの変更などを行う
  • 管理者アカウントの棚卸し:不要な管理者・使っていないアカウントを削除し、権限は必要最小限にする
  • ads.txt を定期的に確認する:身に覚えのないネットワークやアカウントIDが増えていないか、支払先を点検する
  • 広告・コード挿入系プラグインを棚卸しする:ブロック単位・スニペット単位で「何が・どこに・どのアカウントID宛に」入っているかを点検する

まとめ:マルウェアがなくても「安全」とは限らない

今回のように、マルウェアがなくても収益を奪われ、しかも自社の広告アカウントまで危険にさらされるケースがあります。無断マネタイズは「不正コードではない」ために見逃されやすく、気づいたときには長期間の収益を失っていることも少なくありません。定期的な広告・ads.txt・コード挿入プラグインの棚卸しが、最大の防御になります。

私たちEdel Heartsは、「身に覚えのない広告が出る」「不正ログインされたかもしれない」「マルウェアか判断できない」といったWordPressの調査・復旧を、原因特定から完全除去・検証まで対応するWordPress専門チームです。今回のように、マルウェアではない”見えにくい被害”の切り分けも得意としています。少しでも不安があれば、無理に触らず、まずはご相談ください。

この記事をシェア