Дмитрий DarkByte Москин

Мой блог, да.
logo

PHDays Quals 2012 writeup

Опубликовано 17.12.2012 автором Дмитрий Москин
Закончился отборочный тур PHDays 2012. Задания прикольные, но всё не удалось порешать, ибо, команда из 2.5 игроков - это не весело.

Задания были разделены на пять категорий: Binary, PWN, Real World, Forensic, Misc. Решить все задания удалось только в категории Real World. Меньше всего решили в Binary и Forensic.

Forensic 100
Real World 100
Real World 200
Real World 300
Real World 400
Real World 500
Misc 100
Misc 200
Misc 400
PWN 300
PWN 400

Forensic 100
Task: Find the flag, which is provided in the MD5 format. The task is available through this link.


Видим QR-код, распознаём, получается строка в HEX, при переводе в ASCII получается ELF бинарник, который при запуске выводит на экран 004305B220CD80252000010093CD80.
Так же видим в картинке LSB. Достаём, получаем ещё один HEX, только уже с запароленным RAR архивом. В качестве пароля используем полученную ранее строку.
В архиве лежит файл secret.txt с флагом 90f3910ff22f4be0dfa95a2fd6cb8a25.

И всё, больше ничего из Forensic до конца не решили.


Real World 100
Task: Find flag on http://ctf.phdays.com:1411


На сайте была Error based SQL инъекция в заголовке X-FORWARDED-FOR. Флаг лежал в таблице web.flags в поле flag: 94bd6136818878b5dd97d3a231a97649. Ничего сложного.


Real World 200
Task: Top up your bank account and you will find the cherished flag. http://ctf.phdays.com:1629


Задача была в том, чтобы отправить админу $2000, имея на счету всего $1000. Счёт админа выглядел так 40433343a063d26054a3169b42b5957f, с помощью md5.darkbyte.ru декодировал его как md5 в число 1000000001, сразу появилась мысль, что номера счетов нумеруются по порядку и нужно зарегистрировать два аккаунта, узнать счёт одного, перевести на него деньги со второго. Тогда на одном аккаунте будет $2000 и можно будет перевести их админу.

К сожалению, так и не удалось найти свой идентификатор. После появления подсказки, стало ясно, что нужно отправить синхронно два запроса. Но т.к. при каждом запросе меняется ID сессии, то нужно было предварительно получить два идентификатора, чтобы оба запроса выполнились одновременно. Из-за неправильной логики в скрипте, деньги списались со счёта дважды, админ получил свои $2000 и отдал флаг: e8b434d21354e1a2ab61f4c672109559.


Real World 300
Task: Star Death: Your goal is to launch SuperLaser to blow up the planet :)

For this purpose you will have to start up the reactor using 4 generators. Every generator has its own energy storage. By summarizing all energy you can reach the main goal and get the cherished flag.

Скачиваем архив, видим куча пустых папок, находим все файлы:
Windows\NTDS\edb.chk
Windows\NTDS\ntds.dit
Windows\System32\config\DEFAULT
Windows\System32\config\SAM
Windows\System32\config\SECURITY
Windows\System32\config\SYSTEM
Users\gen1\Desktop\g1.zip
Users\gen2\Desktop\g2.zip
Users\gen3\Desktop\g3.zip
Users\gen4\Desktop\g4.zip
Users\reactor\Desktop\Reactor.zip
Users\sl\Desktop\Blow up the planet.zip

Все архивы под паролем. Достаём из виндовых файлов хеши паролей пользователей и начинаем их брутить:
Administrator 217e50203a5aba59cefa863c724bf61b P@ssw0rd!
Guest 31d6cfe0d16ae931b73c59d7e0c089c0 P@ssw0rd
Reactor 8833023b5bda9bc5fc96a617f09a8142 startme
SuperLaser de2c9ace2cd4deefe80f95290ecd5c6b Init

