UCTF autumn 2017 write-ups
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
assets
.DS_Store
README.md
_config.yml
bad1.png
best-logotype.png
bw1.png
bw2.png
bw3.png
desc1.png
desc2.png
dire1.png
down1.png
down2.png
down3.png
file
gogo1.png
gogo2.png
hack1.png
hack2.png
hard1.png
hindi.enc
index.md
letter.dat
loca1.png
logo1.png
magi1.png
old-flag.png
post1.png
ppc150.py
pret1.png
public.pem
refr1.png
rsa-free.py
task.txt
very-pretty.png

README.md

Написала команда «Собака Павлова»: Ярик @javache и Ваня @vanyaklimenko.

CTB

Run, Dot, Docker

@vanyaklimenko

Run

Мы нашли уязвимый сервер: кажется, на порту 5001. На сервере ctb.upmlctf.ru поднят SSH! Логин run, пароль run.

Dot

Ещё одна таска на стегу? ssh: ctb.upmlctf.ru:5002, логин и пароль dot

Docker

Написано, что флага нет. Но мне кажется, что этот докер-контейнер всё же хранит в себе секреты. ssh: ctb.upmlctf.ru:5004, login & pass: user.

Ничего интересного. Захожу на серверы через ssh и нахожу флаги практически моментально. В последнем таске, правда, пришлось поизучать историю в файле ~/.bash_history.

🚩  uctf_bash_is_so_easy, uctf_it_is_hidden_file, uctfhardcodedpassisclassic

Hack hackers

@vanyaklimenko

Захожу на http://virus.upmlctf.ru/. Вижу, что «вирус» стучится на нашу машину по ssh:

Разворачиваю ssh-ханипот (например, sshesame) на порт 22 и собираю пароли. Вхожу на сервер «вируса» как john (у него самый сложный пароль) и ловлю flag.txt в домашней папке.

🚩  uctf_botnets_make_more_bugs

Forensics

Bad developer 1

@vanyaklimenko

Разработчики UPML CTF, наверное, не очень шарят в безопасности. Кажется, они оставляют заметки о тасках на telegra.ph. Да ещё и называют их UPML CTF.

Создаю пост в телеграфе с таким же названием. Вижу, что урлы создаются в формате название-месяц-число. Догадаться, когда был создан нужный пост не так уж трудно — пробую дату начала регистрации и тут же попадаю на страницу с флагом.

🚩  uctf_y0u_f0und_t3l3gra_ph_s3cr3t

Bad developer 2

@vanyaklimenko

Разведка обнаружила, что кроме таска разработчики слили кое-что посерьёзнее. И, кажется, они это пытались скрыть.

Скроллю ту же телеграфную страницу и нахожу ссылку, которая ведёт в телеграм-чат разработчиков. В самом начале переписки лежит секретный ключ и данные от сервера. Вхожу с этим ключом (логин можно было с лёгкостью угадать — ilya), листаю ~/.bash_history и вижу ссылку на файл с флагом. Открываю на своём компьютере и выигрываю.

🚩 uctf_dont_look_in_others_files

Misc

Start from down

@vanyaklimenko
516r1rh06l4vhp3377o yr1z3v54po3c
4
<hen

Одна из самых сложных и интересных, как мне кажется, задачек. Мы с Яриком чудом успели решить её ровно за пять минут до конца соревнования.

Сначала мы ничего не поняли. Потом мы тоже ничего не поняли. Мы брали подсказку в названии и действительно начинали снизу. Но длинная строка никак не хотела себя раскрывать. Потом, однако, до Ярика дошло, что <hen — это Брут с неправильной раскладкой клавиатуры. Ну, раз Брут, то мы имеем дело с шифром Цезаря, а 4 означает сдвиг. Идём дешифровывать: 516n1nd06h4rdl3377k un1v3r54lk3y. Похоже на leet, очеловечиваем: signirdoghardleettk universalkey.

