2026年5月20日

2026年5月20日

WordPressのSEOスパム(ハッキングによる)を排除する方法

はじめに

SEOスパムハック(SEO spam hack)は、攻撃者がWordPressサイトに大量の偽ページや隠しリンクを埋め込み、自分のサイトのSEOを不正に強化する攻撃です。日本語キーワードハック・製薬ハック・ギャンブルハック等の種類があり、発見が遅れるとGoogle検索から除外される場合があります。

症状・原因

  • Google Search Consoleで「カバレッジ」に大量の不審なURLが表示されている
  • サイト名でGoogle検索すると「カジノ」「バイアグラ」等の日本語キーワードが含まれる説明文が表示される
  • ソースコードに隠しリンク(display:nonevisibility:hidden・文字色=背景色)が存在する
  • /wp-content/uploads/内に.phpファイルが発見された

解決手順

ステップ1:SEOスパムの感染を確認する

# Google 検索で感染を確認
# ブラウザで以下を検索:
# site:example.com casino
# site:example.com viagra
# site:example.com 日本語キーワード

# サイトのソースにスパムリンクがないか確認
curl -s https://example.com/ | grep -iE "casino|viagra|poker|drug|pharmacy"

# wp-content 内に不審なPHPファイルがないか確認
find /var/www/html/wp-content -name "*.php" -newer /var/www/html/wp-includes/version.php | head -20

# データベース内のスパムURLを検索
wp eval "
global \$wpdb;
\$results = \$wpdb->get_results(\"
    SELECT ID, post_title, post_status FROM {\$wpdb->posts}
    WHERE post_content LIKE '%casino%'
       OR post_content LIKE '%viagra%'
       OR post_content LIKE '%poker%'
    LIMIT 50
\");
foreach (\$results as \$r) {
    echo \$r->ID . ': ' . \$r->post_title . ' (' . \$r->post_status . ')' . PHP_EOL;
}
"

# .htaccess にスパムのリダイレクトが埋め込まれていないか確認
cat /var/www/html/.htaccess | grep -iE "rewriterule|redirect" | head -20

ステップ2:スパムコンテンツをデータベースから削除する

# スパム投稿のIDを取得して確認
wp post list --post_status=any --fields=ID,post_title,post_status --format=table | \
    grep -iE "casino|viagra|poker|pharmacy"

# 特定キーワードを含む投稿を一括削除
wp eval "
global \$wpdb;
\$ids = \$wpdb->get_col(\"
    SELECT ID FROM {\$wpdb->posts}
    WHERE (post_content LIKE '%casino%' OR post_content LIKE '%viagra%')
      AND post_status IN ('publish','private','draft')
\");
if (\$ids) {
    foreach (\$ids as \$id) {
        wp_delete_post((int)\$id, true);  // ゴミ箱を経由せず完全削除
    }
    echo 'Deleted: ' . count(\$ids) . ' spam posts' . PHP_EOL;
}
"

# wp_options にスパムが埋め込まれていないか確認・削除
wp eval "
global \$wpdb;
\$results = \$wpdb->get_results(\"
    SELECT option_name, LEFT(option_value, 100) as preview
    FROM {\$wpdb->options}
    WHERE option_value LIKE '%casino%' OR option_value LIKE '%viagra%'
\");
foreach (\$results as \$r) {
    echo \$r->option_name . ': ' . \$r->preview . PHP_EOL;
}
"

ステップ3:不審なファイルを削除してコアを修復する

# ① WordPress コアファイルの整合性を確認
wp core verify-checksums
wp plugin verify-checksums --all

# ② コアファイルを強制的に再インストール(設定は保持)
wp core download --force --locale=ja

# ③ uploads 内のPHPファイルを削除
find /var/www/html/wp-content/uploads -name "*.php" -delete
find /var/www/html/wp-content/uploads -name "*.phtml" -delete

# ④ 不審なファイルを検索(マルウェアのパターン)
grep -rl "eval(base64_decode\|str_rot13\|gzinflate\|preg_replace.*\/e" \
    /var/www/html/wp-content/ 2>/dev/null

# ⑤ .htaccess を正常な状態に戻す
wp rewrite flush --hard

# ⑥ 不審な .htaccess を確認
find /var/www/html -name ".htaccess" -exec grep -l "eval\|base64\|preg_replace" {} \;

ステップ4:Googleにクリーンアップを報告する

# ① Google Search Console でインデックス削除を要求
# Google Search Console → インデックス → 削除 → 一時的に削除

# ② Google Search Console でセキュリティ問題を確認・解消報告
# セキュリティとマニュアル ペナルティ → セキュリティの問題
# → 問題を解決したら「確認をリクエスト」

# ③ インデックス再クロールをリクエスト(サイトマップ送信)
wp eval "
\$sitemap_url = get_option('siteurl') . '/sitemap.xml';
\$ping_url = 'https://www.google.com/ping?sitemap=' . urlencode(\$sitemap_url);
\$response = wp_remote_get(\$ping_url);
echo 'Pinged Google: ' . wp_remote_retrieve_response_code(\$response) . PHP_EOL;
"

# ④ スパムURLのインデックス削除状況を確認(数日後)
# Search Console → カバレッジ → エラー で不審なURLが消えているか確認

ステップ5:再発防止策を実施する

// functions.php: SEOスパム再感染の防止

// ① 投稿保存時にスパムキーワードを検出して管理者に通知
add_action('save_post', function(int $post_id, \WP_Post $post): void {
    if (wp_is_post_revision($post_id) || wp_is_post_autosave($post_id)) return;

    $spam_keywords = ['casino', 'viagra', 'poker', 'pharmacy', 'buy cheap'];
    $content = strtolower($post->post_content . ' ' . $post->post_title);

    foreach ($spam_keywords as $kw) {
        if (str_contains($content, $kw)) {
            wp_mail(
                get_option('admin_email'),
                '[警告] スパムキーワード検出: ' . get_the_title($post_id),
                "投稿ID: {$post_id}\nキーワード: {$kw}\nURL: " . get_permalink($post_id)
            );
            break;
        }
    }
}, 10, 2);
# 定期的なスキャンをcronで自動化
cat > /usr/local/bin/wp-spam-scan.sh << 'EOF'
#!/bin/bash
SITE_DIR="/var/www/html"
ADMIN_EMAIL="admin@example.com"

# uploads内のPHPファイルを検出
PHP_IN_UPLOADS=$(find "$SITE_DIR/wp-content/uploads" -name "*.php" 2>/dev/null)
if [ -n "$PHP_IN_UPLOADS" ]; then
    echo "PHP in uploads: $PHP_IN_UPLOADS" | mail -s "[緊急] SEOスパム感染の疑い" "$ADMIN_EMAIL"
fi
EOF
chmod +x /usr/local/bin/wp-spam-scan.sh
echo "0 */6 * * * root /usr/local/bin/wp-spam-scan.sh" > /etc/cron.d/wp-spam-scan

注意事項

  • SEOスパムの除去だけでは不完全です。バックドア(攻撃者の再侵入口)が残っている可能性があります。0465「バックドアを検出・除去する方法」を合わせて実施してください
  • Google Search Consoleで「確認をリクエスト」を送信するには、まず全ての問題(スパムページ・バックドア・脆弱性)を解決してから行ってください。解決前にリクエストすると審査が通らず、次回のリクエストまでに待機期間が発生します
  • 大量のスパムページがインデックスされている場合、完全に削除されるまで数週間かかることがあります

まとめ

SEOスパム除去は①site:example.com casinoでGoogle検索して感染を確認、②find -name "*.php" -newer version.phpで不審ファイルを特定・削除、③wp core download --forceでコアファイルを修復、④データベースからLIKE '%casino%'でスパム投稿を削除、⑤Google Search Consoleで「確認をリクエスト」してインデックス回復を促します。

お気軽にご相談ください

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