Хомяки, быки и питон

Привет, криптаны!
Началось всё с того, что мне на глаза попался вот этот мультик. Как ни странно, я сейчас не могу вспомнить, как он мне попался, но скорее всего, просто кто-то скинул в одном из tg-каналов. Также было сказано, что в мультик зашита загадка, приз за которую - 1 btc. Кто же откажется от халявного битка? Вот и я не отказался :)
Посмотрев мультик, почитав описание и комментарии, стало понятно, что суть загадки в том, чтобы собрать приватный ключ от bitcoin-кошелька, используя подсказки, которые есть в самом мультике. И я уже при первом просмотре мультика обратил внимание на то, что кое-где в видео раскиданы QR-коды, ссылки и названия различных компаний. Видимо, это ж-ж-ж не спроста...
Первый же QR-код, который мне попался на глаза был в самом начале видео и привёл меня на сайт https://cyclebit.io/ И что мы видим? После недолгого скроллинга, в глаза прямо-таки бросается странная качающаяся бирка :)
Да! Те, кто немного знакомы с форматами bitcoin-ключей, без проблем узнают в символах "5JRd42nU1" начало bitcoin-ключа в формате WIP!
Конечно, строго говоря, это могла быть не обязательно первая часть, однако, мне это показалось логичным, поскольку это была самая первая подсказка в видео и по формату очень похоже на начало ключа. Кроме того, позже, на одной из трансляций PRO BLOCKCHAIN, ребята явно дали подсказку, что именно это первая часть ключа.
Что же, смотрим мультфильм дальше и видим второй QR-код, который ведёт нас на знакомый youtube-канал. Думаю понятно, что вряд ли ребята могли спрятать что-то в коде самого сайта, так что варианты были либо искать что-то в загруженных видосах, либо в информации, которая доступна для редактирования автору канала. Первый вариант показался мне слишком сложным, а вот второй...
Бинго! Еще одна часть ключа! На этот момент я еще не думал о порядке, но опять же предполагал, что скорее всего части нужно составлять по порядку их появления в мультфильме.
Дальнейший просмотр мультфильма привёл меня на сайт очередного партнёра https://storiqa.com/ Однако, тут меня ждало разочарование, потому что ничего подходящего мне найти не удавалось, несмотря на изучение каждого кусочка текста. "Окей - подумал я, - может быть это просто рекламная ссылка, а не подсказка?" и решил отложить эту отсылку на потом.
Следующая подсказка, которая есть в мультике выглядела просто как надпись на двери: "HammWallet". Во-первых, она не вязалась с происходящим в мультике, во-вторых, странным образом совпадала с названием кошелька, который указан в партнерах видео. Я решил, что с этим нужно разобраться повнимательнее, но как я ни старался, ни на странице приложения, ни в самом приложении, мне так и не удалось найти ничего похожего на ключ. У меня было подозрение (как позже оказалось - правильное), что нужно сделать какие-то манипуляции с криптой, раз уж это приложение кошелька, но проверять предположение уже не было времени, да и морочиться с переводами не хотелось.
На этот момент, я был уверен, что часть ключа есть в приложении, потому что ребята на одной из трансляций явно пообещали рассказать, как достать ключ из HammWallet. Но, так этого и не сделали, кстати :) Зато стало понятно, что ключ там точно есть.
Окей, что же делать, если не можешь заставить глупое приложение отдать то, что тебе нужно? Хех, конечно же залезть внутрь и взять это самостоятельно. Поскольку приложение - это apk-файл (а по сути, zip-архив), достать внутренности оттуда не составляет труда. Но вот дальше меня ждало разочарование, поскольку ни среди декомпилированного кода, ни среди ассетов я не нашёл ничего нужного. Однако, тут мой взгляд среди исходников упал на библиотеку, с названием "libHammWallet.so". Так-так. Вот тут уже интереснее. Библиотека, конечно, оказалась бинарником в ELF-формате и выудить из неё осмысленные данные довольно проблематично. Но если предположить, что авторы хранят нужную мне часть кода обычной строкой без шифрования (а я не думал, что они настолько запаривались), то есть шанс, найти её и обычным текстовым редактором. Открываем библиотеку, находим кусок, где лежат текстовые данные, и...
Аххаха, да! Не зря в школе ходил на информатику!
Ну и последняя подсказка из мультика - это ссылка на сайт https://pro-blockchain.com/, где после непродолжительных поисков обнаружилась еще одна часть ключа:
Итого, на текущий момент у меня имеется 4 части ключа. И глядя на эти части и представляя как выглядит ключ в WIF-формате, уже можно предположить, что нам не хватает еще двух кусочков по 8-9 символов. Также я был уверен, что один из них находится на сайте https://storiqa.com/ (об этом тоже была явная подсказка от ребят), но я не могу его найти.
Поиск и сбор частей приватного ключа биткоин-кошелька
Обдумав, что же делать дальше, я решил, что пришло время воспользоваться коллективным разумом и заглянуть в чат, где ребята уже некоторое время, как и я, пытаются победить загадку. Пролистав историю, стало понятно, что общими усилиями нашлось 4 части ключа, причём одной из них у меня не было! Это была как раз та самая часть, спрятанная на одной из страниц сайта storiqa:
Ну что же, на текущий момент у меня 11 часов вечера, пять кусков ключа из шести и абсолютное отсутствие идей, где искать последний. Опять же, я предположил, что вряд ли умнее коллективного разума комьюнити и если бы у кого-то были идеи где искать последнюю часть, скорее всего её бы кто-нибудь уже озвучил или как минимум предложил направление для поисков. Однако, никаких намёков на это не было. Да и честно говоря, я почти сразу заподозрил, что какой-то части ключа еще нет в общем доступе, иначе игра была бы слишком простой (и то, что исходный ролик на английском вышел еще 9 мая и до сих пор не разгадан, наводило на те же мысли).
Тут я решил посмотреть, что же в итоге у меня есть. На руках имеются все части из подсказок в мультике, причём мы знаем, что первая часть ключа, находилась под первой подсказкой. Попробуем расположить наш ключ в порядке появления подсказок в мультике, почему бы и нет?
5JRd42nU1 gL5wuDRg VRRTCdHR AhiF1tpuG fy2nm3YtN ????????
Кажется, осталось не так много, если быть уверенным в расстановке частей. Однако, без знания последних символов, подбор ключа может затянуться на пару лет. Или?...
Тут у меня в голове всплыла информация, которую я прочитал, изучая утром форматы ключей. WIF-ключ - это не "настоящий", секретный ключ от кошелька, а преобразованный по специальному алгоритму секретный ключ, с некоторыми дополнениями. Кому интересно, советую ознакомится вот с этой страницей, там очень подробно описан алгоритм конвертации секретного ключа в WIF и обратно. И если изучить его внимательно, то можно увидеть, что изменение последних 8 символов в WIF-ключе влияет на изменение только 2 последних байт секретного ключа! (на самом деле, трёх байт, но в большинстве случаев, третий байт не меняется и я сделал еще одно предположение, для упрощения). То есть получается, что уже сейчас я могу получить секретный ключ кошелька, в котором будет не хватать всего двух байт в конце, а это всего лишь 256*256 вариантов!!
Трясущимися руками открываю PyCharm и накидываю код, для получения уже настоящего секретного ключа:
80 50 3B EB D4 76 8D AB 14 BB 32 4F 0F B9 24 B6 95 99 0C 88 4E F9 0C 0D 1F E2 C3 8C 85 A3 4F XX XX ZZ ZZ ZZ ZZ
Последние 4 байта фактически не нужны, это контрольная сумма, которая высчитывается по первой части ключа. То есть получается, если все мои предположения верны, нужно подобрать лишь два байта XX XX, чтобы получить готовый ключ. Вперёд! Сгенерировать 65 тысяч вариантов (256*256), было не сложно, сложнее было найти рабочую библиотеку, которая позволяет по секретному ключу создать адрес кошелька. Ведь нам нужно, чтобы ключ подходил именно к одному конкретному кошельку. Довольно много времени ушло именно на проверку того, что всё работает правильно, потому что я раньше никогда не писал код для работы с ключами. И для начала проверял всё на известной паре ключа и кошелька. И вот, скрипт готов.
Ответственный момент. Исходные данные заряжены, у меня тем временем 5 утра. Запускаю и спустя час... Ничего :(
Ну что же, думаю. Наверное, либо я где-то просчитался, либо у частей ключа порядок другой, либо вообще какая-то из них неверная (такие предположения тоже были в комьюнити). Грустно тушу компьютер и отправляюсь спать. Сплю плохо :)
С утра конечно же решаю всё перепроверить и понимаю, что вчера в спешке поставил две части ключа, не в том порядке, в котором они появлялись в видео! Меняю части местами, запускаю проверку и через 20 минут вижу вот такой вывод моей программы:
- 0 keys checked...
- 1024 keys checked...
- 2048 keys checked...
- 3072 keys checked...
- 4096 keys checked...
- 5120 keys checked...
- 6144 keys checked...
- 7168 keys checked...
- 8192 keys checked...
- 9216 keys checked...
- 10240 keys checked...
- 11264 keys checked...
- 12288 keys checked...
- 13312 keys checked...
- 14336 keys checked...
- 15360 keys checked...
- 16384 keys checked...
- 17408 keys checked...
- 18432 keys checked...
- 19456 keys checked...
- 20480 keys checked...
- 21156 GOTCHA! 1HammaXcmybjPK4yLJxWkCrYQHd3fyLcU7 == 1HammaXcmybjPK4yLJxWkCrYQHd3fyLcU7
- WIP key: 5JRd42nU1gL5wuDRgVRRTCdHRAhiF1tpuGfy2nm3YtNYMNWuouv
Даааа! Попался родимый!
Трясущимися руками копирую ключ в кошелёк и вижу баланс в 1 btc. Не менее трясущимися руками, делаю перевод и стараюсь выдохнуть. Получается плохо.
Эпилог
В tg-чате, мою транзакцию заметили практически мгновенно, не прошло и полминуты, наверное.
Ну и как оказалось, я действительно немного сломал организаторам всю схему, потому что шестую часть ключа планировалось выложить только после того, как мультфильм наберёт миллион просмотров (об этом тоже была подсказка в самом мультике, но, честно говоря, не обратил на неё внимания), однако, к чести ребят из PRO BLOCKCHAIN, никаких претензий по этому поводу не было, наоборот только поздравляли с решением, хоть и немного читерским способом.
На всё про всё у меня ушло около суток, но это было действительно круто, давно не ощущал такого фана! Ну и то, что мои умения позволили мне забрать приз, тоже греет моё сердечко, конечно :)
Спасибо ребятам из PRO BLOCKCHAIN за крутое приключение и не менее крутой приз!
Спасибо комьюнити за помощь, общение и коллективный разум!





