hash format for 1password 3.7.2
1password version 3.7.2 is using the sqlite database to store all the information (the backup file with extension 1ptbackup is the same 1password.sqlite file).
Looking in the DB structure I found the table “securityLevels2” where items “iterations”, ”keyEncrypted” and “keyValidation” are present. 
This version of 1password is using the PBKDF2-HMAC-SHA1 to store the master password:

Based on the example found “hashcat.agilekeychain” I prepared a file which starts with “sha1”, iterations (10000), “keyEncrypted” without first 8 bytes (Salted__) and “keyValidation”.

Based on the recommendation from other post of hashcat forum (to use base64 for oclHashcat v1.37) I converted the Salt to base64 by “echo "bae3d9555f89caeecd3c1026ac92bd116d9442736f3b1a41c94a609f99e2ee104a1655a90a0db23e" | xxd -r -p | base64”.

the final file looks like this:

Would you please check if my hash file is prepared correctly and if my approach is correct using option PBKDF2-HMAC-SHA1 (12000)?
You can't use raw PBKDF2 modes here, there's some AES128 stuff to be done afterwards. You must stick to -m 6600 mode
./oclHashcat-1.37/oclHashcat64.bin -m 6600 SL6hash -a 3 dict2
oclHashcat v1.37 starting...

WARNING: Hashfile 'SL6hash' in line 1 (10000:bVpLO5RmZc3eN7vMYYB9FBcOfBbKdb392gkfRDhUu187tx37pc+qHA==:40c357a77cf91ec9851116fb43a9978b460c3eb0e2ad2a1108b6578e494b27a3): Line-length exception
Parsed Hashes: 1/1 (100.00%)

ERROR: No hashes loaded

I changed to -m 6600 mode but I get the this error message. What is the problem now? Where can I find what is the correct format of hash file for -m 6600 mode?
(11-02-2015, 09:10 PM)atom Wrote: http://www.rurapenthe.me/2013/04/crackin...rd-it.html

Thank you for sharing this information. 

The provided homepage describes how to prepare hash file for Hashcat from the encryptionKeys.js file. 

But I do not have any encryptionKeys.js file in my 1password version 3.7.2 for iPhone. I have only 1password.sqlite file where is existing the table securityLevels2 - the row with name =“SL5” contains keyEncrypted (48 bytes including “Salted__……”) and key validation (32 bytes) as following (I made a reset of the Master code to create this example database):

keyID = “16C280F53DBA4E11B206E2FA554239B8”
keyEncrypted = “53616c7465645f5fc98fbec6ee5c2665cd1f2a6b204a0dd99e8f21bf2a6f3e63cace7d9c25b334cbf0443035e3d860e7”               
keyValidation = “35e3fa70d8138a92555f309ba9f4bf144c0d3f1a0775d1c91ee330f21662b64f”
iterations = “1000”

Would you please describe the steps how I can prepare the hashfile for Hashcat (-m 6600) from this information?

