#!/usr/bin/perl # Version 1.0.8 Updated 2000-1-7 - Elvis' Birthday ###################################################### # This is provided As-Is with NO WARRANTY of any kind! # Use at your OWN RISK!!! # ---***--- Do NOT Run this from BBEdit !!! ---***--- # # BBEdit won't give you the chance to select the folder, # etc. and you will be stuck. #Hack to extract passwords from SIMS account files #Code snippets By Joe Laffey joe@laffeycomputer.com #Additional code and UI Ideas by #Karl Dubost #Additional date format idea #Rich Missey #Uses bad style, and is generally sloppy ;-) ###################################################### #### CONFIG HERE #### $use_tab_format = 1; #Set this to 1 to print in tab delimited format # Set to 0 for more human readable output $use_alternate_date_format = 1; #Set to 1 or zero depending on the date format you want #0 = Thu Jan 6 14:35:46 2000 #1 = 01/05 10:20:54 2000 # ^tab ##################### use Mac::Memory; use Mac::Files; use Mac::Resources; use Mac::StandardFile; use File::Find; my @listing; #holds the list of files sub AddFile { return if( -d $_ ); push( @listing, $_); $hash{$_} = $File::Find::name; } #Figure our TZ offset since SIMS stores dates in gmtime (undef, undef, $hour1) = localtime; #Is there a better way to find this offset ? (undef, undef, $hour2) = gmtime; $tzOffset = $hour1 - $hour2; #Could be negative or positive $secsOffset = $tzOffset * 3600; #seconds of offset require 'GUSI.ph'; #for the choose folder below -- stolen from MacPerl FAQ $folder = MacPerl::Choose(&GUSI::AF_FILE(), 0, "Find SIMS Accounts folder...", "", &GUSI::CHOOSE_DIR); exit(1) if( !defined($folder)); $reply = StandardPutFile("Where would you like the list?", "SIMS Accounts.txt"); exit(1) if( $reply->sfGood == false); FSpDelete($reply->sfFile); FSpCreate($reply->sfFile, 'R*ch', 'TEXT'); $outFileName = MacPerl::MakePath($reply->sfFile); open(OUTFILE, ">$outFileName") || die( "Could Not Open file $outFileName for writing"); #opendir(DIR, $folder) || die "can't opendir $folder: $!"; find (\&AddFile, $folder ); #find files @users = sort {uc($a) cmp uc($b)} grep(!/\@[LFR]$|^Icon$|^..?$/,@listing); #weed out the List files, ending with "@L" #closedir DIR; #also weed "@F" and "@R" and "Icon" files and sort case-insensitively #Loop over files foreach $user (@users) { #Open up the resource fork if ( defined($RFD = OpenResFile($hash{$user})) ) { #Load in the resource $myRes = GetResource("uUsT", 1); if ( defined $myRes ) { # The offsets are hard coded in here # if Stalker changes them you're SOL if($use_tab_format) { print OUTFILE "$user\t"; } else { print OUTFILE "UserID: $user"; } $nameLength = ord($myRes->get(46,1)); #length of real name if($use_tab_format) { print OUTFILE $myRes->get(47, $nameLength) . "\t"; #The real name } else { print OUTFILE "\nRealName: ". $myRes->get(47, $nameLength); #The real name } $passLength = ord($myRes->get(14,1)); #length of password if($use_tab_format) { print OUTFILE $myRes->get(15, $passLength) . "\t"; #The password } else { print OUTFILE "\nPassword: ". $myRes->get(15, $passLength); #The password } } else { print OUTFILE ("\n***Could not get the resource for $user\n"); } #Load in the second resource resource $myRes2 = GetResource("uVdT", 1); if ( defined $myRes2 ) { # The offsets are hard coded in here # if Stalker changes them you're SOL $accessTime =$myRes2->get(6,4); #length of the access time (32 bit) $timeInSecs = $secsOffset + unpack('L',$accessTime); if($use_tab_format) { if($use_alternate_date_format) { ($sec,$min,$hours,$day,$month,$year) = localtime($timeInSecs); printf OUTFILE ("%02d/%02d %02d:%02d:%02d\t%04d\n",$month+1,$day,$hours,$min,$sec,$year+1900) } else { print OUTFILE localtime($timeInSecs) . "\n"; } } else { print OUTFILE "\nLast Access: ". localtime($timeInSecs) . "\n\n"; } } else { #No 'uVdT' resource so the user never logged in if($use_tab_format) { print OUTFILE "Never\n"; } else { print OUTFILE "\nLast Access: Never\n\n"; } } #Cleanup CloseResFile $RFD; } else { print OUTFILE ( "\n***Could not open res file for $user. Perhaps it is busy.\n\n"); } } close(OUTFILE);