2025年11月20日

2025年11月20日

データベースに感染するマルウェアの特徴

気づいた時には手遅れだった、あるECサイトの事件

5年ほど前、中規模のECサイトを運営するクライアントから「最近サイトが重い」という相談を受けた。アクセス数は変わっていないのに、ページの読み込みに時間がかかる。最初はサーバースペックの問題かと思ったんだ。

でも、データベースをチェックしてみて驚いた。正規のテーブルの中に、見覚えのないデータが大量に埋め込まれていた。商品テーブルの説明文カラムに、不正なJavaScriptコードが数百件も追加されていたんだ。ページを表示するたびに、そのコードが実行されて、訪問者を詐欺サイトに誘導する仕組みになっていた。

データベースに直接マルウェアを埋め込むという手口は、ファイルベースのマルウェアよりも発見が遅れがちだ。ウイルススキャンソフトではファイルしかチェックしないから、データベース内の不正なデータには気づかない。このクライアントの場合、感染から3ヶ月も気づかなかったらしい。その間、何人もの顧客が被害に遭っていた。

データベースの全テーブルを調べて、不正なデータを一つ一つ削除していった。作業は2日間かかった。さらに、どこから侵入されたのか調査して、脆弱性を塞ぐ必要があった。結局、古いプラグインのSQLインジェクション脆弱性が原因だったんだ。

この記事では、データベースに感染するマルウェアの特徴と、その発見方法、対策について解説する。データベースマルウェアは目に見えない分、厄介だ。でも、特徴を知っていれば、早期発見できる可能性が高まるんだよね。

データベースマルウェアとは何か

ファイルではなくデータとして潜む

通常のマルウェアは、サーバー上のファイルとして存在する。shell.phpとか、悪意のあるJavaScriptファイルとか。こういったファイルは、ファイルシステムをスキャンすれば見つけられる。

でも、データベースマルウェアは違う。MySQLやMariaDBのデータベース内に、データとして保存されるんだ。テーブルのカラムに不正なコードを埋め込んで、ページが表示される時に実行させる。

データベースマルウェアの特徴:

  • ファイルシステムに痕跡を残さない
  • ウイルススキャンでは検出できない
  • バックアップに含まれてしまう
  • データの一部として偽装している
  • 手動でデータベースを確認しないと見つからない

WordPressの場合、投稿内容、コメント、メタデータ、オプションテーブルなど、あらゆる場所に埋め込める可能性がある。特に狙われやすいのは、頻繁に表示される場所だ。

よくある感染パターン

データベースマルウェアには、いくつか典型的なパターンがある:

1. JavaScriptインジェクション

投稿内容や固定ページに、悪意のあるJavaScriptを埋め込む。ページが表示されると、そのコードが実行されて、訪問者を別のサイトに誘導したり、フィッシング画面を表示したりする。

2. SEOスパム

投稿のメタデータや隠しリンクを大量に追加する。検索エンジンには見えるけど、人間には見えないようにCSSで隠している。検索順位を操作したり、スパムサイトへのリンクを仕込んだりするんだ。

3. 管理者アカウント追加

wp_usersテーブルに、攻撃者が用意した管理者アカウントを追加する。これで、いつでも管理画面にアクセスできるバックドアを作られてしまう。

4. リダイレクトコード

wp_optionsテーブルなどに、リダイレクトコードを仕込む。特定の条件(検索エンジンからのアクセスなど)で、別のサイトに飛ばす仕組みだ。

なぜデータベースが狙われるのか

発見されにくい

データベースマルウェアの最大の利点は、攻撃者にとって発見されにくいことだ。サイトオーナーの多くは、ファイルの改ざんには気づいても、データベースの中身までチェックしない。

セキュリティプラグインも、主にファイルシステムをスキャンする。データベースの内容まで詳しくチェックするプラグインは少ない。だから、感染していても何ヶ月も気づかないケースが多いんだよね。

