Skip to content

Commit

Permalink
Fix compatibility with Metamask v11 wallets
Browse files Browse the repository at this point in the history
*Fix compatibility in btcrecover
*Update extract script
*Add CI tests & Wallet sample
  • Loading branch information
3rdIteration committed Mar 18, 2024
1 parent c3017f3 commit d5317d9
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 14 deletions.
26 changes: 19 additions & 7 deletions btcrecover/btcrpass.py
Original file line number Diff line number Diff line change
Expand Up @@ -3053,27 +3053,32 @@ def load_from_filename(cls, wallet_filename):
# For LDB files and Ronin wallet log files
if b"vault" in record.key or b"encryptedVault" in record.key:
data = record.value.decode("utf-8", "ignore").replace("\\", "")
if "salt" in data:
if "\"salt\"" in data:
if data in walletdata_list:
continue

wallet_data = data[1:-1]

if b"data" in record.key:
data = record.value.decode("utf-8", "ignore").replace("\\", "")
if "salt" in data:
walletStartText = "vault"
if "\"salt\"" in data:
walletStartText = "\"vault\""

wallet_data_start = data.lower().find(walletStartText)

wallet_data_trimmed = data[wallet_data_start:]

wallet_data_start = wallet_data_trimmed.find("data")
wallet_data_trimmed = wallet_data_trimmed[wallet_data_start - 2:]
wallet_data_start = wallet_data_trimmed.find("\"data\"")
wallet_data_trimmed = wallet_data_trimmed[wallet_data_start - 1:]

wallet_data_end = wallet_data_trimmed.find("}")
wallet_data_end = wallet_data_trimmed.find("}\"}")
wallet_data = wallet_data_trimmed[:wallet_data_end + 1]

if wallet_data in walletdata_list:
continue

walletdata_list.append(wallet_data)

except ValueError:
tryLoadJSONFile = True

Expand Down Expand Up @@ -3111,6 +3116,13 @@ def load_from_filename(cls, wallet_filename):
self.encrypted_block = base64.b64decode(wallet_json["cipher"])[:16]
self.iv = binascii.unhexlify(wallet_json["iv"])
self._mobileWallet = True
elif "keyMetadata" in wallet_data:
hash_iterations = wallet_json["keyMetadata"]["params"]["iterations"]
self = cls(hash_iterations, loading=True)
self.salt = base64.b64decode(wallet_json["salt"])
self.encrypted_vault = base64.b64decode(wallet_json["data"])
self.encrypted_block = base64.b64decode(wallet_json["data"])[:16]
self.iv = base64.b64decode(wallet_json["iv"])
else:
self = cls(10000, loading=True)
self.salt = base64.b64decode(wallet_json["salt"])
Expand Down Expand Up @@ -3139,7 +3151,7 @@ def load_from_data_extract(cls, file_data):

