#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 місяця
Також варто подивитися