Slowly cracking 1Password8 iOS password w/ Python. How can I do better with Hashcat?
#1
Hi all,

I've had to finally start learning about password cracking to recover passwords stored in 1Password8 iOS vault. I think I figured out how to attempt different passwords and confirm when I find the correct one; however, being a beginner in the matter I know I'm blind to better methods to solve this.

The account only exists in iOS and was created only about 4 months ago, so I'm not sure if Hashcat supports their format. I tried passing the .sqlite database file to 1password2john but it wasn't able to work on it. I'm waiting for my code to finish running to uninstall the GPU driver and install the compatible one for Hashcat to see if it works.
If it doesn't work I'd like to know if I can run a similar process like the one on my script. I know some of the words I used when I created it so I think I could have a good start regarding the dictionary, and now that I have a better understanding of how rules and masks work I think I could crack it.

Brief introduction to how I got here:

So the problem is I forgot the master password/account password for a vault I created for my mom. I suggested moving all her passwords written in plain text to the app and even transcribed some of them for her. The ones I hadn't yet gotten to I locked up in the Notes app using a password generated by 1Password. I showed her how she can copy and paste the password for the (now encrypted) notes whenever she needed to.

So now we both can't remember what the master password and I'm trying to fix. I first reached out for tips on r/1Password thinking there was something else I could do, like a tip to make FaceID prompt again [1] .

I then continued researching on ways to get information from the iPhone device and I got an encrypted backup -- which at first I decrypted using the Mobile Verification Toolkit by Amnesty International Security Lab [2] and even ran the software to see if there were helpful logs that would show the password or hints to remember it.

I then decrypted the backup using a free backup browser to extract the 1Password files, and with the help of this series of posts [3] I went through the .sqlite database and found each of the pieces 1Password uses to create your AUK (Account Unlock Key, previously MUK) which is the central piece to then encrypt your private key that then is used to encrypt vaults.

I learned a lot from the series and 1Password's White Paper [4]. It all made me appreciate everything that has been developed by people to keep data secure, it makes me appreciate math in general; although, it's also scary how your physical device can compromise you in the wrong hands. Finally, it's all intimidating too since I feel like trying to go through armour with a stick.

Where I'm at:

I have now written a script in Python that goes through the same process 1Password goes through to generate the AUK. I do this for each password in a wordlist. I relied heavily on this repository from the same author of the 1Password series [5] .

So these things I know or have from a backup of the device:
  • Secret Key (version, account id, secret)
  • email
  • algorithm
  • iterations
  • salt
  • encrypted sqlite database (keysets, account, vaults, etc.)

With this I then get the HKDF salt:

Code:
hkdf_salt = HKDF(ikm=p2s, len=32, salt=email, hash=SHA256, count=1, info=algorithm)

Then the derived password key using the HKDF salt:

Code:
password_key = PBKDF2(sha256, password, salt=hkdf_salt, iterations=p2c, 32 bytes)

Then the HKDF secret key:

Code:
hkdf_key = HKDF(ikm=secret, len=32, salt=AcctID, hash=SHA256, count=1, info=version)

Then XOR the password key and the HKDF secret key:

Code:
auk = bytes(a ^ b for a, b in zip(password_key, hkdf_key))

Then I check if the resulting auk is valid by trying to decrypt and verify the data in the symmetric key:

Code:
C = AES.new(auk, AES.MODE_GCM, enc_sym_key_iv, mac_len=16)
    try:
        PT_enc_sym_key = C.decrypt_and_verify(enc_sym_key_data[:-16], enc_sym_key_data[-16:])
        if PT_enc_sym_key is not None:
            jwk_loaded = json.loads(jwk_json)
            decrypted_kid = jwk_loaded['kid']
            if(decrypted_kid == keyset_uuid):
                # Found password
            except ValueError:
            continue

My conclusion is that if the current password from the wordlist manages to decrypt the data and in the data the 'kid' matches the unencrypted 'uuid' from the keyset then the password is the correct one.

I divide the wordlist.txt file into chunks and do this to traverse through the words with simultaneous processes:

Code:
num_cores = 12
chunk_size = math.ceil(len(passwords) / num_cores)
pool = multiprocessing.Pool(processes=num_cores)

for i in range(num_cores):
    start = i * chunk_size
    end = start + chunk_size
    pool.apply_async(find_password, args=(passwords, start, end, hkdf_pass_salt, hkdf_key, enc_sym_key_iv, enc_sym_key_data, keyset_uuid))

pool.close()
pool.join()

After attempting this with a new 1Password account on another iOS device, getting the data needed from the backup and going through a wordlist that contained the correct password I managed to confirm that this works and it's very likely that it will work on the main device.

So, how can I do better?

I tried to optimize the code bit by bit and I understand there's plenty more to improve in it. However, I'd like to move to doing something like this on an environment that would make this a lot faster or more efficient. I know I won't be able to code more efficient solutions than the ones already out there by experts, even if I wanted to reinvent the wheel.

I started to feel the lack of optimization in my solution when John The Ripper output a wordlist in the almost hundreds of millions of lines from a set of rules I thought could contain the right password but no luck yet. I know I have to grow the list even more but optimize my approach even more. I would appreciate any help pointing me in the right direction.


Thank you for reading me!


Links

[1] https://www.reddit.com/r/1Password/comme...he_master/

[2] https://github.com/mvt-project/mvt

[3] https://darthnull.org/series/1password/

[4] https://1passwordstatic.com/files/securi...-paper.pdf (PDF)

[5] https://github.com/dschuetz/1password
Reply


Messages In This Thread
Slowly cracking 1Password8 iOS password w/ Python. How can I do better with Hashcat? - by GonnZerg - 03-18-2023, 08:28 AM