Пишу письмо на signin@hardleet.tk в надежде, что universalkey — это какое-то кодовое слово. Получив ответ, я очень быстро осознал, что мои надежды были напрасны:

Принимаю это пиьсмо близко к сердцу, обижаюсь и иду ломать почту. Поглядев на служебные заголовки догадываюсь, что это яндексовский аккаунт. Пароль — universalkey, весьма очевидно.

В инбоксе лежит письмо с последней частью пазла: @upm1c7f_d0n3bot. Это телеграм-бот, который раздаёт флаги.

🚩  uctf_YnlfTTRETjM1NSAg

Black and white are fighting

@javache
0. start == win  
1. 4r3/1P1R2Q1/b2P4/4p3/2q1N3/p4K2/2N5/1n5k w KQkq - 0 1  
2. s4y t0 60t  
3. u r awesome!

Из условия задачи очевидно только то, что ее решение будет как-то связано с ботом (s4y t0 60t — это say to bot), и что ссылку на бота нужно получать из непонятной строки под номером 1.

Погуглив эту строку или отдельные ее части, нахожу различные файлы с подобным содержанием, и замечаю, что у одного из результатов расширение .epd. Гуглю «epd online viewer» и понимаю, что непонятная строка является строкой FEN, и служит для указания позиций фигур на шахматной доске, пихаю туда нашу строку:

Что ж, направление правильное, но что дальше? Вернемся к условию таска, а именно start == win, что в применении к шахматам может означать, что нам необходимо поставить мат, да ещё и с первого хода. Использую первого попавшегося бота для шахмат, и перекладываю данную задачу на него.

Подумав, бот отвечает, что белые, сделав ход g7g2, ставят мат черным. Я также проверял, что будет, если предложить боту ходить за черных — но там только шах.

Как и говорилось выше, решение таска как-то связано с ботом, поэтому я просто забил в телеграм @g7g2bot и сразу же нашёл нужного бота. Осталось только запустить его — и вот он флаг:

🚩 uctf_cG93ZXJlZEJ5TTRE

D35c4r735

@javache

Flag is uctf_ + ...
task.txt

Буквы сопоставлены с числами. Сразу бросается в глаза, что каждое число не превышает 25, что может указывать нам на то, что они как-то связаны с номерами букв в алфавите. К сожалению, начальные попытки составить из чисел строки по номерам в алфавите ничего полезного не дают, как и другие способы манипуляций с буквами и числами. Значит, что-то другое.

Название таска — Descartes, написанное литом. Поначалу я искал что-то связанное с Декартом, шифрами и алфавитом, но ничего дельного не нашёл. Осталась самая безумная идея: возможно, что имя Декарта связано с системой координат. Возможно, что буквы и числа в файле есть точки формата (буква, число). Я начал перерисовывать всё это дело и на определенном этапе понял, что это ничто иное, как QR-код. Потом я устал и быстро написал программу, которая бы сделала нудную работу за меня, и получил готовый QR-код:

Осталось только декодировать его — мы получаем строку TWFkZSBCeSBATTRETjM1NQ. Добавляем uctf_ в начало.

P.S. На самом деле Ярику пришлось немного сложнее. Он до последнего верил, что ту строку надо было дешировать, не смотря на тот факт, что подходящий ответ ну никак не получался.

🚩 uctf_TWFkZSBCeSBATTRETjM1NQ

Stegano

Logotype

@vanyaklimenko

У нас отличный логотип. Ты тоже так думаешь?
best-logotype.png

Сорок секунд в Стегсолве — и я вижу куар, в котором закодирован плейнтекст: sorry, try harder. Хе-хе, ну ладно. Ещё сорок секунд — и находится подходящий куар.

🚩 uctf_stegsolve_master

Foreign

@javache

Наши спецслужбы перехватили сообщение подозрительного содержания. Что же хотел сказать его автор на самом деле?

