Найти в Дзене
Hypro-Y

Решаем задачки CTF ringzer0team раздел Web: Password reset

Очередная задачка по CTF, с поучительной историей и с небольшой "хитростью", которая помогает не потратить в пустую пару лишних часов... Итак, форма восстановления: Вроде бы вектор наших действий с самого начала очевиден, в форме восстановления пароля вводим admin, субмитим (отправляем), получаем сообщение вида: Ясности для дальнейших действий пока нет, но есть исходный код (который скачается как отдельный файл, видимо что то пошло не так на сайте), код: Тут мы видим что при отправке формы восстановления пароля удалилась последняя запись о восстановлении пароля для данного IP, а затем создалась новая, в котором токен для восстановления это рандомное число от 1000000000000000 до 9999999999999999. Решение в лоб это попытаться перебрать 8000000000000000 комбинаций, но в течении часа это реализуемо только если у вас есть свой ботнет на 100к+ устройств и скорее всего раньше вы заDDOSите ресурс чем угадаете код. Но если более внимательно прочитать код то на 3 строке видно что используется с

Очередная задачка по CTF, с поучительной историей и с небольшой "хитростью", которая помогает не потратить в пустую пару лишних часов... Итак, форма восстановления:

Вроде бы вектор наших действий с самого начала очевиден, в форме восстановления пароля вводим admin, субмитим (отправляем), получаем сообщение вида:

-2

Ясности для дальнейших действий пока нет, но есть исходный код (который скачается как отдельный файл, видимо что то пошло не так на сайте), код:

-3

Тут мы видим что при отправке формы восстановления пароля удалилась последняя запись о восстановлении пароля для данного IP, а затем создалась новая, в котором токен для восстановления это рандомное число от 1000000000000000 до 9999999999999999. Решение в лоб это попытаться перебрать 8000000000000000 комбинаций, но в течении часа это реализуемо только если у вас есть свой ботнет на 100к+ устройств и скорее всего раньше вы заDDOSите ресурс чем угадаете код. Но если более внимательно прочитать код то на 3 строке видно что используется стандартная функция php srand, которая меняет начальное значение генератора псевдослучайных чисел. Для нас это означает только одно что если мы передаем туда параметр (целое число), то последующее генерирование функцией rand нас приведет одному и тому же значению. Например:

(пример сделан на http://sandbox.onlinephpfunctions.com, но подойдет любой онлайн редактор php)
(пример сделан на http://sandbox.onlinephpfunctions.com, но подойдет любой онлайн редактор php)

Данный код будет генерировать одно и то же значение постоянно (это и будет основной поучительной истории в заключении). Зная это мы можем получить сгенерированный токен который поможет получить нам ключ для восстановления пароля.

Я написал элементарный скрипт для генерации требуемого нам рандомного числа (оказывается эта фраза может иметь смысл!):

-5

код для копирования:

<?php
echo strtotime('Mon, 23 Jul 2018 01:46:26 -0400')."\r\n";
srand(strtotime('Mon, 23 Jul 2018 01:46:26 -0400'));
echo rand(1000000000000000,9999999999999999);

Теперь попробуем полученное нами число...

-6

Печали моей не было предела, далее был промежуток времени с всевозможными ухищрениями, при том что в исходном коде не было явно указано что нам выводится время которое использовалось в srand, я пробовал убавлять от 3 до 1 секунд после получения unix timestamp, потом я грешил что что-то не так при создании unix timestamp из-за часовых поясов, прошло еще сколько то времени и я добрался до документации php по функции rand, в которой сказано:

-7

Тут меня осенило что я уже не раз обращал свое внимание на то что на сервере ringzer0team используется допотопная версия php (5.5.19 или что то типа того, видел в одном из заданий), просто сменим версию php:

-8

Как видим получилось другое значение (потому что использовалась другая функция rand вместо mt_rand), пробуем с этим результатом:

-9

Получили заветный восстановленный пароль, осталось просто ввести его с логином admin и получить заветный флаг!

-10

Первое что мы должны извлечь из данной задачи: не в коем случае не пользоваться подобным решении даже на самом маленьком домашнем production, поскольку подобные действия не безопасны, хотя и врядли бы кто-то делал такое всерьез. Второй момент из документации:

Данная функция не генерирует криптографически безопасные значения и не должна использоваться в криптографических целях. Если вам требуется криптографически безопасное значение, подумайте об использовании функций random_int(), random_bytes() или openssl_random_pseudo_bytes() вместо данной.

Thats all, folks!