Command Injection: Базовая инъекция команд
Панель администратора содержит функцию ping, передающую ввод напрямую в shell без фильтрации.
easyphpPro
Задача
# OS Command Injection: чтение `LAB_FLAG` через форму диагностики сети
## Сценарий
Ты — пентестер, нанятый для проверки безопасности интернет-магазина **HackShop**. Приложение написано на PHP и обслуживается через Apache. В админ-панели появился инструмент **Диагностика сети** — форма, позволяющая администратору проверить доступность хоста через системную утилиту `ping`. Удобно: вводишь IP или имя, нажимаешь кнопку, видишь вывод команды прямо на странице.
Архитектор уверен, что инструмент безопасен, потому что доступ к нему ограничен ролью `admin`. На практике ограничение по роли не защищает от внутренних злоупотреблений и от компрометации одной admin-сессии: если из такой формы получится получить RCE, атакующий тут же прочитает переменные окружения процесса — включая секреты вроде `LAB_FLAG`.
## Цель
1. Войти в админ-панель и открыть инструмент **Диагностика сети**.
2. Убедиться, что значение поля `host` напрямую попадает в системную команду — через интерпретатор shell.
3. С помощью разделителей команд оболочки (`;`, `&&`, `||`, `|`, перенос строки) дописать к `ping` чтение переменной окружения `LAB_FLAG`.
4. Получить значение `LAB_FLAG` в HTTP-ответе — это и есть флаг лабы.
## Теория
**OS Command Injection** возникает, когда приложение строит команду через конкатенацию строки с пользовательским вводом и затем передаёт результат в **системную оболочку** (`/bin/sh`, `/bin/bash`, `cmd.exe`). Оболочка интерпретирует метасимволы (`;`, `&&`, `||`, `|`, `$()`, `\n`, `` ` ``) и выполняет произвольные команды, заданные атакующим.
В PHP популярный анти-паттерн — `shell_exec("cmd " . $userInput)`, `system($cmd)`, `exec($cmd)`, `passthru($cmd)` или `proc_open(string $cmd, ...)` (строковая форма). Любая из этих функций при передаче строки разворачивается во внутренний `sh -c "<строка>"`, и пользовательский ввод в этой строке становится потенциальной точкой инъекции. Безопасный путь — либо вызывать процесс с массивом аргументов (`proc_open(array $argv, ...)`), либо строго экранировать каждое значение штатной функцией PHP для экранирования shell-аргументов.
**Уязвимый паттерн (упрощённо):**
```php
function handleAdminPing(PDO $db): void
{
$host = trim($_POST['host'] ?? '');
// VULNERABILITY: пользовательский ввод конкатенируется в строку
// команды и передаётся в shell без какой-либо обработки.
$cmd = "ping -c 3 {$host} 2>&1";
$result = (string) shell_exec($cmd);
renderPage('admin.html', ['ping_result' => $result]);
}
```
Здесь сразу две ошибки: (1) данные `$host` и структура команды слиты в одну строку, (2) строка отправляется в shell через `shell_exec`, который внутри запускает `/bin/sh -c "ping -c 3 ..."`. Метасимволы внутри `$host` интерпретируются оболочкой как синтаксис.
## Точка входа атаки
- **Эндпоинт:** `POST /admin/ping`, поле формы `host`
- **Учётные данные администратора:** `admin` / `lab-secret`
- **Где искать флаг:** значение переменной окружения `LAB_FLAG` процесса лабы — попадает в HTTP-ответ после успешной инъекции
## Данные для входа
| Роль | Логин | Пароль |
|------|-------|--------|
| Администратор | `admin` | `lab-secret` |
| Обычный пользователь | `demo` | `demo` |