27

On OS X 10.11 - I have opened up my user's .plist file, and have looked inside of the file.

I did this with the following command:

sudo defaults read /var/db/dslocal/nodes/Default/users/<username>.plist ShadowHashData|tr -dc 0-9a-f|xxd -r -p|plutil -convert xml1 - -o -

The file said SALTED-SHA512 in it, so I assumed it was a SHA512 hash.

But, I went to a few SHA512 hash generator sites, and I put in my password. I ended up getting a different hash than what was in the .plist file.

So, how do I convert what is in the .plist file into an actual hash, or exactly what type of hash is stored in the file?

4
  • 3
    What kind of OS X password do you try to crack? OS X 10.7/10.8? Because my file says SALTED-SHA512-PBKDF2 (OS X 10.10)!
    – klanomath
    Commented Dec 23, 2015 at 23:14
  • @klanomath OS X El Capitan; and that is what it says, wasn't sure if PBKDF2 was sensitive data. Is SALTED-SHA512-PBKDF2 the type, and if so, are there any c++ functions/libraries that can generate this type? (Preferably a fast function/library)
    – Flare Cat
    Commented Dec 24, 2015 at 0:35
  • I thought the OS X password hashes were stored in /var/db/shadow/hash ?
    – voices
    Commented Dec 24, 2015 at 18:51
  • 1
    @tjt263 not on Yosemite+
    – Flare Cat
    Commented Dec 24, 2015 at 19:03

2 Answers 2

48
+50

Password cracking (valid in OS 10.8 and newer)

First I want to explain your command:

sudo defaults read /var/db/dslocal/nodes/Default/users/user.plist ShadowHashData|tr -dc 0-9a-f|xxd -r -p|plutil -convert xml1 - -o -

The first part of the command reads the key ShadowHashData in the plist

sudo defaults read /var/db/dslocal/nodes/Default/users/user.plist ShadowHashData

Result (mostly hex):

(
    <62706c69 73743030 d101025f 10145341 4c544544 2d534841 3531322d 50424b44 4632d303 04050607 0857656e 74726f70 79547361 6c745a69 74657261 74696f6e 734f1080 c5f19863 9915a101 c99af326 dffe13e8 f14456be 8fd2312a 39a777b9 2178804e 204ca4fe e12a8667 871440ef f4288e81 1d86d746 c6d96a60 c919c341 8dfebba4 2f329f5d 73c0372d 636d61d5 dfda1add 61af36c7 0e4acd77 12761072 09e643ae 92a0f43e 95a45274 4e50fb45 40d9bdf4 e0b70172 5d7db488 fbe18c1a b7737c6b 4f10200d ba6246bd 38266b2e 827ff7e7 27138075 7c71d653 893aa361 d5902398 30236911 c160080b 22293136 41c4e700 00000000 00010100 00000000 00000900 00000000 00000000 00000000 0000ea>
)

the second part of the command tr -dc 0-9a-f removes anything except 0-9a-f.

Result (hex):

62706c6973743030d101025f101453414c5445442d5348413531322d50424b444632d303040506070857656e74726f70795473616c745a697465726174696f6e734f1080c5f198639915a101c99af326dffe13e8f14456be8fd2312a39a777b92178804e204ca4fee12a8667871440eff4288e811d86d746c6d96a60c919c3418dfebba42f329f5d73c0372d636d61d5dfda1add61af36c70e4acd771276107209e643ae92a0f43e95a452744e50fb4540d9bdf4e0b701725d7db488fbe18c1ab7737c6b4f10200dba6246bd38266b2e827ff7e7271380757c71d653893aa361d590239830236911c160080b2229313641c4e700000000000001010000000000000009000000000000000000000000000000ea

the third part xxd -r -p reverts it to a (mal-formed) binary:

?bF?8&k.???'?u|q?S?:?aՐ#?0#i?`WentropyTsaltZiterationsO???c??ɚ?&????DV???1*9?w?!x?N L???*?g?@??(????F??j`??A????/2?]s?7-cma????a?6?J?wvr    ?C????>??RtNP?E@ٽ??r]}?????s|kO                              ")16A??    ?

