Блог Ивана Комарова - RuCTF 2009
Мар. 1, 2009
21:41 - RuCTF 2009
В качестве компенсации за убогий ICFPC 2008 боги сниспослали нам увлекательнейший марафон RuCTF 2009 (отборочный этап). Такого разнообразия заданий я ещё не видел никогда. Несколько категорий по пять задач (на 100, 200, 300, 400 и 500 баллов), 48 часов времени, интернет, 5+ ноутбуков и около десяти человек в команде; побеждает тот, у кого больше всех очков — штрафные попытки и время сдачи таска роли не играют; задача открывается тогда и только тогда, когда все меньшие по ценности задачи этой категории сданы хотя бы одной командой. Безумно затягивающе и очень-очень в духе ICFPC 2007!
На подробный отчёт (c привязкой ко времени) у меня не хватит сил, так что кратко пробегусь по категориями и выложу некоторые медиаматериалы. :)
- admin Задачи на системное администрирование. 400 и 500 были на копание во внутренностях зашифрованных образов виртуальных машин, до них мы добраться не успели совсем. На 100 баллов надо было настроить OpenVPN (все команды видели друг друга через один VPN) так, чтобы внутри нашей подсети пинговались хотя бы две машины.
to_the_future, думаю, надолго запомнит этот таск. :) Кажется, в итоге всё решилось настройкой моста между виртуальной машиной и невиртуальной, хотя я не уверен. На 200 баллов надо было настроить приём и отправку почты внутри этого VPN'а. Этот таск мы так и не добили, потому что в конце сконцентрировались на других. На 300 баллов нужно было поднять MediaWiki с определённым набором настроек. Самое сложным оказалось допилить поддержку теховых формул. Поскольку полноценный TeX на хостинг поставить мы не могли, пришлось обработать исходный код MediaWiki напильником так, чтобы генерация картинок делегировалась любимому сервису
sharpc — http://l.wordpress.com. - forensics Задачи в стиле «криминальное расследование». 100 и 200 баллов решил
sharpc, а мы только похлопали ушами: в первой надо было по «содержимому флешки» восстановить «удалённую» картинку (выцепили её из Thumbs.db), во второй — проанализировать логи tcpdump, понять, какой IP распространял вирус внутри локальной сети и определить тип этого вируса. Задачи на 300 не было по непонятным причинам; 400 — это мегагроб, который никто не решил. На видео была снята и «замазана» карточка, нужно было восстановить, что на ней написано. По ней у нас была гипотеза в последние полчаса, но увы, она оказалась неверной. 500, соответственно, даже не открывали. - ctb Задачки на взлом серверов. Вот это было весело. :) Мы коллективно сдали 100 и 200. В первой оказалось, что на веб-сервер можно заливать файлы с помощью метода PUT, после чего выцепление нужного файла было делом техники. Во второй был многоуровневый квест — набор всё более и более сложных SQL-инъекций. Над 300 мы корпели последние часы контеста, но так и не осилили. Был какой-то движок блога (то ли самописный, то ли просто очень редкий), надо было его взломать и поместить свою ссылку в раздел «Ссылки». Всё, что нам удалось поиметь — простая SQL-инъекция, которая ничего не дала. Увы. :( В 400 надо было взломать самописный сервис на amd64 с помощью шеллкода (причём довольно хитрого), за это мы даже не брались. 500 при нас не открылся, хотя вроде бы под конец одна команда таки пробила 400.
- history «Кто умеет быстрее всех пользоваться гуглом». Разминочные задачки, на которых все команды набрали по 1500 баллов. Пользуясь случаем, хотел бы отметить идиотизм жюри, которые в вопросе «Назовите такую-то революционную статью» умудрились написать название статьи с ошибкой (признавшись тем самым, что они эту статью в глаза не видели, а просто скопировали название с википедии).
- reverse Задачи на дизассемблирование и reverse engineering. Вот здесь я увы, по задачам ничего сказать не могу, потому мои знания ассемблера находятся на уровне «знаю, что такое esp».
sharpc решил 100, на 200 и 300 мы застряли. 400 и 500 остались неоткрытыми. - ppc Задачи на программирование. Вот тут мы оттянулись! :) 100 — стандартная олимпиадная задачка, сдали очень быстро, а вот 200, по-моему, жемчужина контеста. Есть исходник на Common Lisp'е, который что-то делает за экспоненциальное время, надо разобраться, что именно, и сделать это за полиномиальное. Эту задачку пробило команд 5, и мы были первыми, чем я очень горжусь. :) Раскрывать решение пока не буду, а лучше покажу исходник и файл, на котором надо было запускать эту программу. Крайне поразительно, что тот же автор, который предложил этот замечательный таск, в качестве 300 дал какую-то унылую херню с ELF-бинарником без исходников (хотя и не стрипнутым) и двумя входными файлами (не решил никто). Считаю, ничего общего с professional programming & coding 300 не имеет. 400 и 500 открыты не были.
- stegano Ещё одна прекрасная категория — стеганография. Первая задачка — картинка, на которой был изображён пингвин и текст сказки «Колобок». Естественно, это был red herring, — если поиграть в с картинкой в графическом редакторе, можно было вытащить QR-код. Он был довольно зашумленный, поэтому нам пришлось написать программку, которая его «очищала». Оставалось только вбить в гугл фразу «decode qr code online» и получить заветную фразу «JURY LIKES SMALL PENGUIN DISTROS». :) Второе задание состояло из картинки с водяным знаком и программку, которая его генерировала. Исходники не прилагались, но рефлектором восстанавливались в наилучшем виде. Алгоритм вставки ЦВЗ был предельно прост — введённое число-ключ использовалось в качестве затравки для генератора случайных чисел вида (ax + b)mod c, после чего получались случайные двумерные точки на картинке. Для пикселей с чётным индексом к каждой координате RGB прибавлялось 5, для пикселей с нечётным — вычиталось. Нужно было понять, какое множество точек затрагивалось проходом алгоритма и выдать сумму их координат; это всё при том, что ключ, которым картинка подписывалась, мы не знали. Долго ли, коротко ли, но мы её зарешали. :) 300 и 400 мы продавить не смогли (500 не открывалась вообще). В 300 был файлик размером 143 байта и подсказка: «x86». Понять, что имелось в виду, мы не смогли, хотя гипотез перепробовали немало. 400 — .swf-файл и спрятанная внутри картинка интересного вида. Понять «что бы это могло значить» мы не смогли ни по отношению к флешке, ни по отношению к картинке.
Особняком стоит категория joy, за которую жюри нужно выдать медаль. Мы потратили всю ночь второго дня, но в итоге решили все пять заданий, получили 1500 баллов и невероятное количество позитива. :) Смотрите сами:
- Сделать фотографию команды. Три человека на ней (включая меня) выглядят редкостными фриками. ;)
- Сделать клип на хакерскую песню. (Все видеоролики мы записывали на камеру мобильного телефона и без монтажа, так что с технической точки зрения получилось не очень хорошо.) Клип, слова песни. Режиссёр и оператор — Михаил Рубинчик, в ролях — ВПС (оператор ноутбука, человек разумный № 1),
vadimmer (гитарист, оператор поливочной чашки), Дмитрий Косолобов (человек разумный № 2, счастливый человек). - Экранизировать сценку из «Записок невесты программиста». Здесь нам понадобилась девушка, которую мы в 3 ночи благополучно нашли. :) Конечный результат. Режиссёр и оператор — ВПС, мужская роль —
vadimmer, женская роль — приглашённая звезда Оксана (огромное ей спасибо). К сожалению, пришлось посылать лучший из промежуточных дублей (промежуточный дубль от финального отличается отсутствием в кадре геймера и одной запинки), потому что
vadimmer решительно отказался сниматься ещё раз, мотивируя это тем, что он «устал ржать». Позор ему. - Снять рекламу RuCtf. Результат. Режиссёры — ВПС и Михаил Рубинчик, оператор — ВПС, в ролях —
vadimmer (захватчик флага), Дмитрий Косолобов (охранник флага) и Илья Шахматов (страшный голос в темноте). - Сделать страничку команды. Без комментариев.
Медиаматериалы других команд можно посмотреть тут.
Организаторам большой 72-пунктовый РЕСПЕКТ. Я пришёл просто поиграть в какое-то дурацкое соревнование, не ожидая ничего интересного, а фактически обнаружил ICFPC образца 2006 и 2007 годов.
Более того, тут для эффективного участия надо быть универсалом, и это очень здорово! На удивление, благодаря «общей эрудиции», я решал и администрирование (сети + Unix-системы), и взлом (знание того, откуда берутся дыры в безопасности), и программированние (моя узкая специализация), и стеганографию (тут сложно сформулировать точно, что пригодилось). Причём, судя по количеству нерешённых задач, в каждой из этих областей мне есть куда расти. ;) Единственная область, в которой я по большому счёту я ничего не понимаю — это дизассемблирование и reverse engineering. К счастью, у нас были
Кстати, большая часть нашей команды выпала из процесса на 5 с лишним часов — решала личное первенство УрГУ по программированию. Я в силу определённых причин не мог присутствовать лично и собрался решать соревнование на тимусе, но после сдачи пяти халявных задач и получения WA16 по шестой простой задаче понял, что мне скучно его исправлять, забил и продолжил решать stegano 200. Удовольствия от этого было намного больше.
P.S. Пока писал, появились результаты. У нас 9-е место из 31, а в основной тур проходят первые 16 команд. Do the math. :)

а я и не знал, что проходит такой клевый чемп - ограничился тимусом. вы круты, ребята!
мне особо понравился вотермарк
А за lisp благодарствую :) Общая формулировка так тоже уже была предложена (тем же человеком, кстати, что и на 300), но оформление мне в голову пришло как-то неожиданно, и вообще я думал что это будет простой таск, в котором ничего даже курить не надо. Просто взять и вычислить :) В конце концов, если не знали лиспа — я тоже не знал в тот вечер, когда придумал таску :) А через день (вроде бы) она уже была готова вместе с документацией. Так что даже в этом случае всё было реально, странно, что всего 5 команд справились. А ещё грустно, что не дошли до полного мяса под названием ppc 400...
ctb300
R.I.P. by [Lobotomy]