41
Эй, кодеры и хакеры! Сегодня мы ныряем в тёмные воды крипто-эксплойтов, где слабые генераторы случайных чисел (CSRNG — Cryptographically Secure Random Number Generators) становятся твоей дверью в святая святых веб-приложений. Мы разберём, как предсказывать сессионные куки через утечки энтропии и как ломать Math.random()
в Node.js, создавая коллизии. Всё с примерами, кодом и хардкорным подходом. Погнали!
Почему CSRNG — слабое звено?
Генераторы случайных чисел — это основа безопасности в криптографии. Они используются для создания ключей, токенов, сессионных идентификаторов и многого другого. Но если генератор предсказуем, вся система рушится как карточный домик. В веб-приложениях часто используют слабые или неправильно настроенные CSRNG, что открывает путь к атакам.
Что мы будем ломать?
Math.random()
в Node.js. Этот генератор псевдослучайных чисел (PRNG) уязвим к атакам, если его состояние можно восстановить.Утечки энтропии: Как предсказать сессионные куки?
Утечка энтропии происходит, когда генератор случайных чисел выдаёт предсказуемые значения из-за недостаточного “шума” (энтропии) или плохой реализации. В веб-приложениях это часто встречается в старых системах или при использовании слабых генераторов вроде PHP mt_rand()
или JavaScript Math.random()
.
Сценарий атаки:
Пример: Утечка через временные метки в PHP
Многие старые веб-приложения используют что-то вроде uniqid()
в PHP для генерации сессий. Этот метод часто основан на временных метках, что делает его предсказуемым.
1 2 3 |
// Пример уязвимого кода на PHP $sessionId = uniqid(); // Часто включает временную метку setcookie("session", $sessionId); |
Если ты можешь угадать временную метку (например, зная время ответа сервера с точностью до миллисекунд), то можешь предсказать sessionId
. Инструмент Burp Suite
или простой перехват запросов через mitmproxy
помогут собрать данные для анализа.
Практика: Сбор и предсказание
Вот пример простого Python-скрипта для анализа временных меток:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import time import hashlib def predict_session_id(timestamp): # Имитация генерации на основе временной метки seed = int(timestamp * 1000) # Предположим, что сервер использует миллисекунды return hashlib.md5(str(seed).encode()).hexdigest()[:16] # Проверяем диапазон времени current_time = time.time() for offset in range(-100, 100): # Пробуем диапазон ±100 секунд candidate_time = current_time + offset candidate_id = predict_session_id(candidate_time) print(f"Timestamp: {candidate_time}, Predicted ID: {candidate_id}") |
Лайфхак: Если сервер выдаёт последовательные идентификаторы, можно использовать линейную регрессию для прогноза следующего значения. Это работает с простыми PRNG.
Атака на Math.random() в Node.js: Генерация коллизий
Math.random()
в Node.js (и в браузерах) — это не криптографически безопасный генератор. Он основан на алгоритме Mersenne Twister (MT19937) или его вариациях в зависимости от движка V8. Если у тебя есть доступ к нескольким последовательным значениям, ты можешь восстановить внутреннее состояние генератора и предсказать будущие числа.
Почему это проблема?
Math.random()
для генерации “уникальных” идентификаторов или токенов.Сценарий атаки:
Math.random()
(например, через уязвимость в приложении, которая раскрывает ответы сервера).Практика: Восстановление состояния MT19937
Для этого можно использовать библиотеку вроде mersenne-twister
или писать кастомный код. Вот пример на JavaScript с использованием готового решения:
1 2 3 4 5 6 7 8 9 10 11 12 |
const MersenneTwister = require('mersenne-twister'); // Собираем несколько значений Math.random() (предположим, мы их получили) const collectedValues = [0.123456, 0.789012, 0.345678]; // Восстанавливаем состояние (это упрощённый пример, для точности нужно больше значений) const mt = new MersenneTwister(); mt.init_by_array(collectedValues.map(v => Math.floor(v * 1000000))); // Предсказываем следующее значение const predictedValue = mt.random(); console.log("Predicted next random value:", predictedValue); |
Как получить значения?
Генерация коллизий
После восстановления состояния ты можешь генерировать те же значения, что и сервер. Например, если это временный токен для сброса пароля, ты можешь подменить его своим значением и получить доступ к аккаунту жертвы.
Лайфхак: Используй инструмент jsfuzz
или пиши свой парсер для анализа фронтенд-кода на предмет использования Math.random()
.
Как усложнить обнаружение?
Чтобы твоя атака осталась незамеченной, следуй этим советам:
Как защититься от таких атак?
Если ты разработчик, вот что нужно сделать, чтобы не стать жертвой:
crypto.randomBytes()
вместо Math.random()
.Пример безопасного кода в Node.js:
1 2 3 4 5 |
const crypto = require('crypto'); // Генерация безопасного токена const token = crypto.randomBytes(16).toString('hex'); console.log("Secure token:", token); |
Заключение: Будь на шаг впереди
Крипто-эксплойты на слабые CSRNG — это мощный инструмент в арсенале хакера. Предсказание сессионных куков через утечки энтропии и генерация коллизий для Math.random()
в Node.js показывают, как небольшие ошибки разработчиков превращаются в катастрофу. Но помни: с большой силой приходит большая ответственность. Используй эти знания для пентеста или обучения, а не для вреда.
Лайфхак на прощание: Если хочешь углубиться, изучи атаки на генераторы вроде Dual_EC_DRBG (да, это та самая уязвимость от АНБ). А пока — копай исходники приложений, ищи слабые PRNG и тестируй в безопасной среде.