削除されにくい

ファイルベースのマルウェアは、ファイルを削除すれば済む。でも、データベースマルウェアは、どのテーブルのどのレコードに埋め込まれているか特定する必要がある。

WordPressの標準的なインストールでも、データベースには数十のテーブルがある。プラグインを使っていれば、さらに増える。全テーブル、全レコード、全カラムをチェックするのは、相当な手間なんだ。

しかも、不正なデータを削除した後、サイトが正常に動くか確認する必要もある。正規のデータまで消してしまったら、サイトが壊れてしまうからね。

複数の場所に分散できる

攻撃者は、一箇所だけでなく、複数のテーブルに不正なデータを埋め込むことがある。投稿テーブル、オプションテーブル、メタテーブル、コメントテーブル。いろんな場所に分散して隠すんだ。

一つ見つけて削除しても、別の場所にまだ残っている。完全に削除したと思っても、見落としがあれば、そこから再び増殖する。まるでイタチごっこだよね。

バックアップに含まれる

定期的にバックアップを取っているサイトは多い。でも、データベースマルウェアに感染している場合、バックアップにも不正なデータが含まれてしまう。

バックアップから復元しても、マルウェアも一緒に戻ってきてしまう。いつの時点で感染したか分からないと、クリーンなバックアップを見つけるのも困難なんだ。

感染の兆候と特徴的な動き

不審なデータベースクエリの急増

データベースマルウェアは、通常のページ表示時に何らかの処理を実行することが多い。そのため、不自然なSQLクエリが増加する。

確認方法:

MySQLのスロークエリログを有効にして、実行時間が長いクエリをチェックする。

# my.cnf または my.ini に追加

[mysqld]

slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow-query.log long_query_time = 2

これで、2秒以上かかるクエリがログに記録される。普段は一瞬で終わるクエリが、急に遅くなっていたら要注意だ。

テーブルサイズの異常な増加

マルウェアがデータを追加していると、テーブルサイズが不自然に大きくなる。定期的にテーブルサイズをチェックしておくと、異常に気づきやすい。

確認方法:

-- 各テーブルのサイズを表示
SELECT 
    table_name AS 'Table',
    ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Size (MB)'
FROM information_schema.TABLES 
WHERE table_schema = 'your_database_name'
ORDER BY (data_length + index_length) DESC;

特に、wp_postsやwp_postmeta、wp_optionsテーブルが急激に大きくなっていたら、不正なデータが追加されている可能性が高い。

見慣れないデータパターン

データベース内に、明らかにおかしなパターンのデータが見つかることがある:

よくある兆候:

  • Base64エンコードされた長い文字列
  • eval()やexec()を含むコード
  • <script>タグが投稿内容に大量に含まれている
  • 外部サイトへのリンクが急増
  • 意味不明な文字列の繰り返し
  • 正規表現パターンのような複雑な文字列

特に、Base64エンコードされたデータには注意が必要だ。正規の用途でBase64を使うこともあるけど、マルウェアが自身を隠すためにも使われるんだよね。

管理画面での不審な動き

データベースマルウェアは、管理画面にも影響を与えることがある:

  • 投稿一覧の表示が異常に遅い
  • 保存していない投稿が勝手に追加される
  • オプション設定が勝手に変わる
  • 見覚えのない管理者アカウントがある
  • プラグインやテーマが勝手に無効化/有効化される

こういった現象が起きたら、データベースをチェックする価値がある。

データベースマルウェアの検出方法

手動でのデータベース検索

最も確実なのは、phpMyAdminやMySQLコマンドラインで、不審なパターンを検索することだ。

JavaScriptインジェクションの検出:

-- script タグを含む投稿を検索
SELECT ID, post_title, post_content 
FROM wp_posts 
WHERE post_content LIKE '%<script%' 
   OR post_content LIKE '%</script>%';

