具体的なスクショ画像で見る、改ざんサイトの復旧作業メモ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94360/75d0d1c0-5b0d-4b0a-39c4-41a83406310e.png)
**「サイトが攻撃を受けた。ウイルスに感染したらしい」**

・・みたいな話。何が起きているのか、この記事で「見える化」します。

改ざんサイトの復旧作業を依頼されることが時々ありますが、「実際にはこんな作業をします」というのを事前にお伝えできるといいかなと思って、先日受けた依頼についてメモをまとめてみました。外部からの攻撃により設置されたのは「バックドア」。ウェブシェル、トロイの木馬と呼ばれることもあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94360/7be7a195-1a1d-d48f-98bc-80926e50eb86.png)
絵文字がキモい。こんなのがサイトに埋め込まれ、悪用目的でこっそり起動したりできます。

考えようによっては、普通に便利なファイル管理ソフト。レンタルサーバのコントロールパネルには、これのもっと高機能なやつが設置されていたりします。

ちなみに、サイトを止めずに現状で修復してほしいという依頼だったりすると、だいぶアプローチが変わります。常に改ざんを監視しながら作業したりとか、高度なシェル操作スキルが必要になります。SSHが使えないような古いサービス体系のレンタルサーバだったりするとサーバを止めるしかないです。

今回はテーマのバックアップがあったので簡単でしたが、バックアップがない場合はサーバ上のテーマを検査して無害化する必要があるため少し手間がかかります。

ちなみに記事中のスクショ画像は文字列など手を加えています。

------------------------------

## 前提

WordPress本体は過去バージョンを公式サイトから取得し、Themeファイルは感染前のバックアップを用いる。正常な構成が明確なため作業時間を大幅に圧縮できる。つまり今回の作業は、感染領域の実態調査と、無害なデータのみを用いた安全な復旧作業ということになる。

## 事前調査

- FTPでサーバに接続し、全ファイルを取得し検査
    - バックドアスクリプトを20ファイル、改ざんされた.htaccessを403ファイル確認
    - サイトは休止状態になっていたが、バックドアは外部リクエストを受けて活動を継続していた
- PHP5.2.17(2011年1月6日リリース)
- WordPress2.8.6(2009年11月12日リリース)
- WordPress公式サイトよりversion2.8.6のパッケージを入手し差分を確認したところ、さらにindex.phpが改ざんされていることが分かった
- 構成ファイル群を観察し、改ざんが発生したのは2021年12月9日と特定
- 感染してから4か月たっておりログも残ってないため、感染経路については分からない
- PHPもWordPressも多数の脆弱性を抱える古いバージョンなので、いつどのように感染してもおかしくない状態ではあった

## 課題と解決

### 準備

- サーバ上のファイルをローカルにバックアップ
    - 納品後一か月たって問題なければ削除
- サーバ上に作業領域を作成
- 作業領域用のサブドメインを作成(temp.*****.com など)
- ひとつのDBに複数サイトの設定とデータが格納されており、作業ミスが起きやすい
    - 今回のサイト専用にDBを作成
- ファイルを大量にコピーする作業を行なうため鍵を設置しSSHを使えるようにする
    - SSHを使えば数万ファイルでも数秒でコピーできる
- ベーシック認証を設置

## 感染領域に対する対策

- バックドアの活動は停止していないため対策が必要
    - ウェブからのリクエストが届かない領域を作成し退避、これにより外部から遮断。参考のため作業中はそのまま残しておく

## サイト復旧

- 感染前のシステムバックアップがあるため作業領域に転送
- データのバックアップがないため既存の最新データを取得
    - <b>【重要】</b>データに踏み台スクリプトや改ざん記事などが仕込まれている可能性があるため念入りに調査
        - 問題ないため新規作成したDBにインポート
- バックアップに含まれていたバイナリ形式のphp.cgiファイルは現在のさくらインターネットでは利用できないため、新しい方法でphp.cgiを設置
    - PHPのバージョンを5.6に変更(※最新の7.4にするとWordPress2.8.6は動作せずシステムアップデートのために管理画面を開くことができない)
- wp-config.phpを作業領域用に編集
- siteurl・homeurlの設定を作業領域用に変更
- 作業用WordPressアカウントを作成
- サイトが動作することを確認

## アップデート作業

- 不要なテーマ・プラグインを削除(セキュリティ的観点と作業の効率化のため)
- 実記事は100件程度しかないのにリビジョンデータが4000件以上あり、不要データが多い
    - リビジョン制御用のプラグインをインストールし、不要なリビジョンを削除
    - リビジョンは2件くらいあれば十分なので生成数を記事あたり2件に制限
        - 制限しないと記事を更新するたびに無限に増える
- WordPress本体を最新化
- プラグイン・テーマを最新化
- 無事にアップデートできたので、PHPのバージョンを最新化(7.4)
- 各部にデザインの崩れ
    - （原因１）お預かりしたバックアップファイルに含まれない画像が多数あったため既存サイトから画像の差分を取得し転送(画像が感染していないことを検査の上で)
    - （原因２）パンくずリストなどデザインの一部をプラグインが生成する構成になっており、プラグインのアップデートにより生成htmlが変わってしまった。これは修正できないため(修正すると今後アップデートできなくなる)、見た目で帳尻がつくようにCSSなどを変更
    - （原因３）WordPress最新化の影響で、コンテンツに含まれるHTMLの整形ルールが変わり、その影響を受けた
        - 今回のサイトはパンくずリストがテンプレート側ではなく記事本文側に記述する構成になっており、パンくずリスト全体が影響を受けた
        - これも修正のしようがないため、WordPress本体の整形ルールを緩めに変更することで対応

