Nuit du Hack 2k15

2 июля 2015

Вместо экзамена по физике на этой сессии я был в составе нашей университетской команды по CTF в Париже на финале Nuit du Hack. К слову, это мой первый в жизни перелет и ранее далее Новосибирска я никуда не выбирался. Пилот этого самолета оказался самым приветливым, и даже хотел устроить «экскурсию», показывая пассажирам города, над которыми мы пролетаем. Правда, ничего у него не вышло, потому что большинство пассажиров спали, но он по крайней мере старался. В Москве мы разве что взяли немного евро в банке, и полетели дальше.

В аэропорту Парижа нас встретила первая неприятность — автоматы для покупки билетов на RER. Они, во-первых, не принимали наличные, а, во-вторых, карты некоторых из нас. К тому же мы не совсем были уверены, в какую там зону нам надо, и затруднялись с выбором нужной станции. К слову, запах на станциях у них не сильно приятный, да и внешне мне новосибирское метро как-то больше нравится. Зато есть прикольные двухэтажные поезда. На станции, на которой мы собрались пересаживаться, мы не смогли найти автомат, и обратились в справочную, где на наши вопросы на английском нам отвечали по-французски и показывали в сторону выхода. Этот автомат был уже чуть более приветлив, и не отказывался от наличных, поэтому мы купили билеты и отправились к отелю.

Отель не был особо удивительным, разве что карта-ключ для комнаты показалась мне необычной. Комната была небольшой, но с мягкими кроватями-подушками. Расположившись, мы сходили в замеченный неподалеку McDonald’s, а потом отправились гулять по окрестностям. Найденный на карте замок был закрыт на реставрацию, а больше ничего особенного в округе и не было.

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

На следующий день мы отправились в центр, пофоткаться у достопримечательностей. На станции мы взяли универсальный билет во все пять зон на два дня. Как сказал нам местный француз, «It’s quite expensive» — 37 евро или около того. Зато по этому билету можно было ездить хоть на RER, хоть на метро, а не покупать билеты на станции каждый раз.

Когда мы фотографировали небольшой фонтанчик, к нам подоспели цыгане. Сначала я отказывался от подачи «глухонемым», но потом решил, что пять-то центов занести можно. Когда я достал кошелек, одна из цыганок вырвала тысячу рублей и удалилась в неизвестном направлении. Евро, кстати, не пытались вырывать. Проходящий мимо чернокожий парень пытался нам показать, что связываться с ними не надо, но было уже поздно.

Мы шли в сторону Лувра вдоль какой-то реки, а на тротуаре продавали различные сувениры — брелки, магниты, картины, страницы из комиксов, тарелки и все такое. Я, кстати, сбегал в один книжный магазин, но не заметил там комиксов.

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

Завершив свой небольшой тур по достопримечательностям, мы сели на RER и поехали туда, где должны были пройти соревнования. На этой станции турникеты были закрыты решёткой, а сбоку была открыта калитка. Район казался каким-то заброшенным, поскольку там было очень мало прохожих, а большинство магазинов и кафе были закрытыми. Мы попытались найти хоть какое-нибудь место, в котором можно было бы поесть, но они были либо какими-то непривлекательными, либо закрытыми. Поэтому мы дошли до McDonald’s, и снова поели в нем.

Потом мы добрались до места проведения соревнований. Оставалась ещё пара часов до начала, все футболки и другой стафф уже были раскуплены (разве что были наклейки). Мы походили по зонам, в которых проходили разные мероприятия в рамках евента, и сели дожидаться начала в каком-то клубе, где организаторы играли друг с другом в настольный футбол. Когда мы пошли в здание, выделенное для CTF, большинство команд уже расположились там. В общем-то, мы успели только подключить ноутбуки, когда организаторы выгнали всех — одна из команд получила доступ к заданиям и машинам других участников, в то время как некоторые другие команды не имели доступа к собственной сети. Игру отложили на час, а для нас сготовили барбекю. Через час, правда, ничего они не починили, поэтому вместо Attack/Defense (который они называли Private CTF) они просто дали всем доступ к проходившему здесь же Jeopardy (Public CTF).

Некоторые таски были очень простыми; удивило также наличие двух похожих тасков с использованием азбуки Морзе. Над одной из задач парень из нашей команды бился очень долго, а все дело было в переносе строки, который не подразумевался, но при этом-таки был нужен. В общем, среди девяти участвовавших команд, наша заняла шестое место.

Уставшие, мы вернулись в отель и поспали несколько часов перед вылетом. Когда ехали в аэропорт на RER’е, в наш вагон зашли музыканты и играли, пока мы не доехали. Перелёт в Москву был довольно удачным — мне не сильно хотелось спать, сидел у окна, было светло, покормили вкусно. Успел повторить теорию вероятностей. Во время перелёта в Новосибирск уже стал засыпать, и вернувшись в общагу утром, лег подремать, а проснулся уже вечером.

Тервер я подготовил не очень, физику сдавал на самой дальней пересдаче, 30 июня, но нормально разобраться тоже не смог. Сессию закрыл и вернулся в Новокузнецк вместе со своим стационарным компом. Теперь можно спокойно работать над своим Google Summer of Code проектом, а остаток времени провести за компьютерными играми.

Spider Player Addon

12 апреля 2015

В одном из обновлений своей утилиты я сделал так, что название трека добавляется к ссылке как параметр запроса, который игнорируется vk, чтобы в подсказке я мог всё-таки увидеть название.

Недавно я слушал в Spider Player какой-то трек, и в его названии был слэш. В плеере в качестве названия отображалось то, что было после этого слэша, и я решил проверить, всегда ли это происходит. Оказалось, что плеер не слишком умно парсит имя файла из ссылки, и берёт просто всё от последнего слэша в строке до конца. Поэтому я быстренько изменил утилиту так, чтобы добавлялось не просто название трека, но ещё и слэш перед ним, и таким образом получил приличный вид названий для треков из vk. Добавил ещё длину трека, чтобы выглядело совсем как прослушивание треков оффлайн.

Кроме того, я поискал Spider Player по Github, и нашёл один-единственный репозиторий, в котором был веб-интерфейс для плеера на Meteor. Я никогда не пользовался веб-интерфейсом Spider Player, потому что не знал, что он вообще у него есть. Оказывается, можно сделать так, чтобы плеер выдавал инфу о своём состоянии и реагировал на простые команды по http. Сначала я побаловался с Meteor-версией, но потом решил пойти дальше.

Я написал расширение для Firefox, которое следит за состоянием плеера и выдаёт стильную подсказку с именем исполнителя и названием трека при переключении.

Оно также добавляет кнопочку, которая открывает небольшое окошко с минималистической версией плеера (да, только кнопка Play/Pause, но я всё равно даже ею не пользуюсь).

Но самое главное — оно добавляет в контекстное меню браузера возможность быстро добавить треки в плейлист. Если нажать правой кнопкой по ссылке на пост vk или если нажать правую кнопку на странице самого поста, то в менюшке будет пункт «Добавить в Spider Player». При этом расширение создаёт временный txt-файл для моей утилиты и небольшой bat-скрипт, который делает всё необходимое. Потом она запускает этот скрипт, скрипт запускает утилиту на Java и передаёт сгенерированный плейлист плееру. Всё это работает пару секунд, и при этом не требует правки файла и запуска утилиты скриптиком вручную.

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

P.S. Я ещё не придумал название, поэтому не выкладываю никуда. К тому же, кто вообще им будет пользоваться?

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-го уровня и лёг спать. Утром бета уже кончилась. В принципе, сделана игра неплохо. Так выглядит лобби — показаны персонажи игроков и монстр крупным планом:

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

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

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

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

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

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

1 2 3 4 5