def difficulty_info(self):
if not self._mobileWallet:
return "10,000 PBKDF2-SHA256 iterations"
return str(self._iter_count) + " PBKDF2-SHA256 iterations"
else:
return "5,000 PBKDF2-SHA512 iterations"

Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MANIFEST-000001
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
2024/03/18-06:48:42.105 170 Creating DB C:\Users\crypto\AppData\Local\Google\Chrome\User Data\Default\Local Extension Settings\nkbihfbeogaeaoehlefnkodbefgpgknn since it was missing.
2024/03/18-06:48:42.109 170 Reusing MANIFEST C:\Users\crypto\AppData\Local\Google\Chrome\User Data\Default\Local Extension Settings\nkbihfbeogaeaoehlefnkodbefgpgknn/MANIFEST-000001
2024/03/18-06:52:44.112 b0 Level-0 table #5: started
2024/03/18-06:52:44.130 b0 Level-0 table #5: 2523551 bytes OK
2024/03/18-06:52:44.132 b0 Delete type=0 #3
2024/03/18-06:52:52.047 b0 Level-0 table #7: started
2024/03/18-06:52:52.064 b0 Level-0 table #7: 2524042 bytes OK
2024/03/18-06:52:52.065 b0 Delete type=0 #4
2024/03/18-06:53:04.453 b0 Level-0 table #9: started
2024/03/18-06:53:04.472 b0 Level-0 table #9: 2526103 bytes OK
2024/03/18-06:53:04.474 b0 Delete type=0 #6
2024/03/18-06:53:09.554 b0 Level-0 table #11: started
2024/03/18-06:53:09.573 b0 Level-0 table #11: 2527469 bytes OK
2024/03/18-06:53:09.575 b0 Delete type=0 #8
2024/03/18-06:53:50.523 b0 Level-0 table #13: started
2024/03/18-06:53:50.543 b0 Level-0 table #13: 2526942 bytes OK
2024/03/18-06:53:50.545 b0 Delete type=0 #10
2024/03/18-06:53:59.945 b0 Level-0 table #15: started
2024/03/18-06:53:59.961 b0 Level-0 table #15: 2527193 bytes OK
2024/03/18-06:53:59.963 b0 Delete type=0 #12
2024/03/18-06:53:59.963 b0 Compacting 4@0 + 1@1 files
2024/03/18-06:54:00.003 b0 Generated table #16@0: 1 keys, 1263638 bytes
2024/03/18-06:54:00.003 b0 Compacted 4@0 + 1@1 files => 1263638 bytes
2024/03/18-06:54:00.004 b0 compacted to: files[ 0 1 1 0 0 0 0 ]
2024/03/18-06:54:00.004 b0 Delete type=2 #7
2024/03/18-06:54:00.004 b0 Delete type=2 #9
2024/03/18-06:54:00.004 b0 Delete type=2 #11
2024/03/18-06:54:00.004 b0 Delete type=2 #13
2024/03/18-06:54:00.004 b0 Delete type=2 #15
Binary file not shown.
1 change: 1 addition & 0 deletions btcrecover/test/test-wallets/metamask_vault_v11_12_1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"data":"Kxj05Qf3witT0tIBopkUcO9nzzgUunEjIC7NUGUI0mqYVI94lOnBb2uDJhRNgXyog7KYG7/e7ZU9/xg6bVmucpvstEGgWfa2jM0vdGKhh8e9QsxOnAAt9fMXpqhXO8Bo+GUWtX2ykmfqATp1bgpstTzVGZUK+fFn9vpgstCLcLDJlOheR61V7ZkZYsTzhdida/hGan3Dgc0jNDeQDCbf4sd84fFSJiszNQxcvM7tJmy6ARN8zsuxsMGIjySe3UlYxX7anec7rUnG8uduuDs9E1FuP6nYMpWmk4g6KJzVC2dtK7+VKkDs8DJkxdMKhob0Tt5HWWzRYs97uz9c+xPlkQmq10PD/DZqWRvjmQLTwr3es/BIsywCcU8D6646xz4nhu9x1STWeKFep325YXHK+MAHlPX87eWtDb/PGFYe2s+ku7rp6Gh4tRysq7TwRb1VTqlZ85VpCP0aLStHLs8vgtvZ2Au9NztWesaq8cjgXSkGgOxAFMsT4xOHsVI1bB6Suu9fmBKzi0lw3mr4JswSJMb7EBEDeDeXRN5PG88OZm/QGiO6XV+b2TXvA3LzcuAAg5EZd04NhUujuudxRTG1ql2jPUSsqTFUXlBUMZf6TkJfAkp+kcGSbaKfSrd59wzmR/6bPIvepyX68vamKOZ7XAmOsc6C85i6AluH+dpObHMC0lAV4Mv0vlkLMGO9OBPeAUlAAYtoWiVohv7erHLvzKabC8MVSvPDJxZzDrOaojU39aP5RexIM07dYp2PXlWM8/LZkz+GZfGWxw8UcIeq/1vbu+L+SsY=","iv":"IbxXQknyfC6AW3yDKX8kKw==","keyMetadata":{"algorithm":"PBKDF2","params":{"iterations":600000}},"salt":"QU1D7Egd9J+2E+CyPFiZ7Rl8BVAsTX1jESAV2/J4/+A="}
8 changes: 8 additions & 0 deletions btcrecover/test/test_passwords.py
Original file line number Diff line number Diff line change
Expand Up @@ -1403,6 +1403,14 @@ def test_metamask_leveldb_chrome_cpu(self):
def test_metamask_v10_11_3_leveldb_chrome_cpu(self):
self.wallet_tester("metamask/nkbihfbeogaeaoehlefnkodbefgpgknn-v10_11_3")

@skipUnless(can_load_leveldb, "Unable to load LevelDB module, requires Python 3.8+")
def test_metamask_v11_12_1_leveldb_chrome_cpu(self):
self.wallet_tester("metamask/nkbihfbeogaeaoehlefnkodbefgpgknn-v11_12_1")

@skipUnless(can_load_leveldb, "Unable to load LevelDB module, requires Python 3.8+")
def test_metamask_v11_12_1_json_chrome_cpu(self):
self.wallet_tester("metamask_vault_v11_12_1.txt")

def test_metamask_JSON_firefox_cpu(self):
self.wallet_tester("metamask.9.8.4_firefox_vault")

Expand Down
14 changes: 7 additions & 7 deletions extract-scripts/extract-metamask-vaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@
for record in leveldb_records.iterate_records_raw():
#print(record)
#For LDB files and Ronin wallet log files
if b"vault" in record.key or b"encryptedVault" in record.key:
if b"\"vault" in record.key or b"encryptedVault" in record.key:
data = record.value.decode("utf-8", "ignore").replace("\\", "")
if "salt" in data:
if "\"salt\"" in data:
if data in walletdata_list:
continue

Expand All @@ -49,17 +49,17 @@

if b"data" in record.key:
data = record.value.decode("utf-8", "ignore").replace("\\", "")
if "salt" in data:
walletStartText = "vault"
if "\"salt\"" in data:
walletStartText = "\"vault\""

wallet_data_start = data.lower().find(walletStartText)

wallet_data_trimmed = data[wallet_data_start:]

wallet_data_start = wallet_data_trimmed.find("data")
wallet_data_trimmed = wallet_data_trimmed[wallet_data_start - 2:]
wallet_data_start = wallet_data_trimmed.find("\"data\"")
wallet_data_trimmed = wallet_data_trimmed[wallet_data_start - 1:]

wallet_data_end = wallet_data_trimmed.find("}")
wallet_data_end = wallet_data_trimmed.find("}\"}")
wallet_data = wallet_data_trimmed[:wallet_data_end + 1]

if wallet_data in walletdata_list:
Expand Down

0 comments on commit d5317d9

Please sign in to comment.