## 完成サイトの本番化

- homeurl・siteurlの設定を元に戻す
- その他、DB内にテスト領域URLが混入していないことを確認
- テスト領域・本番領域それぞれのディレクトリ名を入れ替える
- 正常に表示されることを確認
 
## 検索エンジン対策

- 改ざんされた内容で検索エンジン(Google)にインデックスされているため更新する必要がある
    - ブランド品販売サイトのような感じになっている
    - Googleサーチコンソールにsitemap.xmlを登録
    - 反映されるまで最長で2～3日くらいかかる

## 今後の課題

- https化(常時SSL化)
- 同サーバ内に設置されている他サイトも改ざんの可能性があるため点検が必要

## 参考

### 見た目上の改ざん

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94360/a1dd0bb7-b9ab-5d20-213d-165c0bb4832b.png)
サイトのURLで検索すると上記のような結果になっていたが、依頼者のサイトは全く別業種。ウイルス対策ソフトの設定が効いている場合は、危険なサイトとして警告が表示される。今回は緩めの改ざんだったためか、Google上では危険サイトとして認識されていない。

今回はDB上のコンテンツは改ざんされておらず、上記はJavaScriptを通じて外部サイト上のデータを引いてきたものを表示している結果であることが分かった。利益誘導が目的とは限らず、コンテンツ引用元のサイトも被害者である可能性がある。

### バックドア(ウェブシェル)について

https://eset-info.canon-its.jp/info/virusinfo/detail/php_webshell.nea

上記は、今回検出された「PHP/Webshell.NMT」と同じ種類のバックドアに関する日本語による解説。Apache権限においてあらゆるサーバ改ざん操作が可能。同ユーザ領域にインストールされている他サイトも改ざんされている可能性があるため注意が必要。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94360/05f45a72-d205-51b2-fe26-1245daf6bc4f.png)
バックドアはウイルス対策ソフトで検出するのが手軽だが、インデントを調整する程度の簡単な変更でも検出を免れることができる。念のため、感染前のシステムバックアップとの差分照合も行なった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94360/4e1c27a5-7057-4802-2dc9-efe9cfb877c8.png)
上記はバックドア本体の内容。処理の内容は難読化されており、復号を行なった上で危険な処理を削除し、ブラウザで開くと下記のような画面が表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94360/75d0d1c0-5b0d-4b0a-39c4-41a83406310e.png)
サーバ内の任意のファイルを自由に閲覧・ダウンロード・編集・削除することができる。また、URLやPOSTメソッドでパラメータを渡し、画面上の操作を行わずに任意のコマンドを直接実行することもできる。

### 検出されたバックドア

```
/about.php
/blog/wp-admin/css/2index.php
/blog/wp-admin/css/content.php
/blog/wp-admin/css/radio.php
/blog/wp-admin/css/new-index.php
/blog/wp-admin/images/2index.php
/blog/wp-admin/images/new-index.php
/blog/wp-admin/import/index.php
/blog/wp-admin/import/content.php
/blog/wp-admin/includes/index.php
/blog/wp-content/languages/new-index.php
/blog/wp-content/languages/content.php
/blog/wp-content/languages/2index.php
/blog/wp-content/languages/radio.php
/blog/wp-content/plugins/index.php
/blog/wp-content/plugins/radio.php
/blog/wp-content/themes/index.php
/blog/wp-content/uploads/content.php
/blog/wp-content/uploads/2index.php
/blog/wp-content/uploads/new-index.php
```

上記の20ファイル。いずれも PHP/Webshell.NMT

### 改ざん処理

```
<FilesMatch ".(py|exe|php)$">
 Order allow,deny
 Deny from all
</FilesMatch>
<FilesMatch "^(about.php|radio.php|index.php|content.php|lock360.php)$">
 Order allow,deny
 Allow from all
</FilesMatch>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
```

上記のような内容の.htaccessが403ファイル設置されており、バックドアスクリプトへのリクエスト以外はindex.phpにリーチするようになっていた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94360/29b2cf40-a27e-6925-705d-0eb26bd9d7ab.png)
index.phpを開くと上記のようになっている。事前調査により、このファイルが改ざんされていることは確認済み。冒頭部分では文字列難読化処理が行なわれており、難読化される前の元の文字列を解読した結果は下記のとおり。

```
preg_replace_callback
stream_socket_client
stream_get_meta_data
stream_set_blocking
stream_set_timeout
file_put_contents
file_get_contents
sys_get_temp_dir
http_build_query
function_exists
gethostbyname
base64_encode
base64_decode
rawurlencode
rawurldecode
gzuncompress
str_replace
json_encode
file_exists
curl_setopt
array_shift
preg_split
preg_match
curl_error
curl_close
urlencode
urldecode
str_split
parse_url
gzinflate
gzdeflate
curl_init
curl_exec
array_pop
var_dump
is_array
tmpfile
tempnam
print_r
mt_rand
implode
explode
usleep
unlink
strpos
strlen
hexdec
getenv
fwrite
fclose
fread
fgets
count
chmod
trim
join
feof
md5
```

主要なPHPビルトイン関数名が生成されることが分かる。後続の処理では、これら難読化された文字列を用いて、リクエストのたびに .htaccess生成・上書きすることができるようになっている。

### 他ファイルの改ざん

なし

https://asec.ahnlab.com/jp/18910/
画像ファイルに仕込むことも可能なので検査したが改ざんの形跡はなかった