As I’m not an expert in programming neither encryption, if any information about the format of sqlite (1password 3.7.2 for iPhone) is needed I can try to contact Agile support directly. If the 1password.sqlite is needed, please let me know and I will share it with you.
(I hope that after successful recovery I will be allowed to donate some money for your team who spent the time on development of Hashcat and is spending time on my ticket/post as well).
Thank you.
When we compare the content of your .sqlite file with the normal parsing of the .js file (see https://github.com/philsmd/1password_agi...hashcat.pl ), we see:
- we only need the "data" and "iterations" part when parsing .js files
- if salt is being used, the base64 decoded data part starts with Salted__ (8 chars), 8 binary salt (16 hexadecimal characters) and the remaining part is the data part (about 1040 binary chars, or 2080 hex chars)
- the level, identifier and validation string can simply be ignored (we do not need them to crack the hashes)

The format for hashcat is:
[iteration_count]:[salt]:[data] (without the brackets)
note: there is no "sha1" etc (see https://hashcat.net/wiki/doku.php?id=example_hashes and search for 6600)

so I think the Salted__ part is a good start, the first 8 bytes (16 hexadecimal chars) should be the salt indeed, but now you need the 1040 binary chars (or 2080 hex chars) for the data too

with .js this "Salted__" splitting looks like this: https://github.com/philsmd/1password_agi...#L140-L144

So I think there must be a longer "data" string somewhere with exactly 1040 bytes (or 2080 hex chars)

It could also be that 1password 3.7.2 did use a different format/algorithm, it would not suprise me because this version is quite old and the web is full of tutorials how to upgrade starting with version 3.7.2.

It would also make sense to at least mention the password that the fields found in the sample database correspond to. Without the password it is very difficult to understand anything.
(11-04-2015, 11:00 AM)philsmd Wrote: It could also be that 1password 3.7.2 did use a different format/algorithm, it would not suprise me because this version is quite old and the web is full of tutorials how to upgrade starting with version 3.7.2.

It would also make sense to at least mention the password that the fields found in the sample database correspond to. Without the password it is very difficult to understand anything.

I performed the Reset of the database - I attached the 1Password0100-20151107_Hashcat.sqlite (please remove the .txt extension - I was not able to attach it as .sqlite) where the Unclock code was set to “0000” and the Master password to “Hashcat009?”

There are 2 items - one with protection of Master password and one just with protection of Unlock code. 

the second row with name = “SL5” has following content:

keyID = “8873B3F992114412802E8AA107529DE6”
keyEncrypted = “53616c7465645f5ffb48ad370166a38cefdc083240a0fff362064e98312f48aeb8f5e67481d39dc7c1c144558ef49c4e”
keyValidation = “c80262e2aa1b03a763db738824e7022ec5abc3a1e8ad5505472ab7c613a54eaa”
iterations = “10000”

I hope it will help.

Attached Files
.txt   1Password0100-20151107_Hashcat.sqlite.txt (Size: 40 KB / Downloads: 15)
yes it cracks see:

echo Hashcat009? | ./1Password_372.pl
full:   fb48ad370166a38cefdc083240a0fff362064e98312f48aeb8f5e67481d39dc7c1c144558ef49c4e
salt:   fb48ad370166a38c
iv:     efdc083240a0fff362064e98312f48ae
hash:   b8f5e67481d39dc7c1c144558ef49c4e

started cracking...

match: 'Hashcat009?'

where 1Password_372.pl is just a simple POC perl script:

#!/usr/bin/env perl

use strict;
use warnings;

use Crypt::PBKDF2;
use Crypt::CBC;

my $iterations = 10000;
my $key_encrypted = "53616c7465645f5ffb48ad370166a38cefdc083240a0fff362064e98312f48aeb8f5e67481d39dc7c1c144558ef49c4e";
#my $key_encrypted = "53616c7465645f5fc98fbec6ee5c2665cd1f2a6b204a0dd99e8f21bf2a6f3e63cace7d9c25b334cbf0443035e3d860e7";

$key_encrypted =~ s/53616c7465645f5f//; # strip of "Salted__"

my $length = length ($key_encrypted);

my $offset = 0;
my $prefix_length = $length;

my $salt_hex = substr ($key_encrypted, 0, 16);
my $salt     = pack   ("H*", $salt_hex);

$offset += 16;
$prefix_length -= 16 + 32 + 32;

my $prefix = substr ($key_encrypted, $offset, $prefix_length);

$offset += $prefix_length;

my $iv_hex = substr ($key_encrypted, $offset, 32);
my $iv     = pack ("H*", $iv_hex);

$offset += 32;

my $hash_hex = substr ($key_encrypted, $offset);

print "full:   " . $key_encrypted . "\n";

print "salt:   " . unpack ("H*", $salt) . "\n";
print "prefix: " . $prefix . "\n";
print "iv:     " . unpack ("H*", $iv) . "\n";
print "hash:   " . $hash_hex . "\n";

my $data = pack ("H*", "10101010101010101010101010101010");

my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA1');

my $pbkdf2 = Crypt::PBKDF2->new (
  hasher       => $hasher,
  iterations   => $iterations,
  output_len   => 16

print "\nstarted cracking...\n\n";

while (my $word_buf = <>)
  chomp ($word_buf);
  my $key = $pbkdf2->PBKDF2 ($salt, $word_buf);

  my $cipher = Crypt::CBC->new({
    key         => $key,
    cipher      => "Crypt::Rijndael",
    iv          => $iv,
    literal_key => 1,
    header      => "none",
    keysize     => 16
  my $encrypted = unpack ("H*", $cipher->encrypt ($data));
  my $hash_buf  = substr ($encrypted, 0, 32);

  if ($hash_buf eq $hash_hex)
    print "match: '$word_buf'\n";

    exit (0);

exit 1;

So this proofs that you only need that field starting with "Salted__", i.e. the keyEncrypted field, to verify the password.

Unfortunately, oclHashcat/cudaHashcat currently expects a fixed size 1040 bytes (or 2080 hex chars as "data") because of the new agilekeychain format (but the algo is indeed still the same!), you could go ahead and open a trac ticket with explanations here: https://hashcat.net/trac such that the devs can implement it (i.e. maybe remove this 2080 hex chars restriction).


BTW the input for oclHashcat would be something like this (if this short non-2080 hex char version would be supported, which it is NOT yet):

it also works with a little bit of padding see this:
$ cat m06600.txt
$ cudaHashcat64 --quiet -m 6600 m06600.txt dict.txt

So it cracks already, you just need to pad it to the correct length (or open a trac ticket and devs may help to reduce this length restriction Wink)
(11-07-2015, 08:25 PM)philsmd Wrote: ----
it also works with a little bit of padding see this:

So it cracks already, you just need to pad it to the correct length (or open a trac ticket and devs may help to reduce this length restriction Wink)

Awesome. I would like to thank all the team members for their fantastic support. 
I was already able to recover the Master password of my old 1password 3.7.2 iPhone database. 

Thank you once again.