Home Crack Bitcoin wallet.dat passwords using John

Crack Bitcoin wallet.dat passwords using John

Fuzzing Script


This article is inspired by my other article on cracking /etc/shadow hashes with John the Ripper. I’ve seen some people asking about a hot topic these days, bitcoin wallet recovery. You’ve heard the story, someone has xyz number of BTC in their wallet and blah you lost the private key! Here I will show you how to recover that.

You will need John from the Jumbo branch on GitHub. The old school John does not support bitcoin as a format.

I’m using a Linux (Ubuntu) computer, preferably use one with as many cores as you can find or reasonably afford to rent.

You can grab a wordlist for this exercise here.

The help page for john:

John the Ripper 1.9.0-jumbo-1+bleeding-73e006c67 2019-12-20 15:41:04 -0300 OMP [linux-gnu 64-bit x86_64 AVX2 AC]
Copyright (c) 1996-2019 by Solar Designer and others
Homepage: https://www.openwall.com/john/

--single[=SECTION[,..]]    "single crack" mode, using default or named rules
--single=:rule[,..]        same, using "immediate" rule(s)
--wordlist[=FILE] --stdin  wordlist mode, read words from FILE or stdin
--pipe   like --stdin, but bulk reads, and allows rules
--loopback[=FILE]          like --wordlist, but extract words from a .pot file
--dupe-suppression         suppress all dupes in wordlist (and force preload)
--prince[=FILE]            PRINCE mode, read words from FILE
--encoding=NAME            input encoding (eg. UTF-8, ISO-8859-1). See also
doc/ENCODINGS and --list=hidden-options.
--rules[=SECTION[,..]]     enable word mangling rules (for wordlist or PRINCE
modes), using default or named rules
--rules=:rule[;..]]        same, using "immediate" rule(s)
--rules-stack=SECTION[,..] stacked rules, applied after regular rules or to
modes that otherwise don't support rules
--rules-stack=:rule[;..]   same, using "immediate" rule(s)
--incremental[=MODE]       "incremental" mode [using section MODE]
--mask[=MASK]              mask mode using MASK (or default from john.conf)
--markov[=OPTIONS]         "Markov" mode (see doc/MARKOV)
--external=MODE            external mode or word filter
--subsets[=CHARSET]        "subsets" mode (see doc/SUBSETS)
--stdout[=LENGTH]          just output candidate passwords [cut at LENGTH]
--restore[=NAME]           restore an interrupted session [called NAME]
--session=NAME             give a new session the NAME
--status[=NAME]            print status of a session [called NAME]
--make-charset=FILE        make a charset file. It will be overwritten
--show[=left]              show cracked passwords [if =left, then uncracked]
--test[=TIME]              run tests and benchmarks for TIME seconds each
(if TIME is explicitly 0, test w/o benchmark)
--users=[-]LOGIN|UID[,..]  [do not] load this (these) user(s) only
--groups=[-]GID[,..]       load users [not] of this (these) group(s) only
--shells=[-]SHELL[,..]     load users with[out] this (these) shell(s) only
--salts=[-]COUNT[:MAX]     load salts with[out] COUNT [to MAX] hashes
--costs=[-]C[:M][,...]     load salts with[out] cost value Cn [to Mn]. For
tunable cost parameters, see doc/OPTIONS
--save-memory=LEVEL        enable memory saving, at LEVEL 1..3
--node=MIN[-MAX]/TOTAL     this node's number range out of TOTAL count
--fork=N                   fork N processes
--pot=NAME                 pot file to use
--list=WHAT                list capabilities, see --list=help or doc/OPTIONS
--devices=N[,..]           set OpenCL device(s) (see --list=opencl-devices)
--format=NAME              force hash of type NAME. The supported formats can
be seen with --list=formats and --list=subformats

Note: that all the “=” signs are important and must be used for correct syntax.


Just to get an idea. First though, we have to conver it into the correct format.

λ ~/ Tools/JohnTheRipper/run/bitcoin2john.py enc-wallet.dat | tee bitcoin.hash

The Crack

We’ll then take the string that is interpreted out of bitcoin2john.py, and load it into john…

λ ~/ /var/storage/Hack/Tools/JohnTheRipper/run/john --wordlist=/var/storage/Wordlists/darkweb2017-top10000.txt --format=bitcoin bitcoin.hash
Using default input encoding: UTF-8
Loaded 1 password hash (Bitcoin, Bitcoin Core [SHA512 AES 256/256 AVX2 4x])
Cost 1 (iteration count) is 141611 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
password1        (?)
1g 0:00:00:00 DONE (2023-01-06 17:23) 4.761g/s 76.19p/s 76.19c/s 76.19C/s 123456..1234
Use the "--show" option to display all of the cracked passwords reliably
Session completed


So we’ve found our encryption password for the wallet and can now access the funds!

Depending on the size of your wordlist and complexity of the password, this can take a very long time. Also Please only use this method on your own wallet.dat files! I hope you are able to now recover your wallet.dat password.

If you felt so inclined, you could couple this article with my other on stealing wallet.dat files over Tor to really get your hands dirty…

If you enjoy my work, sponsor or hire me! I work hard keeping oxasploits running!
Bitcoin Address:

Thank you so much and happy hacking!
This post is licensed under CC BY 4.0 by the author.