Ещё сорок секунд, но уже в Гугле. Шифр называется HINDIA-4X.

🚩  uctf_googletranslate_cant_solve_stego

Pretty

@vanyaklimenko

Какой умилительный котик!

А тут уже интереснее. Джипег меньше мегапикселя, а весит 2,5 МБ. Прогоняю через binwalk — чё-то ничего. Пробую hexdump — та же история. Даже Стегсолв ничего не даёт.

Через некоторое время додумываюсь сравнить этого котика с любой такой же картинкой из Яндекса. Оп:

🚩  uctf_it_s_stego_time

Old flag

@vanyaklimenko

This flag was generated a long time ago.

Картинка похожа на надпись, набранную на Маке, потому что на ней видны артефакты субпиксельного сглаживания — значит, это какой-то символьный шрифт. Какой? Какой-то из «Звёздных войн» судя по прямой отсылке к ним в условии. Бинго, это шифр Эребеш. Скачиваю шрифт и за пару минут подбираю текст.

🚩  uctfflaginagalaxyfarfaraway

Magic bytes

@vanyaklimenko

Что это за странный файл?

Файл действительно странный. Стандартные инструменты анализа (типа утилит или здравого смысла) не дают понять, в какую сторону двигать. Поэтому в сторону девяностых и кулцхакинга, включаю саундтрек из «Кинга Фьюри» и пытаюсь найти скрытое послание, открыв его в hexdump. И-и-и… всё ещё не ясно.

Через пару часов возвращаюсь к заданию и случайно запрокидываю голову на девяносто градусов. Вау.

🚩  uctf_xxd_can_do_stego

Crypto

@bash

@javache

Расшифруйте секретное послание: ZnhndV9nc3pnX3hpYmtnbF9kemhfdnpoYg==

Сразу видно, что это base64, после декодирования получаем fxgu_gszg_xibkgl_dzh_vzhb. Похоже на флаг, но зашифрованный ещё одним способом. Если обратить внимание на название таска (знак собачки по-английски будет at), становится понятно, что строка зашифрована шифром atbash. Расшифровываем и получаем флаг.

🚩 uctf_that_crypto_was_easy

Directories

@vanyaklimenko

Я распаковывал архив терминалом и сразу увидел его причудливую структуру. Символ — номера мест в строке:

🚩 uctf_placing_letters_is_very_funny_job

Hack RSA

@vanyaklimenko

Во-первых, это ЦТФ. Во-вторых, я в другом городе. В-третьих, если на ЦТФе дают публичный ключ, то он должен быть слабым. Атака Вейнера (чтобы не вникать, можно попробовать готовый инструмент) ломает его и выигрывает RSA. 🚩 uctfyouwonrsaencryption

RSA без регистрации и СМС

@javache

Будущее уже здесь! Мы нашли в Интернете новый стартап по дешифровке шестнадцатеричных чисел. Правда, у него есть свой секрет, расшифровывать который он не хочет. Однако, мы вытащили его исходники и зашифрованный секрет. Может быть, с ними что-то можно сделать?
Говорят, что у сервиса есть консольный интерфейс: nc crypto.upmlctf.ru 5005

encrypted_secret = 0x5c25cfe2dbbb9467d8f5e94733abba928a444b7d7e2f2166bc3c8eb0f8d414f3d556f5e513319c8e9bf530b6208b8c4804def2eb7ad669593283abdaf18c849dc36c3e93cc2f256e21b59937b98234c93a639df5284330d9118dfa0b9e0911f70e2d3bf94fe5d2095c8bcfdce933856ad01a846dbc9ddffc6b0deee2a7238effc533bf1a881a360f418b405a6f32420072ac8194169ed65a3e7df02dd99555f41a75f23a60831e79a9a2f3e812536a80d5f7418d5354b00db0086d74b8d430b202da9bdeec36effb8eddefaa0121a4b89b30284aa31aafc5d5f40461450e43b015c130e55530668959e949804effd97e6e41cacd4b4b105c956cae3a577e13c6`

Нужно получить вывод консоли при вводе секрета, но система не даёт нам этого сделать. Изучив файл, я вижу значения N и e для алгоритма RSA, а также сам этот алгоритм (результат считался по формуле decrypted = data ^ d % n). Я, радостный (потому что шарю в этом алгоритме), бегу на factordb.com, дабы найти там разложение числа N на простые множители и найти d, но, увы, хоть сайт и говорит, что это число составное, делители его неизвестны.

Что же делать? Погуглив данную проблему, я точно понял — крипта хорошая, и не зная разложения N мы не можем найти d, а, значит, я не смогу просто решить всё это дело. В итоге я купил подсказку (−100 баллов!), в которой говорилось о возведении в степень, и о том, что на входе запрещено только одно число не без причины.

Поначалу я подумал, что подсказка бесполезная, но, поразмыслив над ней, я пришёл к предположению, что если скормить сервису секрет в квадрате (decrypted = data ^ (2 * d) % n), а потом взять корень от полученного результата, то можно получить необходимое нам число (в своих мыслях я просто-напросто игнорировал % n оттуда и надеялся на лучшее). Полученное в результате всех этих манипуляций HEX-число я перевёл в строку, и, к моему удивлению и радости, увидел читабельный флаг.

Как оказалось позже, мое решение было результатом одного бага: система не должна была разрешать числа, большие n. Но идея правильного решения была более-менее похожей: узнать дешифровку для числа 2, затем для encrypted/2, а полученные результаты перемножить по модулю n.

🚩 uctfyouneedsomepadding

Joy

Вы сейчас серьёзно, да?

Web

Location

@vanyaklimenko

Говорят, что все зарегистрированные пользователи этого сайта получают флаг. Но так ли это на самом деле?

Регистрируюсь через форму, рву себе шаблон: какого-то хрена флаг действительно в адресной строке.

🚩  uctf_why_is_flag_here

Go, go

@vanyaklimenko

Какой-то странный сайт. И безопасность у него странная.

В коде ничего, в адресной строке тоже пусто (хе-хе). Пробую разные вещи и выясняю, что сайт хранит стейт авторизации в куке, да ещё и не особо безопасным образом. Впускаю себя:

Однако система спалила неладное и потребовала пароль. А также почему-то вдруг в коде страницы как обнаружился комментарий с каким-то хешем:

<!--
            if my_super_hash(password) == "2af9b1ba42dc5eb01743e6b3759b6e4b":
            -->

Ломаю его с помощью гугля и попадаю в админку. Какой удивительно случайный факт дня мне сегодня попался:

🚩  uctf_need_more_easy_web_tasks

Hard security

@vanyaklimenko

Посылаю get-запрос с нужным заголовком — благо, что локальный адрес дан в условии. Единственная сложность — на сервере стоит https, а telnet и nc с такими не разговаривают. Как быть? Поставить (если ещё не) OpenSSL и сделать вот так: openssl s_client -connect admin.upmlctf.ru:443. Ну и вот так, конечно:

GET / HTTP/1.1
Host: admin.upmlctf.ru
X-Forwarded-For: 10.8.0.111

Ловлю флаг в ответе сервера и бегу вбивать. Ой:

Пишу Никите. Никита быстро фиксит ответ на платформе. Такой вот мини-joy с социальным взаимодействием.

🚩 uctf_untrusted_proxy

PPC

Refresh

@javache

А в этом таске мы расскажем о том, как быстро увеличить посещаемость сайта. Вот и пример:

Наша задача — обновить страницу 2017 раз. Это можно сделать и ручками (я знаю как минимум одного человека, который таким образом получил флаг), но мы-то не за этим пришли на CTF. Пишу простенькую программу на питоне, используя библиотеку requests. Так как сайт запоминает пользователя с помощью куков, необходимо создать сессию (s = requests.Session()) и делать get-запросы в её пределах. Пара минут — и флаг готов.

🚩 uctficandomanyrequests

Not easy reverse

@javache

Эта программа делает что-то непонятное. Не поможешь узнать её секрет?

Флагом является строка, при которой программа выведет Success. Пробежимся по условиям:

  1. len(flag) == 22 — строка должна содержать в себе 22 символа. Сразу можно сказать, что первые 4 символа — uctf.
  2. flag[9:3:-1] == "yz4rc_" — 3—9 символы — _cr4zy.
  3. 0О0О00… — здесь и в следующих условиях это название переменной, для удобства я заменил его на i. Условие: sum([ord (i) for i in flag ]) // 2 == 967. Ничего конкретного это условие не даёт, оставим его на потом.
  4. ''.join([chr(ord(i) ^42) for i in flag[10:15]]) == 'uibou' — для символов с 10 по 15 должны выполняться условия: chr(ord(flag[10]) ^ 42) == 'u'; chr(ord(flag[11]) == ‘b’ и т. д. Я решил просто пробежаться по числам от 0 до 1000, и найти число, для которого будет выполняться условие chr(i ^ 42) == 'u', а потом взять chr(i). Проделав эти операции для всех остальных символов, я получил строку _CHE_.
  5. ''.join([chr((ord(i)- 65 + 8) + ord('a')) for i in flag [20 :14 :-1]]) == 's' * 4 +'{' * 2 — аналогично с 4 условием ('s' * 4 +'{' * 2 == 'ssss\{\{'), только строка перевернута. Строка, подходящая по условию - SSKKKK.

Соединив части флага, я получил uctf_cr4zy_CHE_SSKKKK, в которой всего 21 символ, а нужно 22. Здесь нам пригодится условие 3, которое как раз и определяет этот последний недостающий символ. Я, аналогично 3 и 4 пункту, решил просто пробежаться по числам от 0 до 1000, брать от них chr(i) и, добавляя к флагу, прогонять по условиям. Оказалось, что удовлетворяет всем условиям строка uctf_cr4zy_CHE_SSKKKK!, которая и является флагом.

🚩 uctf_cr4zy_CHE_SSKKKK!

Postfix

@javache

Я люблю математику. А ты? Покажи мне это!
nc ppc.upmlctf.ru 5006

Интерфейс, который предлагает нам решать обычные математические примеры:

Если с подключением к сервису с помощью сокетов проблем не возникает, то с обработкой примера надо немного постараться — операции представлены в виде число число операция, причем возможны различные конструкции, например, 5 6 + 11 2 + *, что значит (5 + 6) * (11 + 2). В общем, вся сложность заключалась в написании алгоритма обработки подобных примеров.

Как я узнал позже, подобная запись называется постфиксной нотацией или обратной польской записью, и решается стандартным путём (умные люди давным давно решили эту задачу на разных языках программирования), тем не менее, алгоритм решения легко придумывался и сам.

🚩  uctfmysecretisinsidemath

Вместо выводов

ЦТФ был весьма интересным способом провести выходные. Мы вспоминали кучу всего, что знали про математику, алгоритмы и всякие компьютерные штуки, пытаясь решить все эти задачки (и честно решили!). Кроме того, всё это время надо было непрерывно думать и искать нестандартные подходы к решению: например, чтобы решить задачку D35c4r735, мы перепробовали больше пятнадцати разных вариантов и стратегий, задудосили Гугль странными и жуткими вопросами и перечитали некоторую часть работ Рене Декарта. И не сдались.

Вот так всегда — надо думать и не сдаваться.

P.S. Было весьма досадно видеть, что львиная доля участников сидит на Виндоусе. Ребята, откройте для себя мир *NIX-систем и прекратите страдания уже сегодня!


17.11.2017