BackdoorCTF

2 апреля 2015

Мы тут участвовали в BackdoorCTF, и я решил написать небольшой врайтап по поводу таска, который решил.

Решил я, конечно, не один таск, но в основном это были простые таски типа получить 100 QR кодов и быстро их сосканить (т.к. по-быстрому найти что-нибудь подходящее для питона не удалось, взял консольную ZBar для винды и просто вызывал в нужный момент).

Но это не тот таск, о котором я собрался рассказывать. Самым интересным для меня таском оказался bbad. Нам даны 4 файла, один бесполезен, в другом лежит то, что надо расшифровать, и оставшиеся два нужны для того, чтобы понять, как это расшифровывать.

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

Сразу бросается в глаза то, что если вторым параметром идёт 1, то в выводе вторым идёт 0. Так как разделены они символом ’^’, я подумал, что это степень, и что шифруется так, чтобы выражение в указанной степени было равно второму параметру (по модулю, конечно).

Ещё сразу видим, что шифруемый текст разбивается на слова по пробелам, и каждое слово отображается в выводе отдельной парой чисел.

Несложно также заметить множество простых чисел в выводе (для нас специально сделали подборку команд, в которых шифруется только один символ). В голову приходит, что символу соответствует какое-то число, и можно попробовать выяснить закономерность. Сгруппировав команды от ’1′, ’2′, ’3′, ’9′, ’0′, замечаешь, что числа подозрительно простые, и к тому же ’9′ соответствует девятое простое, а ’0′ - десятое.

Вскоре замечаешь, что ’q’ соответствует 11-ое простое число. И другим буквам тоже соответствуют простые, но закономерности не видишь. Смотришь на клавиатуру — а ’q’ идёт сразу после ’0′. Вооружившись первой сотней простых чисел и пробежавшись по клавиатуре, я с помощью регулярки генерирую тело функции, которая будет переводить символ в соответствующее число (кто-то не знает про dict в питоне, да).

Запускаем на всех односимвольных входах с ключом 1 — и выходное первое число всегда совпадает с соответствующим простым. Успех! Идём дальше. Время попробовать более длинный текст с ключом 1: ’abcd’. Вероятно, символы всё ещё кодируются простыми числами, но непонятно, складываются их коды, перемножаются и зависят ли они от позиции символа. Сначала пробуем просто перемножить их все, и получаем неверный ответ. Тогда пробуем возвести код символа в степень, соответствующую его позиции в тексте. Получается. Круто, мы решили таск для ключа, равного 1.

Теперь надо разобраться с тем, как зависит ответ от ключа. Тут нам пригодится группа команд, которые работают с текстом ’V’, но используют разные ключи. Для 1 наш ответ уже совпадает. Если присмотреться, то закрадывается мысль, что ответ примерно в <ключ> раз меньше простого числа, соответствующего нашему символу. Проверяем на калькуляторе — делим нацело — полностью совпадает.

Непонятно только, нужно ли делить на ключ код каждого символа или получающееся сообщение и сколько раз на него нужно делить. Пару раз попробовав, выясняю, что на ключ делят один раз. Это, конечно, неплохо, но что делать с числом, которое стоит после ’^’? Мы ещё не придумали, как вычислить его, если только это не случай с ключом, равным 1 (там просто ставим 0).

Я пробовал свою догадку с возведением в степень и взятием остатка от 12000 (число, встречающееся в условии), но она оказалась неверной. Довольно очевидная идея о том, что это остаток от деления, пришла ко мне не сразу, причём довольно случайно — я просто решил это проверить, хотя и не думал, что это окажется верным решением. В общем, так мы выяснили, как получить оба числа, печатаемых в ответ.

Осталось лишь декодировать зашифрованное сообщение. Правда, у нас нет ключа, который используется для кодирования. В условии написано, что он не может быть больше 12000. Кроме того, мы знаем, что второе число — остаток от деления на наш ключ. Так как остаток от деления больше ключа быть не может, а ключ на всё сообщение один, то минимальный ключ, которым можно было его зашифровать, должен быть больше любого из остатков, указанных в нашем зашифрованном тексте. Максимальный остаток — 8923, так что начинаем перебирать ключи с 8924, и заканчиваем 12000. Отметим также, что у нас в сообщении есть два небольших частных от ключа — 33 и 47. Вероятно, это короткие слова, которые будет несложно декодировать и по ним понять, подходящий ли ключ был найден.

Отметим, что код слова мы можем получить как a*key+b, где a, b — пара чисел, указанных в зашифрованном тексте. Кроме того, код слова — произведение простых чисел, соответствующих символам 0-9a-zA-Z, поэтому если при разложении кода мы получаем слишком большое простое число, можно сразу отбросить подобранный ключ. Более того, каждое число должно встречаться уникальное число раз, и это число раз должно находиться в диапазоне от 1 до количества уникальных простых чисел в разложении. (Сейчас, при написании этого поста, я понял, что если в слове один и тот же символ встречается дважды, то степень при соответствующем ему простом числе будет суммой номеров позиций, в которых находятся эти символы. Я просто отбрасывал подобные комбинации.) Таким образом, мы можем отбросить очень большое число различных неподходящих ключей.

