- PVSM.RU - https://www.pvsm.ru -

История одного бэкдора

Предыстория

Жил-был один старый-старый сайт. Родители от него отказались, и на втором десятке лет существования он попал к нам. Он представлял из себя джунгли PHP кода, разбросанного по папкам. Все это было написано в разное время, с использованием разных паттернкостылей, в разных кодировках (до 3ёх кодировок в пределах одного файла). MVC тогда, наверное, еще не было известно, да и о шаблонизаторах разработчики не слышали, так что не стоит удивляться внезапному

<? if (cond) { ?>

в HTML разметке. Я провел не один час в увлекательных поисках нужного

<? } ?>

Разработчики не забывали и про бэкапы: в корне можно было найти index.php, index_old.php, index.php.bak. Но несмотря ни на что, это чудо работало. А что работает — не трожь.

Завязка

Эта история началась, когда солнечным декабрьским утром специалист по продвижению с удивлением обнаружил ссылки на чужеродные сайты в футере. Немного покопавшись выяснилось 2 вещи:

  1. это сапа [1];
  2. заказчик недоумевает.


Недоумение заказчика можно понять: у него этих ссылок не видно.

Расследование

Поставили задачу — найти, разобраться и уничтожить. Найдя искомое место в HTML-разметкеподключаемом PHP-файле было получено имя функции, делающей кому-то хорошо. Результат поиска по ~60k файлам кода не принес положительного результата — такой функции нигде не объявлено. Пошел в ход перебор всех файлов, подключаемых в искомой точке входа. В процессе глаз цепляется за файл следующего содержания:

История одного бэкдора

Ничего не понятно, но искреннее спасибо тому человеку, который не убрал аннотацию в шапке. Я начинаю гуглить ''Zend Oрtimizer'', справедливо полагая, что он приведет к расшифровке этого трэша. Поиск рабочего декодера заканчивается тут [2]. Особо порадовала капча:

История одного бэкдора

С некоторым геморром, связанным с запретом копирования результата, я получил следующее:

История одного бэкдора

Я с недоверием отношусь к preg_replace() [3]. И чем больше читаю, тем больше недоумеваю. Само регулярное выражение должно идти первым параметром, а во втором — то, на что заменяют. Посмотрел еще раз на то, что было дано. получается, в строке «x» заменяется "#x#e" на ту длинную штуку. Причем в функции preg_replace() используются модификаторы x и e [4]. Но не дадим себя запутать: все, что помещено между # — экранируется, так что x - это на самом деле то, что следует заменить в строке «x» , т.е. все, а модификатор e позволяет исполнить результирующее выражение как PHP код. При внимательном взгляде на строку замены становится понятно, что большая ее часть — это шум.

История одного бэкдора

Если убрать комментарии, получится

@eval(base64_decode($I0));

На этом месте мне пришлось погуглить значение "@" перед вызовом функции [5]. Далее, спасибо онлайн декодерам [6], я получил следующую порцию загадок.

История одного бэкдора

Тут я впервые увидел функцию chr() [7]. Позалипал на

$ll = @explode(chr(187) , @implode('', @array_map('trim', @file($ll))));

Загуглил array_map() [8]. В общем тут используется кусок из того самого первоначального файла, зашифрованного Zend Optimizer. Вот уж не знаю какой там алгоритм, но произведя перестановку символов и взяв уже становящийся привычным base64_decode() я получил крипто-функцию:

История одного бэкдора

Дальше ком стал разрастаться экспоненциально, и после нескольких итераций файл достиг 2к строк. Структуру файла после всего этого расследования я оставил на завтра, а пока пара забав:

История одного бэкдора
позволяет остаться незамеченными с терминалов внутренней подсети.

История одного бэкдора
Интересно, они там сразу делают шифровку такую, или это уже кто-то постарался спецом для нас?

Вместо послесловия

Если верить времени создания файлов — на дворе был суровый 2009. Только вот мне даже немного жаль времени тех людей, которые это все зашивали так упорно, потому как я уверен, что этот процесс занял у них времени поболее, чем обратный. И ведь всё это было бы невозможно, если бы только не осталась аннотация о Zend Optimizer.

Автор: sand_alkr

Источник [9]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/php-2/51057

Ссылки в тексте:

[1] сапа: http://www.sape.ru/

[2] тут: http://www.showmycode.com/

[3] preg_replace(): http://www.php.net/preg_replace

[4] модификаторы x и e: http://www.php.net/manual/ru/reference.pcre.pattern.modifiers.php

[5] значение "@" перед вызовом функции: http://stackoverflow.com/questions/2002610/php-character-before-a-function-call

[6] онлайн декодерам: http://base64.ru/

[7] chr(): http://www.php.net/chr

[8] array_map(): http://php.net/manual/ru/function.array-map.php

[9] Источник: http://habrahabr.ru/post/206536/