Предсказуемые Токены Сессии (MD5)
Сессионные токены генерируются через MD5(username), что позволяет предсказать токен администратора и захватить его сессию.
mediumgolangPro
Задача
# Auth: предсказуемые сессионные токены
## Сценарий
Вы аудируете интернет-магазин **SecureShop**. Приложение использует cookie `session_token` для идентификации пользователей: после успешного логина сервер устанавливает её клиенту, а на каждом последующем запросе проверяет значение для определения текущего пользователя. Команда уверена, что сессионная подсистема безопасна — токен выглядит как длинная случайная строка. По данным внутреннего аудита, в админ-панели хранится конфиденциальная метка, доступная только пользователям с ролью администратора; её требуется получить, имея только обычную учётную запись.
## Цель
1. Изучите формат значения `session_token` после собственного логина — как именно оно выглядит, какова его длина и алфавит.
2. Найдите закономерность между значением токена и известными вам данными о текущей учётной записи.
3. Используя обнаруженную закономерность, вычислите токен учётной записи администратора без знания её пароля и получите доступ к admin-панели; извлеките флаг.
## Теория
Криптографически безопасный сессионный токен должен быть **непредсказуемым**: получив один валидный токен, атакующий не должен иметь возможности вычислить другие. На практике это означает, что токен генерируется криптографически стойким генератором случайных чисел (CSPRNG) и имеет достаточно энтропии (минимум 128 бит, лучше 256). Любая «оптимизация» — производный токен от username, email, ID, временной метки, последовательного счётчика — нарушает это свойство и превращает сессию в **детерминированную функцию известных атакующему данных**.
**Уязвимый паттерн:**
```go
// Токен — детерминированная функция от username
token := fmt.Sprintf("%x", md5.Sum([]byte(username)))
http.SetCookie(w, &http.Cookie{Name: "session_token", Value: token, Path: "/"})
```
Атака: атакующий получает один валидный токен (через собственный логин — это вычисляет ему «соль» алгоритма), сравнивает со своими известными данными (`md5(username)`, `sha1(username)`, `sha256(username)`), идентифицирует функцию, и затем применяет её к username привилегированной учётной записи. Username администраторов часто очевиден (`admin`, `administrator`, `root`) или раскрывается через публичные эндпоинты (страницы профиля, API списков пользователей, журналы коммитов в репозитории кода). MD5 для коротких строк дополнительно есть в публичных rainbow-таблицах — `md5("admin")` известен всем.
## Точка входа атаки
| Параметр | Значение |
|----------|----------|
| Учётные данные | `demo` / `demo` |
| Cookie сессии | `session_token` (значение видно через DevTools после логина) |
| Привилегированный эндпоинт | `GET /admin` (требует session_token администратора) |