Где-то третий найденный подходящий ключ выдал слово «is». Я остановил перебор и попробовал дешифровать всё сообщение этим ключом. Так я получил сообщение, в котором говорилось, что флаг — sha-256 от xY3wL1Sg. Его и сдаём.

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

Если что — мы восьмые.


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

Музыка

15 февраля 2015

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

Интересно то, что подобный плейлист можно открыть плеером, который поддерживает потоковое воспроизведение и слушать музыку из вк в нём, а не в браузере. Я попробовал запустить плейлист в Spider Player, которым пользовался оффлайн, пока не переехал вк и Яндекс.Музыку, и всё заработало. То есть можно не открывать вкладку в браузере и пользоваться его интерфейсом, а по-человечески переключать треки, включать и выключать перемешивание нажатиями горячих клавиш.

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

К сожалению, тот сайт не предназначен для создания плейлистов из прикреплений в постах. Поэтому я решил написать собственную утилиту. Я начал было писать iframe-приложение на javascript, но вк хотел открыть мой сайт по https-ссылке, а у меня нет SSL-сертификата, и потому приложение просто не загружалось. Я написал ещё несколько версий на javascript и php, использующих различные методы работы с VK API, но несмотря на то, что они работали, им приходили неправильные ссылки. Как заметили в комментарии на хабре, вк может отдавать ссылки на vk-cdn.net или на vk.me. Моим скриптам сервер возвращал ссылки на vk-cdn.net. Они выдавали 404, когда я их открывал, и не работали в плеере. Я пробовал менять настройки приложения, получать другие права и бессрочный токен, но это не помогало.

Честно говоря, я так и не понял, как же на том сайте такие же методы VK API, вызываемые через PHP, получают ссылки, которые нормально работают для нужного пользователя, но в конце-концов я просто попробовал написать Desktop-приложение, и оно получило необходимые ссылки.

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

Правда, он предпочитает отображать в качестве названия записи имя файла, а не прописанное в плейлисте название, поэтому при переключении на трек из вк отображается что-то такое:

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

Evolve

16 января 2015

Несколько дней назад я обнаружил Evolve [Closed Beta] у себя в списке игр в Steam. Я не особо интересовался игрой, но понемногу следил и читал пару материалов по игре — о классах и режимах игры. Я подумал, что это очень неплохая возможность посмотреть игру до её выхода, чтобы узнать, потянет ли мой компьютер её и решить, стоит ли её покупать. (Бета раздавалась тем, кто участвовал в альфе или имеет Left 4 Dead или Bioshock Infinite.)

Я запустил скачивание 22 Гб и пошёл узнавать информацию о бете. На странице игры в магазине Steam была новость, которая говорила о старте 16-го января; на официальном сайте были указаны даты вместе с точным временем. Бета начиналась в пятницу в 20:00 по Москве, и заканчивалась в понедельник в 7:00 по Москве (на самом деле я ошибся на сутки, когда переводил время — закончилась она во вторник). До старта беты я часто заходил в группу игры в Steam и отвечал на одинаковые вопросы русских о том, когда старт, за что бету дали и останется ли она после завершения.

К слову, я впервые столкнулся с предзагрузкой в Steam. Оказалось, что небольшие задержки со стартом — дело обычное. Кроме того, я не ожидал, что для «расшифровки» потребуется столько же места, сколько требовалось для скачивания, а потому пришлось экстренно перемещать часть файлов. В общем, примерно через час после обещанного старта я смог запустить бету.

Она встречает нас обучением игры за первого монстра, Голиафа. Поскольку во время игры менять расширенные настройки графики нельзя, я поиграл с лагами и решил, что за монстра я играть не хочу — думаю, что я быстро бы сливался, потому что и в Left 4 Dead 2 я не слишком хорошо играл за танка. Кстати, меня удивило, что в бете был перевод на русский язык и множество готовых роликов с описанием персонажей и режимов игры.

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

Получив пять в понедельник, я снова открыл Steam и увидел, что бета ещё не закончилась. Тогда я сел в неё играть и иногда делал скриншоты для этого поста. Где-то за пять часов я прокачался до восьмого уровня и открыл пару новых персонажей. Потом я внезапно вылетел из игры, и поэтому прервался на пару часов.

Читая ленту вк, я заметил, что Игромания собралась делать стрим по игре на Twitch в 20:00 по Москве. Делать мне было нечего, поэтому я зашёл посмотреть. Ведущие почти не играли в игру, а потому, например, редко пользовались щитом, о чём им писали зрители в чат. Меня это тоже не сильно устраивало, и я зарегистрировался в Twitch, чтобы сообщить им, что взбираться по стенам с разряженным реактивным ранцем можно, а про щит не стоит забывать во время сражения с монстром.

Так как ведущие играли «командой» (я не совсем уверен, откуда Evolve знает, кто с кем в «команде»), то им не давали выбрать монстра (что логично, потому что тогда противоположные стороны могли бы общаться между собой). Поэтому, чтобы показать геймплей за монстра, им нужна была команда на пять человек. И тут они решили пригласить зрителей. Я написал свой ник, был найден ведущим стрима и добавлен в друзья в Steam, после чего поспешил подключиться к игре.

В первом матче я играл за медика и, поскольку у меня был запущен браузер, игра опять тормозила. Настолько, что при высадке с корабля я остался на большой высоте. Игра запрещает выходить за пределы карты (например, уплывать за буйки), и моё нахождение в облаках её тоже не сильно устраивало. Через несколько секунд моё здоровье упало до нуля, и мне пришлось ждать высадки две минуты. К слову, однажды я умудрился «провалиться в текстуры» и улетел за пределы карты снизу. Монстра мы в этом матче успешно победили, причем довольно быстро.

Во втором матче мне удалось зайти за штурмовика, за которого я обычно набирал довольно большой урон с помощью мин. За монстра играл второй приглашённый зритель, и, если я не ошибаюсь, он нас раскидал ещё на первом уровне эволюции.

После этого стрим закончился, а я поиграл ещё несколько матчей, докачался до 11-го уровня и лёг спать. Утром бета уже кончилась. В принципе, сделана игра неплохо. Так выглядит лобби — показаны персонажи игроков и монстр крупным планом:

В начале матча и при возрождении игроки высаживаются на карту из небольшого корабля:

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

Далее начисляется опыт за матч, показывается эффективность вашей игры и общая статистика:

Кроме того, повтор всего матча ускоренно показывается на мини-карте, что выглядит довольно забавно. Особенно интересно смотреть, как обманывает охотников монстр или как заблудившиеся охотники бегут через всю карту туда, где уже идёт сражение.

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

Не думаю, что стал бы играть в эту игру слишком долго, а потому вряд ли куплю её, когда она выйдет. Разве что, возможно, куплю её тогда, когда будет комп помощнее.

Новый Год

31 декабря 2014

Новогодние праздники в этом году у меня не сильно отличаются от прошлогодних. Долго сплю, поздно ложусь, сижу за компьютером и играю в игры или ничего не делаю. Иногда хожу в гости к родственникам, но, как и в том году, не пересекаюсь с друзьями и одноклассниками.

Десятого числа будет экзамен по матану, а потому первая неделя января собирается быть менее насыщенной прохождением пропущенных за год игр. Тем не менее, сейчас качаю Dragon Age: Origins в Origin, потому что нахаляву достался и потому что надо же во что-то играть сегодня.

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

Сейчас кажется, что в этом году почти не было ничего особо интересного. Тем не менее, в начале апреля я был на CTF в Томске (где наша команда отхватила первое место), летом — в летней школе Parallels и в Бобровке на ACM-сборах, осенью участвовал в Поттосинской (не слишком удачно), в KrasCTF (снова с первым местом). Совсем недавно был NSU Crypto, где я оказался на третьем месте (и получил очередную флешку). И есть ощущение, что кроме этого ничего и не было. Я даже не помню, чтобы я занимался собственными проектами. Этот факт мне не сильно нравится, и надо что-то с ним сделать в следующем году.

Написание поста немного затянулось, и сейчас мы с одногруппниками играем в Mass Effect 3. Думаю, нужно будет бросить играть в древние игры, чтобы попробовать наконец новые. Пользуясь случаем, поздравляю всех с уже почти наступившим две тысячи пятнадцатым, и желаю в новом году вам побольше времени на любимые занятия и собственное творчество.

Код с подсветкой

21 декабря 2014

Сегодня я искал себе подходящий js-скрипт для подсветки кода (потому что раньше кто-то подсвечивал код вручную или применяя последовательность регулярок).

У меня есть собственная тема для Sublime Text, и я хотел использовать её же для подсвечивания кода на своём сайте. В ней подсвечиваются и имена функций, и форматная строка, и экранированные последовательности в строках, и поэтому всё это должен был поддерживать скрипт, используемый для подсветки.

Я посмотрел Prettify от Google и highlight.js, в которых имена функций считаются plain-текстом; syntaxhighlighter, который часто можно встретить в интернете и в котором подсветки имен функций также нет. В минимизированном коде первых копаться было лень, а в последнем по-хорошему эта функциональность прикручиваться не хотела.

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

В конце-концов остановился на SHJS, у которого немного странно записываются правила раскраски кода, зато довольно просто прикручиваются новые правила. Немного поправив его и приделав мою цветовую схему, мы получаем следующее:

#include <iostream>
using std::cout;

int main() {
	cout << "Hello, World!\n";
	return 0;
}

Кроме того, я подредактировал код блога, и нужные скрипты подключаются сами по мере необходимости.

1 2 3 4 5 6