and the last part plutil -convert xml1 - -o - creates a well-formed xml plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>SALTED-SHA512-PBKDF2</key>
    <dict>
        <key>entropy</key>
        <data>
        xfGYY5kVoQHJmvMm3/4T6PFEVr6P0jEqOad3uSF4gE4gTKT+4SqGZ4cUQO/0
        KI6BHYbXRsbZamDJGcNBjf67pC8yn11zwDctY21h1d/aGt1hrzbHDkrNdxJ2
        EHIJ5kOukqD0PpWkUnROUPtFQNm99OC3AXJdfbSI++GMGrdzfGs=
        </data>
        <key>iterations</key>
        <integer>49504</integer>
        <key>salt</key>
        <data>
        DbpiRr04Jmsugn/35ycTgHV8cdZTiTqjYdWQI5gwI2k=
        </data>
    </dict>
</dict>
</plist>

To get a real file replace -o - by -o ~/Desktop/tempuser.plist

The plist contains three key parts: iterations, entropy and salt.

iterations is just an integer, but entropy and salt are base64 encoded. To continue working with them you have to decode and xxd them:

To decode salt remove all spaces and new lines from the data part and use

echo  "salt_data" | base64 -D | xxd -p | tr -d \\n > salt

With my data above that's

echo  "DbpiRr04Jmsugn/35ycTgHV8cdZTiTqjYdWQI5gwI2k=" | base64 -D | xxd -p | tr -d \\n > ~/Desktop/salt

with the salt(hex) result:

0dba6246bd38266b2e827ff7e7271380757c71d653893aa361d5902398302369

The same for entropy:

echo  "xfGYY5kVoQHJmvMm3/4T6PFEVr6P0jEqOad3uSF4gE4gTKT+4SqGZ4cUQO/0KI6BHYbXRsbZamDJGcNBjf67pC8yn11zwDctY21h1d/aGt1hrzbHDkrNdxJ2EHIJ5kOukqD0PpWkUnROUPtFQNm99OC3AXJdfbSI++GMGrdzfGs=" | base64 -D | xxd -p | tr -d \\n > ~/Desktop/entropy

with the entropy(hex) result:

c5f198639915a101c99af326dffe13e8f14456be8fd2312a39a777b92178804e204ca4fee12a8667871440eff4288e811d86d746c6d96a60c919c3418dfebba42f329f5d73c0372d636d61d5dfda1add61af36c70e4acd771276107209e643ae92a0f43e95a452744e50fb4540d9bdf4e0b701725d7db488fbe18c1ab7737c6b

If you need a text file for hashcat to crack the password you have to combine the hash data you have found into a single string:

$ml$<iterations(integer)>$<salt(hex)>$<entropy(hex)>

With my example hash data that's:

$ml$49504$0dba6246bd38266b2e827ff7e7271380757c71d653893aa361d5902398302369$c5f198639915a101c99af326dffe13e8f14456be8fd2312a39a777b92178804e204ca4fee12a8667871440eff4288e811d86d746c6d96a60c919c3418dfebba42f329f5d73c0372d636d61d5dfda1add61af36c70e4acd771276107209e643ae92a0f43e95a452744e50fb4540d9bdf4e0b701725d7db488fbe18c1ab7737c6b

Save this to a file named hash.txt and use it in hashcat. The proper brute force command to find the password (=my simple test password only containing 4 digits) is:

./hashcat-cli64.app -m 7100 hash.txt -a 3 ?d?d?d?d

The resulting password after 3 minutes cracking (in a VM) is 1111.


Now the reverse: Creating ShadowHashData (valid in OS 10.8 and newer)

This elucidates why you can't use a simple SHA512 hash generator to create your "password" data. SHA512 is still important though. The background is explained here: PBKDF2-Key_derivation_process.

You need:

  • PRF is a pseudorandom function of two parameters with output length hLen (e.g. a keyed HMAC)
  • Password is the master password from which a derived key is generated
  • Salt is a sequence of bits, known as a cryptographic salt
  • c is the number of iterations desired
  • dkLen is the desired length of the derived key

to create DK = PBKDF2(PRF, Password, Salt, c, dkLen)

To create DK ~ the entropy key in SALTED-SHA512-PBKDF2 (the only part in the intermediate plist that relies on your password) use php hash_pbkdf2:

string hash_pbkdf2 ( string $algo , string $password , string $salt , int $iterations [, int $length = 0 [, bool $raw_output = false ]] )

In Terminal (PHP ⩾ 5.5 is needed) enter:

php -a
Interactive shell

php > $password = "1111";
php > $iterations = 49504;
php > $length = 256;
php > $salt = "\x0d\xba\x62\x46\xbd\x38\x26\x6b\x2e\x82\x7f\xf7\xe7\x27\x13\x80\x75\x7c\x71\xd6\x53\x89\x3a\xa3\x61\xd5\x90\x23\x98\x30\x23\x69";
php > $hash = hash_pbkdf2("sha512", $password, $salt, $iterations, $length);
php > echo $hash;

