Password wallet recovery wasabi
(03-29-2020, 02:29 PM)Mem5 Wrote: We don't crack hashes here. Same for atom.
Your wallet may uses Scrypt, which is slow as hell.
Note that if you give your 12 words + password, one can get the master private key, and steal your funds.

If you have the seed words you can simply restore your wallet by creating a new one with the same seed.
(03-29-2020, 03:29 PM)undeath Wrote: If you have the seed words you can simply restore your wallet by creating a new one with the same seed.

Hello there undeath,

When I'm generating a new one with the wasabi wallet.
They ask me to create a new password than they give me a new 12 WORD Seed also.

How can I restore it by creating a new one if they don't ask me for the SEED from the early stucked wallet 

You understand me bro ?
(03-29-2020, 03:50 PM)undeath Wrote:

The wallet is basically a master private key (the result of combining two things: 12 words + your password). This means that you can see the wallet balance and the transaction history but you cannot spend because you don't have one of the components of the private key (the password).

The password is encrypted in such a way that is extremely hard to brute force, I would say that it is unfeasible to do with current technology. The idea is precisely to protect users' wallets against brute force attacks.

I did recover wallet with the good old 12 word seed and a new password + new wallet name > Wallet was created with 0,0 BTC..

Undeath, I can give you the wallet .json file with the 12 WORD SEED. If you succeed, Take 100 EURO from it Tongue

Wasabi uses the BIP 39 mnemonic code for generating BIP 32 hierarchical deterministic wallets. With both your password and the generated 12 mnemonic recovery words you can import all the necessary secrets to Wasabi and do a full wallet recovery. You can set a wallet name so that you know for what reason the wallet is used. When you type in your 12 recovery words, Wasabi checks the spelling based on the official wordlist and offers the right word below the textbox. Now you can click on 
, and Wasabi will recover your wallet, and scan the blockchain for transactions of this wallet. After a short loading period, you can use Wasabi as usual.


At recovery, Wasabi is unable to check if your password is correct or not. If you type a wrong password a completely different wallet will be recovered.
I had a quick glance at that tool from github (nopara73 etc) and did develop a quick perl POC:
#!/usr/bin/env perl

# Author: philsmd
# Date: April 2020
# License: public domain, credits go to philsmd and hashcat

# credits also go to:

use strict;
use warnings;

use Digest::SHA qw (sha256);

use Bitcoin::Crypto::Base58 qw (decode_base58check);
use Bitcoin::Crypto::Key::Private;

use Crypt::ECB;
use Crypt::ScryptKDF qw (scrypt_raw);

# Constants:

my $SCRYPT_N   = 16384;
my $SCRYPT_R   =     8;
my $SCRYPT_P   =     8;
my $SCRYPT_LEN =    64;

# Examples:

# Example 1:

# my $secret_string = "6PYSeErf23ArQL7xXUWPKa3VBin6cuDaieSdABvVyTA51dS4Mxrtg1CpGN";
# my $pass = "";

# Example 2:

my $secret_string = "6PYSJ71rbacdSS2htBcpSccutEEEJqGHq3152FuT357ha6iat6BkENGwUB";
my $pass = "pato";

# Example 3:

# my $secret_string = "6PYL1uxQPXwNV6BMruXaSbAcpBEDPuA8biUfvy3g1vc8V54t5rn4f6Z1na";
# my $pass = "MariaN3ll4&";

# Start:

my $data = decode_base58check ($secret_string);

if (substr ($data, 0, 2) ne "\x01\x42") # Base58Type.ENCRYPTED_SECRET_KEY_NO_EC
  print STDERR "not a valid secret string\n";

  exit (1);

my $type = substr ($data, 2, 1);

# (x & 0x20) div 2^5 == (x & 0x20) / 32 == (x >> 5) & 1 (extract the 6th rightmost bit)

my $is_compressed = ((ord ($type)) & 0x20) >> 5;

my $salt      = substr ($data, 3,  4);
my $encrypted = substr ($data, 7, 32); # to the very end: substr ($data, 7)

# Hashing (most demanding task of the whole algorithm):

my $hash_buf = scrypt_raw ($pass, $salt, $SCRYPT_N, $SCRYPT_R, $SCRYPT_P, $SCRYPT_LEN);

# AES256 decrypt:

my $derived_half1 = substr ($hash_buf,  0, 32);
my $derived_half2 = substr ($hash_buf, 32, 32);

my $aes = Crypt::ECB->new ({
  key         => $derived_half2,
  cipher      => "Crypt::Rijndael",
  # iv        => "\x00" x 16,
  literal_key => 1,
  header      => "none",
  padding     => "null",

my $out = $aes->decrypt ($encrypted);

my $h = "";

for (my $i = 0; $i < 32; $i++)
  my $x = substr ($out,           $i, 1);
  my $y = substr ($derived_half1, $i, 1);

  $h .= chr (ord ($x) ^ ord ($y));

# Adress conversion (bitcoin ECC):

# priv key to pub key to legacy address:

my $priv = Bitcoin::Crypto::Key::Private->from_bytes ($h);

my $pub = $priv->get_public_key ();

$pub->set_compressed ($is_compressed);

my $address = $pub->get_legacy_address ();

# Double SHA256 the address and verify checksum:

my $hash = sha256 (sha256 ($address));

if (substr ($hash, 0, 4) eq $salt)
  print "Password found: '$pass'\n";

  exit (0);

print "FAILED\n";

exit (1);

license: public domain with credits go to philsmd, hashcat and the authors of the referenced tools.

As expected, the code is quite demanding... giving this secret_string from wallet.json, you need to hash the password and salt with scrypt (N = 16384, r = 8, p = 8, i.e. quite high params for a GPU attack, maybe faster on CPU depending on your hardware). After that the secret string (data) is decrypted with AES256 with the key from scrypt (last 32 bytes) and mixed/xored with the remaining 32 bytes from scrypt (first 32 bytes).

The result is the Bitcoin private key for which we need to get the (compressed or uncompressed) public key and generate the legacy address from the pub key. The first 4 bytes of the double sha256 hash of the address is compared against the salt (that means that the salt, 4 bytes, used for scrypt are directly related to the bitcoin address).

I think it would be quite a difficult task to get this algo working with hashcat (ECC pub key, addresses needed, base58 conversions and high scrypt parameters) and it might not be very performant with GPUs (probably for the time being faster on some modern CPUs). That said, the tools written in C# might of course not be the fastest ones and there is of course room to improve the speed of password recovery (with a minimal ANSI C scrypt/parallelized or even implementing it in a hashcat module <- quite difficult). Of course, I don't want to blame anybody here... that C# code was of course also only meant to show how one could verify the correctness of a password (POC).

I hope you appreciate the research, was quite a lot to understand and debug until the C# code made sense to me and could be "converted" to a standalone perl proof of concept. Thanks
I like it Smile