вторник, 22 ноября 2011 г.

Впечатления от HackQuest ZeroNights

Небольшой обзор HackQuest ZeroNights от команды Antichat.

Что хочется отметить - идея квеста проста и гениальна. Карта Питера, реальные места и задания к ним. Особенно понравилось то, что новые уровни появилялись по мере прохождения квеста участниками, что постоянно подогревало интерес, а также градация уровней на крипт, веб и соц.инженерию. Как ни странно, но первый флаг был получен нами в задании на соц.инженерию, где надо было угадать номер аськи, который был написан на солфетке без первых двух цифирок, и извлечь у "жертвы" фото. Как оказалось впоследствии, фото груди :)
Этот конкурс прошли всего 4 команды, судя по баллам (Топ-4 итоговой таблицы). Не знаю что было в этом сложного. Вычислить номер аськи не составляло труда, если прикинуть, что сейчас регаются 9знаки, начиная с цифры 6. Вторую цифру хоть и размыто, но можно было различить на солфетке. А далее просто общение с "жертвой", путем обещания вина, конфет и шоколадки был получен первый флаг и соответственно фото :) Уважаемая девушка, которая сидела в ICQ и Skype, к сожалению, не имеем возможности выполнить свои обещание ввиду того, что соц.инженерия поразумевает обман жертвы, но с нас шоколодка :)
Параллельно решился квест Vitebsky Rail Terminal. Прохождение довольно простое: при вводе тикета 10000000, справа появляется табличка:
Train number: 0000
Depart time: 00/00/00 00:00
Arriv. time: 00/00/00 00:00
Comment: DEV TEST
Смотрим на урл, vitebsky.php?train_id_num=debug .
Меняем на vitebsky.php?train_id_num=1 и получаем в комменте флаг :).
Следующим задание было boywithafish. Долго думали над ним, но в итоге в задании оказалась ошибка, после исправления которой мы отложили его в дальний ящик. Забегая вперед скажу, нам удалось решить этот крипт буквально за час до окончания квеста.
На уровнь Crypto 90 с дедом было потрачено куча времени. Узнали алгоритм (ADFGVX_cipher), а вот подобрать саму матрицу долго не получалось.
Уровень с baltic оказался решился довольно быстро одним из наших участников - был найден "старый" файл уровня - baltic.php.old :)
Непробиваем оказался для нас уровень с заливкой фото на Эрмитаж. Про GPS-координаты догадались ещё до хинта, но вот пройти уровень, к сожалению, так и не удалось.
В задании "Seaport" до инъекции догадались быстро, получили QR-код "Shipment ticket", расшифровали "10002511", и затем долго тупили :). Далее была проведена sqli в поле ввода тикета, подобраны таблицы и колонки. Вся сложность оказалась в поиске колонки pass таблицы users, ну и немного нестандартная вещь как запросы на SQLite (использование оператора LIKE).

Криптографическое задание "Троицкий собор" было практически сходу взято нашим глазастым участником :) На фреске достаточно было разглядеть шифровку Pigpen_cipher.
Следующим был начат уровень с wi-fi, где было подобрана связка test:pass. Дальше забили на него, не было понятно что делать с сессией, которая при успешой авторизацией появлялась. Этот уровень в итоге добили в последний день квеста. Тут уже начинает работать фантазия, найти то, не знамо что, случайно отыскать директорию, где прячутся сессии, проинклудить случайно найденный passwd.php, сколько случайностей-то! Такие квесты не всем по душе, где больше надо отгадывать, чем реально ломать.
Параллельно с этим, был пройден уровень по соц.инженерии со skype. Надо отдать девушке должное, весьма находчива. Мы оказались первыми, кто прошёл всю соц.инженерию квеста :).
Бонусный флаг нашли благодаря подсказке d0znpp на форуме рдота.
Уровень, где мы сломали мозг, можно полноценно считать метро. Расшифровав формат карточки и узнав, где располагаются дата, время, номер карты, пытались понять каким образом генерируются оставшиеся 8 байт. Оказалось, что никак :) Достаточно было только изменить дату на текущую (спасибо d0znpp за подсказку) и уровень пройден. На уровень метро2 нас уже просто не хватило..
Появившиеся крипто-уровни с flag.enc нами так пройдены не были, квалификации не хватило.
Последним появился мощный уровень кировского завода на 270 баллов. В то же время прошла информация в твиттере о таймере обратного отчета до окончания квеста. Вот тут можно поставить жирный минус организаторам. Дату начала и окончания лучше изначально сразу согласовывать. Была озвучена дата окончания квеста - 24 ноября, а затем все завершилось аж 20. Уровень с кировским заводом без подсказок со стороны организаторов считаем непроходимым :) Никаких подсказок, кроме поверхностых "сначала получите сорцы", ничего.. решали этот уровень до последней секунды, успели только найти нужную директорию,авторизоваться и найти скулю в кукисах. И то без подсказок не обошлось. В итоге, мы 4-ые.
Спасибо организаторам конурса, я думаю он был познавателен для каждого участника квеста, что самое главное.