c5f198639915a101c99af326dffe13e8f14456be8fd2312a39a777b92178804e204ca4fee12a8667871440eff4288e811d86d746c6d96a60c919c3418dfebba42f329f5d73c0372d636d61d5dfda1add61af36c70e4acd771276107209e643ae92a0f43e95a452744e50fb4540d9bdf4e0b701725d7db488fbe18c1ab7737c6b
php > 

The string used in $salt is the escaped hex (\x) presentation of salt(hex):
0dba6246... -> \x0d\xba\x62\x46...

Since you can define or know the hash algorithm (it has to be sha512 for Mac 10.8 and later), iterations (a number bigger than zero and smaller than 2^32-1), salt (length 64 bytes hex but random!) and length (256 byte) you can create a well-formed intermediate plist file, by reversing all commands above.

By reversing your command (better: each of the subcommands) from the very first step you can create the data of the key ShadowHashData in the original plist using the intermediate plist.


And to answer your question finally: the hash algorithm used to process the OS X password (and other data like the salt) is SHA512. But you can't say your user password is stored as SHA512 hash.

Your password and the salt is grilled by sha512 many times, then the result is base64'ed and reverse xxd'ed. Together with the salt and the iterations it's xxd'ed and base64'ed again.

I hope I didn't forget any step.

5
  • 2
    has an exceptional answer but here is a collection of scripts that puts it all together. One interesting thing I found out when trying to implement this was that the Dklen was 128. Hopefully this will help someone down the line!
    – 3martini
    Commented Apr 7, 2016 at 1:19
  • 2
    This is an amazing answer. I wonder how close it ends up being to github.com/octomagon/davegrohl
    – bmike
    Commented Nov 20, 2017 at 17:45
  • @bmike not much, given that this doesn’t try to crack the hash; but github.com/octomagon/davegrohl has an option to dump a user's password hash to the screen without trying to crack it, that is what this does in hashcat format.
    – dardo82
    Commented Jun 5, 2019 at 9:35
  • 1
    @3martini you are right,I’ve found that out too,here is my version of the shell script: gist.github.com/dardo82/a529db7a191f375ef401adfea7156b6d
    – dardo82
    Commented Jun 5, 2019 at 9:59
  • thanks @dardo82, your dscl-based pipe worked for me where the defaults-based one would not.
    – billkw
    Commented Mar 22, 2023 at 20:36
0

You would need the salt of your user account on that system. That's a random string of chars invented for you when you created your account (or perhaps when you changed your password last maybe). You'd need to add that to your password, eg:

[that massive chunk of numbers below then...][your password]

Not sure if this is added to the front or back: [yourPassword][salt]? who knows.

For the user USERNAME you can see the hash here:

