Сыграем в ещё одну игру, дорогой друг?
Не прошло и года, а у нас уже вовсю идёт новый хакерский квест. В этот раз мы не стали делать явного анонса и пошли по более интересному пути, с привлечением аудитории извне. Рояль, азот и котики показался нам слишком простым и было принято решение немного усложнить задачу 🙂
Вы думаете, что квест только начался, но нет, он вовсю уже идёт. Всё началось с неприметной раздачи визиток в разных городах России — 10 февраля. На визитках не было ничего, совсем ничего, только рисунок черепа и спектр на другой стороне.
Что по награде?
Разбор первого задания
Разбор второго задания
Места основного движа
Какое-то время раздача визиток оставалась без внимания, и мы решили, что необходимо дать маленький толчок. На канале нашего тикток амбассадора вышло первое видео, и активность потекла ручьём. У нас был ручной чат на 150 человек, 1500 тысячи визиток и 1 админ, через сутки после публикации видео, количество людей в чате увеличилось в четыре раза!
По случайному стечению обстоятельств этот чат стал основной платформой для обсуждения заданий. Честно сказать, мы думали, что через денёк там всё заглохнет, но накал страстей возрос настолько, что если ты отлучался на час, то понять, что же произошло за этот час, было уже практически невозможно. Тысячи сообщений в час, 24/7. Подогревали интерес публики дополнительные видеоролики по теме от случайных людей, которые тоже получили визитки.
Ну а дальше уже понеслось, подробно разбирать все переписки не будем, некоторые отборные скрины добавили в конец поста.
▍ Какие ставки, господа?
Прежде чем мы начнём разбирать, что же уже было сделано, и что нас ожидает впереди, обсудим, что же у нас на кону, какой же будет приз.
Сумма выигрыша — 142 857 рублей.
Первое место всего одно и выигрыш заберёт команда, которая пройдёт последнее задание. Сумма распределится в зависимости от вклада человека в победу. Оценка будет производиться участниками сторон — самостоятельно, путём голосования внутри команды.
Теперь, когда приз понятен, расскажем, какие этапы квеста были пройдены. По понятным причинам рассказывать, сколько ещё осталось, мы не будем, но в этот раз в квесте успеют поучаствовать все.
▍ Первое задание
Итак, перед нами странного вида визитка.
Да-да, мы в действительности немножко косякнули и забыли убрать лого Canva.
На обратной стороне видно стилизованный в виде волны спектр видимого света. Изображение спектра будто чуть-чуть сдвинуто вправо, намекая нам на ту часть, которой не хватает слева (тогда бы спектр был выровнен по центру визитки), а именно на ультрафиолетовую часть электромагнитного спектра.
Если посветить на обратную сторону визитки ультрафиолетовым фонариком или устройством для сушки лака для ногтей, то визитка покажет нам свою скрытую от невооружённого взгляда часть:
В ней явно узнаётся штрих-код. Так и есть, это штрих-код по стандарту Code 128, и если мы, например, сфотографируем проявившийся код и подправим в графическом редакторе (для того, чтобы он приобрёл свои привычные цвета, не искажённые отраженным ультрафиолетом), то получим что-то подобное:
Декодируем любым доступным декодером (можно и онлайн на соответствующих сайтах), получаем длинное число, как обычно и бывает в штрих-кодах, а именно 62075940530548. Переведём его из десятичного вида в шестнадцатеричный (например, в стандартном калькуляторе), получим 0x38752E626974, а затем декодируем (тоже можно при помощи сайта) как текст в стандартной кодировке ASCII, получаем «8u. bit». Кстати, похожие манипуляции происходят при шифровании по стандарту RSA, ведь он определяет операции над большими числами, а не над более привычным нам произвольным текстом.
«8u. bit« (напоминает старые добрые 8 бит). Вроде похоже на доменное имя, только доменная зона немного непривычная, потому что она независимым от ICANN (организация, управляющая регистрацией доменных зон верхнего уровня) образом используется в системе Namecoin. Раньше разрешить такое доменное имя можно было при помощи свободно доступных DNS-серверов OpenNIC, однако с некоторых пор такая поддержка была прекращена этим проектом. Сейчас же для просмотра записей, ассоциированных с именем «8u» (строго говоря, в системе Namecoin точный ключ для данной записи выглядит как «d/8u», поскольку для DNS-имен в зоне «. bit» там сопоставлено пространство имён «d») можно выбрать один из способов:
- Воспользоваться онлайн-API блокчейн-эксплорера для Namecoin: найти в нём самый свежий «opupdate» (соответствует операции OP_NAME_UPDATE) и посмотреть значение в поле «value», которое было присвоено данному имени в последний раз; эта операция обновляет значение имени после самого первого значения, а если мы посмотрим внимательно, то увидим, что самое первое значение в «opfirstupdate» было пустым и не представляет интереса).
- Выполнив предыдущий шаг, установить DNS-сервер ncdns, а затем выполнить команду nslookup 8u.bit 127.0.0.1 в командной строке (или временно установить 127.0.0.1 в качестве адреса своего DNS-сервера).
В результате мы получили значение, связанное с полученным с визитки доменным именем. Если мы последуем по первому или второму варианту, то перед нами предстанет значение целиком:
▍ Второе задание
Возможно, «кубики» — это блоки, и они намекают нам на блокчейн, как цепочку связанных блоков? А тот, что присоединяется — это новый блок, который становится его частью? И действительно, если мы сравним увеличивающееся число, приходящее с сервера, то заметим, что его увеличение совпадает с выходом нового блока в сети Namecoin (в которой и зарегистрировано доменное имя 8u. bit), а его значение совпадает с текущим номером последнего блока.
Значит таймер отсчитывает время до блока 600581, в итоге вышедшего 24. 2022 22:36:28 по Москве. В него попало 163 транзакции, и конечно можно просмотреть их все в поисках чего-нибудь интересного, но можно просто вспомнить адрес кошелька, на который в данный момент зарегистрировано доменное имя 8u. bit (запись d/8u), и он таков:
Посмотрим на транзакции с участием данного кошелька в указанном блоке, и увидим что такая есть, и её идентификатор 126e36b6031e2c246192e1cd317cf2cc6a173c8994e84881dcb4469adc861958. Совершить её мог только владелец кошелька, зарегистрировавший домен, ведь только у него есть приватный ключ от этого кошелька, а значит и возможность совершать транзакции от его имени. В транзакции мы видим 2 выхода:
- Пересылка 0,95075163 NMC (неймкоинов) на другой кошелёк, ничем не примечательна, вполне стандартная по своему коду транзакция;
- Пересылка 0,00000001 NMC на неизвестный адрес.
Разберём код первой транзакции и попытаемся понять, чем отличается от неё вторая, и почему обозреватель блокчейна Namecoin не смог извлечь из неё адрес назначения. Для этого выполним такую команду в RPC-консоли демона Namecoin:
getrawtransaction 126e36b6031e2c246192e1cd317cf2cc6a173c8994e84881dcb4469adc861958 true f07d480ebb9e787f0cdbb0b2bff1f33cf34962efaee1b96fadc32b39991f9408
Первый параметр — собственно хеш (идентификатор) транзакции, второй — флаг «verbose», для того чтобы сразу получить и результат её декодирования, а третий — хеш блока 600581, в который она включена. В результате получим следующий дизассемблированный код (lock-скрипт) для первого выхода:
OP_DUP OP_HASH160 9b91a85022e1038679fc4f52f8426b08ad13850b OP_EQUALVERIFY OP_CHECKSIG
Поскольку Namecoin основан на кодовой базе Bitcoin, то и большая часть операций в нём такая же и несёт тот же смысл. Так, код этой транзакции вполне совпадает с «обычным» переводом средств типа «pay to public key hash», современным типом скрипта для этой операции. А именно, данный скрипт можно прочитать как «заблокировать средства на данном выходе для того, кто сможет предоставить верную подпись публичным ключом, хеш которого по алгоритму Hash160 равен 9b91a85022e1038679fc4f52f8426b08ad13850b». И действительно, если мы декодируем адрес получателя по алгоритму Base58Check, то получим байты:
9b91a85022e1038679fc4f52f8426b08ad13850b (Hash160 от публичного ECDSA-ключа, совпадает со значением из скрипта первого выхода транзакции)
834a6ff4 (контрольная сумма, основанная на SHA256).
Разобрали первый выход, разберём так же и второй. Вот код его lock-скрипта:
Всего одна операция OP_RETURN, которая обычно используется для «сжигания» криптовалют или для помещения текстовых посланий в блокчейн. Если мы декодируем возвращаемое ей значение, то получим строку «55. 754865,37. 636275». Эти же данные можно получить в другом обозревателе блокчейна Namecoin, который сам умеет вытаскивать такие закодированные данные из транзакций.
Также если был введён почтовый адрес на сайте 8u. bit, то на почту после выхода этого блока приходит письмо от некоего John Doe с темой «Notification from 8u. bit» такого содержания:
—–BEGIN PGP SIGNED MESSAGE—–
Hash: SHA256
This is your friendly reminder from 8u. bit. The game continues. If in doubt, use PGP key 39EB6E8B380C4AB1. There’s no need to reply to this email. —–BEGIN PGP SIGNATURE—–
iQIzBAEBCAAdFiEEw8odG5+U/LvC05GQOetuizgMSrEFAgAAAAAACgkQOetuizgM
SrFQng/+JhscSH89wNGu9W+l6hzzGmkdNK2MxV7ttbqX4ZJGiqvimF8fqdmSQb2L
KkpU+dDwFYqYqRxN3yeEM5y1P36Zam5fuXUzMeq4gTc5U5mpSh2ZVTSyZlLsho2B
2OekKbV7ygTn7Ovg8uVra0saNSx+H3APC9CxIIyMQnxD/fYt5eTtHlY+6U0ZOEbu
stImLKEuK/oogCJQMusHh4eXmKS+ZKGJy49J+mDIr59/+R6HoXxMgf88HJdQVm86
kNgvUhsNb4tCAA+dMHBTgJoNSBRZ3sb7dI5WarDbpoKEWSEfq2UJFferRK+XQVn+
yt1LtfeyUILLgRIpQz67JNmBLZQj5sOISf2v+xWMK8Bx4ahTpN4+tRaTYalzlQSa
fORLbrzH0p5cekfEtiYKbasJDGjljPm75BTLmdu66e/ziIG2YKRvwJZjMRrPDRf3
9L3hxBRz0W2W43ETuaLm8kX5LlvWIL3k0knD61sCX2KK3mxwlTd2qtRfgBZm4FQs
NEqiyyEieNrMcXXjbUPDqzJ2r3XjzQdW86TcKNtCF1dy/QCQQQJRJB1rT430EQWb
ediN9LoBU9cp6lvHaV04wTNglnwPyd7H8PGHiJztHDFTaZOX8WVnbOyZy15Qn5vw
KHNuyOdVnEoulkVyaO84Uf1h+lK4ASlxKVBgRHB8S9R6PvD8MgU=
=ZNP3
—–END PGP SIGNATURE—–
Хм, говорят что это обещанное напоминание от 8u. bit, заверение что «игра продолжается» и подписанный PGP текст с указанием на идентификатор ключа, которым он подписан. Получим этот ключ с любого из публично известных GPG-серверов (или через веб-версию):
gpg –keyserver pgp. mit. edu –recv-keys 39EB6E8B380C4AB1
Сохраним текст письма, например, в файл message. txt, и выполним команду
gpg –verify message. txt
Получим сообщение об ошибке, говорящее о том, что gpg не может проверить подпись, поскольку сам ключ был выпущен позднее, чем сделана подпись (время подписи установлено в 0, а точнее, в начало эпохи UNIX). Может, мы попали во временную петлю? Давайте попробуем проигнорировать время, и всё-таки проверить подпись без оглядки на него, у gpg как раз есть специальная опция для этого:
gpg –ignore-time-conflict –verify message. txt
Получим вывод о том, что подпись действительна, а значит текст сообщения не был изменен (в чём мы можем убедиться, если изменим или удалим хоть ненамного текст — подпись тут же станет невалидной).
Вернёмся к нашей транзакции, а именно к тексту из её второго выхода. Похоже на координаты, не так ли? Посмотрим на них, например, на картах Яндекса:
Координаты указывают нам на перестраиваемое здание по адресу Большой Спасоглинищевский переулок, 9/1с8 в Москве.
Здание небольшое, и если мы придём в него, то сможем увидеть такую вот интересную вывеску на одной из колонн:
Применим все доступные нам технологии улучшения изображений из «CSI: Miami», и получим такой стилизованный QR-код:
После его декодирования (если штатный QR-декодер смартфона вдруг подвёл, можно воспользоваться известным онлайн-сервисом) получим:
URI указывает на использование IPNS (InterPlanetary Name System), одной из технологий в протоколе распределённой файловой системы IPFS, претендующим в будущем даже на «межпланетность». Установим демон IPFS, подождём небольшое время для синхронизации с сетью и выполним команду:
ipfs name resolve k51qzi5uqu5dh4m4kl25w2w8ash9cas87a1yo1ea1rmyoa600ut6sy5y6pwlf4
получим адрес объекта-директории в IPFS:
ipfs ls /ipfs/QmP8cqfFuFPUjLQVjG4u6F8Uqk5MANyPK9pDatny1VmXCm
и получим список файлов в этой директории:
QmTVCWQFNDWfo2vnskNbj3xEG7yB7oeESo5Xs8zRZLhPBE 70862 index. html
QmZL6dXTUXsE28XDRbmiRunsjcupJ4XMVGgKDRm7WbtojN 566 index. html. sig
Наконец, скачаем директорию целиком к себе на компьютер, выполнив команду:
ipfs get QmP8cqfFuFPUjLQVjG4u6F8Uqk5MANyPK9pDatny1VmXCm
Проверим, как и раньше с текстом письма, подпись под файлом index. html:
gpg –verify –ignore-time-conflict index. html. sig
Она действительна, а значит полученный файл тоже относится к загадочному John Doe и мы на правильном пути.
Та же символика, и виднеется куча пространного текста по тематике игр, особенно если нажать Ctrl+A (выделить все). Присмотримся к тексту внимательно, и увидим, что некоторые буквы в верхнем регистре не на своих местах (не в начале предложения или имён собственных). Попробуем их выписать, благо они находятся в начале текста:
Пока непонятно, что делать с полученным текстом, мы пойдём дальше, может этот текст скрывает и что-то еще? Заметим, что в тексте в конце строк и между них есть «лишние» пробелы и табуляции, которые можно увидеть в текстовом редакторе, который поддерживает их отображение в явном виде (например, Notepad++):
Есть один метод текстовой стеганографии, реализованный в программе stegsnow (название расшифровывается как «Steganographic Nature Of Whitespace», и она же первая по запросу «whitespace steganography», а также с учётом подсказки «если долго не смотреть на текст, то может пойти снег»). Запустим ее, на вход подав текст со страницы:
snow text. txt
Получим скрытый текст «ipfs://QmTvLhJfoXCuUExW7Wx8b6ZTjasxfqkUMNhWCo8xttTwDj». Ага, снова IPFS.
Посмотрим, что имеется в IPFS по полученной ссылке: файл «stage2. 7z», снова с отделённой подписью. Проверяем подпись, применяем полученную на предыдущем этапе первую строку в качестве пароля и распаковываем архив:
steghide extract -sf 55916. jpg -xf 55916. txt
Получаем скрытый в указанной картинке текст:
Ага, кажется можно сразу получить аналогичный архив для следующего этапа (не забыв снова проверить его подпись). Но где же пароль от архива? Вероятно, в одной из PNG-картинок. Попробовав различные варианты, можно вспомнить о том, что ширина и высота изображения берутся программами-просмотрщиками из данных самого файла. В PNG, как и в большинстве графических форматов, данные записываются построчно, а значит в картинках могут быть «дополнительные» строки. Служебные данные файла, как известно, можно и подменить: так, если исправить в файле 75956. png высоту с 256 пикселей на 257 (или более) пикселей, исправив значение в чанке IHDR (заголовок, служебные данные):
и исправить контрольную сумму CRC на 184cec94 (этого можно и не делать, многие просмотрщики картинок покажут полученные пиксели и с неправильной контрольной суммой), то можно увидеть скрытые 11 пикселей:
Их цвета в RGB, по порядку: 70384D 47474B 515A36 4B5537 45674C 746943 6E5837 6A3337 55634A 445151 4D7100 (можно продолжить и дальше, но там чёрный цвет, т. 000000). После декодирования из шестнадцатеричного представления в ASCII получим пароль для следующего архива:
Пароль же ожидает нас в спектрограмме файла 24516. mp3, на высоких, почти не слышимых ухом частотах на 20 секунде:
После графической обработки (обрезки, приведения к чёрно-белому изображению, и небольшого размазывания) можно получить закодированное в QR-коде значение «GqyFS2trfgTleAis91TaU36hXsOq0xuz» (один из онлайн-сервисов декодирования успешно декодирует даже зашумлённые коды).