-- iframe を含む投稿を検索
SELECT ID, post_title, post_content 
FROM wp_posts 
WHERE post_content LIKE '%<iframe%';

-- Base64エンコードされたデータを検索
SELECT ID, post_title, post_content 
FROM wp_posts 
WHERE post_content LIKE '%base64%';

オプションテーブルのチェック:

-- 長いオプション値を検索(1000文字以上)
SELECT option_name, LENGTH(option_value) as length
FROM wp_options
WHERE LENGTH(option_value) > 1000
ORDER BY length DESC;

-- eval や exec を含むオプションを検索
SELECT option_name, option_value
FROM wp_options
WHERE option_value LIKE '%eval(%'
   OR option_value LIKE '%exec(%'
   OR option_value LIKE '%base64_decode%';

これらのクエリで、不審なデータが見つかれば、詳しく調べる必要がある。

WP-CLIでの一括チェック

WP-CLIを使えば、コマンドラインから効率的にチェックできる。

# すべての投稿で script タグを検索
wp post list --post_type=post --format=csv | while read line; do
    wp post get $line --field=content | grep -i "<script" && echo "Found in post $line"
done

# オプションテーブルを検索
wp option list --search="*eval*" --format=table

# 不審なユーザーアカウントを確認
wp user list --role=administrator --format=table

WP-CLIは、大量のデータを処理する時に便利だ。GUIのphpMyAdminより、スクリプト化しやすいからね。

セキュリティプラグインの活用

一部のセキュリティプラグインは、データベーススキャン機能を持っている。

Wordfence Security:

無料版でもマルウェアスキャン機能があり、データベース内の既知のマルウェアパターンをチェックしてくれる。ただし、完全版は有料プランが必要だ。

Sucuri Security:

データベースの整合性チェック機能がある。正規のWordPressインストールと比較して、追加されたデータや変更されたデータを検出する。

Anti-Malware Security and Brute-Force Firewall:

データベースマルウェアの検出に特化したプラグイン。疑わしいパターンを自動的に検索して、レポートを生成してくれる。

プラグインは便利だけど、100%信頼できるわけじゃない。手動でのチェックと組み合わせるのがベストだ。

外部サービスによるスキャン

自分でチェックするのが難しい場合、外部のスキャンサービスを使う方法もある。

Sucuri SiteCheck:

無料でサイトをスキャンしてくれるサービス。表面的なチェックだけど、明らかなマルウェアは検出できる。

VirusTotal:

ファイルやURLをチェックできるサービス。データベースは直接スキャンできないけど、サイトのURLをチェックすれば、不正なコンテンツが含まれていないか確認できる。

ただし、これらのサービスはデータベースの中身までは見られない。あくまで補助的な手段として使うべきだよね。

駆除と予防の具体的な手順

感染確認時の初動対応

マルウェアを見つけたら、まず落ち着いて対応しよう。慌ててデータを削除すると、サイトが壊れる可能性がある。

手順:

  1. サイトをメンテナンスモードにする
    訪問者への被害を防ぐため、一時的にサイトを閉じる。
  2. 完全バックアップを取る
    感染した状態でもバックアップを取る。後で検証が必要になるかもしれない。
  3. 感染範囲を特定する
    どのテーブルのどのレコードが感染しているか、すべてリストアップする。
  4. 侵入経路を特定する
    どこから侵入されたのか調査する。これを塞がないと、再感染する。
  5. 不正なデータを削除する
    特定した不正なデータを、慎重に削除する。
  6. 動作確認
    サイトが正常に動くか、すべての機能をチェックする。

不正なデータの削除

不正なデータを削除する時は、慎重に。間違えて正規のデータを消すと、サイトが壊れてしまう。

JavaScriptの削除:

-- まず確認
SELECT ID, post_title, post_content 
FROM wp_posts 
WHERE post_content LIKE '%<script src="http://malicious-site.com%';

-- 問題を確認したら削除(REPLACEを使う)
UPDATE wp_posts 
SET post_content = REPLACE(post_content, '<script src="http://malicious-site.com/malware.js"></script>', '')
WHERE post_content LIKE '%<script src="http://malicious-site.com%';

REPLACEを使えば、特定の文字列だけを削除できる。でも、複雑なパターンの場合は、手動で一つ一つ確認した方が安全だ。

不正なユーザーアカウントの削除:

-- 管理者ユーザーを確認
SELECT ID, user_login, user_email, user_registered 
FROM wp_users 
WHERE ID IN (
    SELECT user_id FROM wp_usermeta 
    WHERE meta_key = 'wp_capabilities' 
    AND meta_value LIKE '%administrator%'
);

-- 不正なユーザーを削除(IDを確認してから)
DELETE FROM wp_users WHERE ID = 123;
DELETE FROM wp_usermeta WHERE user_id = 123;

ユーザー削除は慎重に。間違えて正規の管理者を消すと、管理画面にアクセスできなくなる。

予防策の実装

マルウェアを駆除した後は、再感染を防ぐための対策が必須だ。

1. SQLインジェクション対策

WordPressのプリペアドステートメントを使って、SQLインジェクションを防ぐ。

<?php
// 悪い例:SQLインジェクションの脆弱性あり
$id = $_GET['id'];
$query = "SELECT * FROM wp_posts WHERE ID = $id";

// 良い例:プリペアドステートメントで安全
global $wpdb;
$id = intval($_GET['id']);
$query = $wpdb->prepare("SELECT * FROM wp_posts WHERE ID = %d", $id);
?>

カスタムプラグインやテーマを開発する時は、必ずこの方法を使おう。

2. データベースユーザーの権限を制限

WordPressのデータベースユーザーに、必要以上の権限を与えない。

-- 新しいユーザーを作成(必要最低限の権限)
CREATE USER 'wp_limited'@'localhost' IDENTIFIED BY 'strong_password';
GRANT SELECT, INSERT, UPDATE, DELETE ON wordpress_db.* TO 'wp_limited'@'localhost';
FLUSH PRIVILEGES;

DROP、CREATE、ALTERなどの権限は、通常の運用では不要だ。これらを除外することで、攻撃者がテーブル構造を変更するのを防げる。

3. データベースの定期的なチェック

週に1回程度、データベースをスキャンする習慣をつける。自動化できれば理想的だ。

#!/bin/bash
# データベーススキャンスクリプト

# 不審なscriptタグを検索
mysql -u user -p database -e "SELECT COUNT(*) FROM wp_posts WHERE post_content LIKE '%<script%';"

# 大きすぎるオプション値を検索
mysql -u user -p database -e "SELECT option_name FROM wp_options WHERE LENGTH(option_value) > 10000;"

# 結果をメールで送信

このスクリプトをcronで定期実行すれば、異常があった時にすぐ気づける。

4. Web Application Firewall(WAF)の導入

Cloudflareなどのサービスを使えば、SQLインジェクション攻撃を自動的にブロックできる。サーバーに到達する前に、不正なリクエストを弾いてくれるんだ。

よくある質問(FAQ)

Q1: データベースマルウェアとファイルマルウェア、どちらが危険ですか?

両方とも危険だけど、データベースマルウェアの方が発見が遅れる傾向がある。ファイルベースのマルウェアは、セキュリティプラグインで比較的簡単に検出できる。でも、データベースマルウェアは、手動でチェックしないと見つからないことが多いんだ。

対策:

両方に備える必要がある。ファイルシステムのスキャンに加えて、定期的にデータベースもチェックする習慣をつけよう。

Q2: バックアップから復元すれば、マルウェアも消えますか?

いや、それは危険な考え方だ。いつ感染したか分からない場合、バックアップにもマルウェアが含まれている可能性が高い。