sudo plutil -p /var/db/dslocal/nodes/Default/users/**USERNAME**.plist

Then out comes:

"ShadowHashData" => [
  0 => <62706c69 73743030 d2010203 04524e54 5f101453 414c5445 442d5348 41353132 2d50424b 4446324f 1010f5d1 dcc424b1 a6173adf 2b69b6b4 e043d305 06070809 0a57656e 74726f70 79547361 6c745a69 74657261 74696f6e 734f1080 8d6f15f8 36cf219f c4854634 62706c69 15f23eec 1615bb8a 04524e54 48dcd5fa c6e45319 faf0f12a ae0bebb0 7881dcdd 92fab792 9f354bf8 04524e54 a50cad3b d04e867b 689fbaa5 e1be59ff be37c6f3 60e41e59 3fdc0702 f296c9f9 8aedd2d6 77f5608a 337add70 5a6b39ba 64665f54 a85adb30 54b791d1 62706c69 aa4d0c9a 4f1020a2 99ead6a5 42730425 41353132 01247c53 6442646a 41353132 e2555d2e a3baee11 8e0b0008 000d0010 0027003a 00410049 004e0059 00dc00ff 00000000 00000201 00000000 0000000b 00000000 00000000 00000000 00000102>

Interestingly, while I have altered some of the random looking number blocks above so Stack don't get my salt (you may notice some repeated random blocks that was my paste-work!) but I didn't paste over the ones at the end … it seems to dissolve into zeroes at the end these 512 SHA hashes interesting!!!

PS. They've moved it around a bit … used to be really well hidden. I got lost and could not find mine (see below), its hidden in some wicked folder structure from 'Nam!

sh-3.2# pwd
/var/db/uuidtext
sh-3.2#  ls -R
00  10  20  30  40  50  60  70  80  90  A0  B0  C0  D0  E0  F0  dsc
01  11  21  31  41  51  61  71  81  91  A1  B1  C1  D1  E1  F1
02  12  22  32  42  52  62  72  82  92  A2  B2  C2  D2  E2  F2
03  13  23  33  43  53  63  73  83  93  A3  B3  C3  D3  E3  F3
04  14  24  34  44  54  64  74  84  94  A4  B4  C4  D4  E4  F4
05  15  25  35  45  55  65  75  85  95  A5  B5  C5  D5  E5  F5
06  16  26  36  46  56  66  76  86  96  A6  B6  C6  D6  E6  F6
07  17  27  37  47  57  67  77  87  97  A7  B7  C7  D7  E7  F7
08  18  28  38  48  58  68  78  88  98  A8  B8  C8  D8  E8  F8
09  19  29  39  49  59  69  79  89  99  A9  B9  C9  D9  E9  F9
0A  1A  2A  3A  4A  5A  6A  7A  8A  9A  AA  BA  CA  DA  EA  FA
0B  1B  2B  3B  4B  5B  6B  7B  8B  9B  AB  BB  CB  DB  EB  FB
0C  1C  2C  3C  4C  5C  6C  7C  8C  9C  AC  BC  CC  DC  EC  FC
0D  1D  2D  3D  4D  5D  6D  7D  8D  9D  AD  BD  CD  DD  ED  FD
0E  1E  2E  3E  4E  5E  6E  7E  8E  9E  AE  BE  CE  DE  EE  FE
0F  1F  2F  3F  4F  5F  6F  7F  8F  9F  AF  BF  CF  DF  EF  FF

./00:
229B1EE4463244AED56CD907B7BEF5  41D012E18834E9A89637A804BE488C  A7D6EBD5D63A45918E4C3DCD479708
28400DB8373232B480C57B68EFA51D  7EE5E1A8A839CE9EBB017702B87E4A  AE3ABF3C8333BF8A4917C38946F37F

./01:
56B34D8B03387CA319BDC11BEFB2ED  A8359C18A633C9815A5C528BCD7E18  DD590C6953D428FEFCA59CDAD53349
62DA3DA0C73CE2AA227F372A727765  C05AE85AE73DF492529DCD10F0F60B  ECD5DB35653A50ABCA585948E1295C

./02:
C7513934DD9D8EB73B4B0765D8  98F679561A3957947E381448224549  DBAB00E98835D2853386FF37C39FB7  FA85B4876B3E1D81B742C6C1F8D368
541FAC57203B75BD333F7EC33EBD32  C25AE52FA438AD9006931512A8A522  EFA98EEFF13799BFDFDE3033209EC2
3234B636EEA71A903E204E9599  CA252B6EA03E5A811ACFC88F0987C0  F815F784DC35A5B1D5F658F1DB666B

./03:
FA758E3DA4996D1CD5FF53B7EA  419205BFBB3469BCDCFE528FDE2C9B  73F0433FBB35A0AD1CD160020F60F0  D0034745E035D183CB344308FC05E5
26539F480B31D8B65F1495C85AADE2  69BF1B56BB30DE9BBE83BD3FDAB067  A7CA24A6E1E06B3F20084298054F41  D9727CA86A396CAD1CC1B1BD1FA8DF

./04:
87C3CF30E3ADCCDBD0A0D56913  B398A52A3C3041B8C89F91CB154B25  C004143AB43CD18D5808C2A3017BDE  F478D3BCB6313782CBBD803691DE4F
99FBF1F9B439EB92551A096F187EC3  BA704190633F04B0BB5DE3ECB6C013  CA7AE366FA34BD86DB77974A1A4BED

./05:
67AE763654A52CBF399D33EB29  4D4B7528803C138C4D2330B51326C1  7B6C998C5331159A4ADC1F73D72E71  BEEC66F8573CF0BE339189FD1A688B
11E586F995DADC9A6E2AC531963BD2  503FAB2A9C331A95670849CC595B30  8C0FAFB09A3526BEAA3A06976C42E7  CCC4737FBE915B2A8C636060DFDE78
138A1B31EC95D1588BF15328A2  560F3EDCED38B29C14CAB39287EA26  988FAB9E6E70E0C21C9424703A5895  E1A892FA8D378C8C6BA9376A74EB00
2669F6338C3AF9A9FBF365EE3294F3  708E7FDA333D6E951F5870047A266B  98E3BB24DF3BE8B49D27EE2F30DA42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .