Basic Command Injection: Сетевой пинг
Простая OS Command Injection через инструмент сетевой диагностики в админ-панели.
easygolangPro
Задача
# OS Command Injection (Дамп переменной окружения через ping-инструмент)
## Сценарий
Вы проводите аудит безопасности **SecureShop**. В админ-панели появился новый инструмент — **Network Diagnostics**, позволяющий администраторам проверять доступность складов и серверов с помощью команды `ping`. Разработчик утверждает, что инструмент безопасен, потому что доступен только пользователям с ролью `admin`. Однако ограничение по роли никак не защищает от внутренних злоупотреблений и от компрометации одной admin-сессии: если злоумышленник получает RCE через такой эндпоинт, он сразу читает переменные окружения процесса — включая секреты вроде `LAB_FLAG`.
## Цель
1. Войдите в админ-панель и найдите инструмент **Network Diagnostics**.
2. Подтвердите, что значение поля `host` напрямую попадает в системную команду — в обходом интерпретатора shell.
3. С помощью разделителей команд оболочки (`;`, `&&`, `||`, `|`, переноса строки) допишите к `ping` чтение переменной окружения `LAB_FLAG`.
4. Получите содержимое `LAB_FLAG` в HTTP-ответе или out-of-band каналом — это и есть флаг лабы.
## Теория
**OS Command Injection** возникает, когда приложение строит команду через конкатенацию строки с пользовательским вводом и затем передаёт результат в **системную оболочку** (`/bin/sh`, `/bin/bash`, `cmd.exe`). Оболочка интерпретирует метасимволы (`;`, `&&`, `||`, `|`, `$()`, `\n`, `` ` ``) и выполняет произвольные команды, заданные атакующим.
В Go популярный анти-паттерн — `exec.Command("sh", "-c", commandString)` с подставленным `fmt.Sprintf`. Каждый раз, когда разработчик «удобно» формирует команду как строку и запускает через `sh -c`, любой пользовательский ввод в этой строке становится потенциальной точкой инъекции. Безопасный путь — вызывать бинарник напрямую через `exec.Command(name, args...)` с **отдельными аргументами**: тогда оболочка не участвует и метасимволы интерпретируются как обычный текст параметра.
**Уязвимый паттерн:**
```go
func (h *Handler) AdminPing(w http.ResponseWriter, r *http.Request) {
host := r.FormValue("host")
// Конкатенация ввода в строку команды + вызов через sh -c:
commandString := fmt.Sprintf("ping -c 3 %s", host)
cmd := exec.Command("sh", "-c", commandString)
output, _ := cmd.CombinedOutput()
// ...
}
```
## Точка входа атаки
* **Эндпоинт:** `POST /admin/ping` (поле `host`)
* **Учётные данные администратора:** `admin` / `LabAdmin2024!`
* **Где искать флаг:** значение переменной окружения `LAB_FLAG` процесса лабы — в HTTP-ответе после успешной инъекции