Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
OS X Lion Password Hash Instructions

Password Hash Accessing:

  • Grab plist file from /var/db/dslocal/nodes/Default/users/username.plist

  • Convert to xml

      plutil -convert xml1 username.plist
  • Grab the ShadowHashData key and base64 decode it (install base64 with port install base64)

      echo "Data from ShadowHashData Key" | base64 -d > ShadowHashData
  • Convert the resultant binary plist file into xml

      plutil -convert xml1 ShadowHashData
  • Grab the SALTED-SHA512 Key and base64 decode it

      echo "Data from SALTED-SHA512 Key" | base64 -d > hashfile

*Reveal hash:

    xxd -p -c 256 hashfile | cut -c 9-

Opening a user plist from 10.7 and getting the binary-encoded bit

    require 'facter/util/plist'
    users_plist = Plist::parse_xml(`plutil -convert xml1 -o /dev/stdout /var/db/dslocal/nodes/Default/users/brit_xml.plist`)
    password_hash_plist = users_plist['ShadowHashData'][0].string
    IO.popen('plutil -convert xml1 -o - -', mode='r+') do |io|
      io.write password_hash_plist
      @converted_plist =
    converted_hash_plist = Plist::parse_xml(@converted_plist)
    password_hash = converted_hash_plist['SALTED-SHA512'].string.unpack("H*")[0]
    puts password_hash

The problems here are that facter/util/plist cannot handle binary plists - so we need to convert them. Which sucks.

Using CFPropertyList

    require 'cfpropertylist'
    require 'base64'
    newplist = => 'demouser_edit.plist')
    newdata = CFPropertyList.native_types(newplist.value)
    bplist =
    bplistdata = CFPropertyList.native_types(bplist.value)
    password_hash = bplistdata['SALTED-SHA512'].unpack("H*")[0][8..-1]

Nate's Gist -->

user { 'testuser': ensure => 'present', comment => 'Demonstration User', gid => '20', home => '/Users/testuser', password => 'aaa6c1f945132d2599079fe90c9d20e608e607344b86328c1ef8ad8dc820c1bb5a31fd816b8ae546fed6dcf58ff023794f8250a66935d6d0687b737f24aae2ed', shell => '/bin/bash', uid => '1026', }

Can you do it in RubyCocoa without converting the plist with plutil? I can't seem to figure it out.


glarizza commented Jan 6, 2012

Updated plist to include revised/updated facter/util/plist method WITHOUT writing a file.
Thanks for the tip. Getting the password is simple, but storing it again is problem. There is a RubyCocoa bug in Lion that generates a Segmentation fault when trying to init an NSData object.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment