PukiWiki・QHMマルウェア駆除実例|Webシェルと賭博スパムを隔離・復旧【復旧実例】

PukiWikiのマルウェア感染を調査し不正ファイルを隔離するイメージ

PukiWikiやQHM(クイックホームページメイカー生産終了)で作られたサイトが突然403 Forbiddenになり、
バックアップを調べると見覚えのないPHPや巨大なHTMLが増えていた――。

この状態では、不審ファイルだけを削除しても安全とはいえません。
入口となった脆弱性や欠損した設定ファイルを残せば、表示が戻らないだけでなく再感染するおそれがあるためです。

よこやま良平

わたしは20年以上Webシステムに携わり、WordPressだけでなく古いPHP製CMSや自作システムの復旧も行っています。今回は、PukiWiki 1.4.7を基にしたQuick Homepage Maker 5.2のバックアップを、原本を保全したまま静的解析しました。

この記事でわかること
  • PukiWikiで見つかったWebシェルと賭博スパムの実態
  • 旧SWFUploadが侵入口として疑われた理由
  • 改ざんファイルを証拠ごと安全に隔離する手順
  • index.phpだけを戻してはいけない理由と再発防止策

結論からいうと、33,486ファイルを調査して感染21件を特定し、
攻撃痕跡などを含む24件を元のディレクトリ構造のまま隔離できました。

この記事では、実際に確認できた事実と推定を分けながら、調査から復旧設計までの流れを紹介します。
サイト名・ドメイン・攻撃者の外部URLなどは伏せています。

目次

【無料プレゼント】
WordPress緊急チェック50

「自分のサイトは今、安全なのか?」
自信を持って答えられますか?

WordPress緊急チェック50

こんなお悩みはありませんか?

  • ある朝、サイトを開いたら真っ白画面になっていた
  • 管理画面にログインできなくなって手が止まった
  • 身に覚えのない記事やページが勝手に増えていた
  • プラグインを更新したらサイト全体が崩れてしまった
  • 以前バックアップを取ったか自分でも覚えていない

累計1,000件以上のWordPressトラブル対応の経験から、「壊れる前に備える」ためのチェックリストを1冊にまとめました。
ログイン・本体・バックアップ・サーバー・運用の5分野を、50項目で「危険度・確認方法・対処法」まで解説しています。

セキュリティプラグイン・WordPressの教科書も含めた3大特典を、
今なら無料で受け取れます。

今すぐ無料ダウンロードする →

※登録後すぐにメールで特典をお届けします

PukiWikiの403は感染を疑うべき調査の入口だった

今回のご相談は「サイトを開くと403 Forbiddenになり、閲覧できない」というものでした。

403はアクセス制御やサーバー設定でも発生するため、
この表示だけでマルウェアが原因とは断定できません。

しかし、受領したバックアップにはCMS本来の構成では説明できないファイルが複数あり、
感染と改ざんの調査が必要な状態でした。

今回の静的解析対象
  • CMS:PukiWiki 1.4.7 / Quick Homepage Maker 5.2 revision 2019
  • 受領物:サイトファイル一式をまとめたZIP
  • 規模:33,486ファイル、106ディレクトリ、約3.07GB
  • 調査方法:原本ZIPを変更せず、ハッシュを記録した作業コピーで静的解析

調査では、拡張子だけでなくファイルの中身、設置場所、
同一ハッシュ、CMSの標準構成、タイムスタンプのまとまりを横断して確認しました。

感染サイトのファイル確認で見るべきポイントは、以下の記事でも解説しています。

PukiWiki内から21件の感染ファイルと複数の欠損を確認した

全体走査の結果、高い確度で感染と判断できるファイルは21件でした。

さらに、自動攻撃の試行を示す痕跡2件と、正規設置か攻撃者設置かを所有者に確認すべきGoogle所有権確認ファイル1件を分けて管理しました。

確認した主な改ざん
  • パスワード認証、ファイル操作、コマンド実行、アップロード機能を備えたWebシェル
  • system($_GET['cmd'])形式の簡易コマンド実行シェル
  • 検索エンジンには賭博コンテンツを見せ、人間には通常ページを見せるクローキング
  • 外部の賭博サイトへ誘導するドアウェイページと大型HTML
  • Wiki本文へ直接書き込まれた外国語の賭博スパム
  • index.phppukiwiki.ini.phpqhm.ini.phpの欠損
ルート直下から隔離したPukiWikiの不審ファイル一覧

Wikiのスパム本文には、通常の編集で作られる差分・バックアップ・カウンターの対応記録が見当たりませんでした。

これは正規の編集画面ではなく、Webシェルなどからファイルへ直接書き込まれた可能性を高める材料です。
ただし、ログが完全に揃っていないため、記録がないことだけを決定的証拠にはしていません。

外から見える賭博ページだけを消しても、Webシェルが残れば何度でも作り直されます。
一般的な賭博サイト改ざんの症状と初動は、次の実例記事も参考にしてください。

PukiWikiへの侵入口は旧SWFUploadの任意ファイルアップロードが最有力だった

侵入口として最も疑わしかったのは、
Quick Homepage Makerに同梱された旧式の画像アップロード機能SWFUploadです。

アップロード処理はファイル名の文字種を確認していましたが、
PHPなどの危険な拡張子やMIMEタイプを拒否せず、元の拡張子のままWeb公開領域へ保存する構造でした。

$upload_name = $_FILES['Filedata']['name'];
if (preg_match('/^[-_.+a-zA-Z0-9]+$/', $upload_name)) {
    $upload_file = SWFU_DATA_DIR . $upload_name;
    move_uploaded_file($_FILES['Filedata']['tmp_name'], $upload_file);
}

実際の保存先swfu/d/には、Webシェル、コマンド実行スクリプト、ルートへ自身を複製するドロッパーが集中していました。

さらに、拡張子の大文字・小文字を変えた複数のアップロード試行ファイルが同時刻帯に残っており、
自動スキャナーが実行可能な拡張子を探った痕跡と整合します。

SWFUploadの保存先で確認したWebシェルと攻撃痕跡
SWFUploadの保存先で確認したWebシェルと攻撃痕跡

ただし、当時のアクセスログは受領物に含まれていません。
したがって「旧SWFUploadが最有力」とはいえても、侵入元IPや最初のPOSTリクエストまで確定したとは表現していません。

タイムスタンプも攻撃者が変更できるため、古い日付のファイル1件だけから感染開始年を断定しないことが重要です。

ファイルアップロード対策は、拡張子の許可リスト、MIME検証、サーバー側でのファイル名生成、
認証済み利用者だけへの制限、Webルート外への保存を組み合わせるのが基本です。

PukiWikiのクローキングは通常閲覧だけでは発見しにくい

guardian.phpという一見安全そうな名前のファイルには、検索エンジンのユーザーエージェントを判定し、
攻撃者の外部サーバーから取得したコンテンツを返す処理が追加されていました。

一方、一般の利用者にはPukiWiki本来の起動処理を続けるため、
ブラウザで普通に開いただけでは不正表示に気づきにくい構造です。

検索エンジン向けクローキング処理を含むguardian.phpのコード
検索エンジン向けクローキング処理を含むguardian.phpのコード

このファイルは本来のindex.phpに似たブート処理を持ち、代替入口として動作できるものでした。

ただし、元のindex.phpを改名したものか、攻撃者が別途作成したものかまでは証明できません。
調査報告では「書き換えられたindex.phpそのもの」と断定せず、確認できたコードの動作だけを記録しました。

クローキングを見落とさない確認方法
  • Google検索結果のタイトルや説明が自社ページと一致するか確認する
  • 不審PHP内のUser-Agent・Referer判定と外部通信先を確認する
  • 一般ブラウザだけでなく検索エンジン向け応答も安全な環境で比較する
  • Search Consoleの所有者、登録URL、セキュリティ警告も確認する

PukiWikiの改ざんファイルは元の構造を保って24件隔離した

駆除では、発見したファイルをその場で完全削除しませんでした。

原本ZIPを保全し、解析用コピーから判定済み24件を隔離フォルダへ移動しています。
感染21件、攻撃痕跡2件、所有者確認が必要な1件を同じ一覧で管理し、分類の違いも残しました。

実施した隔離手順
  1. 受領ZIPのSHA-256を記録して原本を変更しない
  2. 危険なパスや展開サイズを確認して隔離解析フォルダへ展開する
  3. シグネチャ、難読化、外部通信、標準構成との差分から対象を分類する
  4. 元の相対パスを保ったまま隔離フォルダへ移動する
  5. 24件すべてのハッシュ一致と元位置からの不在を確認する

同じディレクトリ構造で隔離すると、どこに何が置かれていたかを後から説明でき、
誤検知が判明した場合も戻しやすくなります
ファイル名、元パス、分類、理由、ハッシュをTSV形式の一覧にも残しました。

cache/内のファイルも調査対象には含めますが、復旧時にそのまま戻す必要は通常ありません。

キャッシュは不正コードやスパム表示が残る可能性があるため、安全なコアとデータを復元した後に再生成します。

一方、wiki/attach/は利用者コンテンツなので、機械的に全削除せず、ページ単位・添付単位で精査します。

PukiWikiはindex.phpだけ戻さずコアと設定を一体で復旧する

今回のバックアップではindex.phpだけでなく、pukiwiki.ini.phpqhm.ini.phpも欠けていました。

index.phpを1枚戻しても、設定が不足すれば起動できません。
さらに、侵入口のアップロード処理とWebシェルが残っていれば、表示が戻った直後に再感染する可能性があります。

復旧は「不正ファイルの隔離 → 侵入口の停止 → 同一系統の正規コアと設定の復元 → データ精査 → 認証情報変更 → 動作確認」の順で進めます。

クリーンな比較元には、後期の同一メジャーバージョンを参考にしました。

ただし、公開されているQuick Homepage Maker 5.2のタグと今回のrevision 2019が完全一致するとは限りません。

差分を見ずに新しい一式を上書きすると、独自設定や拡張機能を壊すため、対象環境の版に合わせた復元が必要です。

また、依頼時点の実行環境はPHP 5.3という非常に古い世代でした。

PHP公式ではPHP 5.3のサポート終了日は2014年8月14日とされています。

復旧後も古いPHPを公開運用し続けるのではなく、対応バージョンへの段階的移行、静的サイト化、
別CMSへの移行を含めた出口戦略が欠かせません。

PukiWikiの再感染防止はアップロードの入口と実行の出口を両方ふさぐ

再発防止では、使われていないSWFUploadを停止・削除するのが第一候補です。

業務上どうしても残す場合は、アップロード処理の検証だけに頼らず、
保存先でPHPなどを実行できないようWebサーバー側でも制限します。

<FilesMatch "\.(php|php3|php4|php5|phtml|pht|phar|cgi|pl|py|sh)$">
    Order allow,deny
    Deny from all
</FilesMatch>

この例は旧Apache系の記法です。実際にはサーバーのApache・nginx・PHP-FPM構成に合わせて設定し、
テスト用ファイルがHTTP経由で実行されないことまで確認します。設定ファイルを置いただけでは完了ではありません。

復旧後に必ず確認する項目
  • 管理者、FTP・SFTP、サーバー、データベース、メールの認証情報を変更する
  • 危険な拡張子を拒否し、画像は内容とMIMEタイプも検証する
  • アップロード先・セッション・内部データをWebから直接読めないようにする
  • 同一アカウント内の別サイト、Cron、SSH鍵、Search Console所有者を確認する
  • キャッシュを破棄して再生成し、検索結果とアクセスログを一定期間監視する

駆除直後は正常でも、攻撃者が残した別の入口から再侵入されることがあります。

復旧後の監視項目は、次の記事もあわせて確認してください。

PukiWikiマルウェア駆除のよくある質問

cache内のファイルは復旧に必要ですか?

調査には必要ですが、復旧時は原則として安全な状態から再生成します。感染中の表示や不正コードが残る可能性があるため、キャッシュ一式を無条件に戻すのは避けてください。

削除されたindex.phpだけ復元すれば表示は戻りますか?

今回のように設定ファイルも欠損し、侵入口やWebシェルが残っている場合は戻りません。コア・設定・データの整合性と再感染経路をまとめて確認する必要があります。

ファイルの更新日時から侵入日を特定できますか?

更新日時は手がかりですが、攻撃者が変更できるため単独では確定できません。アクセスログ、サーバーログ、同時刻のファイル群、バックアップとの差分を組み合わせて判断します。

WordPress以外の古いCMSでもマルウェア駆除を依頼できますか?

はい。PukiWiki、Quick Homepage Maker、自作PHPなども、標準構成との比較、コード解析、隔離、復旧、再発防止の順で対応できます。製品やPHPの世代によっては、修復と同時に移行計画も提案します。

PukiWikiマルウェア駆除は原因特定と証拠保全まで行う

今回の実例では、PukiWiki/QHMの33,486ファイルを静的解析し、感染21件を特定しました。攻撃痕跡と要確認ファイルを含む24件は、元のディレクトリ構造とハッシュを保って隔離しています。侵入口は旧SWFUploadの任意ファイルアップロードが最有力でしたが、アクセスログがないため断定の範囲も明確にしました。

古いCMSの復旧では、目立つスパムを消すだけでなく、欠損したコアと設定、直接書き換えられたコンテンツ、実行可能なアップロード先、流出し得る認証情報まで一体で扱う必要があります。もう更新されていないシステムでも、現状を正確に調べれば、安全に止める・復元する・移行する判断材料を作れます。

PukiWikiや古いCMSのマルウェア感染を自分で復旧できない時は

WordPress修復マルウェア駆除トラブル専門「クイックレスキュー」

PukiWiki・Quick Homepage Maker・自作PHPなど、古いCMSの乗っ取りやマルウェア感染でお困りなら、
クイックレスキューが調査から隔離・復旧・再発防止まで対応します。

こんなお悩みはありませんか?
  • PukiWikiや古いCMSが403・真っ白・不正表示になった
  • 見覚えのないPHPや賭博ページが大量に見つかった
  • index.phpや設定ファイルが削除・改ざんされている
  • WordPress以外なので対応先が見つからない
  • 証拠を残しながら安全に隔離・復旧したい

調査費用・初期費用は0円です。まずは現在の症状と利用中のCMSをお知らせください。

3つの安心保証
  • 万一復旧できない場合やマルウェア駆除できない場合は全額返金保証で安心
  • 90日間再感染保証・動作保証で安心
  • 初期費用・調査費用0円で安心

この記事を書いた専門家

こんにちは!20年以上ITエンジニアとして活動してきた
よこやま良平です。

Wordpress復旧やサイト修復、オンライン講座では
776件以上のレビューを頂いており

「すぐに復旧してくれる!」
「当日行ってくれて助かった!」など

評価は4.9/5.0と非常に高く好評です。

またWordPress、SEO、Officeなど30冊以上の書籍を出版しており、
売上ランキング1位を連続で獲得致しました。

その他これまでに3000以上のサービス・システム・サイトを作成。

多くの方の「できない」や「悩み」を解決してきました。
その観点からわかりやすく解説しています。

目次