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-
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
io.close_write
@converted_plist = io.read
end
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.
require 'cfpropertylist'
require 'base64'
newplist = CFPropertyList::List.new(:file => 'demouser_edit.plist')
newdata = CFPropertyList.native_types(newplist.value)
bplist = CFPropertyList::List.new
bplist.load_binary_str(newdata['ShadowHashData'][0])
bplistdata = CFPropertyList.native_types(bplist.value)
password_hash = bplistdata['SALTED-SHA512'].unpack("H*")[0][8..-1]
Nate's Gist --> https://gist.github.com/1445697
user { 'testuser': ensure => 'present', comment => 'Demonstration User', gid => '20', home => '/Users/testuser', password => 'aaa6c1f945132d2599079fe90c9d20e608e607344b86328c1ef8ad8dc820c1bb5a31fd816b8ae546fed6dcf58ff023794f8250a66935d6d0687b737f24aae2ed', shell => '/bin/bash', uid => '1026', }
Updated plist to include revised/updated facter/util/plist method WITHOUT writing a file.