Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date: Mon, 11 Feb 2008 15:59:43 +1300
From: Russell Fulton <>
Subject: Re: extracting hashes from openldap for cracking

On 10/02/2008, at 6:09 PM, RB wrote:

> You should use that same Perl script to base64 decode them:
> {crypt}$1$FB98YJtW$/c5B1Uv5Q6nFUorti5Z4e1
> {crypt}$1$7tlOuzrV$qJhfuBZcB9w8Z38gg0Yl3.
> {crypt}$1$nOba6Dat$ZGI1XKaXEfDZadTRrnXxB0
> {crypt}$1$txtofhsU$huV7EEoOtvjdh9wLEKuz7.
> Those come out as FreeBSD MD5 on my system (less the '{crypt}', of
> course), and made it through single-crack and wordlist modes without
> breaking.

Works like a charm -- and I'm not going to admit how many accounts  
I've broken so far except to say that it was pretty bad.  I've found  
out that our service desk have been resetting passwords using simple  
passwords and telling users to change them.   Sigh...  The interface  
that the service desk used to reset passwords did not enforce  
complexity rules as does the password change interface used by the  
users :(

But then that's why we have audit tools like JTR.  This is yet another  
illustration of the problem of important but non urgent stuff not  
getting done. So to help anyone else out there who wants to audit  
openldap password here are a couple of simple perl scripts that I used  
to get the hashes out of ldap and into something that JTR could  
understand.  They almost certainly will not work for you out of the  
box because we use modified schema but the guts of the stuff is all  
there.  In particular we use upi (Unique Public Identifier) for  
account names.


#! /usr/biun/perl -w

use strict;
use MIME::Base64;

while( <> &&  ! eof) {    # need eof since we will hit eof on the  
other <>
     my( $uid, $passw, $cn, $dn);
     $cn = $uid = '';
     while( <> ) {    # get an object
	last  if /^\s*$/;     # object have blank lines between then
	if( /^cn: (.+)/ ) {
	    $cn = $1;
	}   elsif( /^dn: (.+)/ ) {
	    $dn =  $1;
	}   elsif( /^userP\w+:: (.+)/)  {
	    $passw= substr( decode_base64($1), 7);   # assuming {crypt}
	}   elsif( /^uid: (.+)/)  {
	    $uid = $1;
     print "$uid\:$passw\:\:\:$cn\n" if defined $passw;  # only output  
if object has password

run ladp search:

ldapsearch -D "<dn for root>" -w xxxxxx -b "<base dn for users>" ""  
userpassword uid cn | ldap2pw >

then feed to john

once you have a long list of account you want to disable feed the  
output from John to:

while( <> ) {
     my( $pass, $acc ) = /(\S+)\s+\(([^)]+)\)/;
     print "$acc :"
     system("ldappasswd  -D \"<dn for root>\" -w yyyyyyy \"uid= 
$acc,<base dn for user>\"");

To unsubscribe, e-mail and reply
to the automated confirmation request that will be sent to you.

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.