Pull to refresh

Подбор пароля на свой кошелек Bitcoin


В начале 2012 года я впервые услышал о крипто валюте Bitcon. Сразу было решено — майнингу быть. Зарегистрировался на mining.bitcoin.cz и начал майнить. Везде где читал про Bitcoin авторы настойчиво рекомендовали шифровать кошелек. Хакеры, спецслужбы, вирусы и т.д. все норовят стянуть ваш wallet.dat. Вот и я поддался и решил зашифровать свой. Процесс шифрования происходил поздно вечером, спустя пару дней после начала майнинга и в состоянии небольшого алкогольного опьянения. Итак прошло 3 месяца до того момента когда я решил первый раз воспользоваться намайненым и каково же было мое удивления когда ни один из паролей которыми я пользовался не подошел. Срочно был создан новый wallet.dat без пароля а этот отложен до лучших времен. Я надеялся что с течением распространения Bitcoin найдутся «добрые» люди который напишут взломщик кошелька и я восстановлю свой пароль. Но время шло и такого решения все не было хотя в Интернете было множество постов на форумах с призывами о помощи восстановления забытых паролей, когда человек знал свой пароль но мог ошибиться в нескольких символах в нескольких местах.

Было принято решение писать подборщик паролей самому. В одном из сообщений на форуме bitcointalk.org/index.php?topic=85495.0;all я наткнулся на ruby скрипт который перебирает пароли для открытия кошелька. Разобравшись в коде выяснилось что алгоритм очень прост.

Далее я буду описывать что и как делал я, но поняв суть процесса написать свой подборщик паролей сможет любой программист.
Итак у меня есть старый wallet.dat за март 2012, есть клиент того времени bitcoin-0.5.2-win32-setup.exe. Для простоты было решено поставить Windows XP на виртуальную машину и все эксперименты проводить в ней. После установки Windows и клиента Bitcoin в ней был выключен сетевой адаптер виртуальной машины и первый раз запущен c:\Program Files\Bitcoin\bitcoin-qt.exe. Зачем выключать сетевой адаптер? При старте клиента кошелька он лезет в Интернет и скачивает всю цепочку транзакций, а это на текущий момент 14Gb — процесс долгий и не нужный в данном случае. В c:\Documents and Settings\Администратор\Application Data\Bitcoin\ появился новый wallet.dat. Далее закрываем bitcoin-qt.exe. Заменяем только что созданный wallet.dat на свой старый с забытым паролем. Теперь нужно положить в c:\Documents and Settings\Администратор\Application Data\Bitcoin\ рядом с wallet.dat файл bitcoin.conf со следующим содержимым:

rcpuse=zeta
rpcpassword=somerandomcrap
daemon=1


Далее идем в c:\Program Files\Bitcoin\daemon\ там находится файл bitcoind.exe. Он то нам и нужен. Замечу что клиент bitcoin-qt.exe должен быть выключен. Итак создаем bat файл со следующим содержимым:

bitcoind.exe -daemon

Запускаем его. Клиент запустился в режиме демона причем консольное окно не должно исчезнуть а как бы зависнуть. Сворачиваем его.
Теперь немного теории. Процесс подбора состоит в запуске еще одного экземпляра bitcoind.exe с параметрами командной строки:

bitcoind.exe walletpassphrase some_pass 20

где some_pass это новый пароль который пытается открыть кошелек. Процесс возвращает код в зависимости от результата. 0 если пароль подошел, во всех остальных случаях число будет отлично от 0. Например если bitcoind.exe сейчас не работает как демон будет выдано сообщение в консоль:

error: couldn't connect to server

если bitcoind.exe работает как демон то мы увидим:

error: {"code":-14,"message":"Error: The wallet passphrase entered was incorrect."}

Зная это, дело остается за малым — написать программу генерирующую новые пароли, запускающую bitcoind.exe с параметром walletpassphrase далее через пробел новый пароль потом пробел и число 20. Смотрим вернувший код и либо генерируем новый пароль либо сообщаем что пароль найден.

Свою реализацию я писал на с++. Вот часть кода запуска:

STARTUPINFOW si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );

std::string sFull= " walletpassphrase "+sPass+" 20";

if(!CreateProcess("bitcoind.exe", sFull.c_str(), NULL, NULL,FALSE, 0,NULL,NULL,&si,&pi))
WaitForSingleObject(pi.hProcess, INFINITE);

DWORD exitCode=0;

// Get the exit code.
GetExitCodeProcess(pi.hProcess, &exitCode);

if (exitCode==0)
resTry=pswSuccess;
else
{
if (exitCode==87)
resTry=pswTryAgain;
}


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

intel i7 2600K - 1900 паролей в минуту
intel i5 2500K - 920 паролей в минуту
amd a8-3870@3.4Gh - 900 паролей в минуту
intel q9650 - 520 паролей в минуту


Надеюсь мой опыт поможет кому то еще восстановить свой пароль. Удачи.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.