Для пользователей g1...g4 находим историю паролей, брутим. Большая часть оказывается фейковыми, но по одному оказываются нормальными. Полученными паролями распаковываем архивы:
g1.zip пароль keyStr1ng, внутри [#*#*#*#*#*#*#
g2.zip пароль tost4Rtre, внутри ++++CLEAR++++
g3.zip пароль anDsup3rl, внутри ~~~~ENERGY~~~~
g4.zip пароль 053n14stg3n, внутри *#*#*#*#*#*#*]


У архива Reactor.zip в комментарии написано "Launch 4 generator sequentially", пробуем к нему в качестве пароля строку "[#*#*#*#*#*#*#++++CLEAR++++~~~~ENERGY~~~~*#*#*#*#*#*#*]". Внутри видим файл с текстом " SuperLaser!", вспоминаем, что у пользователя SuperLaser пароль Init, а пробел в начале строки как бы намекает.

Распаковываем архив Blow up the planet.zip паролем "Init SuperLaser!" и получаем флаг: 6da6ced8a40980ba8675f9b03ff92c10.


Real World 400
Task: Check out this awesome website, an administrator has some interesting stuff.


Задача - сбросить администратору пароль и зайти под ним. Для запроса сброса пароля, нужно знать только имя пользователя. При сбросе пароля, на почту приходит письмо с токеном, который является md5(mt_rand()).

Первое, что бросается в глаза, наличие файла /phpinfo.php и заголовок X-Debug с содержимым типа "88420; 87.249.222.21; 1355640133", которое можно понять как "PID; IP; TIMESTAMP". А это всё, что нужно, чтобы по PHPSESSID сбрутить микросекунды и восстановить текущее состояние mt_srand. Берём тулзу от PT. Запрашиваем восстановление пароля, предварительно удалив сессию из кук. По имеющимся данным получаем недостающую информацию:
SEED = 87.249.222.2113556834896610888.74386514
PID = 36860
IP = 87.249.222.21
SEC = 1355683489
USEC = 661088
COMB_LCG = 8.743865013123
S1 = 8195745
S2 = 1353963516
DELTA1 = 3
DELTA2 = 8

Используем скрипт из хинта:
./pass_gen.php 1355683489 36860 8195745 1353963516

Получаем несколько токенов, примерно 4й сверху подходит, пароль от пользователя admin успешно сбрасывается. Но флага там нет. Потому что ник у админа другой, его можно увидеть в тексте новости на сайте. Повторяем процедуру и получаем флаг: 15024b5523f75e8023b7f127bcc29068.


Real World 500
Task: Find flag on http://ctf.phdays.com:12391

Writeup.


Misc 100
Task: Hi! I`ve got a strange binary. Take a look at it.


Скачиваем файл, смотрим внутрь, видим сколько строк: $Sys, %x %x %x %x, Z29vLmdsLzI4bmg0, init, print /af9b5be72c4135a93079b83d0519f2c6/1c4543c1.phd
Строка Z29vLmdsLzI4bmg0 записана в кодировке base64, декодируем, получаем ссылку goo.gl/28nh4, по которой открывается картинка, отсылающая к игре Limbo.
Дальше нужно было понять, что бинарник от ОС Inferno, скачать её, собрать, выполнить бинарник, программа выводит "98f6bcd 4621d373 -3521b17d 2627b4f6", инвертируем третье число и добавляем в начале ноль. Получается флаг: 098f6bcd4621d373cade4e832627b4f6.


Misc 200
Task: There are rumors that Lamevich could be a spy.. Check it please, maybe you could find something in the "Very Brown Square"... square.gif


Рандомизируем таблицу цветов и видим флаг: 41306ef634207607771deff1a0db76888.


Misc 400
Task: I am lost. ctf.phdays.com:1165


При подключении на порт, предлагают ввести юзернейм в качестве капчи (скорее всего для того, чтобы при открытии в браузере не вываливало в него весь вывод).
Hi there! Stupid CAPTCHA: enter your name, user63912

После ввода, в консоль вываливается куча строк 3D лабиринта и предложение найти в нём путь между двумя точками.
Find a path between (45, 0, 5) and (6, 49, 45):
The solution must be in format:
(a0_x,a0_y,a0_z)(a1_x,a1_y,a1_z)...(aN_x,aN_y,aN_z)
Steps must differ in exactly one coordinate

Пишем скрипт для прохождения лабиринта misc400.py. Проходим первый уровень, появляется следующий, затем ещё несколько, затем сервис выводит "You win! How do you like the flag? ;)" и всё.

Думали долго, в итоге пришли к тому, что нужно построить проекции пройденного пути по всем трём плоскостям.

В итоге получился флаг: NOF3ARNO3XITHER3


PWN 300
Task: You have gained access to the control panel of the cozy small town of South Park (ctf.phdays.com:2137). The authorities give the townspeople no peace every day, or even oftener, they kill Kenny and bully other dwellers. Make fairness triumph.

Get Sources: southpark.zip.

Декомпилируем process.pyc, получаем process.py. И сразу становится понятно, что уязвимость в параметрах choice и human, которые без всяких проверок подставляются в скрипт. Передаём в human что-нибудь, типа "str(open('/etc/passwd', 'r').read())" и получаем в ответ флаг: d9301a72ee12eabb2b913398a3fab50b.


PWN 400
Task: You can try it on ctf.phdays.com:1831

Allowed logs to read: log.1, log.2, log.3
Usage: Reader(filename)
Get Sources

Сервис предоставляет доступ к питоновой консоли, но запрещены вызовы функций: 'open', 'file', 'execfile', 'reload', 'input', 'eval', 'type', 'compile', аттрибуты '__globals__', '__closure__', а Reader может читать только файлы log.1, log.2, log.3, в которых ничего интересного нет. Но стоит выполнить немного питоновской магии...
Reader.func_closure[0].cell_contents.func_globals['ALLOWED_FILES'].append('/etc/passwd')

И Reader уже может читать нужный файл:
Reader('/etc/passwd')
root:*:0:0:Charlie & flag 41f20268caa093e1b746e5ca750d3aa0:/root:/bin/csh