Posts: 3
Threads: 1
Joined: Jan 2023
I have a Coinbase seed phrase backup which is purportedly encrypted with AES-256-GCM encryption. The 12 word seed phrase looks like this test backup: 1WKkQX7s_T3E3zDvijWhOBarbzzXfDSY+fL7rsYgYEA= I would like to use Hashcat to attempt to crack the password that will unlock the seed phrase, but it seems like there is a lot going on here. I am assuming that the whole 12 words isn't being encrypted because I think it would not be possible to store this in 44 characters. Perhaps the first few letters of each BIP39 word is encrypted. Does anyone have experience with this or know how I might get started?
Here is how Coinbase explains thier google drive backup: "As an added safeguard, we built an encrypted Google Drive and iCloud feature so you can back up your recovery phrase."
When I tested it, I was able to restore the seed phrase using only the text "1WKkQX7s_T3E3zDvijWhOBarbzzXfDSY+fL7rsYgYEA=" and the password.
Posts: 889
Threads: 15
Joined: Sep 2017
first, without "really" knowing how coinbase stores or computes the seedphrase, it is impossible to attack this encryypted string
you assume storing the frst letters, why so complicated? lets assume the follwing, bip 39 is standardized 2048 words in a sorted manner, so all you need to store is the position of the words in that dictionary, for storing max 2048 in hex you need 3 chars., 12 * 3 = only 36 chars needed with plain position in dict to hex
but the next way for storing could be a vector like approach, instead of storing the exact postion per word, the ongoing position is computed by index predecessor + value X = index word+1 and so on, so you dont store the index itself but just the positional difference
there are more ways but anyway, i dont think you can attack this unless you know how coinbase computes the input for the encryption (known plaintext attack)
Posts: 3
Threads: 1
Joined: Jan 2023
Thank you for your response. The encryption type is known and published. We have the encrypted string and password, I suppose the padding (which certainly does not change) is the 'unknown' needed to get to a starting point. If it can be decrypted then we can figure out what parts of the BIP39 wordlist are being stored. There is a lot of $ to be made here.
Posts: 889
Threads: 15
Joined: Sep 2017
known encryption type doesnt help if you dont know how coinbase generates the input for the encryption or compute the output of the decryption, there are so many more blackboxes like secret? iterations?
but to crack a password you need full knowledge of the processing pipline from input to output
you have unknown input > next unknown processing pipeline (password could be part of the input message like a salt, as well as part of the processing line, or the password itself generates the secret for the message for encrypting/decrypting, if so next blackbox how is the secret generated?
in terms of an equation
output = known_encryption( f1(unknown_data) + f2(unknown_secret) + f3(unknown_iterations) + .. + f4(known_password + ... + f*)
there are so many unknown parts
i mean when it would be so simple, why you dont decrypt your given test output with your known password and take a look at the output? (without using the app aka balckbox)
Posts: 3
Threads: 1
Joined: Jan 2023
(01-19-2023, 08:27 PM)Snoopy Wrote: known encryption type doesnt help if you dont know how coinbase generates the input for the encryption or compute the output of the decryption, there are so many more blackboxes like secret? iterations?
but to crack a password you need full knowledge of the processing pipline from input to output
you have unknown input > next unknown processing pipeline (password could be part of the input message like a salt, as well as part of the processing line, or the password itself generates the secret for the message for encrypting/decrypting, if so next blackbox how is the secret generated?
in terms of an equation
output = known_encryption( f1(unknown_data) + f2(unknown_secret) + f3(unknown_iterations) + .. + f4(known_password + ... + f*)
there are so many unknown parts
i mean when it would be so simple, why you dont decrypt your given test output with your known password and take a look at the output? (without using the app aka balckbox)
I agree, and there may be an initialization vector component as well. I was hoping that someone may have figured out a way to reverse engineer the process. To solve the problem, I would need to know all of the above and then I still have the problem of cracking the password.
Posts: 1
Threads: 0
Joined: Oct 2024
(01-18-2023, 11:08 PM)ob1 Wrote: I have a Coinbase seed phrase backup which is purportedly encrypted with AES-256-GCM encryption. The 12 word seed phrase looks like this test backup: 1WKkQX7s_T3E3zDvijWhOBarbzzXfDSY+fL7rsYgYEA= I would like to use Hashcat to attempt to crack the password that will unlock the seed phrase, but it seems like there is a lot going on here. I am assuming that the whole 12 words isn't being encrypted because I think it would not be possible to store this in 44 characters. Perhaps the first few letters of each BIP39 word is encrypted. Does anyone have experience with this or know how I might get started?
Here is how Coinbase explains thier google drive backup: "As an added safeguard, we built an encrypted Google Drive and iCloud feature so you can back up your recovery phrase."
When I tested it, I was able to restore the seed phrase using only the text "1WKkQX7s_T3E3zDvijWhOBarbzzXfDSY+fL7rsYgYEA=" and the password.
Code: def convert_to_hashcat_format(encrypted_data):
# Parse the JSON string
data = json.loads(encrypted_data)
# Extract the necessary fields
iterations = 300000 #?
salt = base64.b64encode(bytes(data["salt"])).decode()
iv = base64.b64encode(bytes(data["passwordIv"])).decode()
mnemonic = data["SOME_KEY"] #!
# Construct the hashcat format string
hashcat_format = f'$SOME_MODULE${iterations}${salt}${iv}${mnemonic}' #!
return hashcat_format
# Example usage
encrypted_data = '{"ultiAccountEncryptedMnemonic":"/MQ5BKTJw9Ghy47Dod2bh0OngvAESvnj+QAepD7UgXQKJWaz3TNiXJAFnHNzCvxMRioQUqEmWCe8aQ=","salt":[33,23,217,22,81,26,111,247,252,38,239,158,93,94,19,61,135,195,124,22,175,26,161,72,235,240,25,10,99,149,9,51],"passwordIv":[44,32,60,200,4,2,136,42,11,206,22,72]}'
hashcat_format = convert_to_hashcat_format(encrypted_data)
print(hashcat_format)
|