PS Dagestan отказался от инвайта, и его любезно предложили нам, таким образом, представитель команды Античата поедет на конферению ZeroNights.

БОНУС#1
Логика прохождения уровня мальчика с рыбкой от нашего участника:
Делим весь шифр на блоки по 8 байт
Поочереди берем блоки:
1) 91716dcd9c6f8fc5
Повторяем блок 2 раза, остальные 256 символов можно дописать любые

Ответ делим на блоки по 8 байт:
2a 2a 2a 2a 2a 2a 2a 2a - блок 1
86 2a 2a c2 f3 1c ea b2 - блок 2

2a - неизвестный байт. Для удобства пока можно заменить нулями.

91 71 6d cd 9c 6f 8f c5 - блок 1 шифра
XOR
31 32 33 34 35 36 37 38 - ключ (12345678)
XOR
2a 2a 2a 2a 2a 2a 2a 2a - блок 1 ответа
=
86 2a 2a c2 f3 1c ea b2 - блок 2 ответа

Из этого уравнения восстанавливаем недостающие байты блока 1

91 71 6d cd 9c 6f 8f c5 - предыдущий блок шифра (для первого блока - он сам)
XOR
31 32 33 34 35 36 37 38 - ключ (12345678)
XOR
86 00 00 c2 f3 1c ea b2 - блок 2 ответа
=
26 ?? ?? 3B 5A 45 52 4F - расшифрованный текст для первого блока шифра

2) dbd28e46318afc88

db d2 8e 46 31 8a fc 88 - блок 1 шифра
XOR
31 32 33 34 35 36 37 38 - ключ
XOR
6a c5 8f ea ca d8 51 7d - блок 2 ответа
=
80 25 32 98 ce 64 9a cd - блок 1 ответа (с уже восстановленными байтами)

91 71 6d cd 9c 6f 8f c5 - предыдущий блок шифра
XOR
31 32 33 34 35 36 37 38 - ключ
XOR
80 25 32 98 ce 64 9a cd - блок 1 ответа
=
20 66 6C 61 67 3D 22 30 - расшифрованный текст для второго и последующих блоков шифра

Использование одного блока шифра как первого и второго блоков запроса выбрано только для удобства. Таким образом расшифровывается весь текст, но часть байтов при этом остается скрыта (например 2 и 3 байт в первом блоке текста - "26 ?? ?? 3B 5A 45 52 4F")

Ниже приведен общий алгоритм решения, с помощью которого были найдены недостающие байты:
Первый блок запроса - рандомный, второй - блок, который расшифрован не до конца.
Блок 1 запроса подбирается так, чтобы во втором блоке ответа байты, которые необходимо найти, не были равными нулю.

11 22 33 44 55 66 77 88 - блок 1 запроса
XOR
31 32 33 34 35 36 37 38 - ключ
x
00 18 cf 96 ff 00 00 00 - блок 2 ответа
=
00 09 cf e6 9f 00 00 00 - расшифрованный текст.

БОНУС#2
Прохождение уровня wi-fi.
1) Авторизуемся с test:pass
2) Видим в куках PHPSESSID=(тут base64 упакованный gzdeflate)
3) Дальше методом тыка видим диру /userdata/sid в которой sid это наш PHPSESSID.
4) Тем же волшебным методом находим файл passwd.php
5) Делаем так: print(base64_encode(gzdeflate('passwd.php')));
6) Дальше подставляем в куки, и в сорцах наш инклуд с флагом.

2 комментария:

  1. Опубликуй прохождение левела с инклудом сессии.

    ОтветитьУдалить
  2. Rebz, что-то прохождение рыбы очень мутно написано. Я сначала в ходе экспериментов заметил, что при изменении одного байта в i-м блоке, i-й блок текста меняется целиком, а в (i+1)-м меняется ровно тот по счёту байт, что изменён в i-м блоке шифра. Потом мне напомнили, что эта техника называется bit-flipping attack on cbc mode.

    ОтветитьУдалить