howto: convert btcrecover bc: hashes to hashcat hash format
#1
Recently an user contacted me via forum PM on how to convert a "bc:" hash extracted by btcrecover from a bitcoin wallet (wallet.dat) to the format that hashcat supports:
Code:
-m 11300 = Bitcoin/Litecoin wallet.dat

(see https://github.com/3rdIteration/btcrecov...re-mkey.py)

the answer of course is that you need to understand each field and the format that btcrecover uses (it's some binary data concatenated together and base64 encoded).
The "bc:" at the start of the decoded string indicates that it's a hash of the bitcoin core wallet.

So the answer is to study and try to understand the extract script of btcrecover and construct a hashcat-compatibe script out of it.

You can use this conversion script to automatically convert them (it's a very simple script, not guaranteed to work in 100% of the cases, but it definitely worked for the user):
Code:
#!/usr/bin/env perl # Author: philsmd # Date: August 2020 # License: public domain, credits go to philsmd and hashcat use strict; use warnings; use MIME::Base64 qw (decode_base64); # Example: # YmM6CcwT/6fzCWA95uNbWemYLaaJDCQbQ59hvgNpUlQLXu3DUa02UDvnzdsUAgC3gZPC:abc if (scalar (@ARGV) != 1) { print "USAGE: $0 <base64 string>\n"; exit (1); } my $base64_string = $ARGV[0]; if (length ($base64_string) != 68) { print "ERROR: The base64 string (hash, salt, iterations) was not specified correctly as the second command line argument\n"; exit (1); } my $bin_string = decode_base64 ($base64_string); if (length ($bin_string) != 3 + 32 + 8 + 4 + 4) { print "ERROR: the base64 decoded string does NOT have a valid length\n"; exit (1); } if (substr ($bin_string, 0, 3) ne "bc:") { print "ERROR: signature of the decoded base64 string did not match 'bc:'\n"; exit (1); } my $mkey = substr ($bin_string, 3, 32); my $salt = substr ($bin_string, 35, 8); my $iter = substr ($bin_string, 43, 4); my $crc32 = substr ($bin_string, 47, 4); $iter = unpack ("L<", $iter); print sprintf ("\$bitcoin\$%i\$%s\$%i\$%s\$%i\$%i\$%s\$%i\$%s\n", length ($mkey) * 2, unpack ("H*", $mkey), length ($salt) * 2, unpack ("H*", $salt), $iter, # fake data at the end: 2, unpack ("H*", "\x00"), 2, unpack ("H*", "\x00"), ); exit (0);

The problem seemed to be that the user didn't have access to the original wallet.dat file (for instance a wallet recovery service etc could be in that situation, just an example, but again: it's still dangerous to share those hashes with untrusted parties).

So just to be very clear: if you have access to the wallet.dat file you shouldn't use this method but use bitcoin2john.py instead
Reply