#7 – Инъекции в код: command injection, RCE, SSRF
Видеоурок
Что такое Command Injection и RCE?
Command Injection — это уязвимость, при которой пользователь может внедрить фрагмент команды в системный вызов, и эта команда будет выполнена на сервере.
Рассмотрим простой пример. Допустим, мы хотим узнать пинг сайта, но сам сайт указывает пользователь:
os.system("ping " + user_input)Если пользователь вместо google.com введёт команду whoami, то сервер выполнит её:
google.com && whoamiВторая часть запроса вызовет команду whoami и покажет, от имени какого пользователя работает сервер. Это уже частичный доступ к системе. А если удастся вставить rm -rf, можно попрощаться с проектом:
google.com && rm -rf /Второй тип — это RCE (Remote Code Execution), то есть удалённое выполнение кода. Хакер может не только вставлять команды, но и полностью выполнять произвольный код на удалённой машине: Python, Bash, PHP — всё, что доступно в окружении.
SSRF — Server-Side Request Forgery
SSRF — это атака, при которой злоумышленник заставляет сервер делать запрос от своего имени туда, куда пользователь сам доступ не имеет.
Пример: у вас есть API, которое делает скриншот сайта. Запрос к нему выглядит так:
GET /api/screenshot?url=https://example.comХакер подставляет другой URL. Если сервер имеет внутреннюю админ-панель по адресу localhost:8000, вы открываете к ней доступ через своё API:
http://localhost:8000/adminПример: уязвимый Python-код
Плохой пример на Python, где от пользователя принимается хост для проверки доступности:
import os
def run_ping(host):
os.system("ping -c 1 " + host)
host = input("Введите хост: ")
run_ping(host)Введём: 127.0.0.1 && whoami
Результат — выполнение двух команд. whoami выведет информацию о пользователе, от имени которого работает сервер.
Пример: PHP + RCE
Теперь пример на PHP, демонстрирующий RCE. Допустим, вы получаете код от пользователя через URL и хотите его выполнить:
<?php
$code = $_GET['code'];
eval($code);
?>Если пользователь введёт phpinfo(), она будет выполнена:
http://localhost/test.php?code=phpinfo();А если вставить system("ls"), то выполнится shell-команда — это уже уязвимость RCE:
system("ls");Как защищаться?
Главное правило: никогда не выполняйте команды на основе неконтролируемого пользовательского ввода.
Рекомендуется использовать жёсткий список допустимых значений. Пример безопасного кода на Python:
allowed_hosts = ['google.com', 'yahoo.com']
if user_input in allowed_hosts:
os.system("ping -c 1 " + user_input)
else:
print("Недопустимый хост")Если всё же нужно выполнять команды — используйте безопасные методы, которые не передают строку в shell:
import subprocess
subprocess.run(["ping", "-c", "1", user_input])Дополнительные меры:
Не используйте eval, exec, Function(), если они обрабатывают пользовательский ввод. Фильтрации недостаточно — избегайте их в принципе для выполнения кода.
Если проект требует выполнения кода (например, онлайн-интерпретатор) — изолируйте это в песочнице:
- ограничьте доступ к файловой системе;
- установите таймауты;
- используйте контейнеры (например, Docker);
Проводите аудит кода: ищите обработку входящих данных в:
- сетевых запросах,
- файловых путях,
- вызовах внешних программ.
Даже простой просмотр кода помогает выявить до 90% потенциальных уязвимостей RCE.
Задание к уроку
Необходимо оформить подписку на проект, чтобы получить доступ ко всем домашним заданиям
Большое задание по курсу
Вам необходимо оформить подписку на сайте, чтобы иметь доступ ко всем большим заданиям. В задание входит методика решения, а также готовый проект с ответом к заданию.
PS: подобные задания доступны при подписке от 1 месяца
Также стоит посмотреть