正しい対処法:

  1. 感染の時期を特定する
  2. その前の時点のバックアップを探す
  3. 復元後、最新の状態まで手動で更新する

感染時期が不明な場合は、クリーンインストールから始めて、コンテンツだけを慎重に移行する方が安全だ。

Q3: phpMyAdminが使えない環境では、どうすればいいですか?

phpMyAdminがなくても、MySQLコマンドラインやWP-CLIでチェックできる。

WP-CLIの例:

# データベースを直接検索
wp db query "SELECT * FROM wp_posts WHERE post_content LIKE '%<script%' LIMIT 10"

# エクスポートしてgrepで検索
wp db export - | grep -i "eval"

サーバーにSSHアクセスできれば、コマンドラインの方が効率的なこともあるんだよね。

Q4: セキュリティプラグインで防げないのですか?

セキュリティプラグインは、既知のマルウェアパターンを検出できる。でも、新しい手口や巧妙に偽装されたマルウェアは、検出できないこともある。

多層防御が重要:

  • セキュリティプラグイン(第一段階)
  • 定期的な手動チェック(第二段階)
  • ログ監視(第三段階)
  • WAF(第四段階)

一つの対策に頼らず、複数の防御策を組み合わせることが大事なんだ。

Q5: データベースが感染した場合、すぐにサイトを閉じるべきですか?

訪問者に被害が及ぶ可能性がある場合は、すぐに閉じるべきだ。特に、以下のような場合:

  • フィッシングサイトへのリダイレクト
  • 訪問者のブラウザに悪意のあるコードを実行させる
  • 個人情報を盗むスクリプトが実行される

でも、単なるSEOスパムのような、訪問者に直接の被害がない場合は、メンテナンスモードにしてから対処しても間に合う。状況に応じて判断しよう。

まとめ:データベースマルウェアは見えない敵だからこそ、定期的なチェックが必須

データベースマルウェアは、ファイルシステムに痕跡を残さない分、発見が遅れがちだ。でも、特徴を知っていれば、早期に発見できる可能性は十分ある。

冒頭で紹介したECサイトのケースは、3ヶ月も感染に気づかなかった。でも、もし定期的にデータベースをチェックしていれば、もっと早く発見できたはずだ。被害も最小限に抑えられただろう。

この記事のポイント:

  • データベースマルウェアはファイルとして存在せず、データとして潜む
  • 発見が遅れやすく、削除も困難
  • SQLクエリでパターン検索すれば検出できる
  • 手動チェックとプラグインを組み合わせる
  • 予防にはSQLインジェクション対策が必須
  • 定期的なデータベーススキャンを習慣化する

データベースは、WordPressサイトの心臓部だ。ここが感染すると、サイト全体に影響が及ぶ。ファイルシステムのセキュリティだけでなく、データベースの健全性も守っていく必要があるんだよね。

月に1回、いや週に1回でもいい。5分だけ時間を作って、データベースに不審なデータがないかチェックしてみよう。SQLクエリを一つ実行するだけで、大きな被害を未然に防げるかもしれない。

データベースマルウェアは、「見えない敵」だ。でも、見えないからこそ、意識的に探す必要がある。定期的なチェックを習慣にして、サイトを守り抜いていこう。


WordPressのセキュリティ、不安に思っていませんか?

WordPressセキュリティ診断

「自分のサイトは大丈夫だろうか…」
「何から手をつければいいか分からない…」

もしあなたが少しでもそう感じているなら、専門家によるセキュリティ診断を受けてみることを強くお勧めします。

>> WordPressセキュリティ無料診断はこちら

上記のサイトでは、WordPressのプロがあなたのサイトの脆弱性を無料で診断してくれます。問題が見つかれば、具体的な対策方法についてもアドバイスをもらえます。手遅れになる前に、一度プロの目でチェックしてもらい、安心を手に入れましょう。

お気軽にご相談ください

お見積りへ お問い合わせへ