autopsy-2.24/0000755000076500000240000000000011355002266012457 5ustar carrierstaffautopsy-2.24/base/0000755000076500000240000000000011355002266013371 5ustar carrierstaffautopsy-2.24/base/.perltidyrc0000755000076500000240000000022111070040246015543 0ustar carrierstaff-i=4 # indent of 4 -pt=2 # paren tightness -sbt=2 # square paren tightness -bt=2 # curly paren tightness -nsfs # no space after semi in for loop autopsy-2.24/base/autopsy.base0000644000076500000240000005615411301344041015733 0ustar carrierstaff# # autopsy gui server # Autopsy Forensic Browser # # # This file requires The Sleuth Kit # www.sleuthkit.org # # # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2001-2005 by Brian Carrier. All rights reserved # # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # refer to Security Considerations in README for a description of the # cookie authentication # require 5.008; use strict; use Socket; use Main; use Print; require Fs; require Caseman; require 'conf.pl'; require 'lib/define.pl'; # Import variables from conf.pl use vars '$LOCKDIR', '$INSTALLDIR', '$PICTDIR'; use vars '$SANITIZE_TAG', '$SANITIZE_PICT'; use vars '$USE_STIMEOUT', '$STIMEOUT', '$CTIMEOUT'; use vars '$SAVE_COOKIE', '$GREP_EXE', '$FILE_EXE'; use vars '$NSRLDB'; # Default port my $port = 9999; # Default 'remote' host my $rema = 'localhost'; $| = 1; $::LIVE = 0; $::USE_NOTES = 1; $::USE_LOG = 1; sub usage { print "\n\nusage: $0 [-c] [-C] [-d evid_locker] [-i device filesystem mnt] [-p port] [remoteaddr]\n"; print " -c: force a cookie in the URL\n"; print " -C: force NO cookie in the URL\n"; print " -d dir: specify the evidence locker directory\n"; print " -i device filesystem mnt: Specify info for live analysis\n"; print " -p port: specify the server port (default: $port)\n"; print " remoteaddr: specify the host with the browser (default: $rema)\n"; exit 1; } my $cook_force = 0; my $vol_cnt = 0; # Were options given? while ((scalar(@ARGV) > 0) && ($ARGV[0] =~ /^-/)) { my $f = shift; # Evidence Locker if ($f eq '-d') { if (scalar(@ARGV) == 0) { print "Missing Directory\n"; usage(); } my $d = shift; # We need to do this for the tainting # We don't need to check for special characters in this case because # all commands will be run with the same permissions as the # original user. We will check for the obvious ';' though if ($d =~ /;/) { print "Illegal argument\n"; exit(1); } # If the path is relative, autopsyfunc will get screwed up when # this is run from a directory other than where autopsyfunc is # so force full paths elsif ($d !~ /^\//) { print "The evidence locker must be full path (i.e. begin with /)\n"; exit(1); } elsif ($d =~ /(.*)/) { $LOCKDIR = $1; } } # Force no cookie elsif ($f eq '-C') { $::USE_COOKIE = 0; $cook_force = 1; } # force a cookie elsif ($f eq '-c') { $::USE_COOKIE = 1; $cook_force = 1; } elsif ($f eq '-i') { $::LIVE = 1; $::USE_LOG = 0; $::USE_NOTES = 0; $::SAVE_COOKIE = 0; if (scalar(@ARGV) < 3) { print "Missing device, file system, and mount point arguments\n"; usage(); } my $vol = "vol" . $vol_cnt; $vol_cnt++; my $dev = shift; if ($dev =~ /($::REG_IMG_PATH)/) { $dev = $1; } else { print "invalid device: $dev\n"; usage(); } unless ((-e "$dev") || (-l "$dev")) { print "Device ($dev) not found\n"; usage(); } my $fs = shift; if ($fs =~ /($::REG_FTYPE)/) { $fs = $1; } else { print "invalid file system: $fs\n"; usage(); } unless ((exists $Fs::root_meta{$fs}) && (defined $Fs::root_meta{$fs})) { print "File system not supported: $fs\n"; usage(); } $Caseman::vol2ftype{$vol} = "$fs"; my $mnt = shift; if ($mnt =~ /($::REG_MNT)/) { $mnt = $1; } else { print "invalid mount point: $mnt\n"; usage(); } $Caseman::vol2mnt{$vol} = "$mnt"; $Caseman::vol2cat{$vol} = "part"; $Caseman::vol2itype{$vol} = "raw"; $Caseman::vol2start{$vol} = 0; $Caseman::vol2end{$vol} = 0; # This makes me nervous ... $Caseman::vol2par{$vol} = $vol; $Caseman::vol2path{$vol} = "$dev"; $Caseman::vol2sname{$vol} = "$dev"; } # Specify a different port elsif ($f eq '-p') { if (scalar(@ARGV) == 0) { print "Missing port argument\n"; usage(); } my $p = shift; if ($p =~ /(\d+)/) { $p = $1; } else { print "invalid port: $p\n"; usage(); } if (($p < 1) || ($p > 65535)) { print "invalid port: $port\n"; usage(); } $port = $p; } else { print "Invalid flag: $f\n"; usage(); } } # remote address if (scalar(@ARGV) > 0) { $rema = shift; } # Get remote address my @acl_addr; # Array of host addresses my $hn; # Host name my $tmp; if ($rema =~ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/) { $acl_addr[0] = pack('C4', ($1, $2, $3, $4)); $hn = $rema; } else { ($hn, $tmp, $tmp, $tmp, @acl_addr) = gethostbyname($rema); unless (defined $tmp) { print "Host not found: $rema\n"; usage(); } } # Determine the address that will be used to access this server my $lclhost; my @ta = unpack('C4', $acl_addr[0]); my $bindaddr; # If we are being accessed by localhost, we need that and not the hostname if ( ($ta[0] == 127) && ($ta[1] == 0) && ($ta[2] == 0) && ($ta[3] == 1)) { $lclhost = "localhost"; $bindaddr = $acl_addr[0]; # Force no cookie to be used unless we already set this value # with arguments $::USE_COOKIE = 0 unless ($cook_force == 1); } else { $lclhost = `/bin/hostname`; chop $lclhost; $bindaddr = INADDR_ANY; # Force a cookie to be used unless we already set this value # with arguments $::USE_COOKIE = 1 unless ($cook_force == 1); } # Verify the variables defined in the configuration files check_vars(); # Remove the final '/' from TSKDIR if it exists $::TSKDIR = $1 if ($::TSKDIR =~ /(.*?)\/$/); # # Verify that all of the required executables exist # check_tools(); # Currently, HFS is in beta and not enabled by default. # Autopsy has been configured for it though, so disable it if # the user has not compiled support into TSK. remove this when # HFS support is standard. # This redirects stderr to stdout so we can easily capture it my $out = `\'$::TSKDIR/fls\' -f list 2>&1`; unless ($out =~ /hfs/) { for (my $i = 0; $i < @Fs::types; $i++) { if ($Fs::types[$i] eq "hfs") { $Fs::types[$i] = ""; last; } } } # remove environment stuff that we don't need and that could be insecure # We allow basic bin directories for CYGWIN though, since they are # required for the CYGWIN dlls my $UNAME = ""; if (-e "/bin/uname") { $UNAME = "/bin/uname"; } elsif (-e "/usr/bin/uname") { $UNAME = "/usr/bin/uname"; } my $ispathclear = 1; if (($UNAME ne "") && (`$UNAME` =~ /^CYGWIN/)) { $ENV{PATH} = '/bin:/usr/bin:/usr/local/bin'; $ispathclear = 0; } else { $ENV{PATH} = ''; } delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; my $date = localtime; if ($::LIVE == 0) { # Remove the final '/' if it exists $LOCKDIR = $1 if ($LOCKDIR =~ /(.*?)\/$/); } # Setup socket my $proto = getprotobyname('tcp'); socket(Server, PF_INET, SOCK_STREAM, $proto) or die "Error creating network socket: $!"; setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, 1) or die "Error setting network socket options (reuse): $!"; setsockopt(Server, SOL_SOCKET, SO_KEEPALIVE, 1) or die "Error setting network socket options (keep alive): $!"; bind(Server, sockaddr_in($port, $bindaddr)) or die "Error binding to port $port (is Autopsy already running?): $!"; listen(Server, SOMAXCONN) or die "Error listening to socket for connections: $!"; my $magic; # magic authentication cookie my $cook_file; my $cookie_url = ""; if ($::USE_COOKIE == 1) { # Try for a real random device, or use rand if all else fails if (-e "/dev/urandom") { my $r; open RAND, "$cook_file") { chmod 0600, "$cook_file"; print COOK "$magic\n"; close COOK; } else { print "WARNING: Cannot open file to save cookie in ($cook_file)"; } } } print < to exit EOF2 Print::log_session_info("Starting session on port $port and $hn\n"); # Set the server alarm $SIG{ALRM} = \&SIG_ALARM_SERVER; $SIG{INT} = \&SIG_CLOSE; # setting this to ignore will automatically wait for children $SIG{CHLD} = 'IGNORE'; # Wait for Connections while (1) { alarm($STIMEOUT) if ($USE_STIMEOUT == 1); my $raddr = accept(CLIENT, Server); next unless ($raddr); my ($rport, $riaddr) = sockaddr_in($raddr); die "Error creating child" unless (defined(my $pid = fork())); if (0 == $pid) { open(STDOUT, ">&CLIENT") or die "Can't dup client to stdout"; # open(STDERR, ">&CLIENT") or die "Can't dup client to stdout"; open(STDIN, "<&CLIENT") or die "Can't dup client to stdin"; $| = 1; my @rip = unpack('C4', $riaddr); # Check ACL foreach $tmp (@acl_addr) { if ($tmp eq $riaddr) { spawn_cli($riaddr); close CLIENT; exit 0; } } forbid("$rip[0].$rip[1].$rip[2].$rip[3]"); Print::log_session_info("ERROR: Unauthorized Connection from: " . "$rip[0].$rip[1].$rip[2].$rip[3]\n"); close CLIENT; exit 1; } else { close CLIENT; } } # Error messages sub forbid { my $ip = shift; $ip = "" unless defined ($ip); print "HTTP/1.0 403 Forbidden$::HTTP_NL" . "Content-type: text/html$::HTTP_NL$::HTTP_NL" . "
\n" . "

Access Denied

\n" . "

Your connection from: $ip has been logged

\n" . "
$::HTTP_NL$::HTTP_NL$::HTTP_NL"; return; } sub bad_req { print "HTTP/1.0 404 Bad Request$::HTTP_NL" . "Content-type: text/html$::HTTP_NL$::HTTP_NL" . "
\n" . "

Invalid URL
" . shift() . "

\n" . "
" . "$::HTTP_NL$::HTTP_NL$::HTTP_NL"; return; } # Alarm Functions sub SIG_ALARM_CLIENT { Print::log_session_info("Connection timed out\n"); close CLIENT; exit 1; } sub SIG_ALARM_SERVER { print "Server Timeout ($STIMEOUT seconds), Exiting\n"; Print::log_session_info("Server Timeout ($STIMEOUT seconds), Exiting\n"); exit 0; } # Close the system down when Control-C is given sub SIG_CLOSE { # delete the cookie file if (($::USE_COOKIE == 1) && ($SAVE_COOKIE == 1)) { unlink "$cook_file"; } print "End Time: " . localtime() . "\n"; Print::log_session_info("Ending session on port $port and $hn\n"); exit 0; } # Pass the remote IP address as the argument for logging sub spawn_cli { # Set timeout for 10 seconds if we dont get any input alarm($CTIMEOUT); $SIG{ALRM} = \&SIG_ALARM_CLIENT; while () { last if (/^\s+$/); if (/^GET \/+(\S*)\s?HTTP/) { my $url = $1; my $script; my $args; if (/\x0d\x0a$/) { $::HTTP_NL = "\x0d\x0a"; } else { $::HTTP_NL = "\x0a"; } # Magic Cookie # If we are using cookies, then the url should be: # cookie/autopsy?var=val ... if ($::USE_COOKIE == 1) { if ( ($url =~ /^(\d+)\/+([\w\.\/]+)(?:\?(.*))?$/) && ($1 == $magic)) { $script = $2; $args = $3; } else { my @rip = unpack('C4', shift()); Print::log_session_info("ERROR: Incorrect Cookie from: " . "$rip[0].$rip[1].$rip[2].$rip[3]\n"); forbid("$rip[0].$rip[1].$rip[2].$rip[3]"); return 1; } } # if we aren't using cookies, then it should be: # autopsy?var=val ... else { if ($url =~ /^\/?([\w\.\/]+)(?:\?(.*))?$/) { $script = $1; $args = $2; } else { bad_req($url); return 1; } } if ($script eq $::PROGNAME) { $args = "" unless (defined $args); # Turn timer off alarm(0); my $has_ref = 0; while () { last if (/^\s+$/); if (/^Referer: /) { $has_ref = 1; last; } } if (($has_ref == 0) && ($args ne "")) { Print::log_session_info("ERROR: Missing referer value"); forbid(); return 1; } # Print status print "HTTP/1.0 200 OK$::HTTP_NL"; ::main($args); } elsif ($script eq "global.css") { show_file($script); } # Display the sanitized picture or reference error elsif ($script eq $::SANITIZE_TAG) { Appview::sanitize_pict($args); return 1; } # Display a picture or help file elsif (($script =~ /^(pict\/[\w\.\/]+)/) || ($script =~ /^(help\/[\w\.\/]+)/)) { show_file($1); } elsif ($script eq 'about') { about(); } # I'm not sure why this is needed, but there are reqs for it elsif ($script eq 'favicon.ico') { show_file("pict/favicon.ico"); } else { bad_req($url); Print::log_session_info("Unknown function: $script\n"); return 1; } return 0; } } # end of while (<>) } # end of spawn_cli # Print the contents of a local picture or help file sub show_file { my $file = "$INSTALLDIR/" . shift; if (-e "$file") { print "HTTP/1.0 200 OK$::HTTP_NL"; open FILE, "<$file" or die "can not open $file"; if ($file =~ /\.css$/i) { print "Content-type: text/css$::HTTP_NL$::HTTP_NL"; } elsif ($file =~ /\.jpg$/i) { print "Content-type: image/jpeg$::HTTP_NL$::HTTP_NL"; } elsif ($file =~ /\.gif$/i) { print "Content-type: image/gif$::HTTP_NL$::HTTP_NL"; } elsif ($file =~ /\.ico$/i) { print "Content-type: image/ico$::HTTP_NL$::HTTP_NL"; } elsif ($file =~ /\.html$/i) { print "Content-type: text/html$::HTTP_NL$::HTTP_NL"; } else { print "HTTP/1.0 404 Bad Request$::HTTP_NL" . "Content-type: text/html$::HTTP_NL$::HTTP_NL" . "\n" . "Error\n" . "

Unknown Extension

\n" . "$::HTTP_NL$::HTTP_NL$::HTTP_NL"; exit(1); } while () { print "$_"; } close(FILE); print "$::HTTP_NL$::HTTP_NL"; } else { print "HTTP/1.0 404 Bad Request$::HTTP_NL" . "Content-type: text/html$::HTTP_NL$::HTTP_NL" . "\n" . "Error\n" . "

File Not Found

" . "$::HTTP_NL$::HTTP_NL$::HTTP_NL"; exit(1); } return; } sub about { print "HTTP/1.0 200 OK$::HTTP_NL" . "Content-type: text/html$::HTTP_NL$::HTTP_NL"; my $tskver = ::get_tskver(); print < About Autopsy

About Autopsy


\"Logo\"

Version: $::VER
http://www.sleuthkit.org/autopsy/
http://www.sleuthkit.org/informer/

Credits

  • Code Development: Brian Carrier (carrier at sleuthkit dot org)
  • Interface Assistance: Samir Kapuria
  • Mascot: Hash the Hound

Configuration

The Sleuth Kit:
  URL: http://www.sleuthkit.org/sleuthkit/
  Installation Location: $::TSKDIR
  Version: $tskver
Evidence Locker: $LOCKDIR
grep: $GREP_EXE
file: $FILE_EXE
NIST NSRL: $NSRLDB
EOF return 0; } ### Check that the required tools are there sub check_tools { # Sleuth Kit execs unless (-x $::TSKDIR . "/icat") { print "ERROR: Sleuth Kit icat executable missing: $::TSKDIR\n"; exit(1); } unless (-x $::TSKDIR . "/istat") { print "ERROR: Sleuth Kit istat executable missing\n"; exit(1); } unless (-x $::TSKDIR . "/ifind") { print "ERROR: Sleuth Kit ifind executable missing\n"; exit(1); } unless (-x $::TSKDIR . "/ils") { print "ERROR: Sleuth Kit ils executable missing\n"; exit(1); } unless (-x $::TSKDIR . "/fls") { print "ERROR: Sleuth Kit fls executable missing\n"; exit(1); } unless (-x $::TSKDIR . "/ffind") { print "ERROR: Sleuth Kit ffind executable missing\n"; exit(1); } unless (-x $::TSKDIR . "/blkcat") { print "ERROR: Sleuth Kit blkcat executable missing\n"; exit(1); } unless (-x $::TSKDIR . "/blkcalc") { print "ERROR: Sleuth Kit blkcalc executable missing\n"; exit(1); } unless (-x $::TSKDIR . "/blkls") { print "ERROR: Sleuth Kit blkls executable missing\n"; exit(1); } unless (-x $::TSKDIR . "/img_stat") { print "ERROR: Sleuth Kit img_stat executable missing\n"; exit(1); } unless (defined $::FILE_EXE) { print "ERROR: File executable location not defined in config file\n"; exit(1); } unless (-x "$::FILE_EXE") { print "ERROR: File executable ($::FILE_EXE) missing\n"; exit(1); } unless (-x $::TSKDIR . "/fsstat") { print "ERROR: Sleuth Kit fsstat executable missing\n"; exit(1); } unless (defined $::MD5_EXE) { print "ERROR: MD5 executable location not defined in config file\n"; exit(1); } unless (-x "$::MD5_EXE") { print "ERROR: md5 executable ($::MD5_EXE) missing\n"; exit(1); } if ($::SHA1_EXE ne "") { unless (-x "$::SHA1_EXE") { print "ERROR: sha1 executable missing\n"; exit(1); } } unless (-x $::TSKDIR . "/srch_strings") { print "ERROR: Sleuth Kit srch_strings executable missing\n"; exit(1); } if ($::LIVE == 0) { unless (-x $::TSKDIR . "/sorter") { print "ERROR: Sleuth Kit sorter executable missing\n"; exit(1); } unless (-x $::TSKDIR . "/hfind") { print "ERROR: Sleuth Kit hfind executable missing\n"; print " You likely have an old version of The Sleuth Kit or TASK\n"; exit(1); } } unless (-x "$GREP_EXE") { print "ERROR: grep executable missing\n"; exit(1); } } # check values that should be defined in the configuration files # This will show incomplete installations sub check_vars { unless ((defined $::TSKDIR) && ($::TSKDIR ne "")) { print "ERROR: TSKDIR variable not set in configuration file\n"; print " This could been caused by an incomplete installation\n"; exit(1); } unless (-d "$::TSKDIR") { print "Invalid Sleuth Kit binary directory: $::TSKDIR\n"; exit(1); } return if ($::LIVE == 1); # Verify The evidence locker directory unless ((defined $LOCKDIR) && ($LOCKDIR ne "")) { print "ERROR: LOCKDIR variable not set in configuration file\n"; print " This could been caused by an incomplete installation\n"; exit(1); } unless (-d "$LOCKDIR") { print "Invalid evidence locker directory: $LOCKDIR\n"; exit(1); } } autopsy-2.24/base/make-live-cd.base0000644000076500000240000000721111303263001016451 0ustar carrierstaff# # This makes a directory ($CD) with the needed files to burn to # a CD for live analysis # # Current limitations are that Perl needs to be on the suspect system and # that it uses the untrusted Perl files. require 'conf.pl'; use vars '$USE_STIMEOUT', '$STIMEOUT', '$CTIMEOUT', '$SAVE_COOKIE'; use vars '$GREP_EXE', '$TSKDIR'; my $CD = "./live-cd/"; # Make the directories if (-d "$CD") { print "Live CD directory already exists ($CD)\n"; print "Plese delete and run this again\n"; exit (1); } print "Making base directory ($CD)\n"; die "Error making Live CD directory ($CD)" unless (mkdir "$CD", 0775); die "Error making Live CD binaries directory ($CD)" unless (mkdir "$CD/bin/", 0775); print "Copying executables\n"; # Copy the executables die "Missing grep executable ($GREP_EXE)" unless (-x "$GREP_EXE"); `cp '$GREP_EXE' '$CD/bin/grep'`; die "Error copying grep executable" unless (-x "$CD/bin/grep"); die "Missing MD5 executable ($::MD5_EXE)" unless (-x "$::MD5_EXE"); `cp '$::MD5_EXE' '$CD/bin/md5sum'`; die "Error copying MD5 executable" unless (-x "$CD/bin/md5sum"); # Sleuth Kit Binaries die "Missing Sleuth Kit Directory ($TSKDIR)" unless (-d "$TSKDIR"); foreach my $exec ("blkcalc", "blkcat", "blkls", "blkstat", "ffind", "fls", "fsstat", "icat", "ifind", "ils", "istat", "srch_strings", "img_stat", "mmls") { die "Missing Sleuth Kit executable ($exec)" unless (-x "$TSKDIR/$exec"); `cp '$TSKDIR/$exec' '$CD/bin/$exec'`; die "Error copying Sleuth Kit executable ($exec)" unless (-x "$CD/bin/$exec"); } # Make a fake file open FILE, ">$CD/bin/file" or die ("Error creating Live CD file exec"); print FILE "#!./bin/perl\n"; print FILE "print STDOUT \"File Type Not Supported During Live Analysis\n\";\n"; close FILE; `chmod +x "$CD/bin/file"`; # Copy the autopsy directories print "Copying autopsy files\n"; `cp -r help "$CD"`; `cp -r lib "$CD"`; `cp -r pict "$CD"`; # Get the path for Perl from the current autopsy open AUT, "<./autopsy" or die ("Error opening normal autopsy exec"); my $perl; while () { $perl = $_; last; } close AUT; if ($perl =~ /^#!(\S+)/) { $perl = $1; } else { die "Error parsing Perl location from autopsy" } # Copy the perl exec # @@@ I'm not sure if just copying the bin is enough ... die "Missing Perl executable ($perl)" unless (-x "$perl"); `cp '$perl' '$CD/bin/perl'`; die "Error copying perl executable" unless (-x "$CD/bin/perl"); # Make a new autopsy open AUT, ">$CD/autopsy" or die ("Error opening Live CD autopsy exec"); print AUT "#!./bin/perl -wT\n"; print AUT "use lib '.';\n"; print AUT "use lib './lib/';\n"; open BASE, "<./base/autopsy.base" or die ("Error opening base autopsy"); print AUT $_ while (); close (AUT); close (BASE); `chmod +x "$CD/autopsy"`; print "Creating configuration file using existing settings\n"; # Make the configuration file open CONF, ">$CD/conf.pl" or die ("Error opening Live CD Config file"); print CONF "# Configuration file for Live CD version of Autopsy\n"; print CONF "# http://www.sleuthkit.org/autopsy\n"; print CONF "# Created on ".localtime()."\n\n"; # Variables print CONF "\$USE_STIMEOUT = $USE_STIMEOUT;\n"; print CONF "\$STIMEOUT = $STIMEOUT;\n"; print CONF "\$CTIMEOUT = $CTIMEOUT;\n"; print CONF "\$SAVE_COOKIE = $SAVE_COOKIE;\n"; print CONF "\n"; print CONF "\$INSTALLDIR = './';\n"; print CONF "\$NSRLDB = '';\n"; print CONF "\$LOCKDIR = './read-only-live-version/';\n"; print CONF "\n"; print CONF "# System Utilities\n"; print CONF "\$GREP_EXE = './bin/grep';\n"; print CONF "\$FILE_EXE = './bin/file';\n"; print CONF "\$MD5_EXE = './bin/md5sum';\n"; print CONF "\$TSKDIR = './bin/';\n"; close CONF; print "\n"; autopsy-2.24/CHANGES.txt0000644000076500000240000006202311355002261014266 0ustar carrierstaff--------------------------- Version 2.24 -------------------------------- 3/22/10: Bug Fix: resolved issue 2950986 to support HFS directories. --------------------------- Version 2.23 -------------------------------- 2/12/10: bug fix: resolved issue 2950693 where previous searches were not shown if they used quotes. 2/12/10: bug fix: resolved issue 2932385 where wrong flag was being used to do only doing category searching" 2/12/10: bug fix: resolved issue 2779244 where wrong sorter path was being used. --------------------------- Version 2.22 -------------------------------- 10/27/09: Update: Change istat to use -B instead of -b (new change in TSK). 11/19/09: Update: Improved configure script process and error message for FILE_EXE check. 11/25/09: Fixed MD5 exe bug when building live CD 12/30/09: Fixed issue 2923857 re: cookie errors for the icon and css file links when cookies are used. --------------------------- Version 2.21 -------------------------------- 11/7/08: Bug Fix: Changed case management code to not error when 'dls ...' line was encountered. 11/14/08: Bug Fix: Fixed bug 2288406 (parsing of new fls -l format when file name searching and deleted file listing) --------------------------- Version 2.20 -------------------------------- 7/1/08: Update: Updated FAT sizes based on new "special" files. 7/9/08: Update: Updated NTFS processing for orphan files / removed ifind -p etc. 7/9/08: Update: Updated mactime and time formats to ISO formats. 9/13/08: Update: Changed usage to new TSK d* to blk* names. 9/26/08: Bug Fix: Input check on host was printing invalid host values w/out encoding HTML entities. Reported by Russ McRee. 10/01/08: Update: HFS support is enabled if TSK was compiled with support for it. 10/08/08: Bug Fix: Added some more HTML entity escaping to case management values (such as description). Reported by Daniel Medianero. 10/13/08: Update: Added perl version check back into configure, but used perl $] variable to do checking. Based on patch by Joerg Friedrich. --------------------------- Version 2.10 -------------------------------- 2/20/08: Bug Fix: Added 'tsk' to the path for sorter to find the 'images' config file. Reported by Russell Reynolds. 3/2/08: Update: Modified the adding of disk image process to save a call to mmls (reported by Pope). 3/2/08: Update: Added more basic control char filtering back into Print(). --------------------------- Version 2.09 -------------------------------- 2/4/07: Update: Bind only to localhost network if remote addr is local. Suggested by Markus Waldeck. 4/19/07: Bug Fix: Event sequencer notes for file did not have clock skew in the times. Reported by Len CulBreath. 12/21/07: Update: updated configure and install process for TSK 2.50 1/28/08: Update: Added NSRL support back in. --------------------------- Version 2.08 -------------------------------- 8/23/06: Bug Fix: The configure script did not like TSK directory names with a space in them. 8/23/06: Update: The PATH variable is not entirely cleared anymore. Instead, it is replaced by the basic bin directories (this was causing some problems with Cygwin). 8/31/06: Update: If Autopsy is running under Cygwin, then it will set the PATH to contain the basic bin directories. Otherwise, it is clear (original behavior). --------------------------- Version 2.07 -------------------------------- 3/15/06: Bug Fix: Caseman.pm had DATA_DIR instead of DATADIR and a concatenation error message occurred. Reported by Jason DePriest. 5/3/06: Update: Added support for ISO9660 file systems. 5/3/06: Update: Added support for AFF and AFD image formats. 5/03/06: Update: Added image format type to image details screen. 5/3/06: Update: Added hexdump view for file analysis and reports (initial patch by Patrick Knight). 5/3/06: Update: Changed number of dashes in reports to 70 instead of 62. 5/4/06: Update: Integrity checking disabled for non-raw image files until a specialized tool exists in TSK to abstract the embedded hash calculation. 5/8/06: Update: Added support for AFM files. --------------------------- Version 2.06 -------------------------------- 05/02/05: Fix: Typo in timeline creation window (reported by Surago Jones). 06/15/05: Update: Added css style sheet and changed some formatting. 08/13/05: Update: Added "utf-8" as HTML type so that TSK unicode output will be properly dispayed. 10/13/05: Update: Removed print_output() function contents because it broke the Unicode chars. 10/13/05: Update: Require 5.8 version of Perl now (in config and in source) because it has best Unicode support. --------------------------- Version 2.05 -------------------------------- 03/16/05: Update: Image name is given in the Image Details window when adding a new image file. (Suggested by Surago Jones). 03/17/05: Bug Fix: swap and raw host config entries could not be read after the conversion because of a regular expression bug in the read code. (Reported by Surago Jones) (BUG: 1165235) 03/21/05: Bug Fix: When a new host was added to a case with no investigator names, then it would prompt you to select a name from an empty list. (BUG: 1167970). 03/25/05: Update: Check return status of rename functions and print error if failed. 04/04/05: Bug Fix: A missing volume type message was reported when adding a disk image. The flow of add_img_prep was modified to ensure that it was set. (Reported by Bradley Bitzkowski) (BUG: 1177042) 04/08/05: Update: A thumbnail of images is shown when selected in the File mode. Suggested by and patch by Guy Voncken. --------------------------- Version 2.04 -------------------------------- 10/22/04: Update: Changed the way that NTFS lists directory contents. No longer lists the deleted entries from 'fls', only from 'ifind'. Reduces the inaccurate information. 02/XX/05: Update: Incorporated new TSK 2 features: - Disk images (split and raw) - new config file formats - moved images and output md5.txt file into one 03/01/05: Update: Changed behavior of some links that created new Autopsy Windows 03/05/05: Update: timeline output can be in comma delimited format 03/05/05: Update: Added SSN and credit card seach patterns from Jerry Shenk. 03/05/05: Update: Added temporal data when a note is creaed. 03/11/05: Update: Changed to new TSK names for srch_strings and img_stat 03/15/05: Update: improved handling of white space around investigator names and image names (suggested by Brian Baskin). --------------------------- Version 2.03 -------------------------------- 08/24/04: Update: Added SHA-1 hash to the metadata view. 09/01/04: Update: Added sstrings instead of local version of strings. 09/05/04: Update: Added more help text. 09/06/04: Update: Use the local version of file if TSK version is not found. 09/06/04: Update: Added links to the notes and events page after a note or event has been created. 09/06/04: Update: Added Unicode extract and search functionality using the 'sstrings' tool from TSK. --------------------------- Version 2.02 -------------------------------- 07/19/04: Bug Fix: print_err message in Caseman.lib did not have correct Print:: package, which caused an error (BUG: 994199). 07/29/04: Update: Added support for NTFS 'ifind -p' option to find deleted files that do not have a name in the parent directory. 07/29/04: Update: Added a filter to remove duplicate entries from a file listing. Duplicate names with the same name and meta address are removed. 07/29/04: Update: OS X no longer needs the strings script, Autopsy will adjust for the different flags. 07/29/04: Update: When a deleted file name is entered into the find directory box, the recover bit is set so the full contents are shown. --------------------------- Version 2.01 -------------------------------- 03/29/04: Update: Changed text for the data integrity option when adding a new image. 04/20/04: Bug Fix: Fixed error that occured when data browsing with a raw or swap image. The TSK usage for these file system types was inconsistent and it was fixed in version 1.69. (BUG: 925382). (Reported by Harald Katzer) 05/03/04: Update: Changed regular expression in META so that the new recovery listing in FAT istat will not show up as a hyperlink. 05/03/04: Update: Removed usage of '-H' with 'icat' in File.PM. 05/20/04: Bug Fix: Fixed the incorrect error message that was printed when installing autopsy with a newer version of TSK than 1.68. (BUG: 938909) 05/20/04: Update: Added new feature that allows perl regular expressions to be used to find file names. 05/20/04: Update: Added file recovery features to File.pm, Meta.pm, and Appview.pm. 05/27/04: Update: Added a space to $REG_ZONE2 so that CYGWIN would work if no zone was given (Marcus Muller). /05/27/04: Update: Added 'p' as an option for the type of a file in the 'fls' output and made the $::REG_MTYPE global for the pattern. 05/28/04: Update: Cleaned up code so that commands and directories do not have double slashes (//) sometimes. This caused problems with CYGWIN (reported by Marcus Muller). 05/28/04: Bug Fix: Keyword search of unallocated space would link to incorrect data unit (although the address was correct). (Reported by Jorge Ortiz, David Perez, Raul Siles). (BUG: 962410). 05/28/04: Update: Updated dcat usage and syntax to reflect changes to TSK. 05/28/04: Update: Changed the messages printed when multiple data units were displayed. Now the number of units or range are given instead of number of bytes. --------------------------- Version 2.00 -------------------------------- 11/25/03: Update: made evidence locker directory names constant (define.pl) 11/25/03: Update: Started process of re-architecture 12/2/03: Update: Replaced logo.jpg with Hash the Hound 12/7/03: Update: Added favicon.ico with Hash 01/06/04: Update: Changed command line arguments 01/24/04: Update: made it only a warning if cookie file can't be opened 02/15/04: Update: Timezone is now optional. Defaults to local if not given. 02/15/04: Update: Timezone value optional in () in file listing (prevents parsing errors if incorrect timezone is given 03/16/04: Bug Fix: Fixed zombie problem by ignoring child signal (BUG: 860186) Reported by Angus Marshall. 03/18/04: Update: New layout for adding cases, hosts, and images. 03/18/04: Update: changed HTML to use lowercase values instead of all caps. 03/18/04: Update: New windows are no longer opened when changing modes. 03/19/04: Release: Big release with a new redesign and a few other changes (live analysis) --------------------------- Version 1.75 -------------------------------- 09/22/03: Update: Changed the internal 'get_' functions that parse the URL arguments to error instead of just return 0 when a problem occurs. 10/22/03: Bug Fix: Check for an investigator name before trying to log to the exec log. This is a problem when indexing a hash database, an error message is printed because of the null string. reported by Brian Baskin. 11/10/03: Update: Improved error message when strings can't be parsed. (Bug: 823081) 11/15/03: Update: Improved messages in installation script 11/15/03: Bug Fix: Added 'defined' checks to command output to prevent string errors when command fails. (BUG 842824) 11/15/03: Update: Added 'HEIGHT' value to HTML images to make images align better and load faster and with the right size 11/15/03: Update: Added a timer so that a char is printed every 5 seconds during keyword searching, file type sorting, and MD5 for images. --------------------------- Version 1.74 -------------------------------- 08/03/03: Bug Fix: Notes could not be added for some files because the HTML code was missing a closing bracket. 08/18/03: Bug Fix: added POSIX:settz() because some versions of Perl do not use the most recent ENV{TZ} variable when running 'localtime'. This cause some incorrect times for events in the sequencer. 08/19/03: Update: NSRL is no longer used with 'sorter' until it is easier to identify which files in the NSRL are known good and which are known bad. 08/20/03: Update: Added support for swap and raw images for searching and data unit analysis. 08/20/03: Update: Added the unit size to the display of the Data Unit mode. 08/20/03: Update: Search for perl5.6.0 first during install 08/21/03: Update: Changed use of backticks to pipes for executing commands 08/21/03: ?: Added a 'sleep(1)' to the pipe to prevent the loss of data that can be seen with perl5.8.0 in the buffer. This should be fixed in a better way though. 08/21/03: Update: The exact command executed is now saved to the log directory. 08/21/03: Update: Changed 'date' regexp to make year optional. 08/22/03: Update: Added warning if Perl 5.8 is used because of the buffer problem. 08/22/03: Bug Fix: Fixed some keyword escape values in the search mode. 08/22/03: Update: Added a new help page on the limitations of keyword searching. 08/22/03: Update: Moved the unallocated space and strings file creation to the Image Details view instead of the keyword search window (suggested by: Paul Bakker) 08/25/03: Update: improved wording of the Add Image window to better explain the mounting point. 08/26/03: Update: When adding sequencer notes in manually, the time is set to the last note entered to make it easier to add notes from logs and external sources. 08/26/03: Update: The keyword search display has a final clause that prints the results even if they are not found in the 'index' method. This prevents any hits from being lost during the analysis of the output. 08/26/03: Bug Fix: strings less than 4 chars would not be found before because 'strings' only shows strings that are 4 or more in length 08/28/03: Update: if more than 1000 keyword hits are found, then a message is reported and the user must choose a new keyword. This prevents the browser from hanging from a huge HTML table. 08/28/03: Update: A '.' is printed during the keyword search for each 100 hits as a status update. --------------------------- Version 1.73 -------------------------------- 06/10/03: Bug Fix: The '-i day' was not added to the mactime code and caused an error (reported by Cathy Buckman) --------------------------- Version 1.72 --------------------------------- 04/09/03: Bug Fix: The Java Script check on the main page broke in 1.71 because the document.write was on multiple lines 04/11/03: Bug Fix: Keyword Search False Hit code had a bug that it would be printed in error and message was improved 04/22/03: Update: Added examples to case management help file 05/06/03: Bug Fix: calc_md5 did not need 'o' tag on end of regular expression because it would not work if the method was called more than once. (Paul Bakker) 06/01/03: Bug Fix: Some keyword searches with $ in it were failing 06/01/03: Update: Keyword searches are now saved to a file and can be found in the keyword seach main menu 06/01/03: Update: Changed the format a little of the keyword search menu 06/01/03: Update: Added grep cheat sheet 06/03/03: Update: Tables now have alternating colors for file listing and timeline viewing 06/03/03: Update: Sequencer mode added 06/03/03: Update: Sequencer help file added 06/04/03: Bug Fix: Added 'LANG=C LC_ALL=C' to sorter & mactime to prevent UTF-8 errors (Debugging help from Daniel Schwartzer) 06/04/03: Bug Fix: The regular expression for viewing timelines did not allow multiple users to have the same UID (reported by Cathy Buckman) 06/05/03: Update: Added button for Event Sequencer and added tables to the standard notes reading window 06/09/03: Update: Added '-i day' flag to mactime for new feature in The Sleuth Kit --------------------------- Version 1.71 --------------------------------- 02/27/03: Bug Fix: Regular expression searches w/out a strings file had problems because the '-n' value was being incorrectly calculated. 03/17/03: Update: Added more logging to investigator log 03/17/03: Bug Fix: The case opening was not being logged in the case log 03/17/03: Update: The current 'mode' tab is also a hyperlink now 03/17/03: Bug Fix: Fixed bug that did not allow the path for a strings file to have a space in it. 03/17/03: Update: When no port and remote address are given on the command line, port 9999 and localhost are used. Documents also updated to reflect new syntax. 03/18/03: Update: Use the 'x' repetition operator for ASCII reports instead of a row of dashes. 03/18/03: Update: Added tag to MAIN_FR and incorporated more '<<EOF' HTML code. 03/19/03: Update: Added $FIL_NAME function that translates a name to a meta data address using 'ifind -n' 03/19/03: Update: A directory name can be entered in the $FIL_DIR frame now to jump to a directory or file 03/19/03: Update: The directory path in $FIL_LIST was changed to have hyperlinks that allow one to jump to a previous directory (using $FILE_NAME) 03/19/03: Update: Cleaned up HTML code in $FIL_LIST 03/20/03: Update: passwd and group files are now imported in timelines by selecting the image - no more inode values 03/20/03: Update: Cleaned up HTML code in timeline section 03/21/03: Update: Added '-z' flag to usage of 'file' so that comressed files are opened. 03/21/03: Bug Fix: Some special values needed to be escaped in the grep keyword search (for non regular expressions) (\.]^$"-). 03/24/03: Update: Changed how images are added (symlinks, copies, or moves). 03/24/03: Update: Added a file system sanity check when adding one 03/27/03: Update: Added a check to the 'File Type' mode that extracts just graphic images and makes thumbnails. 03/27/03: Update: Added '-i' flag when 'mactime' is run to create the summary file for timelines. 03/27/03: Update: Added link to summary page with hyper links to actual month for timelines 03/27/03: Update: Added more HTML table columns for date in timeline view 03/27/03: Update: Made the 'ifind' process optional in Data Unit and key word searching mode (makes browsing faster) 03/27/03: Update: Evidence Locker now contains entries for when a case is created or opened. 03/30/03: Update: Improved the help file for time lines. 03/31/03: Update: Changed addresses to sleuthkit.org --------------------------- Version 1.70 --------------------------------- Interface Changes: - Too many to note individually - New windows are created when modes or images are changed - Improved error messages - Can load the unallocated image in the Data Unit Mode - Case management 12/10/02: Update: Help is now a directory and contents can be viewed at any time. 01/02/03: Update: Added support for sorter and hfind tools in TASK 01/02/03: Update: NSRL now requested at startup 01/02/03: Update: Alert and exclude hash databases are options when making a new host now 01/09/03: Update: Carriage Returns are now sent if it is a Windows client 01/09/03: Update: Improved the pre-defined IP keyword search expression 01/10/03: Update: Changed use of "_new" as target to "_blank" 01/28/03: Update: Installation and other system directories can now have spaces and other symbols in them (Dave Goldsmith) --------------------------- Version 1.62 --------------------------------- 10/07/02: Update: Added File Type to block mode 10/07/02: Update: Can now add notes to 'dls' image blocks 10/07/02: Update: One can now view as many consecutive data units as they want in data mode. Many other changes and updates were done with this as well. (inspired by the Honeynet sotm) 10/07/02: Update: The File System details view for FAT now has hyperlinks to view the run and follow to the next run. 10/09/02: Bug Fix: Removed use of 'use integer' so that large blocks do no turn into '-1' when doing a keyword search (Michael Stone - Loyola) --------------------------- Version 1.61 --------------------------------- 08/28/02: Update: White space is allowed at the begining of the morgue file 08/28/02: Bug Fix: No error is generated if md5.txt does not exist from main menu 08/28/02: Update: Improved error messages 08/28/02: Update: Added code to Main Menu to check for Java Script turned on 09/19/02: Update: fsmorgue can be a symlink in the morgue directory --------------------------- Version 1.60 --------------------------------- - Changed NTFS c-time to Changed from Created (5/20/02) - Fixed a couple little bugs with parsing NTFS output (5/20/02) - Improved sorting (name is case insensitive and name is used as secondary sorting index) (5/20/02) - Improved error messages of invalid input to inode & block mode - Added ability to import password and group files when making a time line (5/28/02) - Fixed bug that did not allow IP addresses to be used for the ACL when DNS was not available (5/30/02) - Fixed some issues to make Internet Explorer not complain so much (05/30/02) - Improved the logging so that one can retrace their actions (05/31/02) - Moved autopsy.log to logs directory (05/31/02) - Added ability to write Notes about a given block, inode, or file (06/04/02) (suggestion by Dave Dittrich) - Set default investigators name (an error was generated if no name was given) (06/04/02) - Added links in the help page to the window help pages (06/05/02) - Updated timeline to reflect new format in new TASK (06/19/02) - Added '-C' flag to turn off cookies on command line (06/20/02) - Added new main menu (06/20/02) - Made MD5 generation 'opt-out' (06/22/02) - New code to remove duplicate entries in md5.txt and fsmorgue - fsmorgue can have whitespace at end of line (7/6/02) - An error is generated if an image in fsmorgue does not exist (7/6/02) - updated automatic date search (7/9/02) - New feature allows one to save the MD5 values of all files in a directory, which makes the Solaris Finger Print Database easier (7/12) --------------------------- Version 1.50 --------------------------------- - Modified to support TASK instead of TCT and TCTUTILs (8/25/01) - Removed chmod 'bug' for the cookie file (8/25/01) - Fixed number of hits bug in Search mode (off by one) (8/25/01) - Added ftype support (8/28/01) - Added ftype field to reports (8/28/01) - Encoded dir arg in FIL_DEL - Filter option holds for usage of next and rev in block mode - If using fat, a separate option is given to run find_inode due to how slow it runs - removed use of zoneinfo in favor of the new timezone value in fsmorgue. - strings now uses '-a' flag to show all strings - When doing a search, the length of the string is given as the '-n' flag to strings to speed up the search - Allow user to "force" blocks when an inode size is 0 (the istat -b flag) - use the md5 that comes with TCT/TASK - multiple images with the same mounting point can now exist - Added the morgue directory to the MENU to make it easier to manage multiple hosts - Files are sorted by name by default - can import strings files and create them if needed - Run files through 'file' to get data type - case insensitive searches - MAC headers correspond to file system type (create vs change) - Deleted files are displayed in red - Correct address name used (fragment, sector etc.) - Support for NTFS attributes - parse bad tags from HTML when viewing it (send sterile pict) - cookie file has port number to aid in scripting - cookie files are deleted upon closing - log messages are printed for each request - added integrity checker - renamed aux directory to base to make Windows happy - added time line support - added fsstat support - Added built-in search values in search.pl May 29, 2001 1.01 released - Fixed Hex link when in search mode (3/23/01) - Corrected heading of ctime (Addam Schroll, Purdue University) (4/24/01) - Parses output of new istat correctly (5/1/01) - When viewing 'inode as a file', the image and inode are sent as the dir name (5/1/01) - Added wait() to collect zombies in Linux (5/22/01) - Added auto-flush to prevent repeat log entries (5/22/01) - Added a 'save as' option to file and inode browsing (Addam Schroll) (5/22/01) - Added option for unrm block numbers (due to blockcalc) (5/22/01) - Improved side menu for inode, block, and search (5/22/01) - Added "Content-Disposition" so that reports and "save as" have a unique default filename. (5/23/01) - Organization changes to Main Menu (5/24/01) - Automated installation process (5/24/01) March 19, 2001 1.0 released - Added man page for autopsy (3/10/01) - Directory entries in config files no longer require an / at the end - Morgue file names can have a '.' in them (but still not '/') (3/10) - autopsy first checks for /dev/urandom for random cookie (3/10/01) - morgue directory is a command line option to autopsy (3/10/01) - the lib variable in autopsy is no longer set to './' so that it can be run outside of /usr/local/autopsy (3/10/01) - changed all references of device to image (3/11/01) - changed all reports to print full image path (3/11/01) - Investigator is a command line option to autopsy (3/11/01) - CGI support removed. Only autopsy is supported (3/16/01) - renamed autopsyd to autopsy (3/16/01) - Fixed UID and GID heading (3/16/01) - Run image through strings before grep to prevent memory errors (3/16/01) - output of find_file and find_inode is prepended with rdir (3/16/01) Feb 27, 2001 0.2b released - Added stand alone server, autopsyd (as suggested by Dan Farmer) - Reorganized files due to new program - Changed names of some executables that changed in TCTUTILs Feb 19, 2001 0.1b released ------------------------------------------------------------------------ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/configure������������������������������������������������������������������������������0000755�0000765�0000024�00000032203�11355002261�014361� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh # Minimum version of TSK that is required minver="3.1.0"; # The last released version of TSK curtskver="3.1.1"; # Configuration script for the Autopsy Forensic Browser # # Brian Carrier [carrier@sleuthkit.org] # # Copyright (c) 2003-2008 by Brian Carrier. All rights reserved # # Copyright (c) 2001-2003 by Brian Carrier, @stake. All rights reserved # # Copyright (c) 2001 by Brian Carrier. All rights reserved # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Directories to search in dirs='/usr/local/bin/ /usr/bin/ /usr/ccs/bin/ /bin/ /usr/ucb/bin/ /sbin/ /usr/sbin/ /usr/local/sbin/' echo "" echo " Autopsy Forensic Browser Installation" echo "" ############################################################################# # create conf.pl ############################################################################# conf='conf.pl' rep="" if (test -f $conf) then echo "A configuration file already exists, overwrite? (y/n):"; read rep; else rep="y" fi if (test "$rep" = "y") then # First add the variables that are static # # DEFAULT USER SETTINGS # echo '# Autopsy configuration settings' > $conf echo '' >> $conf echo '# when set to 1, the server will stop after it receives no' >> $conf echo '# connections for STIMEOUT seconds. ' >> $conf echo '$USE_STIMEOUT = 0;' >> $conf echo '$STIMEOUT = 3600;'>> $conf echo '' >> $conf echo '# number of seconds that child waits for input from client' >> $conf echo '$CTIMEOUT = 15;' >> $conf echo '' >> $conf echo '# set to 1 to save the cookie value in a file (for scripting)' >> $conf echo '$SAVE_COOKIE = 1;' >> $conf ############################################################################# # INSTALLATION DIRECTORY ############################################################################# echo '' >> $conf; echo \$INSTALLDIR = \'$PWD/\'\; >> $conf; # Now add the variables that need user interaction # # FIND THE UTILITIES # echo '' >> $conf echo '' >> $conf echo '# System Utilities' >> $conf # # GREP # echo '' echo '---------------------------------------------------------------' echo '' found=0 for d in $dirs do if (test -x ${d}grep) then echo \$GREP_EXE = \'${d}grep\'\; >> $conf; echo "grep found: ${d}grep"; grepexe="${d}grep"; found=1; break; fi; done # Prompt if not found if (test $found -eq 0) then echo 'ERROR: grep utility not found'; echo 'Enter location of executable:'; while (test 1 -eq 1) do read grepexe; if (test -x "$grepexe") then echo \$GREP_EXE = \'$grepexe\'\; >> $conf; break; else echo 'grep was not found (try again):'; fi; done fi # # FILE # found=0 for d in $dirs do if (test -x ${d}file) then echo \$FILE_EXE = \'${d}file\'\; >> $conf; echo "file found: ${d}file"; found=1; break; fi; done # Prompt if not found if (test $found -eq 0) then echo 'ERROR: file utility not found'; echo 'Enter location of executable:'; while (test 1 -eq 1) do read fileexe; if (test -x "$fileexe") then echo \$FILE_EXE = \'$filexe\'\; >> $conf; break; else echo 'file was not found (try again):'; fi; done fi # # MD5 # found=0 for d in $dirs do if (test -x ${d}md5) then echo \$MD5_EXE = \'${d}md5\'\; >> $conf; echo "md5 found: ${d}md5"; found=1; break; elif (test -x ${d}md5sum) then echo \$MD5_EXE = \'${d}md5sum\'\; >> $conf; echo "md5 found: ${d}md5sum"; found=1; break; fi; done # Prompt if not found if (test $found -eq 0) then echo 'ERROR: md5/md5sum utility not found'; echo 'Enter location of executable:'; while (test 1 -eq 1) do read md5exe; if (test -x "$md5exe") then echo \$MD5_EXE = \'$md5exe\'\; >> $conf; break; else echo 'md5 was not found (try again):'; fi; done fi # # SHA-1 # found=0 for d in $dirs do if (test -x ${d}sha15) then echo \$SHA1_EXE = \'${d}sha\'\; >> $conf; echo "sha1 found: ${d}sha1"; found=1; break; elif (test -x ${d}sha1sum) then echo \$SHA1_EXE = \'${d}sha1sum\'\; >> $conf; echo "sha1 found: ${d}sha1sum"; found=1; break; fi; done if (test $found -eq 0) then echo 'WARNING: sha1/sha1sum utility not found'; echo \$SHA1_EXE = \'\'\; >> $conf; fi; ############################################################################# # The Sleuth Kit ############################################################################# echo '' >> $conf echo '' >> $conf echo '# Directories' >> $conf echo '' echo '---------------------------------------------------------------' echo '' echo 'Searching for Sleuth Kit Installation.' found=0 for d in $dirs do if ((test -x ${d}fls) && (test -x ${d}ffind) && (test -x ${d}blkstat) && \ (test -x ${d}blkls) && (test -x ${d}blkcat) && \ (test -x ${d}mmls) && (test -x ${d}mmstat) && \ (test -x ${d}fsstat) && (test -x ${d}img_stat) && \ (test -x ${d}istat) && (test -x ${d}ifind) && \ (test -x ${d}icat) && (test -x ${d}ils) && \ (test -x ${d}srch_strings) && \ (test -x ${d}mactime) && (test -x ${d}sorter)) then echo \$TSKDIR = \'${d}\'\; >> $conf; tskdir=${d}; echo "Found in: ${d}"; found=1; break; fi; done if (test $found -eq 0) then echo 'Sleuth Kit tools were not found in the standard install locations.' echo 'If you have not installed them, do so now and configure autopsy again.' echo 'If you have installed them in a non-standard location, then' echo ' enter the "bin" directory now:' while (test 1 -eq 1) do read tskdir; if ((test -x ${tskdir}/fls) && (test -x ${tskdir}/ffind) && (test -x ${tskdir}/blkstat) && \ (test -x ${tskdir}/blkls) && (test -x ${tskdir}/blkcat) && \ (test -x ${tskdir}/mmls) && (test -x ${tskdir}/mmstat) && \ (test -x ${tskdir}/fsstat) && (test -x ${tskdir}/img_stat) && \ (test -x ${tskdir}/istat) && (test -x ${tskdir}/ifind) && \ (test -x ${tskdir}/icat) && (test -x ${tskdir}/ils) && \ (test -x ${tskdir}/srch_strings) && \ (test -x ${tskdir}/mactime) && (test -x ${tskdir}/sorter)) then echo \$TSKDIR = \'${tskdir}\'\; >> $conf; break; else echo 'TSK tools were not found or incomplete (try again):'; fi; done fi; # Test for latest version ver=`"${tskdir}/fls" -V | awk '/The Sleuth Kit ver / {print $5}'`; echo " Version $ver found"; if (test "$ver" '<' "$minver") then echo "Your version of The Sleuth Kit is not current enough - $minver is needed"; if (test "$ver" '>' "0.0.0") then exit 1; fi; elif (test "$ver" '<' "$curtskver") then echo ''; echo "*** NOTE: A more recent version ($curtskver) of The Sleuth Kit Exists ***" echo " [Press Enter to Continue]"; read foo; else echo ' Required version found'; fi # NSRL echo '' echo '---------------------------------------------------------------' echo '' echo 'The NIST National Software Reference Library (NSRL) contains' echo 'hash values of known good and bad files.' echo ' http://www.nsrl.nist.gov' echo '' echo 'Have you purchased or downloaded a copy of the NSRL (y/n) [n]' read rep; if (test "$rep" = "y") then echo 'Enter the directory where you installed it:' while (test 1 -eq 1) do read nsrldir; if (test "$nsrldir" = "cancel") then echo \$NSRLDB = \'\'\; >> $conf; break; fi; if (test -f "${nsrldir}/NSRLFile.txt") then echo ' NSRL database was found (NSRLFile.txt)'; echo \$NSRLDB = \'${nsrldir}/NSRLFile.txt\'\; >> $conf; if (test -f "${nsrldir}/NSRLFile.txt-md5.idx") then echo ' NSRL Index file found (NSRLFile.txt-md5.idx)'; else echo ' NSRL Index file not found, do you want it created? (y/n) [n]:' read rep; if (test "$rep" = "y") then echo '' echo '-------------- begin hfind output --------------' "${tskdir}/hfind" -i nsrl-md5 "${nsrldir}/NSRLFile.txt"; echo '--------------- end hfind output ---------------' echo '' fi; fi; break; else echo 'The NSRL was not found (the directory should have NSRLFile.txt in it)'; echo 'Enter a new directory (or cancel to stop):'; fi; done else echo \$NSRLDB = \'\'\; >> $conf; fi; ############################################################################# # EVIDENCE LOCKER ############################################################################# mdone=0 echo '' echo '---------------------------------------------------------------' echo '' echo 'Autopsy saves configuration files, audit logs, and output to the' echo 'Evidence Locker directory.' echo '' echo 'Enter the directory that you want to use for the Evidence Locker:'; read locker; if (test -d "${locker}") then echo " $locker already exists" else echo ''; echo "WARNING: $locker does not exist" mdone=1 fi echo \$LOCKDIR = \'${locker}\'\; >> $conf; fi # Start of non-conf.pl file configuration ############################################################################# # Setup Perl locations ############################################################################# found=0; for d in $dirs do if (test -x ${d}perl) then if (test -n "`${d}perl -v 2> /dev/null | awk '/This is perl/ {print $0}'`") then ver=`${d}perl -e 'print $];'`; if (`${d}perl -e 'exit( $] >= 5.008);'`) then echo "old version of perl found: ${d}perl (version $ver) -- continuing"; else echo "perl found: ${d}perl (version $ver)"; echo "#!${d}perl -wT" > ./config.tmp; echo "#!${d}perl" > ./config2.tmp; perlexe="${d}perl"; found=1; break; fi; fi; fi; done # If it wasn't found, then prompt for it. if (test $found -eq 0) then echo 'ERROR: perl not found or the incorrect version found'; while (test 1 -eq 1) do echo 'Enter location of perl executable:'; read perlexe; if (test -x "$perlexe") then if (test -n "`$perlexe -v 2> /dev/null | awk '/This is perl/ {print $0}'`") then ver=`$perlexe -e 'print $];'`; if (`$perlexe -e 'exit( $] >= 5.008);'`) then echo "This version of Perl is too old, 5.8.0 or older needed"; else echo "Correct version found"; echo "#!${perlexe} -wT" > ./config.tmp; echo "#!${perlexe}" > ./config2.tmp; found=1; break; fi; else echo "Perl found, but is not working. Try another"; fi; else echo "file not found"; fi done fi # Check if this version of Perl supports large files if (test -z "`$perlexe -V 2> /dev/null | awk '/USE_LARGE_FILES/ {print $0}'`") then echo '' echo ' NOTE: It appears that your Perl does not support large files.'; echo ' You therefore will not be able to analyze images larger than 2GB.'; echo ' Download the source version from www.cpan.org and compile a new version.'; echo " [Press Enter to Continue]"; read foo; echo '' fi; # Get current working directory for lib echo "use lib '$PWD/';" >> ./config.tmp echo "use lib '$PWD/lib/';" >> ./config.tmp if (test -f ./autopsy) then echo "autopsy already exists, overwrite? (y/n):"; read rep; if (test "$rep" = "y") then cat ./config.tmp base/autopsy.base > ./autopsy cat ./config2.tmp base/make-live-cd.base > ./make-live-cd else echo ' original version was kept'; fi else cat ./config.tmp base/autopsy.base > ./autopsy cat ./config2.tmp base/make-live-cd.base > ./make-live-cd fi chmod 0755 ./autopsy chmod 0755 ./make-live-cd # cleanup rm -f ./config.tmp rm -f ./config2.tmp ############################################################################# # CLEANUP ############################################################################# echo '' echo '---------------------------------------------------------------' echo '' echo "Execute the './autopsy' command to start with default settings." echo '' ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/COPYING��������������������������������������������������������������������������������0000644�0000765�0000024�00000043131�11070040246�013506� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. <one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. <signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/docs/����������������������������������������������������������������������������������0000755�0000765�0000024�00000000000�11355002264�013405� 5����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/docs/sleuthkit-informer-13.txt���������������������������������������������������������0000644�0000765�0000024�00000041707�11070040246�020227� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ The Sleuth Kit Informer http://www.sleuthkit.org/informer http://sleuthkit.sourceforge.net/informer Brian Carrier carrier at sleuthkit dot org Issue #13 March 15, 2004 CONTENTS -------------------------------------------------------------------- - Introduction - What's New? - Call For Papers - Did You Know? - UNIX Incident Verification With Autopsy INTRODUCTION -------------------------------------------------------------------- I'm almost done! Releasing version 2.00 of Autopsy that is. I'm polishing up the final changes and documentation and it will be released later this week. March 19 is the birthday of Autopsy and The Sleuth Kit's predecessor, TCTutils, also the goal release date for version 2.00. This issue of the Informer will focus on the new live analysis feature of (the unreleased) Autopsy. This issue also has a lot entries in the "What's New?" category because we are on a bimonthly schedule. If you missed getting the February issue of The Informer and have lessons to share with people then make sure you read the Call For Papers section so that you can learn how to submit articles of your own. WHAT'S NEW? -------------------------------------------------------------------- A new version (1.68) of The Sleuth Kit was released. It contains a couple of bug fixes. There have been discussions on the sleuthkit-developers list about what new functions should be added to the next big version 2.00 release. Michael Cohen has been looking into support for disk images, split images, RAID images, and other non-raw formats. David Collett has been looking into output formats for TSK tools so that they can be imported into databases. Version 2.00 of Autopsy will be released later this week. I'm adding the final touches and documentation and the goal is to release it on March 19, which is the 3 year anniversary of the first release of Autopsy and TCTutils. Version 2.00 has a new internal design and has live analysis features (see below article). If you can't wait for a few days and want one of the beta copies, let me know. Guido Metzner has been translating The Sleuth Kit Informer into German. If anyone else is translating this, let me know and I'll add a link. http://www.guframe.de/sleuthkit.html I started to provide a GPG signature of the source code as it is released. I have meant to do this for ages. This can help to ensure that the code being downloaded has not been modified by an attacker. CALL FOR PAPERS -------------------------------------------------------------------- I posted a call for papers on the website in late January for people that are interested in writing articles for the Informer. Here is the relevant section: The Sleuth Kit Informer is looking for articles on open source tools and techniques for digital investigations (computer / digital forensics) and incident response. Articles that discuss The Sleuth Kit and Autopsy are appreciated, but not required. Example topics include (but are not limited to): - Tutorials on open source tools - User experiences and reviews of open source tools - New investigation techniques using open source tools - Open source tool testing results http://www.sleuthkit.org/informer/cfp.html Writing these articles takes away from my development time of new tool features, so any help is appreciated. To keep with the incident verification theme, any articles on the basics of using 'netstat', 'lsof', etc. to look for signs of an intrusion are also welcome for the next few issues. If we get enough interest, I'll consider going back to a monthly schedule. DID YOU KNOW? -------------------------------------------------------------------- Have you ever noticed that the number of occurrences and locations of keywords for regular expressions in Autopsy are not always accurate? This came up on one of the mailing lists this past month and I'll explain it again here. Previous issues of The Informer have covered keyword searching, but the general idea in Autopsy is that it runs the 'strings' command on the image file and then uses 'grep' to find the keyword. The 'strings' command returns a long ASCII string that grep examines. If the keyword is found in the string, then grep fill flag the string and autopsy will search the string to find the exact location of the keyword. This is easy if a non-regular expression is used, but much more difficult with regular expressions because 'grep' regular expressions are different from Perl regular expressions. I do not have a way to convert the grep regular expression to Perl and therefore I only return the number of big strings that have the keyword and the location of the start of the big string. There could be more than one keyword in the string, in which case the total occurrences value is too small. The location will also be off because it points to the start of the large string and not the specific keyword. If anyone knows of, or wants to write, a grep to perl regular expression converter, let me know so that we can update this. UNIX INCIDENT VERIFICATION WITH AUTOPSY -------------------------------------------------------------------- INTRODUCTION For a couple of years, I have been saying that Autopsy can be used to analyze a live system, but it has taken me a while to make it EASY to use to analyze a live system. When version 2.0 of Autopsy is released later this week, you will find that it is much easier to configure so that it runs on a CD-ROM so that you can examine a system that is suspected of being compromised. This will allow you to view files that are hidden by rootkits and will not change the access times on files that are viewed. This article will give an overview of how to use the new features and what features are available for dead analysis are not for live analysis. I will also show the future work for Autopsy. This article uses many of the same concepts as the "UNIX Incident Verification with The Sleuth Kit" article in issue #10 of the Informer. MOTIVATION Some may be asking "why would I want a live analysis feature?". The primary motivation is for a more automated Incident Verification procedure. We saw in issue #10 of the Informer, that The Sleuth Kit can be used to verify an incident because it can show files that are hidden by rootkits and will not update the access times on files when they are read. Executing a bunch of command line tools is tedious though and Autopsy can provide a more automated investigation procedure. The basic scenario is that Autopsy and The Sleuth Kit will be burned to a CD and inserted into a suspect computer. An investigator will connect to Autopsy on the suspect UNIX computer with her HTML browser on a trusted laptop and remotely examine the hard disk contents. If the computer is found to have been compromised, then it can be taken offline and acquired using normal procedures. Recall from issue #10 that I used two guidelines for incident verification: 1. Minimize the amount of trust that you place in the system so that more accurate information is collected. 2. Minimize the amount of data that you change on the system so that evidence is preserved. CREATING THE CD To satisfy guideline #1 from above, we want to minimize the amount of trust that we place in the system, so we use our own executables. At a minimum, we need The Sleuth Kit and Autopsy on the CD and you will probably have additional tools to examine open network ports and running processes. This has been the most difficult part of using Autopsy for live analysis because Autopsy relies on a given directory structure and locations that it can write to. It is now very easy with v2. With v2, you compile TSK and Autopsy on a similar system to the one that will be investigated just like you do for a dead analysis. Try the 'make static' with TSK to see if you can make static executables for your platform. After both Autopsy and TSK have been compiled, you execute the 'make-live-cd' command in Autopsy. This script will make a 'live-cd' sub-directory in the autopsy directory, which contains a copy of autopsy and copies of TSK executables, grep, strings, perl etc: # ./make-live-cd Making base directory (./live-cd/) Copying executables Copying autopsy files Creating configuration file using existing settings The 'live-cd' directory has a 'bin' directory where additional executables can be copied to and then the whole directory can be burned to a CD. BASIC USAGE After the CD has been created and there is a system suspected of being compromised, then it is time to take advantage of the new features. There are two scenarios for live analysis. The first scenario uses a network share from a trusted system that you can write to. In this case, autopsy is run as normal and you specify the evidence locker directory as the mounted disk. The evidence locker is specified with '-d': # ./autopsy -d /mnt/ev_lock 10.1.32.123 The above would start autopsy, use '/mnt/ev_lock/' as the evidence locker and would allow connections from 10.1.32.123 (where the investigator would connect from using an HTML browser). Remember that we do not want to write to the suspect system, so we should only use a network share and not a local directory in this scenario. The second scenario does not use an evidence locker and does not intentionally write any data to disk. This scenario does not need the network share and each of the devices (or partitions) that will be analyzed are specified on the command line using the '-i' flags. The '-i' flag requires three arguments: the device, the file system type, and the mounting point. For example, to examine the '/dev/hda5' and '/dev/hda8' partitions on a Linux system, the following could be used: # ./autopsy -i /dev/hda5 linux-ext3 / -i /dev/hda8 linux-ext3 /usr/ \ 10.1.32.123 The file system type must be one of the types that are supported by TSK. The remote IP address must also be given, otherwise you will have to use a browser on the suspect system and that will write data to the disk. When you use the '-i' flag, then autopsy will start in the 'Host Manager' view where you can select the image that you want to analyze. You will skip the case and host configuration. The default case name will be 'live', the default host name is 'local', and the default investigator name is 'unknown'. DIFFERENCES WITH DEAD ANALYSIS There are some features that are not available for live analysis because they write files to the disk. In this section, I am using the term live analysis for the scenario where there is not a mounted network share and there is not evidence locker. No auditing is performed during a live analysis because there is no where to write the logs. In the future, if this is needed, then a method of writing logs to a floppy disk could be configured. Timelines of file activity cannot be created because they need to create files. Hash databases are also not currently used, although they could in the future. It may be difficult to maintain the latest hash database on the same CD as the latest autopsy and TSK version though. Notes and event sequencer notes cannot be created. Keyword searches can be performed, but the strings file and unallocated only search cannot be performed because they both require a file to be created. The search results are also not cached. You can also not sort files by their type (all executables, all pictures etc.). In many cases, you would not want to do many of these operations because they are time intensive and you are generally looking for obvious and quick evidence during the incident verification. If you need theses features, then you can use the network share scenario. SIMILARITIES WITH DEAD ANALYSIS Now that we know what is different, I'll cover what is the same. All of the file mode analysis is the same, except that you cannot get the file type. The method that is used to compile 'file' in TSK does not allow autopsy to easily move it around. This behavior may change in the future. Meta data, data unit, and file system mode all work as usual. You can still export file contents to your trusted laptop because it uses the HTTP to save the file. So, you can select the export button on a log file to save a copy. You can also generate ASCII reports and save them to your local analysis station. GUIDELINE COMPLIANCE All of these features may sound great, but lets examine how well the new Autopsy satisfies the two guidelines. I think it is always important to compare a new tool or technique against generic guidelines. The first guideline was about not trusting the local system. No software-based live analysis tool can be 100% independent from the local system because it always needs to request service from the operating system. With Autopsy, we use our own copies of the Autopsy perl code, TSK executables, grep, and strings. There is one large problem with the current Autopsy model and it is because of Perl. Perl is a beast and contains many modules and libraries. When the 'make-live-cd' script is run, a copy of the 'perl' executable is copied to the 'live-cd' directory, but that is it. The executable will still need the modules and libraries on the local system. Solving this may require building a special version of Perl that is more static. I need to investigate this more. Another method of getting around this limitation is to use the 'perl2exe' program that converts a Perl script to a dynamic executable. The resulting executable will still rely on dynamic libraries on the suspect system, but it seems a little cleaner. The perl2exe program is a commercial tool. One of the benefits of the Autopsy design, is that Autopsy did not exist on the system when it was suspected of being compromised. Therefore, the attacker will not know that Autopsy will be used to investigate the system and therefore will be less likely to tamper with its dependencies. If the investigation tools are running on the system during the attack, then I would guess that the attacker will be more likely to tamper with them. The second guideline was about modifying data on the system. I described the features that were removed in the previous section. This was easy to do because there were functions that write the logs or notes. Each of those starts with a check to see if logging is enabled. Timelines and file type sorting were also disabled because it required writing to disk. I can never guarantee that no data will be written from a live analysis. Memory will be overwritten when the software is loaded and the access times on dynamic libraries will updated. Running the tools may require the operating system to write memory to the page file, which may overwrite data from the attacker. This is a shameless plug, but for those that are interested in live analysis, then you may want to check out a paper that a colleague, Joe Grand (author of pdd), and I wrote about a hardware device to acquire memory from a live system. It does not overwrite memory because there is no process to load and it access the physical memory directly so it does not rely on the local operating system. It was recently published in the new Journal of Digital Investigation (reference is below and that issue of the journal is currently free to view). FUTURE WORK There is always more to do, and I'll cover that here. I would like to also include other system utilities, such as 'ps' or 'netstat' on the CD and allow the Autopsy user to run the commands from within autopsy. This should be fairly easy, but the difficult part is that many of the operating systems use different flags for different tools. I would like to start incorporating scripts into the tool (for both dead and live analysis). This will allow you to more easily detect rootkits or other signatures. The biggest thing that needs future work is using Perl. Autopsy still relies on the version of Perl on the suspect system and that could run into problems if an attacker modifies it. Using the perl2exe tool can reduce the risk, but it is a commercial tool. CONCLUSION The live analysis mode of Autopsy allows you to more easily analyze a system that is suspected of being compromised. It can also be used to examine a honeypot. Live analysis is not ideal because you are stilly relying on the suspect operating system for data, but it is required in some situations. More work needs to be done with Autopsy so that it depends less on the local system. REFERENCES Autopsy http://www.sleuthkit.org/autopsy/ perl2exe http://www.indigostar.com/perl2exe.htm Sleuth Kit http://www.sleuthkit.org/sleuthkit Sleuth Kit Informer #10 http://www.sleuthkit.org/informer/sleuthkit-informer-10.html A hardware-based memory acquisition procedure for digital investigations Brian D. Carrier and Joe Grand Volume 1, Issue 1 - Journal of Digital Investigations http://www.sciencedirect.com/science/journal/17422876 -------------------------------------------------------------------- Copyright (c) 2004 by Brian Carrier. All Rights Reserved ���������������������������������������������������������autopsy-2.24/global.css�����������������������������������������������������������������������������0000644�0000765�0000024�00000000374�11070040246�014427� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������h3 { font-size: 18px; color: #000000; } h2 { font-size: 20px; color: #000000; } h1 { font-size: 24px; color: #000000; } body { font-family: Helvetica, Geneva, Arial, sans-serif; font-size: 14px; color: #000000; #background-color: #dedede; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/help/����������������������������������������������������������������������������������0000755�0000765�0000024�00000000000�11355002264�013405� 5����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/help/blank.html������������������������������������������������������������������������0000644�0000765�0000024�00000001124�11070040246�015354� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>Blank Page</TITLE></HEAD> <BODY BGCOLOR=#CCCC99> &nbsp; <p> &nbsp; <p> &nbsp; <p> <center> <h3>HELP!</h3> Here are the help files for using Autopsy. <p>In addition to these files, the <tt>Sleuth Kit Informer</tt> newsletter could be useful.<br> The Informer typically goes into more technical details than what is provided here.</p> <p><a href="http://www.sleuthkit.org/informer/" target=\"_blank\"> http://www.sleuthkit.org/informer/</a></p> <p>Send documentation updates to &lt;doc-updates at sleuthkit dot org&gt;</p> </BODY> </HTML> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/help/caseman.html����������������������������������������������������������������������0000644�0000765�0000024�00000013236�11070040246�015703� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>Autopsy Case Management Help</TITLE></HEAD> <BODY BGCOLOR=#CCCC99> <CENTER><H2>Case Management</H2></CENTER> <P> <H3>Overview</H3> Autopsy organizes images based on the case and host that they came from. A case contains one or more hosts (a new case should be created for each investigation). Each host can contain one or more images, which correspond to disks or partitions on the host. <P> <H3>Creating a New Case</H3> From the Main Menu (at startup) select <U>New Case</U>. You will have to enter the case name and an optional short description. The case name must be a valid directory name (no spaces - no symbols). A list of investigators will also be requested. These will be used for the audit logs, not for authentication. A directory with the same name as the case will be created in the Evidence Locker. To later rename the case, simply rename the directory. <P> For example: <TABLE CELLSPACING=8> <TR> <TD>Case Name:</TD><TD><TT>bankofmars</TT></TD> </TR> <TR> <TD>Case Description:</TD><TD><TT>Theft of $1,000,000,000.01 from The Bank of Mars</TT></TD> </TR> <TR> <TD>Investigators:</TD><TD><TT>gadget</TT></TD> </TR> </TABLE> <P> <H3>Adding a New Host</H3> A Host must then be created in the Case. Select the Case that was just created from the Case Gallery and enter the Host Gallery. Select <U>Add Host</U> and enter the host name, a short description, and time information such as time zone and clock skew. The clock skew is how many seconds the system was off from a synchronized clock. Adding a host will create a directory in the case directory and subdirectories in the host for the images, output data, logs, and reports. If you do not add a time zone, then it will default to the time zone of your analysis system. A list of time zones can be found <a href="timezones.html">here</a>. <P> You can optionally add the path to <A HREF="hash_db.html">hash databases</A>. <P> For example, the 'Bank of Mars' incident could have two hosts involved: <TABLE CELLSPACING=8> <TR> <TD>Host Name:</TD><TD><TT>db_server</TT></TD> </TR> <TR> <TD>Host Description:</TD><TD><TT>Main Database Server - Solaris</TT></TD> </TR> <TR> <TD>Timezone:</TD><TD><TT>EST5EDT</TT></TD> </TR> <TR> <TD>Timeskew:</TD><TD><TT>-100</TT></TD> </TR> <TR> <TD>Known Good Database:</TD><TD><TT>none</TT></TD> </TR> <TR> <TD>Known Bad Database:</TD><TD><TT>none</TT></TD> </TR> </TABLE> <P> <TABLE CELLSPACING=8> <TR> <TD>Host Name:</TD><TD><TT>file_server</TT></TD> </TR> <TR> <TD>Host Description:</TD><TD><TT>Windows File Server - Win 2k</TT></TD> </TR> <TR> <TD>Timezone:</TD><TD><TT>CST6CDT</TT></TD> </TR> <TR> <TD>Timeskew:</TD><TD><TT>0</TT></TD> </TR> <TR> <TD>Known Good Database:</TD><TD><TT>/usr/local/forensics/hash/win2k.txt</TT></TD> </TR> <TR> <TD>Known Bad Database:</TD><TD><TT>/usr/local/forensics/hash/win_hack.txt</TT></TD> </TR> </TABLE> <P> <H3>Adding a New Image</H3> Next, images must be added to the host. Select the host that was just added from the Host Gallery and enter the Host Manager. Select <U>Add Image File</U> and a new form is shown. The first text box in the form is for the path of the image file. If you are importing a split image, then the extension must be ordered based on the file order. Supply a '*' in the file name extension where the numbers or letters are. (i.e. .../image.*). The image file can be of a full disk or of an individual partition. You must select which it is though. Before they can analyzed, the images will have to be located in the evidence locker. You are given a choice to either create a symbolic link from the current location, to copy the file, or to move the file from its current location to the host directory. Select the desired import method. For example: <TABLE CELLSPACING=8> <tr><td>Image Path:</TD><TD><TT>/mnt/sys1/disk2.*</TT></TD></TR> <tr><td>Type:</td><td><tt>Disk</tt></td></tr> <tr><td>Import Action:</TD><TD><TT>symlink</TT></TD></TR> </table> <p> If you are importing a split image, then the next window will confirm the order of the images. After that, the next window will allow you to specify or calculate the MD5 for the file. This should be of the full file and if you are importing a split image then it should be for all files combined. If you are importing a volume image, then Autopsy will try to determine the file system type. You will also need to specify the mounting point. This is used for cosmetic purposes only when printing the full path of files. <p> If the image file is a disk image then Autopsy will list all of the partitions and try to determine the file system in each one. You have the option to not import a partition and to change the file system type. <P> <H3>MD5 Values</H3> Each host has an <TT>md5.txt</TT> file that contains the MD5 value for files in that directory. Autopsy uses that file to validate the integrity of files. By default, when a file is imported into Autopsy, its MD5 will be calculated. If it is already known, then it can be entered in the 'Add Images' window. <P> <H3>Host Subdirectories</H3> Each host has an <TT>images</TT> directory and an <TT>output</TT> directory. All data generated by Autopsy is saved to the <TT>output</TT> directory. The theory behind this design, was to allow the <TT>images</TT> directory to have strict permissions to prevent accidently modifying the images. Therefore, the <TT>images</TT> directory can have its write bits removed to prevent modifications. <p> <h3>References</h3> Issue 2 of <a href="http://www.sleuthkit.org/informer/" target=\"_blank\">The Sleuth Kit Informer</a> discusses case management and how to break a disk image into file system images. <P><HR> <FONT SIZE=0>Brian Carrier</FONT> </BODY></HTML> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/help/data_mode.html��������������������������������������������������������������������0000644�0000765�0000024�00000007064�11070040246�016213� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>Autopsy Data Unit Analysis Help</TITLE></HEAD> <BODY BGCOLOR=#CCCC99> <CENTER><H2>Data Unit Analysis</H2></CENTER> <H3>Overview</H3> <P> The Data Analysis Mode allows an investigator to view the contents of an individual data unit. Data units is a generic term used to describe the areas on the disk that are used to store data. Each file system calls the data unit a different thing (i.e. Fragments or Clusters). This mode is most useful when recovering and analyzing deleted data. <H3>Input</H3> <P> To view the contents of a specific address, enter it into the text box on the left-hand side. By default, only one data unit will be displayed. To view more than one consecutive unit, enter the number in the text box below. <P> It is common to extract the unallocated space from a file system image and analyze it for deleted material. The 'blkls' tool in The Sleuth Kit allows one to extract the data. If interesting data is found in the 'blkls' file, the next step could be to find its location in the original image and examine the surrounding data. To do this, simply calculate which data unit the data was found in (by dividing the byte offset of the interesting data by the data unit size (which can be found in <U>Image Details</U>)). Enter that address into the original text box and select the <U>Unallocated</U> type. This will find the original location and display it for you. <P> If Autopsy knows about the 'blkls' image, then it can be loaded at any time by selecting the <U>Load Unallocated</U> button. Then, any data unit in that file can be examined. <P> The <B>Lazarus</B> tool was part of <TT>TCT</TT>. It analyzes a chunk of data and identifies what file type it is and tries to group consecutive types together. Lazarus numbers its output though starting with 1. Therefore, instead of subtracting 1 every time you want to view a data unit identified by Lazarus, simply select the check box. <P> Press the <U>Ok</U> button to display the contents of the address on the right-hand side of the window. <P> The <U>Allocation List</U> link displays the allocation status of addresses in intervals of 500. <H3>Viewing</H3> <P> After the unit address has been entered, the contents are displayed in the right-hand side. Filters can be used to view the data in the desired format (strings, hexdump, ASCII). <P> A report can be generated so that the contents and meta-data about it will be saved on record. To save the contents locally, press the <U>Export Contents</U> button. The <U>Add Note</U> button will allow one to add a comment about the given data unit so that it can be easily recalled later. <P> The file type is also displayed. This is identified by running the output through the 'file' command in The Sleuth Kit. <P> Autopsy will try to find the meta-data structure that allocated the unit and display both its address and a file name. This process is very slow for FAT file systems, so this process is not done by default during analysis. <H3>FAT Notes</H3> <P> The Sleuth Kit and Autopsy do not use clusters when dealing with a FAT image. Only sectors are used. The reason is because FAT does not start addressing clusters until many sectors into the file system. If clusters were used to address data units, then there would be no way to address the sectors in the FAT and secondary FAT. Therefore, sectors are used for all addresses. NTFS changed the way clusters were addressed and do not have this problem. See the documentation in The Sleuth Kit for more details. <P> <HR> <FONT SIZE=0>Brian Carrier</FONT> </BODY></HTML> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/help/file_category.html����������������������������������������������������������������0000644�0000765�0000024�00000007514�11070040246�017112� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>Autopsy File Category Help</TITLE></HEAD> <BODY BGCOLOR=#CCCC99> <CENTER><H2>File Category Type Analysis Help</H2></CENTER> <H3>Overview</H3> Analyzing large file system images can be very daunting. One way of identifying files that should be examined is to sort the files based on file type. This mode of Autopsy will allow one to sort the files in an image based on type and to exclude known files (i.e. data reduction). It also allows one to flag files that are known to be bad. <H3>Procedure</H3> The <TT>sorter</TT> document in the <TT>docs</TT> directory of The Sleuth Kit has more details on the details, but this will provide an overview of the interface given by Autopsy. <P> The first step is to <U>Sort</U> the image. There are several options to choose when doing this. The <TT>sorter</TT> tool from The Sleuth Kit will perform the sorting. There are two major actions that <TT>sorter</TT> can do: sort files by type and validate extensions. <P> By default, Autopsy will perform both actions. If you do not want it to do a given action, deselect it. <P>Within sorting, there are two options: <UL> <LI> The first is to save the output. By default, details about each file will be added to a category file. For example, a JPEG image will have the meta data address and image name saved to the <TT>images</TT> file. By selecting the <U>Save</U> option, a directory will be created for each category and a copy of the files will be saved. This could require lots of disk space (as much as the original image size). <LI> The second option is to save unknown file types. There are configuration files that contain rules about common data types. If a file is encountered that does not have a rule, it is added to an <TT>unknown</TT> file. If this is not desired, select the <U>Do Not Save Unknown</U> option. </UL> <P> During the sorting process, the <TT>sorter</TT> tool will also examine the extension of the file. If the file type is known, it has known extensions, and the file does not have one of those extensions, it will be added to a <TT>mismatch</TT> file. This can be deselected if it is not wanted. <H3>Hash Databases</H3> One easy way of data reduction is to use hash databases. The <TT>sorter</TT> tool can use three different hash databases. Each can be configured within Autopsy and used in other screens. <UL> <LI><B>NIST NSRL</B>: The NIST NSRL contains hashes of trusted operating systems and programs. This is used to ignore known files. Files found in the NSRL will not be included in the file categories (to save time when reviewing the files). If the file is in the NSRL and has an extension mismatch, it will be noted in a special file. <LI><B>Ignore Database</B>: This database must be created by the user and added to the host. It is similar to the NSRL in that it contains hashes of known good files. They will be ignored in the same way that those from NSRL are. <LI><B>Alert Database</B>: This database must also be created by the user and added to the host. It contains hashes of files that are known to be bad and should identified if found in the image. This would include known rootkits or photographs. Hits from this databases are found in the <TT>alert</TT> file. </UL> <P> More details can be found in the <A HREF="hash_db.html">Hash Database</A> Help. <H3>Output</H3> Currently, there is no way to view the output from within Autopsy. All data can be found in the <TT>output</TT> directory of the host. A directory is created for the <TT>sorter</TT> output. View the <TT>index.html</TT> file and it contains links to the other files. <p> <h3>References</h3> Issues 3, 4, and 5 of <a href="http://www.sleuthkit.org/informer/" target=\"_blank\">The Sleuth Kit Informer</a> discussed using the 'sorter' tool. <HR> <FONT SIZE=0>Brian Carrier</FONT> </BODY></HTML> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/help/file_mode.html��������������������������������������������������������������������0000644�0000765�0000024�00000022274�11070040246�016221� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>Autopsy File Analysis Help</TITLE></HEAD> <BODY BGCOLOR=#CCCC99> <CENTER><H2>File Analysis</H2></CENTER> <H3>Overview</H3> The File Analysis mode allows one to analyze an image from the file and directory perspective. This provides the same interface that users typically use with a normal computer. This mode will also display information about deleted files though. <P> This mode will allow one to examine the contents of files and directories for evidence. It even allows one to perform basic binary analysis by extracting the ASCII strings from a binary file. The files can also be sorted by any field. <H3>Directory List</H3> <P> The left-hand side window has four main options: <UL> <li>Directory Seek <li>File Name Search <LI>Hide / Expand Directories <LI>Show All Deleted Files </UL> <P> By default, the directory listing is not shown when this mode is first entered. By select the <U>Expand Directories</U> button, the full list of directories will be shown. The number of '+' symbols represent the depth of the directory. As this is an HTML interface and there is no state management occurring (no cookies or session id), it would be difficult to have an interface where one or more directories are expanded yet the rest are collapsed. <P> Selecting the <U>All Deleted Files</U> link will display all of the deleted files in the image on the right-hand side. <P> There is a text box where a directory (or file) name can be entered and it will be displayed on the right-hand side. This makes it easy to jump to a directory without going through the directory listings. For example, to seek to the 'windows\system32' folder, you can enter that string into the box instead of scrolling through the directories. <p> There is also a text box where a pattern of a file name can be entered and all files that match that pattern will be displayed on the right-hand side. The search pattern is a Perl regular expression, so some values, such as '.' or '*' will need to be escaped. The search is done case insensitive. To find all files that have a JPG extension, the following could be used "\.jpg". Or to find all files that begin with a dot, then we could use "^\.". <H3>Directory Contents</H3> <P> The window in the upper right-hand side contains the directory contents. In a file system, a directory allocates data units on the disk and fills the data units with structures that contain the name of the file and the address of the meta data structure. This view parses the file name structures in the directory. It is filled by either selecting a directory from the left-hand side directory list or a directory from within the same window. The entries can be resorted by clicking on any of the header values. <P> The column headers have the following definitions: <UL> <LI><B>del</B>: A check in this column represents a deleted file. See below for a discussion on the different color types of deleted files. <LI><B>Type</B>: This column contains the "type" that the file or directory is. There are two values. The first (<TT>dir</TT>) is the type according to the directory entry structure. The directory entry is where the file name is located. The second value (<TT>in</TT>) is the type according to the meta data structure. These should be the same except for deleted files. They are both given to help the investigator identify if a deleted file has been reallocated or not. For example, if the meta data structure type is different than the file name type, then it is likely that one of the structures was reallocated for a new file. <LI><B>Name</B>: The name of the file or directory. Clicking on the name displays file contents in the bottom window or directory contents in the same window. For deleted files, no link will exist if the meta data structure address has been cleared (which many OS do). To identify the destination of a UNIX symbolic link, click on the address at the end of the row. Note that the name will not be a link if the size of the file is 0 or if the meta data structure is unknown. <LI><B>Modified Time</B>: This column exists for UNIX and NTFS file systems. It shows the last time that the file data was last modified. In other words, when was data last written to the data units allocated by the file. In UNIX, the <TT>utimes()</TT> function can modify this value vary easily. <LI><B>Written Time</B>: This column exists for FAT file systems and is the time when the file was last written to. Of the three times, this is the only value that is required by the FAT specification. <LI><B>Accessed Time</B>: This column contains the last accessed time of the file data. On a FAT image, this value is optional and is only accurate to the day (not hours or seconds). This value can be modified by the utimes() function in UNIX. <LI><B>Changed Time</B>: This column exists for UNIX and NTFS file systems. It is the last time that the file status (or meta data) was changed. This is different than the Modified time because modified deals with the file data and this deals with the descriptive data in the inode or MFT entry. This value cannot be changed by the <TT>utimes()</TT> function in UNIX. <LI><B>Created Time</B>: This column exists for NTFS and FAT file systems. It is the time when the file was created. According to the FAT spec, it is an optional time. <LI><B>Size</B>: The size of the file. Note that if the size of the file is 0, no link will be shown with the name. <LI><B>UID</B>: The User ID of the file owner. <LI><B>GID</B>: The Group ID of the file owner. <LI><B>Meta Data</B>: The file name structures contain a pointer to the meta data structure that describes the file. This column contains the address of the structure. Selecting this value will display the details in the bottom window. If the value is invalid, then a link will not exist. If it is for a deleted file name that has a meta data structure with an allocated status, a "realloc" string will exist to identify this. </UL> The <U>Add Note</U> link allows you to make a comment about this directory and have it saved in your personal notes file. <P> The <U>Generate MD5 List</U> link will generate the MD5 value for every file in the directory and allow you to save it as a text file. Using fingerprint data bases, This makes it easy to check for files that were modified by an attacker. <P> The path on top of the window has hyperlinks in it that allow the user to easily change to a previous directory. <P> There are two different colors used for deleted files. The difference is based on the status of the data structures in the file. A <FONT COLOR="red">bright red</FONT> entry means that the file name data structure is not allocated and the meta data structure that it points to is also not allocated. This is what we would expect of a recently deleted file. This means that we can trust the data we are seeing as long as the meta data structure was not allocated and unallocated since the deletion. If it is <FONT COLOR="#800000">darker red</FONT>, then the meta data structure has been reallocated and the data is most likely not accurate. <P> The file size reported by the meta data structure is very important with The Sleuth Kit. The Sleuth Kit uses this value to identify how many data units to display. If this size is 0, but the meta data structure points to data blocks still, they will not be shown. You can force Autopsy to display the values by selecting the meta data address and using the 'force' option. <P> To look a file up in one of the <A HREF="./hash_db.html">Hash Databases</A>, then select the meta data address. That view will provide an interface to the databases. <H3>File Contents</H3> <P> The lower right-hand side window displays the contents of a specified file. The contents can be viewed in either the raw format (which your browser will not likely display much of if the file is non-ASCII) or through 'strings'. The strings option is helpful for a quick analysis of a binary file. <P> Also shown is the file type. This is determined by running the 'file' command on the output. It uses the magic header and footer values to guess the file type. If the file type is an image or HTML, an option will exist to <U>View</U> the data in its interpreted form (i.e. as a picture or as a web page instead of the raw data). Note that any HTML that is viewed will be processed in a sanitized environment that does not load pictures and will not allow one to connect to a remote site. To view the native picture, select 'Export' and open the HTML document in another browser. Refer to issue #1 of The Sleuth Kit Informer for more details on the sanitizing. <P> The <U>Report</U> options create ASCII reports that contain the file contents as well as data such as MD5 values and dates. <P> The <U>Export</U> button extracts the file out of the image so you can save it locally and use other tools on it. <P> The <U>Add Note</U> button adds a personal note to the investigator log for future reference. <p> <h3>References</h3> Issue 1 of <a href="http://www.sleuthkit.org/informer/" target=\"_blank\">The Sleuth Kit Informer</a>. <HR> <FONT SIZE=0>Brian Carrier</FONT> </BODY></HTML> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/help/fs_mode.html����������������������������������������������������������������������0000644�0000765�0000024�00000003103�11070040246�015700� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>Autopsy Image Details Help</TITLE></HEAD> <BODY BGCOLOR=#CCCC99> <CENTER><H2>Image Details</H2></CENTER> <P> <H3>Overview</H3> Sometimes there are details about an image that do not correspond to any file in particular. Those details can likely be found in this mode. This mode gives the general details of the image and therefore the contents will vary depending on the file system type. <P> <H3>FFS & EXT2FS</H3> For the UNIX file systems, this mode will contain the details from the super block. This generally includes times that the file system was last mounted and any special flags. It also has the range of inode addresses and fragment addresses. For advanced file recovery, you can also identify the group layout and on-disk structure details. These could be useful for restricting where you search for data. Files will allocate blocks and fragments in the same Cylinder or Block group as their inode is in, so your attention can be restricted to that area. <P> <H3>FAT</H3> For FAT file systems, this mode will contain the File Allocation Table. It will have the cluster runs, which can be selected to view their contents in <A HREF="data_mode.html">data unit</A> analysis mode. Or, if the file is fragmented, the pointer can be selected and the screen will link to the next cluster chain. <P> <H3>NTFS</H3> The unique information for an NTFS image is the numerical type associated with attributes. These values can be dynamic and this area will identify what they are for that file system. <P> <HR> <FONT SIZE=0>Brian Carrier</FONT> </BODY></HTML> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/help/general.html����������������������������������������������������������������������0000644�0000765�0000024�00000007530�11070040246�015711� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>General Autopsy Help</TITLE></HEAD> <BODY BGCOLOR=#CCCC99> <CENTER><H2>General Autopsy Help</H2></CENTER> <P> The Autopsy Forensic Browser is a graphical interface to command line forensics tools and standard UNIX utilities. It allows you to perform volume and file system analysis on UNIX and Windows systems. <P> All data are saved in a directory in the Evidence Locker, which was specified at install time or at run time. See <A HREF="caseman.html">Case Management</A> for more information. In the normal mode, Autopsy imports an image file from a disk or partition. In the live mode, Autopsy can analyze a running system and does not save any data to the local disk. <P> The browser has the following modes: <UL> <LI> <B><A HREF="file_mode.html">Files</A></B>: Allows you to browse the image file as a file system and view the contents of files and directories. This mode even shows deleted file names and Alternate Data Streams in NTFS images. You can sort the files and directories on meta data. <LI><B><A HREF="meta_mode.html"> Meta Data</A></B>: Allows you to analyze the image file by examining the meta data structures. The address of a structure is entered and the details are shown. This mode is useful for examining unallocated structures and getting all details about allocated files (including all data units and other information such as MD5 value). <LI><B><A HREF="data_mode.html"> Data Unit</A></B>: Allows browsing by block number. This is most useful when used with searching or meta data browsing. The contents of the block can be displayed in ASCII, hex dump, or through <I>strings(1)</I>. The meta data structure that has allocated the block will be displayed (if any) along with the file name (if any). <LI><B><A HREF="srch_mode.html"> Keyword Search </A></B>: Search an image file using <I>grep(1)</I> for a given string or regular expression. The result will be a list of data units that have the string. Each data unit can be selected to view the contents. <LI><B><A HREF="fs_mode.html"> Image Details</A></B>: List the details about the file or volume system. The output of this mode depends on the file system. Examples of the file system data include the last mount time, the last mount location, and a detailed break down of block group information or File Allocation Table contents. <LI><B><A HREF="int_mode.html"> Image Integrity</A></B>: The integrity of the data can be validated at any point by selecting this mode. It uses the values in <TT>md5.txt</TT> to identify if any data have been modified in the analysis process. <LI><B><A HREF="tl.html"> File Activity Timelines</A></B>: Autopsy can create timelines of file activity based on the Modified, Access, and Change (Create in FAT/NTFS) times (MAC). The timeline will contain details about deleted and allocated content. The resulting timeline can be either viewed within Autopsy or using other text viewing tools (WARNING: many HTML browsers do not handle large tables like a timeline very well so using a text editor is recommended). <LI><B><A HREF="file_category.html"> File Type Categories</A></B>: Autopsy can sort the files in an image file based on their file type. For example, all JPEG and GIF files would be identified as images and all executable files would be identified. This mode will also ignore files that are found in hash databases of known good files, identify files that are found in a hash database of known bad files, and identify files that have an extension that is not consistent with their file type. <LI><B>Report Generation</B>: Each of the above browsing techniques allows a report to be generated. This report lists the date, md5 value, investigator, and other context information in a text format. This can be used for record keeping when deleted blocks of data have been found. </UL> <HR> <FONT SIZE=0>Brian Carrier</FONT> </BODY></HTML> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/help/grep.html�������������������������������������������������������������������������0000644�0000765�0000024�00000003323�11070040246�015225� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>Autopsy grep Cheat Sheet</TITLE></HEAD> <BODY BGCOLOR=#CCCC99> <CENTER><H2>grep Cheat Sheet</H2></CENTER> <H3>Escaped Values</H3> Autopsy uses the <TT>grep</TT> utility to search an image. grep requires that some values be "escaped" if they are searched for. Autopsy will automatically escape those values if the serach is being done for a <U>non-regular expression</U>. The escaped values include: <UL> <LI>\ <LI>. <LI>[ <LI>^ <LI>$ <LI>' <LI>* <LI>initial - </UL> <H3>Regular Expressions</H3> Refer to the man page for 'grep' for more details of creating regular expressions. Autopsy uses the '-E' flag with 'grep' to specify extended regular expressions. The following have special meaning with grep: <UL> <LI><B>[A-Za-z]</B>: Any lower and upper case letter <LI><B>[:alpha:]</B>: same as above <LI><B>[0-9]</B>: Any number <LI><B>[:digit:]</B>: same as above <LI><B>[0-9A-Za-z]</B>: Any lower and upper case letter or digit <LI><B>[:alnum:]</B>: same as above <LI><B>[:space:]</B>: Any white space </UL> <P> To specify how many times something can occur, the following are used: <UL> <LI><B>?</B>: Optional and can only occur once <LI><B>*</B>: Optional and can occur more than once <LI><B>+</B>: Required and can occur more than once </UL> <P> To specify more than one string to match, use the <B>|</B> operator. <H3>Examples</H3> <P> To search for 'Jane Smith' or 'Jack Smith': (Jane)|(Jack) Smith <P> To ensure it matches if a tab is between the first and last name: (Jane)|(Jack)[:space:]Smith <P> To search for 'Jane Smith' or 'Jane Anne Smith': Jane( Anne)? Smith <P> or: Jane([:space:]Anne)?[:space:]Smith <HR> <FONT SIZE=0>Brian Carrier</FONT> </BODY></HTML> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/help/grep_lim.html���������������������������������������������������������������������0000644�0000765�0000024�00000007123�11070040246�016070� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>Autopsy grep Search Limitations</TITLE></HEAD> <BODY BGCOLOR=#CCCC99> <CENTER><H2><TT>grep</TT> Search Limitations</H2></CENTER> <H3>Overview</H3> <P> Keyword searches are very basic in Autopsy. Autopsy uses the <TT>strings</TT> and <TT>grep</TT> tools on the image and when a hit is found, it uses <TT>ifind</TT> and <TT>ffind</TT> to identify the file that has allocated the string. This is a very simple and basic method of searching and is not ideal. This will cause false positives and will miss data that crosses a fragmented part of a file. The limitations are outlined in this file. <H3>What Will Be Found</H3> <TT>strings</TT> is first run on the image and the data is passed to <TT>grep</TT> to do the actual search. This process will find ASCII and UNICODE strings that are consecutive anywhere in the file. This is frequently referred to as the physical layout. For example, it will find strings in the middle of an allocated sector, in an unallocated sector, in slack space, and in meta data strutures. This will find a string that crosses sectors, which is good if the two sectors are for the same file. <P> This technique leads to several types of false positives. For example, a string that crosses from the allocated space of a file into the slack space would be found by <TT>grep</TT>. A string that starts in the slack space and ends in the allocated space of a file will also be found. A string that crosses sectors of two different allocated files will also be found. The user must identify if the hit is an actual hit or a false positive. <h3>What Will Be Found, but May Be Confusing</h3> <p> If you are searching with regular expressions, then the exact location and number of hits may not be correctly reported. If the count is incorrect, then it will be too small. If the location is incorrect, then it will be too early (and could even be in the next data unit). The reason that this is in accurate is because the <tt>grep</tt> tool will return a long string to Autopsy that will contain one or more occurances of the keyword. Autopsy can not search the long string to find the exact number and location of the regular expression keywords like it can for non-regular expression keywords, so it returns only the starting location of the long string. <H3>What Will NOT Be Found</H3> The biggest category of 'hits' that will not occur using this technique is strings in a file that cross fragmented data units. For example, consider a file that has two clusters allocated, cluster 100 and cluster 150. A string "mississippi" could have "missi" in the final 5 bytes of cluster 100 and "ssippi" in the initial 6 bytes of cluster 150. The string exists from the logial level, but not at the physical level. Therefore, the <TT>grep</TT> search would not find the string. <P> Although not because of <TT>grep</TT>, Autopsy will also not find data in the slack space during an unallocated-only search. The extraction tool for The Sleuth Kit (<TT>blkls</TT>) differentiates between unallocated sectors in FAT and NTFS and slack space. There is currently no way in Autopsy to extract the slack space and search it. Autopsy currently only extracts the unallocated sectors and not the allocated sectors that may have deleted data in them. <H3>Conclusion</H3> Autopsy has basic keyword search functionality. Future versions may provide more features and better search results. In the mean time, it is important that users understand the abilities and limitations of the tool so that they can be taken into account during the investigation. <HR> <FONT SIZE=0>Brian Carrier</FONT> </BODY></HTML> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/help/hash_db.html����������������������������������������������������������������������0000644�0000765�0000024�00000013277�11070040246�015671� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>Autopsy Hash Database Help</TITLE></HEAD> <BODY BGCOLOR=#CCCC99> <CENTER><H2>Hash Database Help</H2></CENTER> <H3>Overview</H3> Hash databases are used to quickly identify known good and known bad files using the MD5 or SHA-1 checksum value. Autopsy uses three types of hash databases to help the investigator reduce the number of files that they have to look at. <P> The <B>NIST National Software Reference Library (NSRL)</B> contains hashes of files that are found in operating systems and software distributions. These files are <I>known to be good</I> in that they came from trusted sources and are typically on authorized systems. When processing files in the image, this database can be used to ignore files because they are assumed to be known and therefore uninteresting. The location of this database is configured when Autopsy is installed. The NSRL must be obtained from NIST at <TT>www.nsrl.nist.gov</TT>. <P> The <B>Ignore Database</B> is a database that the investigator must create. It is similar to the NIST NSRL in that it contains files that are <I>known to be good</I> and can be ignored if the user chooses to do so (only applicable when in <A HREF="file_category.html">File Type Category Analysis</A>). Examples of files in this category include system binaries for standard builds. See <A HREF="#db_create">Database Creation</A> for information on creating this database. Its location is configured when the host is created and can be edited in the host configuration file. <P> The <B>Alert Database</B> is a database that the investigator must create. It contains hashes of <I>known bad</I> files. These are the files that an investigator wants to know about if they exist on the system. Examples of this include rootkits or unauthorized photographs. When using the <A HREF="file_category.html">File Type Category Analysis</A>, these files will be saved in a special file. See <A HREF="#db_create">Database Creation</A> for information on creating this database. Its location is configured when the host is created and can be edited in the host configuration file. <H3>Database Uses</H3> Autopsy uses the hash databases in three ways. <UL> <LI><B><A HREF="file_category.html">File Type Category Analysis</A></B>: The hash databases are used to identify the <I>known bad</I> files and ignore the <I>known good</I> files. <LI><B><A HREF="meta_mode.html">Meta Data Analysis</A></B>: The hash databases can be used to identify a file from the meta data view. If the databases are configured, the hash from a given file can be looked up by pressing the 'lookup' button. All three databases can be used in this view. This view can be found from the File Analysis mode by selecting the meta data address in the directory listing window. <LI><B>Hash Database Manager</B>: From the Host Gallery view, the Hash Database Manager can be entered. This is where one can re-index the databases and perform single lookups in any of the databases. </UL> <A NAME="db_create"> <H3>Database Creation</H3> Currently, Autopsy will only allows one to look entries up in a hash database. It does not allow one to easily create a database, but this will describe the process (it is quite simple). <P> Autopsy uses the <TT>hfind</TT> tool from The Sleuth Kit to do the lookups. This tool requires the database to be indexed so that it can perform a fast lookup using a binary search algorithm (instead of a slower sequential search that a tool like grep would do). When ever a hash database is updated (or created), it must be indexed. This can be done in Autopsy in the Hash Database Manager (Note that the database must already be configured though). <P> The NIST NSRL obviously does not have to be created, but it does have to be indexed before it is used. <P> To make a hash database, we will create a file with the same format as the <TT>md5sum</TT> command uses. This is just the MD5 hash, some white space, and the file name. For example:<BR> &nbsp;&nbsp;&nbsp;&nbsp;<TT>c4a6761b486de3c6abf7cf2c554289e5 &nbsp;&nbsp;&nbsp;&nbsp;/bin/ps</TT><P> Make a file with this format for every line (it does not have to be sorted). For example, if you have a trusted system then you can make a hash database of its system binaries using the following:<BR> &nbsp;&nbsp;&nbsp;&nbsp;<TT># md5sum /bin/* /sbin/* > bin-md5.db</TT><P> After creation, hash databases must be indexed and sorted (this includes the NSRL). Databases will be indexed by using the <TT>hfind</TT> tool. The NSRL database would be indexed with:<BR> &nbsp;&nbsp;&nbsp;&nbsp;<TT># hfind -i nsrl-md5 PATH_TO_NSRL/NSRLFile.txt</TT><P> A database made by <TT>md5sum</TT> would be indexed with:<BR> &nbsp;&nbsp;&nbsp;&nbsp;<TT># hfind -i md5sum bin-md5.db</TT><P> Or, if Autopsy has this file configured from when the host was added, then it can be re-indexed from the Hash Database Manager. <H3>Autopsy Configuration</H3> The alert and ignore databases are stored in the host configuration file with the headers of 'exclude_db' and 'alert_db'. For example:<BR> &nbsp;&nbsp;&nbsp;&nbsp;<TT>alert_db&nbsp;&nbsp;&nbsp;&nbsp;'/usr/local/hash/bad.db'</TT><P> These entries can be edited at any time. <P> The NSRL database is configured in the <TT>conf.pl</TT> file in the directory where Autopsy was installed. It has the $NSRLDB variable. For example:<BR> &nbsp;&nbsp;&nbsp;&nbsp;<TT>$NSRLDB = '/usr/local/hash/nsrl/NSRLFile.txt';</TT><P> It can be edited, added, and removed at any time (but you must restart Autopsy). <p> <h3>References</h3> Issues 6 and 7 of <a href="http://www.sleuthkit.org/informer/" target=\"_blank\">The Sleuth Kit Informer</a> discussed hash databases. <HR> <FONT SIZE=0>Brian Carrier</FONT> </BODY></HTML> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/help/index.html������������������������������������������������������������������������0000644�0000765�0000024�00000000324�11070040246�015375� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>Autopsy Help</TITLE></HEAD> <LINK REL="SHORTCUT ICON" HREF="../pict/favicon.ico"> <FRAMESET COLS="20%,*"> <FRAME SRC="menu.html"> <FRAME SRC="blank.html" NAME="cont"> </FRAMESET> </HTML> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/help/int_mode.html���������������������������������������������������������������������0000644�0000765�0000024�00000001612�11070040246�016065� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>Autopsy Integrity Check Help</TITLE></HEAD> <BODY BGCOLOR=#CCCC99> <CENTER><H2>Integrity Check</H2></CENTER> <H3>Overview</H3> It is always important to validate the integrity of images during an analysis. Autopsy uses the MD5 algorithm to validate images and other files that are created by Autopsy. <P> The <TT>md5.txt</TT> files contain the MD5 values for files in that directory. Values are added to it when file system images are imported into the system or when Autopsy creates the file. This mode allows one to calculate the MD5 value if it was not created before and to validate the integrity. <P> When the <U>Image Integrity</U> button is selected from the <U>Host Manager</U> window, all files will be shown with their MD5 value if known. Here any image can have its value verified or a new one created. <P> <HR> <FONT SIZE=0>Brian Carrier</FONT> </BODY></HTML> ����������������������������������������������������������������������������������������������������������������������autopsy-2.24/help/menu.html�������������������������������������������������������������������������0000644�0000765�0000024�00000002015�11070040246�015231� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>Autopsy Help Topics</TITLE></HEAD> <BODY BGCOLOR=#CCCC99> <P><A HREF="general.html" TARGET="cont">General Information</A> <P><A HREF="caseman.html" TARGET="cont">Case Management</A> <HR> <P><A HREF="file_mode.html" TARGET="cont">File Analysis</A> <P><A HREF="meta_mode.html" TARGET="cont">Meta Data Analysis</A> <P><A HREF="data_mode.html" TARGET="cont">Data Unit Analysis</A> <P><A HREF="fs_mode.html" TARGET="cont">Image Details</A> <P><A HREF="srch_mode.html" TARGET="cont">Keyword Searching</A> <P><A HREF="grep.html" TARGET="cont">grep Cheat Sheet</A> <P><A HREF="grep_lim.html" TARGET="cont">grep Search Limitations</A> <P><A HREF="tl.html" TARGET="cont">Timelines</A> <P><A HREF="sequencer.html" TARGET="cont">Event Sequencer</A> <P><A HREF="file_category.html" TARGET="cont">File Type Categories</A> <P><A HREF="hash_db.html" TARGET="cont">Hash Databases</A> <P><A HREF="int_mode.html" TARGET="cont">Image Integrity</A> <P><A HREF="timezones.html" TARGET="cont">Time Zones</A> </BODY></HTML> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/help/meta_mode.html��������������������������������������������������������������������0000644�0000765�0000024�00000007474�11070040246�016235� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>Autopsy Metadata Analysis Help</TITLE></HEAD> <BODY BGCOLOR=#CCCC99> <CENTER><H2>Metadata Analysis</H2></CENTER> <H3>Overview</H3> The Metadata Analysis mode allows the investigator to view the details of metadata structures. The metadata structures on the on-disk structures that contain the details of a file, such as times and pointers to the allocated data units. FFS and EXT2FS file systems call them inode structures, NTFS file systems call them Master File Table (MFT) entries (or File Entries), and the FAT file system calls them directory entries. This mode is useful for recovering data and getting a detailed look at a file. <H3>Input</H3> To view the contents of a structure, enter the address in the text box on the left and select <U>Display</U>. <P> The <U>Allocation List</U> button can also be used to view the allocation status of metadata structures in groups of 500. <H3>Viewing</H3> The structure details are displayed on the right-hand side. Typically, the metadata structure does not have the name of the file that uses that structure, so Autopsy will try to locate the file name. This process is slow with a FAT file system, so it is not done by default. <P> The <U>File Type</U> is given, which is the output of the 'file' tool. This tool uses any header information in the file to guess what its type is. The MD5 value of the file is also given. <P> If Autopsy has been configured to use hash databases, then one can select which databases to look for the file in. See <A HREF="hash_db.html">Hash Databases</A> for more details. <P> The rest of the information will vary depending on the file system type. In general, the allocation status will be given as well as the size and each data unit that it has allocated. A link will exist for each data unit that will show its contents. <P> The <U>Report</U> option generates an ASCII report with the structure details, MD5 values, and dates in it. The <U>View Contents</U> option displays the allocated data contents as one large file. The <U>Export</U> option allows one to save the data contents to a file. The <U>Add Note</U> button allows one to add a comment about this structure so that it can be later recalled. <H3>NTFS Notes</H3> <P> NTFS is a much different design than UNIX file systems and the meta data structures are addressed differently. They typically have the form of <TT>A-B-C</TT>, <TT>88-128-3</TT> for example. The <TT>A</TT> value is the address of the file in the Master File Table, 88 for example. This is similar to the inode value in UNIX. Each file has several attributes, including at least one in files for the data. The <TT>B</TT> value is the type of attribute. In most cases, the data attribute has a type of 128 so this is commonly seen. But, if you want to see the file name attribute, you could specify that type and see the contents if you like (it is fairly boring). The final value, <TT>C</TT>, is the id. Every attribute has a unique id value. So, if there are multiple attributes with the same type, you can specify the type. <H3>FAT Notes</H3> <P> FAT does not give addresses to the directory entry structures. in FAT, directory entries can be stored anywhere on the disk. They are stored in the clusters allocated to the parent directory. This is unlike NTFS or UNIX where the structures are in a large table that does not move. get around that, <P> The addressing issue was solved by providing an address to every 32-byte area in the Data Area. Whether that data was currently a directory entry or not. This makes it easy to find a given address and scale when new files are created. The downside is that not every address is possible, so it is likely that you will see jumps in the address values. See the documentation in The Sleuth Kit for more details. <P> <HR> <FONT SIZE=0>Brian Carrier</FONT> </BODY></HTML> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/help/sequencer.html��������������������������������������������������������������������0000644�0000765�0000024�00000003704�11070040246�016265� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>Autopsy Event Sequencer Help</TITLE></HEAD> <BODY BGCOLOR=#CCCC99> <CENTER><H2>Event Sequencer</H2></CENTER> <H3>Overview</H3> <P> In many investigations, evidence is not found in the order that it was created during the incident. The notes feature in Autopsy allows one to make notes about certain files, but it does not help one to put a series of events in order. <P> The Event Sequencer allows the investigator to make notes and comments about pieces of evidence. Each note must have a time associated with it. For files and meta data, the times can be one or more of the MAC times. Other notes can have times entered manually. The sequencer will sort the events after each is entered so that the investigator can quickly identify where there are gaps in the findings. <H3>Adding an Event</H3> <P> To add an event for a file, directory, or meta data structure, select the <U>Add Note</U> button. At the bottom will be check boxes that allow an event to be generated for each of the file's times. The "standard" note does not have to be generated if it is not needed. <P> To add an event from a different source, go to the Event Sequencer from the Host Gallery (where the images are listed). At the bottom of the window will be an area where the new event can be added. The <B>Source</B> of the event will be shown where the file name of a file event is normally shown. Examples of this type include entries from firewall logs or reports from the help desk. <H3>Viewing the Sequence Events</H3> <P> The <U>Event Sequencer</U> button can be found in the Host Gallery. This window shows the events that are sorted by the time. Events that correspond to a file, directory, or meta data structure will have either [M-Time], [A-Time], or [C-Time] in the note that shows what time this event was generated from. Clicking on the name will show the contents of the file or directory. <HR> <FONT SIZE=0>Brian Carrier</FONT> </BODY></HTML> ������������������������������������������������������������autopsy-2.24/help/srch_mode.html��������������������������������������������������������������������0000644�0000765�0000024�00000004647�11070040246�016245� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>Autopsy Keyword Search Help</TITLE></HEAD> <BODY BGCOLOR=#CCCC99> <CENTER><H2>Keyword Search</H2></CENTER> <H3>Overview</H3> <P> This mode searches an image for a given string. This is most useful when searching for deleted content. To decrease the time required for a search, a "strings" file can serve as an index. This file will contain only the ASCII strings in the image. <P> Autopsy will also prompt you to create a file of unallocated data if one does not exist. This obviously is useful for recovering deleted data. If a string is found in this file, Autopsy will also report the location in the original image. <H3>Entering the String</H3> Enter the string or regular expression into the text box. Autopsy allows you to search for a either a specific string or using 'grep' style regular expressions. A case insensitive search will occur if the appropriate box is checked, otherwise it is case sensitive. You will also have the option of searching for the string as an ASCII or a Unicode string. Unicode is much more common in Windows systems than Unix systems. If both types are selected, then two searches will be done. <P> If you have not generated a strings file or unallocated data file yet, that option will exist. <P> The <U>Load Unallocated Image</U> or <U>Load Allocated Image</U> button exists to switch between the two file types if they have both been generated. <P> Autopsy also has the ability to perform pre-configured searches. They are shown in the "Predefined Searches" section. <H3>Viewing the Results</H3> After the image has been searched, a list of "hits" will appear on the left-hand side. Each data unit that contains the string is listed with the offset of each occurrence. If a regular expression is used, then the exact location is not given. <P> If the search was done on an unallocated data file, then an option will exist next to each address to also view the original. Doing so could reveal the inode that allocated it. <H3>Previous Searches</H3> The search results are saved to a file so it is easy to recall the results with out having to perform the search again. <H3>Regular Expressions</H3> You can use grep regular expressions in the search (refer to the 'grep' <A HREF="grep.html"> help page</A> and man page for more details). To search for a couple of different words you would use: <TT>(foo) | (bar)</TT>. <HR> <FONT SIZE=0>Brian Carrier</FONT> </BODY></HTML> �����������������������������������������������������������������������������������������autopsy-2.24/help/temp.html�������������������������������������������������������������������������0000644�0000765�0000024�00000000217�11070040246�015234� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>Autopsy File Analysis Help</TITLE></HEAD> <BODY BGCOLOR=#CCCC99> <HR> <FONT SIZE=0>Brian Carrier</FONT> </BODY></HTML> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/help/timezones.html��������������������������������������������������������������������0000644�0000765�0000024�00000017207�11070040246�016313� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>Autopsy File Analysis Help - Time zone</TITLE></HEAD> <BODY BGCOLOR=#CCCC99> <p> When creating a host, you can specify a time zone. If you do not, it will default to the time zone to which your system is set. If the system being investigated came from a different time zone, then you need to figure out what it was called. Below are a list of time zones that are known by most computers. <p><br> This list was copied from this site: <tt>http://showtunepink.com/ical/TIMEZONES</tt> <pre> Africa/Addis_Ababa Africa/Algiers Africa/Asmera Africa/Bangui Africa/Blantyre Africa/Brazzaville Africa/Bujumbura Africa/Cairo Africa/Ceuta Africa/Dar_es_Salaam Africa/Djibouti Africa/Douala Africa/Gaborone Africa/Harare Africa/Johannesburg Africa/Kampala Africa/Khartoum Africa/Kigali Africa/Kinshasa Africa/Lagos Africa/Libreville Africa/Luanda Africa/Lubumbashi Africa/Lusaka Africa/Malabo Africa/Maputo Africa/Maseru Africa/Mbabane Africa/Mogadishu Africa/Nairobi Africa/Ndjamena Africa/Niamey Africa/Porto-Novo Africa/Tripoli Africa/Tunis Africa/Windhoek America/Adak America/Anchorage America/Anguilla America/Antigua America/Araguaina America/Aruba America/Asuncion America/Atka America/Barbados America/Belem America/Belize America/Boa_Vista America/Bogota America/Boise America/Buenos_Aires America/Cambridge_Bay America/Cancun America/Caracas America/Catamarca America/Cayenne America/Cayman America/Chicago America/Chihuahua America/Cordoba America/Costa_Rica America/Cuiaba America/Curacao America/Dawson America/Dawson_Creek America/Denver America/Detroit America/Dominica America/Edmonton America/Eirunepe America/El_Salvador America/Ensenada America/Fort_Wayne America/Fortaleza America/Glace_Bay America/Godthab America/Goose_Bay America/Grand_Turk America/Grenada America/Guadeloupe America/Guatemala America/Guayaquil America/Guyana America/Halifax America/Havana America/Hermosillo America/Indiana/Indianapolis America/Indiana/Knox America/Indiana/Marengo America/Indiana/Vevay America/Indianapolis America/Inuvik America/Iqaluit America/Jamaica America/Jujuy America/Juneau America/Kentucky/Louisville America/Kentucky/Monticello America/Knox_IN America/La_Paz America/Lima America/Los_Angeles America/Louisville America/Maceio America/Managua America/Manaus America/Martinique America/Mazatlan America/Mendoza America/Menominee America/Merida America/Mexico_City America/Miquelon America/Monterrey America/Montevideo America/Montreal America/Montserrat America/Nassau America/New_York America/Nipigon America/Nome America/Noronha America/Panama America/Pangnirtung America/Paramaribo America/Phoenix America/Port-au-Prince America/Port_of_Spain America/Porto_Acre America/Porto_Velho America/Puerto_Rico America/Rainy_River America/Rankin_Inlet America/Recife America/Regina America/Rio_Branco America/Rosario America/Santiago America/Santo_Domingo America/Sao_Paulo America/Scoresbysund America/Shiprock America/St_Johns America/St_Kitts America/St_Lucia America/St_Thomas America/St_Vincent America/Swift_Current America/Tegucigalpa America/Thule America/Thunder_Bay America/Tijuana America/Tortola America/Vancouver America/Virgin America/Whitehorse America/Winnipeg America/Yakutat America/Yellowknife Antarctica/Casey Antarctica/Davis Antarctica/DumontDUrville Antarctica/Mawson Antarctica/McMurdo Antarctica/Palmer Antarctica/South_Pole Antarctica/Syowa Antarctica/Vostok Arctic/Longyearbyen Asia/Aden Asia/Almaty Asia/Amman Asia/Anadyr Asia/Aqtau Asia/Aqtobe Asia/Ashgabat Asia/Ashkhabad Asia/Baghdad Asia/Bahrain Asia/Baku Asia/Bangkok Asia/Beirut Asia/Bishkek Asia/Brunei Asia/Calcutta Asia/Chungking Asia/Colombo Asia/Dacca Asia/Damascus Asia/Dhaka Asia/Dili Asia/Dubai Asia/Dushanbe Asia/Gaza Asia/Harbin Asia/Hong_Kong Asia/Hovd Asia/Irkutsk Asia/Istanbul Asia/Jakarta Asia/Jayapura Asia/Jerusalem Asia/Kabul Asia/Kamchatka Asia/Karachi Asia/Kashgar Asia/Katmandu Asia/Krasnoyarsk Asia/Kuala_Lumpur Asia/Kuching Asia/Kuwait Asia/Macao Asia/Magadan Asia/Manila Asia/Muscat Asia/Nicosia Asia/Novosibirsk Asia/Omsk Asia/Phnom_Penh Asia/Pyongyang Asia/Qatar Asia/Rangoon Asia/Riyadh Asia/Riyadh87 Asia/Riyadh88 Asia/Riyadh89 Asia/Saigon Asia/Samarkand Asia/Seoul Asia/Shanghai Asia/Singapore Asia/Taipei Asia/Tashkent Asia/Tbilisi Asia/Tehran Asia/Tel_Aviv Asia/Thimbu Asia/Thimphu Asia/Tokyo Asia/Ujung_Pandang Asia/Ulaanbaatar Asia/Ulan_Bator Asia/Urumqi Asia/Vientiane Asia/Vladivostok Asia/Yakutsk Asia/Yekaterinburg Asia/Yerevan Atlantic/Azores Atlantic/Bermuda Atlantic/Canary Atlantic/Cape_Verde Atlantic/Faeroe Atlantic/Jan_Mayen Atlantic/Madeira Atlantic/South_Georgia Atlantic/Stanley Australia/ACT Australia/Adelaide Australia/Brisbane Australia/Broken_Hill Australia/Canberra Australia/Darwin Australia/Hobart Australia/LHI Australia/Lindeman Australia/Lord_Howe Australia/Melbourne Australia/NSW Australia/North Australia/Perth Australia/Queensland Australia/South Australia/Sydney Australia/Tasmania Australia/Victoria Australia/West Australia/Yancowinna Brazil/Acre Brazil/DeNoronha Brazil/East Brazil/West CET CST6CDT Canada/Atlantic Canada/Central Canada/East-Saskatchewan Canada/Eastern Canada/Mountain Canada/Newfoundland Canada/Pacific Canada/Saskatchewan Canada/Yukon Chile/Continental Chile/EasterIsland Cuba EET EST EST5EDT Egypt Eire Etc/GMT+1 Etc/GMT+10 Etc/GMT+11 Etc/GMT+12 Etc/GMT+2 Etc/GMT+3 Etc/GMT+4 Etc/GMT+5 Etc/GMT+6 Etc/GMT+7 Etc/GMT+8 Etc/GMT+9 Etc/GMT-1 Etc/GMT-10 Etc/GMT-11 Etc/GMT-12 Etc/GMT-13 Etc/GMT-14 Etc/GMT-2 Etc/GMT-3 Etc/GMT-4 Etc/GMT-5 Etc/GMT-6 Etc/GMT-7 Etc/GMT-8 Etc/GMT-9 Europe/Amsterdam Europe/Andorra Europe/Athens Europe/Belfast Europe/Belgrade Europe/Berlin Europe/Bratislava Europe/Brussels Europe/Bucharest Europe/Budapest Europe/Chisinau Europe/Copenhagen Europe/Dublin Europe/Gibraltar Europe/Helsinki Europe/Istanbul Europe/Kaliningrad Europe/Kiev Europe/Lisbon Europe/Ljubljana Europe/London Europe/Luxembourg Europe/Madrid Europe/Malta Europe/Minsk Europe/Monaco Europe/Moscow Europe/Nicosia Europe/Oslo Europe/Paris Europe/Prague Europe/Riga Europe/Rome Europe/Samara Europe/San_Marino Europe/Sarajevo Europe/Simferopol Europe/Skopje Europe/Sofia Europe/Stockholm Europe/Tallinn Europe/Tirane Europe/Tiraspol Europe/Uzhgorod Europe/Vaduz Europe/Vatican Europe/Vienna Europe/Vilnius Europe/Warsaw Europe/Zagreb Europe/Zaporozhye Europe/Zurich GB GB-Eire GMT HST Hongkong Indian/Antananarivo Indian/Chagos Indian/Christmas Indian/Cocos Indian/Comoro Indian/Kerguelen Indian/Mahe Indian/Maldives Indian/Mauritius Indian/Mayotte Indian/Reunion Iran Israel Jamaica Japan Kwajalein Libya MET MST MST7MDT Mexico/BajaNorte Mexico/BajaSur Mexico/General Mideast/Riyadh87 Mideast/Riyadh88 Mideast/Riyadh89 NZ NZ-CHAT Navajo PRC PST8PDT Pacific/Apia Pacific/Auckland Pacific/Chatham Pacific/Easter Pacific/Efate Pacific/Enderbury Pacific/Fakaofo Pacific/Fiji Pacific/Funafuti Pacific/Galapagos Pacific/Gambier Pacific/Guadalcanal Pacific/Guam Pacific/Honolulu Pacific/Johnston Pacific/Kiritimati Pacific/Kosrae Pacific/Kwajalein Pacific/Majuro Pacific/Marquesas Pacific/Midway Pacific/Nauru Pacific/Niue Pacific/Norfolk Pacific/Noumea Pacific/Pago_Pago Pacific/Palau Pacific/Pitcairn Pacific/Ponape Pacific/Port_Moresby Pacific/Rarotonga Pacific/Saipan Pacific/Samoa Pacific/Tahiti Pacific/Tarawa Pacific/Tongatapu Pacific/Truk Pacific/Wake Pacific/Wallis Pacific/Yap Poland Portugal ROC ROK Singapore SystemV/AST4 SystemV/AST4ADT SystemV/CST6 SystemV/CST6CDT SystemV/EST5 SystemV/EST5EDT SystemV/HST10 SystemV/MST7 SystemV/MST7MDT SystemV/PST8 SystemV/PST8PDT SystemV/YST9 SystemV/YST9YDT Turkey US/Alaska US/Aleutian US/Arizona US/Central US/East-Indiana US/Eastern US/Hawaii US/Indiana-Starke US/Michigan US/Mountain US/Pacific US/Samoa W-SU WET </pre> <HR> <FONT SIZE=0>Brian Carrier</FONT> </BODY></HTML> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/help/tl.html���������������������������������������������������������������������������0000644�0000765�0000024�00000015162�11070040246�014713� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <HEAD><TITLE>Autopsy Timeline Analysis Help</TITLE></HEAD> <BODY BGCOLOR=#CCCC99> <CENTER><H2>Timeline Mode</H2></CENTER> <H3>Overview</H3> <P> For some investigations, creating a timeline of activity can be useful to identify places where the analysis should begin. Of course file times can be easily modified by an attacker, so they can not be 100% trusted. But, Autopsy can create timelines of file activity. <P> Files have at least three times associated with them. The details of each time varies with the file system type. <P> The following times exist for UNIX file systems (EXT2FS & FFS): <UL> <LI><B>Modified</B>: When the file data was last modified. This time can be modified using the utimes() function. This time is preserved in a 'tar' archive, so it is possible to have M-times of files prior to when they were introduced to the system. <LI><B>Accessed</B>: When the file data was last accessed. This time can be modified using the utimes() function. <LI><B>Changed</B>: When the file status (inode data) was last changed. This time can not be set using the utimes() function in UNIX (but it will be set when utimes() is used to modify other values). </UL> The EXT2FS file system also has a Deleted time, but it is not displayed in the timeline. <P> A FAT File system has the following times: <UL> <LI><B>Written</B>: When the file was last written to. It is the ONLY required time in the FAT file system. <LI><B>Accessed</B>: When the file was last accessed. In FAT, it is only accurate to the day (not minute). It is an optional value, so some Operating Systems may not update it. <LI><B>Created</B>: When the file was created. It is also optional, so some Operating Systems may not update it. In fact, many Windows installations have a C-Time of 0 for directories such as <TT>C:\\Windows</TT> and <TT>C:\\Program Files</TT>. </UL> <P> The NTFS File system has several times, four of which are used in the timeline. These times are gathered from the <TT>\$STANDARD_INFORMATION</TT> attribute. <UL> <LI><B>Written</B>: When the file was last written to. <LI><B>Accessed</B>: When the file was last accessed. <LI><B>Changed</B>: When the MFT entry was last modified. <LI><B>Created</B>: When the file was created. </UL> <H3>How to Create a Timeline</H3> Creating a timeline takes two steps. The first step extracts and saves the needed data from each file system images. This step stores the data from each specific file system in a generic format. Historically (from TCT), this file was called the <TT>body</TT> file. The second step takes the <TT>body</TT> file as input and generates an ASCII timeline of file activity between two specified dates. The resulting timeline can be viewed in Autopsy or using a text editor. <H3>Creating the Body File</H3> The file meta-data must be extracted from the file system images and saved to the <TT>body</TT> file. There are three major types of files that data can be extracted for: <UL> <LI><B>Allocated Files</B>: Files that are seen when doing an 'ls' or 'dir' in a directory. In other words, these are the files that have an allocated file name structure. <LI><B>Unallocated Files</B>: Files that have been deleted, but that TSK can still access. Files in this category include orphan files, which are files that no longer have a name, but whose metadata still exists. If a deleted file name points to an allocated metadata structure, then the name will say (realloc) next to it. </UL> <P> To create the <TT>body</TT> file, select the images to analyze from the list on top. Next, select which types of data that you want to extract. By default all types are extracted. Lastly, identify the name of the body file to create. The file will be created in the <TT>output</TT> directory and an entry will be added to the host config file. You will be given the option to calculate the MD5 value of the new file. <H3>Creating the Timeline</H3> The next window allows one to create a timeline based on the newly created <TT>body</TT> file. Or, one can select the option from the left-hand side menu. The range of dates must be selected as well as the name of the timeline file. The resulting timeline will use the time zone for the host. <P> If the images are from a UNIX file system, then the password and group files can be used to change the UID and GID to actual names. If the partition from the root directory exists in the host, select it from the pull down list and Autopsy will find the <TT>/etc/passwd</TT> and <TT>/etc/group</TT> file contents. <P> The timeline will be created in the <TT>output</TT> directory. You will be given the option to calculate the MD5 hash value of the new file. <H3>Viewing the Timeline</H3> The timeline can be viewed in Autopsy. Timelines tend to be very large though and have thousands of lines. HTML browsers can not handle tables of this size very well and typically have trouble processing it. Therefore, Autopsy only allows you to view the timeline one month at a time. It will likely be easier to open a shell and examine the timeline in a text editor or pager such as 'less' or 'more'. <P> The 'summary' link will show a page that contains a monthly summary of activity. It shows how many many events occured in that month and links to the details. This allows one to get a high level view of when a lot of activity last occured. <P> The following columns are in the timeline (in order): <UL> <LI><B>Date and time</B>of the activity. If no date is given, then the activity occured at the same time as the previous entry with a time. <LI><B>Size</B>. The size of the file. <LI><B>Entry Type</B>. The 'm', 'a', 'c', and 'b' letters will exist to identify which of the activity types this entry corresponds to. 'm' is for modified times, 'a' is for access times, 'c' is for change times, and 'b' is for created (or born) times. <LI><B>Mode</B. The UNIX mode is shown. <LI><B>UID</B>. The User Id or User name is shown. If a password file was provided when the timeline was created, then the colunn should only have names. <LI><B>GID</B>. The Group Id or Group name is shown. If a group file was provided when the timeline was created, then the colunn should only have names. <LI><B>Meta Data Address</B>. The inode or MFT entry address for the associated file. <LI><B>File Name</B>. The name of the file and the destination of a symbolic link. Deleted entries will have '(deleted)' at the end and deleted entries that point to an allocated meta data structure will have '(realloc)'. </UL> <HR> <FONT SIZE=0>Brian Carrier</FONT> </BODY></HTML> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/INSTALL.txt����������������������������������������������������������������������������0000644�0000765�0000024�00000003146�11355002261�014325� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ Autopsy Forensic Browser http://www.sleuthkit.org/autopsy Brian Carrier [carrier@sleuthkit.org] Last Update: March 2010 Installation ----------------------------------------------------------------------------- 1. Install The Sleuth Kit (see README for download locations). This includes doing a 'make install' so that the executables and files are installed in a single directory. Note that this does not currently work natively on Windows. It will work using Cygwin, but you must install and build The Sleuth Kit in Cygwin and not use the Win32 executables that are available on the sleuthkit.org website. 2. Untar the Autopsy file. 3. Run 'make'. It will try to locate the grep and strings utilities. If any are not found, it will prompt you for the location. It will also search for the TSK installation. 4. The install script will ask if you have the NIST National Software Reference Library (NSRL). If you do, you will need to enter the path of it. The NSRL is available from www.nsrl.nist.gov. 5. You will be prompted for the Evidence Locker location. This is the base directory where all cases will be stored. You must create this directory on your own. Live Analysis ------------------------------------------------------------------------------ Type 'make live' or run the 'make-live-cd' script to build the 'live-cd' directory. The 'live-cd' directory can be burned to a CD. ------------------------------------------------------------------------------ Brian Carrier [carrier@sleuthkit.org] ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/lib/�����������������������������������������������������������������������������������0000755�0000765�0000024�00000000000�11355002266�013225� 5����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/lib/.perltidyrc������������������������������������������������������������������������0000755�0000765�0000024�00000000221�11070040246�015377� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-i=4 # indent of 4 -pt=2 # paren tightness -sbt=2 # square paren tightness -bt=2 # curly paren tightness -nsfs # no space after semi in for loop �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/lib/Appsort.pm�������������������������������������������������������������������������0000644�0000765�0000024�00000027600�11335317651�015225� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Sort files based on their application type (content) # # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2001-2008 by Brian Carrier. All rights reserved # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package Appsort; $Appsort::FRAME = 1; $Appsort::MENU = 2; $Appsort::ENTER = 3; $Appsort::RUN = 4; $Appsort::VIEW = 5; $Appsort::BLANK = 6; sub main { if ($::LIVE == 1) { Print::print_html_header("Unsupported for Live Analysis"); print "<center><h2>This feature is not available during a live analysis</h2></center>"; Print::print_html_footer(); return 0; } # By default, show the main frame $Args::args{'view'} = $Args::enc_args{'view'} = $Appsort::FRAME unless (exists $Args::args{'view'}); Args::check_view(); my $view = Args::get_view(); if ($view == $Appsort::BLANK) { return blank(); } # Check Basic Args Args::check_vol('vol'); # These windows don't need the meta data address if ($view == $Appsort::FRAME) { return frame(); } elsif ($view == $Appsort::ENTER) { return enter(); } elsif ($view == $Appsort::MENU) { return menu(); } elsif ($view == $Appsort::RUN) { return run(); } elsif ($view == $Appsort::VIEW) { return view(); } else { Print::print_check_err("Invalid Application Sorting View"); } } sub get_sorter_dir { if ($Args::args{'vol'} =~ /^($::REG_VNAME)$/) { return "$::host_dir" . "$::DATADIR/sorter-$1/"; } Print::print_err("Invalid Sorter Directory"); } sub get_sorter_graphics_dir { if ($Args::args{'vol'} =~ /^($::REG_VNAME)$/) { return "$::host_dir" . "$::DATADIR/sorter-graphics-$1/"; } Print::print_err("Invalid Sorter Graphics Directory"); } # sorter frameset sub frame { Print::print_html_header_frameset("Sorter on $Args::args{'vol'}"); print "<frameset cols=\"20%,80%\">\n"; # Block List print "<frame src=\"$::PROGNAME?mod=$::MOD_APPSORT&view=$Appsort::MENU&" . "$Args::baseargs\">\n"; # Blank print "<frame src=\"$::PROGNAME?mod=$::MOD_APPSORT&view=$Appsort::BLANK&" . "$Args::baseargs\" name=\"content\">\n" . "</frameset>\n"; Print::print_html_footer_frameset(); return 0; } # The left-hand frame for running sorter sub menu { Print::print_html_header("sorter menu"); print "<p><a href=\"$::PROGNAME?mod=$::MOD_APPSORT&view=$Appsort::ENTER&" . "$Args::baseargs\" " . "target=\"content\">Sort Files by Type</a>"; print "<p><a href=\"$::PROGNAME?mod=$::MOD_APPSORT&view=$Appsort::VIEW&" . "$Args::baseargs\" " . "target=\"content\">View Sorted Files</a>"; Print::print_html_footer(); return 0; } # Get the data and print the form so that sorter can be run sub enter { Print::print_html_header("sorter - enter data to create"); print "<center>" . "<h3>File Type Sortings</h3></center><br>" . "<form action=\"$::PROGNAME\" method=\"get\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_APPSORT\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Appsort::RUN\">\n" . "<input type=\"hidden\" name=\"vol\" value=\"$Args::args{'vol'}\">\n" . Args::make_hidden(); print <<EOF1; <p>The <b>sorter</b> tool will process an image and organize the files based on their file type. The files are organized into categories that are defined in configuration files. The categories will be saved in the <tt>$::DATADIR</tt> directory. <hr> EOF1 my $sort_dir = get_sorter_dir(); if (-d "$sort_dir") { print "WARNING: This will overwrite any existing data in:<br>" . "&nbsp;&nbsp;&nbsp;&nbsp;<tt>$sort_dir</tt><br>\n"; } my $tab = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; print <<EOF2; <p> <input type=\"checkbox\" name=\"sorter_cat\" value=\"1\" CHECKED> Sort files into categories by type <p>$tab <input type=\"checkbox\" name=\"sorter_unk\" value=\"1\"> Do not save data about <tt>unknown</tt> file types <p>$tab <input type=\"checkbox\" name=\"sorter_save\" value=\"1\"> Save a copy of files in category directory (may require lots of disk space) <p>$tab <input type=\"checkbox\" name=\"sorter_img\" value=\"1\"> Save ONLY graphic images and make thumbnails <br> $tab (may require lots of disk space and will save to a different directory than sorting all file types) <p> <input type=\"checkbox\" name=\"sorter_ext\" value=\"1\" CHECKED> Extension and File Type Validation EOF2 if (($::NSRLDB ne "") && (-e "$::NSRLDB")) { # NSRL print "<p><input type=\"checkbox\" name=\"sorter_nsrl\" value=\"1\" CHECKED>" . "Exclude files in the <b>NIST NSRL</b>\n"; } if (($Caseman::alert_db ne "") && (-e "$Caseman::alert_db")) { print "<p><input type=\"checkbox\" name=\"sorter_alert\" value=\"1\" CHECKED>" . "Alert files that are found in the <b>Alert Hash Database</b>\n"; } if (($Caseman::exclude_db ne "") && (-e "$Caseman::exclude_db")) { print "<p><input type=\"checkbox\" name=\"sorter_exclude\" value=\"1\" CHECKED>" . "Ignore files that are found in the <b>Exclude Hash Database</b>\n"; } print "<p><input type=\"image\" src=\"pict/but_ok.jpg\" " . "width=43 height=20 alt=\"Ok\" border=\"0\">\n</form>\n"; Print::print_html_footer(); return; } # Run sorter on the image sub run { Print::print_html_header("sorter - create"); my $sort_args = ""; my $ext = 0; my $cat = 0; my $vol = Args::get_vol('vol'); my $mnt = $Caseman::vol2mnt{$vol}; my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; Print::log_host_inv("Running 'sorter' on ($Caseman::vol2sname{$vol}"); $ext = 1 if ( (exists $Args::args{'sorter_ext'}) && ($Args::args{'sorter_ext'} == 1)); $cat = 1 if ( (exists $Args::args{'sorter_cat'}) && ($Args::args{'sorter_cat'} == 1)); if (($cat == 0) && ($ext == 0)) { print "At least one action must be selected\n" . "<p><a href=\"$::PROGNAME?mod=$::MOD_APPSORT&" . "view=$Appsort::ENTER&$Args::baseargs\">" . "<img border=0 src=\"pict/but_ok.jpg\" alt=\"Ok\" " . "width=43 height=20></a>\n"; return; } # If both actions are wanted then no flags are needed $sort_args .= "-e " if (($ext == 1) && ($cat == 0)); $sort_args .= "-E " if (($ext == 0) && ($cat == 1)); my $sort_dir = get_sorter_dir(); if ($cat == 1) { if ( (exists $Args::args{'sorter_img'}) && ($Args::args{'sorter_img'} == 1)) { my $config = "$::TSKDIR/../share/tsk3/sorter/images.sort"; Print::print_err("images configuration file not found ($config)") unless (-e "$config"); $sort_args .= "-C \'$config\' -s -U "; $sort_dir = get_sorter_graphics_dir(); } else { $sort_args .= "-s " if ( (exists $Args::args{'sorter_save'}) && ($Args::args{'sorter_save'} == 1)); $sort_args .= "-U " if ( (exists $Args::args{'sorter_unk'}) && ($Args::args{'sorter_unk'} == 1)); } } if ($::NSRLDB ne "") { $sort_args .= "-n \'$::NSRLDB\' " if ( (exists $Args::args{'sorter_nsrl'}) && ($Args::args{'sorter_nsrl'} == 1)); } if ($Caseman::alert_db ne "") { $sort_args .= "-a \'$Caseman::alert_db\' " if ( (exists $Args::args{'sorter_alert'}) && ($Args::args{'sorter_alert'} == 1)); } if ($Caseman::exclude_db ne "") { $sort_args .= "-x \'$Caseman::exclude_db\' " if ( (exists $Args::args{'sorter_exclude'}) && ($Args::args{'sorter_exclude'} == 1)); } unless (-d "$sort_dir") { unless (mkdir "$sort_dir", $::MKDIR_MASK) { Print::print_err("Error making $sort_dir"); } } if (-e "$sort_dir/index.html") { unlink("$sort_dir/index.html"); } my $exec = "-h -m '$mnt' -d '$sort_dir' -o $offset -i $imgtype -f $ftype $sort_args $img"; # print "Executing: <tt>sorter $exec</tt><p>\n"; # Execute Sorter my $hit_cnt = 0; $SIG{ALRM} = sub { if (($hit_cnt++ % 5) == 0) { print "+"; } else { print "-"; } alarm(5); }; alarm(5); local *OUT; Exec::exec_pipe(*OUT, "LANG=C LC_ALL=C '$::TSKDIR/sorter' $exec"); alarm(0); $SIG{ALRM} = 'DEFAULT'; while ($_ = Exec::read_pipe_line(*OUT)) { print "$_<br>\n"; $hit_cnt = 0; } close(OUT); if (-e "$sort_dir/index.html") { print "<p>Output can be found by viewing:<br>" . "&nbsp;&nbsp;<tt>$sort_dir/index.html</tt><p>\n"; # Print the index.html file from the output print "<hr><center><h3>Results Summary</h3></center>\n"; open INDEX, "<$sort_dir/index.html" or die "Can't open sorter index file ($sort_dir/index.html)"; while (<INDEX>) { next if ((/^<HTML><HEAD><TITLE>/i) || (/^<BODY><center><H2>/i)); # Extract out the symlinks to the categories if (/^\s*<li><a href="\.\/[\w\.]+">([\w\s]+)<\/a> \((\d+)\)\s*$/i) { print "<LI>$1 ($2)\n"; } # Skip the link on the thumbnails link elsif (/^\s*\(<a href=[\"\.\/\w]+>thumbnails<\/A>\)\s*$/) { print "(thumbnails)\n"; } else { print "$_"; } } close(INDEX); } Print::print_html_footer(); return; } # View Page sub view { Print::print_html_header(""); print "<center><h3>File Type Sorting</h3>\n" . "Autopsy does not currently support viewing the sorted files.<br>\n" . "After sorting, you can view the results by opening the following file:<p>\n"; print "<tt>" . get_sorter_dir() . "index.html</tt>"; Print::print_html_footer(); return 0; } # Blank Page sub blank { Print::print_html_header(""); print "<center><h3>File Type Sorting</h3>\n" . "In this mode, Autopsy will examine allocated and unallocated files<br> and " . "sort them into categories and verify the extension.<p>This allows you to find a file based on" . "its type and find \"hidden\" files.<p>\n" . "WARNING: This can be a time intensive process.<br>\n"; Print::print_html_footer(); return 0; } ��������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/lib/Appview.pm�������������������������������������������������������������������������0000644�0000765�0000024�00000021560�11070040246�015174� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # View the application layer (HTML, picutures etc.) # # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2001-2005 by Brian Carrier. All rights reserved # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Updated 1/15 package Appview; $Appview::CELL_FRAME = 1; $Appview::CELL_MENU = 2; $Appview::CELL_CONT = 3; sub main { # By default, show the main frame $Args::args{'view'} = $Args::enc_args{'view'} = $Appview::CELL_FRAME unless (exists $Args::args{'view'}); Args::check_view(); my $view = Args::get_view(); # Check Basic Args Args::check_vol('vol'); Args::check_meta('meta'); Args::check_dir(); Args::check_recmode(); if ($view == $Appview::CELL_FRAME) { return cell_frame(); } elsif ($view == $Appview::CELL_CONT) { return cell_content(); } elsif ($view == $Appview::CELL_MENU) { return cell_menu(); } else { Print::print_check_err("Invalid Application Viewing View"); } } ######################################################################### # # CELL - Sanitized Environment # my $CELL_MODE_SANIT = 1; my $CELL_MODE_NORM = 2; sub cell_frame { Print::print_html_header_frameset("Autopsy Cell"); my $vol = Args::get_vol('vol'); my $mnt = $Caseman::vol2mnt{$vol}; my $fname = "$mnt$Args::args{'dir'}"; print "<frameset rows=\"15%,85%\">\n"; # if a mode was not given, then choose the Sanitized by default $Args::args{'cell_mode'} = $CELL_MODE_SANIT unless ((exists $Args::args{'cell_mode'}) && ($Args::args{'cell_mode'} =~ /^\d$/)); my $url = "&$Args::baseargs&meta=$Args::enc_args{'meta'}" . "&dir=$Args::enc_args{'dir'}&" . "cell_mode=$Args::args{'cell_mode'}&recmode=$Args::args{'recmode'}"; print "<frame src=\"$::PROGNAME?mod=$::MOD_APPVIEW&view=$Appview::CELL_MENU${url}\">\n" . "<frame src=\"$::PROGNAME?mod=$::MOD_APPVIEW&view=$Appview::CELL_CONT${url}\">\n" . "</frameset>\n"; Print::print_html_footer_frameset(); return 0; } # Print the menu on top. This allows one to export the file and change modes sub cell_menu { Args::check_cell_mode(); Print::print_html_header("Cell Header"); my $cell_mode = $Args::args{'cell_mode'}; my $url = "&$Args::baseargs&meta=$Args::enc_args{'meta'}&" . "dir=$Args::enc_args{'dir'}&recmode=$Args::enc_args{'recmode'}"; if ($cell_mode == $CELL_MODE_SANIT) { print <<EOF1; <center> This file is currently being viewed in a <b>sanitized environment</b><br> HTML files have been edited to disable scripts and links. The script contents will be shown as text.<br> Pictures have been replaced by place holders<br> <table width=300 cellspacing=\"0\" cellpadding=\"2\"> <tr> <td align=center> <a href=\"$::PROGNAME?mod=$::MOD_APPVIEW&view=$Appview::CELL_FRAME$url&cell_mode=$CELL_MODE_NORM\" target=\"_top\"> <img src=\"pict/sanit_b_norm.jpg\" alt=\"Normal\" border=\"0\"> </a> </td> EOF1 } elsif ($cell_mode == $CELL_MODE_NORM) { print <<EOF2; <center> This file is currently being viewed in a <b>normal environment</b><br> HTML files are being viewed without modification.<br> <table width=300 cellspacing=\"0\" cellpadding=\"2\"> <tr> <td align=center> <a href=\"$::PROGNAME?mod=$::MOD_APPVIEW&view=$Appview::CELL_FRAME&$url&cell_mode=$CELL_MODE_SANIT\" target=\"_top\"> <img src=\"pict/sanit_b_san.jpg\" alt=\"Sanitized\" border=\"0\"> </a> </td> EOF2 } # Export the file print "<td align=center>\n" . "<a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::EXPORT&$url\">" . "<img src=\"pict/but_export.jpg\" alt=\"export\" border=\"0\" " . "width=123 height=20>" . "</a></td></tr>\n"; print "<tr><td colspan=\"2\" align=\"center\">" . "Deleted File Recovery Mode</td></tr>\n" if ($Args::enc_args{'recmode'} == $File::REC_YES); print "</table>"; Print::print_html_footer(); return; } # Display safe and common things in the browser (pictures, basic html) sub cell_content { Args::check_meta('meta'); Args::check_dir(); Args::check_cell_mode(); my $meta = Args::get_meta('meta'); my $vol = Args::get_vol('vol'); my $mnt = $Caseman::vol2mnt{$vol}; my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $fname = "$mnt$Args::args{'dir'}"; my $recflag = ""; $recflag = " -r " if (Args::get_recmode() == $File::REC_YES); # identify what type it is local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" ); my $file_type = Exec::read_pipe_line(*OUT); close(OUT); $file_type = "Error getting file type" if ((!defined $file_type) || ($file_type eq "")); if ($file_type =~ /JPEG image data/) { Print::log_host_inv("$vol: Viewing $fname ($meta) as JPEG"); print "Content-type: image/jpeg$::HTTP_NL$::HTTP_NL"; } elsif ($file_type =~ /GIF image data/) { Print::log_host_inv("$vol: Viewing $fname ($meta) as GIF"); print "Content-type: image/gif$::HTTP_NL$::HTTP_NL"; } elsif ($file_type =~ /PNG image data/) { Print::log_host_inv("$vol: Viewing $fname ($meta) as PNG"); print "Content-type: image/png$::HTTP_NL$::HTTP_NL"; } elsif ($file_type =~ /PC bitmap data/) { Print::log_host_inv("$vol: Viewing $fname ($meta) as BMP"); print "Content-type: image/bmp$::HTTP_NL$::HTTP_NL"; } elsif ($file_type =~ /HTML document text/) { Print::log_host_inv("$vol: Viewing $fname ($meta) as HTML"); print "Content-type: text/html$::HTTP_NL$::HTTP_NL"; } else { Print::log_host_inv("$vol: Unknown format of meta $meta "); Print::print_check_err("Unknown File Type for Viewing: $file_type"); } local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta" ); while ($_ = Exec::read_pipe_line(*OUT)) { # Parse out bad "stuff" if ( ($file_type =~ /HTML document text/) && ($Args::args{'cell_mode'} == $CELL_MODE_SANIT)) { $_ =~ s/\bsrc=/src=$::SANITIZE_TAG\?/ig; $_ =~ s/\bhref=/href=$::SANITIZE_TAG\?/ig; $_ =~ s/<script/<$::SANITIZE_TAG-script/ig; $_ =~ s/\bbackground=/background=$::SANITIZE_TAG\?/ig; } print "$_"; } print "$::HTTP_NL$::HTTP_NL"; close(OUT); return 0; } sub sanitize_pict { my $url = shift(); my $lurl = $url; $lurl =~ tr/[A-Z]/[a-z]/; print "HTTP/1.0 200 OK$::HTTP_NL"; if ( ($lurl =~ /.jpg/i) || ($lurl =~ /.jpeg/i) || ($lurl =~ /.gif/i) || ($lurl =~ /.png/i) || ($lurl =~ /.bmp/i)) { open PICT, "<$::PICTDIR/$::SANITIZE_PICT" or die "can not open $::PICTDIR/$::SANITIZE_PICT"; print "Content-type: image/jpeg$::HTTP_NL$::HTTP_NL"; while (<PICT>) { print "$_"; } close(PICT); print "$::HTTP_NL$::HTTP_NL"; } else { $url =~ tr/\+/ /; $url =~ s/%([a-f0-9][a-f0-9])/chr( hex( $1 ) )/eig; Print::print_html_header("Denied"); print "<h1><center>Unable to Complete Request</h1><br>\n" . "<tt>Autopsy</tt> will not follow links from " . "untrusted HTML pages:<br><tt>$url</tt><br>\n"; Print::print_html_footer(); } exit(0); } ������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/lib/Args.pm����������������������������������������������������������������������������0000644�0000765�0000024�00000056274�11070040246�014467� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Functions to check and get the arguments from URL # # ver 2.00+ # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2003-2004 by Brian Carrier. All rights reserved # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package Args; # Parse the argument string into the args hash sub parse_args { my $lcl_args = shift; foreach my $nam_val (split(/&/, $lcl_args)) { my ($name, $value) = split(/=/, $nam_val); if (defined $value) { my $dec_name = url_decode($name); $Args::enc_args{$dec_name} = $value; $Args::args{$dec_name} = url_decode($value); } } } sub url_encode { my $text = shift; $text =~ s/([^a-z0-9_.!~*'() -])/sprintf "%%%02X", ord($1)/eig; $text =~ tr/ /+/; return $text; } sub url_decode { my $text = shift; $text =~ tr/\+/ /; $text =~ s/%([a-f0-9][a-f0-9])/chr( hex( $1 ) )/eig; return $text; } # This assumes that the checking of the types has been done and this just # makes a string of the key values if they exist # # case # host # img # Must add & after sub make_baseargs { $Args::baseargs = ""; # The standard case, host, and investigator $Args::baseargs .= "case=$Args::enc_args{'case'}&" if ((exists $Args::enc_args{'case'}) && ($Args::enc_args{'case'} ne "")); $Args::baseargs .= "host=$Args::enc_args{'host'}&" if ((exists $Args::enc_args{'host'}) && ($Args::enc_args{'host'} ne "")); $Args::baseargs .= "inv=$Args::enc_args{'inv'}&" if ((exists $Args::enc_args{'inv'}) && ($Args::enc_args{'inv'} ne "")); $Args::baseargs_novol = $Args::baseargs; # Add the image, file system type, and mount point $Args::baseargs .= "vol=$Args::enc_args{'vol'}&" if ((exists $Args::enc_args{'vol'}) && ($Args::enc_args{'vol'} ne "")); # remove the final '&' $Args::baseargs_novol = $1 if ($Args::baseargs_novol =~ /^(.*?)&$/); $Args::baseargs = $1 if ($Args::baseargs =~ /^(.*?)&$/); return; } # Does not do mnt or img sub make_hidden { my $str = ""; $str .= "<input type=\"hidden\" name=\"host\" value=\"$Args::args{'host'}\">\n" if ((exists $Args::args{'host'}) && ($Args::args{'host'} ne "")); $str .= "<input type=\"hidden\" name=\"case\" value=\"$Args::args{'case'}\">\n" if ((exists $Args::args{'case'}) && ($Args::args{'case'} ne "")); $str .= "<input type=\"hidden\" name=\"inv\" value=\"$Args::args{'inv'}\">\n" if ((exists $Args::args{'inv'}) && ($Args::args{'inv'} ne "")); return $str; } ############################### # block ############################### sub check_block { if ((!exists $Args::args{'block'}) || ($Args::args{'block'} !~ /^\d+$/)) { Print::print_check_err( "Invalid block argument (positive numbers only)"); } return 0; } sub get_block { if ($Args::args{'block'} =~ /^(\d+)$/) { return $1; } Print::print_err("Invalid Block"); } ############################### # body ############################### sub check_body { unless (exists $Args::args{'body'}) { Print::print_check_err("Missing body argument"); } unless ($Args::args{'body'} =~ /^$::REG_VNAME$/o) { Print::print_check_err( "Invalid body value (only letters, " . "numbers,-,., and _)"); } return 0; } sub get_body { if ($Args::args{'body'} =~ /^($::REG_VNAME)$/o) { return $1; } Print::print_err("Invalid Body"); } ################################ # Case name ################################ sub check_case { unless (exists $Args::args{'case'}) { Print::print_check_err("Missing case argument"); } unless ($Args::args{'case'} =~ /^$::REG_CASE$/o) { Print::print_check_err( "Invalid case value (letters, num, and symbols only"); } return 0; } sub get_case { if ($Args::args{'case'} =~ /^($::REG_CASE)$/o) { return $1; } Print::print_err("Invalid Case Name"); } ############################### # cell_mode ############################### sub check_cell_mode { if ( (!exists $Args::args{'cell_mode'}) || ($Args::args{'cell_mode'} !~ /^\d$/o)) { Print::print_check_err( "Invalid cell_mode argument (numbers >= 0 only)"); } return 0; } ################################ # dir ################################ sub check_dir { if ( (!exists $Args::args{'dir'}) || ($Args::args{'dir'} =~ /\/\.\.\//) || ($Args::args{'dir'} =~ /\;/)) { Print::print_check_err("Invalid dir argument (valid file path only)"); } return 0; } sub get_dir { if ($Args::args{'dir'} =~ /([^;]*)/o) { my $d = $1; # Remove double slashes $d =~ s/\/\//\//g; return $d; } Print::print_err("Invalid Directory"); } ############################### # dirmode ############################### sub check_dirmode { if ((!exists $Args::args{'dirmode'}) || ($Args::args{'dirmode'} !~ /^\d+$/)) { Print::print_check_err( "Invalid dirmode argument (positive numbers only)"); } return 0; } sub get_dirmode { if ($Args::args{'dirmode'} =~ /^(\d+)$/) { return $1; } Print::print_err("Invalid dirmode"); } ################################ # do_md5 ################################ sub check_do_md5 { if ((!exists $Args::args{'do_md5'}) || ($Args::args{'do_md5'} !~ /^\d+$/)) { Print::print_check_err("Missing do_md5 argument"); } return 0; } sub get_do_md5 { if ($Args::args{'do_md5'} =~ /^\s*(\d+)$/) { return $1; } Print::print_err("Invalid MD5 Flag"); } ################################ # fname ################################ sub check_fname { unless (exists $Args::args{'fname'}) { Print::print_check_err("Missing fname argument"); } unless ($Args::args{'fname'} =~ /^$::REG_FNAME$/o) { Print::print_check_err( "Invalid fname value (only letters, " . "numbers,-,., and _)"); } return 0; } sub get_fname { if ($Args::args{'fname'} =~ /^($::REG_FNAME)$/o) { return "$::host_dir" . "$::DATADIR/$1"; } Print::print_err("Invalid File Name"); } ################################ # fname_mode ################################ sub check_fname_mode { if (!exists $Args::args{'fname_mode'}) { Print::print_check_err("Missing fname_mode argument"); } unless ($Args::args{'fname_mode'} =~ /^\d+$/) { Print::print_check_err("invalid mode: numbers only"); } return 0; } ################################ # fname_rel # Return the relative fname ################################ sub get_fname_rel { if ($Args::args{'fname'} =~ /^($::REG_FNAME)$/o) { return "$::DATADIR/$1"; } Print::print_err("Invalid Relative File Name"); } ############################### # force ############################### sub get_force { if ($Args::args{'force'} =~ /^(\d+)$/) { return $1; } Print::print_err("Invalid Force Flag"); } ################################ # ftype ################################ sub get_ftype_blah { if (exists $Args::args{'ftype'}) { if ($Args::args{'ftype'} =~ /^($::REG_FTYPE)$/o) { return $1; } } if ( (exists $Args::args{'img'}) && (exists $Caseman::vol2ftype{$Args::args{'img'}})) { return $Caseman::vol2ftype{$Args::args{'img'}}; } Print::print_err("Missing ftype value"); } sub check_ftype_blah { unless ( ( (exists $Args::args{'img'}) && (exists $Caseman::vol2ftype{$Args::args{'img'}}) && ($Caseman::vol2ftype{$Args::args{'img'}} =~ /^$::REG_FTYPE$/o) ) || ( (exists $Args::args{'ftype'}) && ($Args::args{'ftype'} =~ /^$::REG_FTYPE$/o)) ) { Print::print_check_err("Missing or invalid ftype value"); } return 0; } ################################ # host # Host for the case ################################ sub check_host { unless (exists $Args::args{'host'}) { Print::print_check_err("Missing host argument"); } unless ($Args::args{'host'} =~ /^$::REG_HOST$/o) { Print::print_check_err("Invalid host value"); } return 0; } sub get_host { if ($Args::args{'host'} =~ /^($::REG_HOST)$/o) { return $1; } Print::print_err("Invalid Host"); } ################################ # htype ################################ sub check_htype { if ((!exists $Args::args{'htype'}) || ($Args::args{'htype'} !~ /^\d+$/)) { Print::print_check_err( "Invalid htype argument (positive numbers only)"); } return 0; } sub get_htype { if ($Args::args{'htype'} =~ /^(\d+)$/) { return $1; } Print::print_err("Invalid htype"); } ############################### # ifind # ifind is optional and by default is 0 if not given ############################### sub get_ifind { if (!exists $Args::args{'ifind'}) { return 0; } elsif ($Args::args{'ifind'} =~ /^(\d+)$/) { return $1; } Print::print_err("Invalid ifind flag"); } ############################### # img_path is used when adding images - it is the full path to the # non-evidence locker copy of the image ############################### sub check_img_path { if (!exists $Args::args{'img_path'}) { Print::print_check_err("Missing image (img_path) argument"); } elsif ($Args::args{'img_path'} =~ /^$::REG_IMG_PATH$/o) { # Check for its actual existence Print::print_check_err("Image not found at $Args::args{'img_path'}") unless ( (-e "$Args::args{'img_path'}") || ( (-l "$Args::args{'img_path'}") && (-e readlink "$::host_dir" . "$Args::args{$img}")) ); } else { Print::print_check_err("Invalid image path (only letters, " . "numbers,-,.,_/ and start with /) [$Args::args{'img_path'}]"); } return 0; } sub get_img_path { if ($Args::args{'img_path'} =~ /^($::REG_IMG_PATH)$/o) { return "$1"; } Print::print_err("Invalid Image Path"); } sub check_img_path_wild { if (!exists $Args::args{'img_path'}) { Print::print_check_err("Missing wild image (img_path) argument"); } elsif ($Args::args{'img_path'} !~ /^$::REG_IMG_PATH_WILD$/o) { # IF there is extra white space then remove it and move on if ($Args::args{'img_path'} =~ /^\s*($::REG_IMG_PATH_WILD)\s*$/o) { $Args::args{'img_path'} = $1; return 0; } else { Print::print_check_err("Invalid wild image (img_path) argument"); } } return 0; } sub get_img_path_wild { if ($Args::args{'img_path'} =~ /^($::REG_IMG_PATH_WILD)$/o) { return "$1"; } Print::print_err("Invalid Image Path"); } ############################### # meta ############################### sub check_meta { my $meta = shift; if ( (!exists $Args::args{$meta}) || ($Args::args{$meta} !~ /^$::REG_META$/o)) { Print::print_check_err( "Invalid meta address ($meta) argument (numbers >= 0 only)"); } return 0; } sub get_meta { my $meta = shift; if ($Args::args{$meta} =~ /^($::REG_META)$/o) { return $1; } Print::print_err("Invalid Meta Address"); } ################################ # inv # Investigator ################################ sub check_inv { unless (exists $Args::args{'inv'}) { Print::print_check_err("Missing inv argument"); } unless ($Args::args{'inv'} =~ /^$::REG_INVESTIG$/o) { Print::print_check_err( "Invalid inv value (letters, num, and symbols only"); } return 0; } sub get_inv { if ($Args::args{'inv'} =~ /^($::REG_INVESTIG)$/o) { return $1; } Print::print_err("Invalid Investigator"); } ############################### # len ############################### sub check_len { if ( (!exists $Args::args{'len'}) || ($Args::args{'len'} !~ /^\d+$/) || ($Args::args{'len'} == 0)) { Print::print_check_err("Invalid len argument (positive numbers only)"); } return 0; } sub get_len { if ((exists $Args::args{'len'}) && ($Args::args{'len'} =~ /^(\d+)$/)) { return $1; } # return the default len of 1 if it is not defined return 1; } ############################### # min ############################### sub get_min { if ($Args::args{'min'} =~ /^(\d+)$/) { return $1; } Print::print_err("Invalid Minute"); } ################################ # module ################################ sub check_mod { if ((!exists $Args::args{'mod'}) || ($Args::args{'mod'} !~ /^\d+$/)) { Print::print_check_err( "Invalid Module argument (positive numbers only)"); } return 0; } sub get_mod { if ($Args::args{'mod'} =~ /^(\d+)$/) { return $1; } Print::print_err("Invalid Module"); } ################################ # mnt ############################### sub check_mnt { my $ftype = Args::get_ftype(); if (($ftype eq "blkls") || ($ftype eq "swap") || ($ftype eq "raw")) { $Args::args{'mnt'} = $ftype; $Args::enc_args{'mnt'} = $ftype; } elsif (!exists $Args::args{'mnt'}) { # Look it up if it is not found if (exists $Args::args{'img'}) { unless (exists $Caseman::vol2mnt{$Args::args{'img'}}) { Print::print_check_err( "Mounting point not found: $Args::args{'img'}"); } my $mnt = $Caseman::vol2mnt{$Args::args{'img'}}; $Args::args{'mnt'} = $mnt; $Args::enc_args{'mnt'} = Args::url_encode($mnt); } else { Print::print_check_err("Mounting point not found"); } } if ($Args::args{'mnt'} =~ /\/\.\.\//) { Print::print_check_err( "Invalid mount point argument (valid file path only)"); } unless ($Args::args{'mnt'} =~ /^$::REG_MNT$/o) { Print::print_check_err( "Invalid mount point argument (valid file path only)"); } return 0; } sub get_mnt { if ((exists $Args::args{'mnt'}) && ($Args::args{'mnt'} =~ /($::REG_MNT)/o)) { return $1; } Print::print_err("Invalid Mounting Point"); } ################################ # note ################################ sub check_note { if (!exists $Args::args{'note'}) { Print::print_check_err("Missing note argument"); } return 0; } ################# # num_img - adding disk images sub check_num_img { if ((!exists $Args::args{'num_img'}) || ($Args::args{'num_img'} !~ /^\d+$/)) { Print::print_check_err( "Invalid num_img argument (positive numbers only)"); } return 0; } sub get_num_img { if ($Args::args{'num_img'} =~ /^(\d+)$/) { return $1; } Print::print_err("Invalid num_img"); } ############################### # recmode ############################### sub check_recmode { if ((!exists $Args::args{'recmode'}) || ($Args::args{'recmode'} !~ /^\d+$/)) { Print::print_check_err( "Invalid recmode argument (positive numbers only)"); } return 0; } sub get_recmode { if ($Args::args{'recmode'} =~ /^(\d+)$/) { return $1; } Print::print_err("Invalid recmode"); } ################################ # srchidx # # Index for previous keyword search ############################### sub check_srchidx { if ((!exists $Args::args{'srchidx'}) || ($Args::args{'srchidx'} !~ /^\d+$/)) { Print::print_check_err( "Invalid srchidx argument (positive numbers only)"); } return 0; } ############################### # sort ############################### sub check_sort { if ((!exists $Args::args{'sort'}) || ($Args::args{'sort'} !~ /^\d+$/)) { Print::print_check_err("Invalid sort argument (positive numbers only)"); } return 0; } sub get_sort { if ($Args::args{'sort'} =~ /^(\d+)$/) { return $1; } Print::print_err("Invalid sort flag"); } ################################ # st_mon ################################ sub check_st_mon { if ( (exists $Args::args{'st_mon'}) && ($Args::args{'st_mon'} =~ /^(\d\d?)$/)) { if (($1 < 1) || ($1 > 12)) { print("Invalid start month\n"); return 1; } } else { print("Invalid start month\n"); return 1; } } sub get_st_mon { if ($Args::args{'st_mon'} =~ /^(\d\d?)$/) { return $1; } Print::print_err("Invalid Month"); } ################################ # st_year ################################ sub check_st_year { if ( (exists $Args::args{'st_year'}) && ($Args::args{'st_year'} =~ /^(\d\d\d\d?)$/)) { if (($1 < 1970) || ($1 > 2020)) { print("Invalid start year\n"); return 1; } } else { print("Invalid start year\n"); return 1; } } sub get_st_year { if ($Args::args{'st_year'} =~ /^(\d\d\d\d)$/) { return $1; } Print::print_err("Invalid Year"); } ################################ # str # search string ################################ # This should be made more flexible sub check_str { if (!exists $Args::args{'str'}) { Print::print_check_err("Missing string argument"); } return 0; } sub get_str { if ($Args::args{'str'} =~ /^\s*(.*)$/) { return $1; } Print::print_err("Invalid String"); } ############################### # submod # Used by the tab module to identify the actual module ############################### sub check_submod { if ((!exists $Args::args{'submod'}) || ($Args::args{'submod'} !~ /^\d+$/)) { Print::print_check_err( "Invalid sub-mode argument (positive numbers only)"); } return 0; } sub get_submod { if ($Args::args{'submod'} =~ /^(\d+)$/) { return $1; } Print::print_err("Invalid sub-mode"); } ################################ # tl ############################### sub check_tl { if ((!exists $Args::args{'tl'}) || ($Args::args{'tl'} !~ /^$::REG_VNAME$/)) { Print::print_check_err( "Invalid timeline argument (positive numbers only)"); } return 0; } sub get_tl { if ($Args::args{'tl'} =~ /^($::REG_VNAME)$/o) { return $1; } Print::print_err("Invalid Timeline"); } ################################ # ts # time skew ################################ sub check_ts { if ((!exists $Args::args{'ts'}) || ($Args::args{'ts'} !~ /^$::REG_SKEW$/o)) { Print::print_check_err("Missing time skew argument"); } return 0; } sub get_ts { if ($Args::args{'ts'} =~ /^\s*($::REG_SKEW)$/o) { return $1; } Print::print_err("Invalid Time Skew"); } ################################ # tz # timezone ################################ sub check_tz { if ( (!exists $Args::args{'tz'}) || ($Args::args{'tz'} !~ /^$::REG_ZONE_ARGS$/o)) { Print::print_check_err("Missing time zone argument"); } return 0; } sub get_tz { if ($Args::args{'tz'} =~ /^($::REG_ZONE_ARGS)$/o) { return $1; } Print::print_err("Invalid Timezone"); } ################################ # unitsize ################################ sub get_unitsize { my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $blkcat_out; if ($ftype eq 'blkls') { if (exists $Caseman::mod2vol{$vol}) { my $orig = $Caseman::mod2vol{$vol}; my $img = $Caseman::vol2path{$orig}; my $offset = $Caseman::vol2start{$orig}; my $imgtype = $Caseman::vol2itype{$orig}; local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/blkcat' -f $Caseman::vol2ftype{$orig} -s -o $offset -i $imgtype $img" ); $blkcat_out = <OUT>; close(OUT); } # We don't have the original image, so just set the size to 512 else { return 512; } } elsif ($ftype eq 'swap') { return 4096; } elsif ($ftype eq 'raw') { return 512; } elsif ($Caseman::vol2cat{$vol} eq 'disk') { return 512; } else { my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/blkcat' -f $ftype -s -o $offset -i $imgtype $img"); $blkcat_out = <OUT>; close(OUT); } $blkcat_out = "Error getting unit size" if ((!defined $blkcat_out) || ($blkcat_out eq "")); if ($blkcat_out =~ /(\d+): Size of Addressable Unit/) { return $1; } else { Print::print_err("Error identifying block size (blkcat -s output)\n" . "$blkcat_out\n"); } } ################################ # View - subset of module ################################ sub check_view { if ((!exists $Args::args{'view'}) || ($Args::args{'view'} !~ /^\d+$/)) { Print::print_check_err("Invalid View argument (positive numbers only)"); } return 0; } sub get_view { if ($Args::args{'view'} =~ /^(\d+)$/) { return $1; } Print::print_err("Invalid View"); } ############################### # We don't allow much for the volume because this is an argument to # the TSK programs. We keep these files only in one # directory and for easy/simple security only allow basic names # Symbolic links are allowed if these simple names are not desired # # Allowed values are A-Za-z0-9_-. # # The argument is the name of the image ############################### sub check_vol { my $vol = shift; if ((!exists $Args::args{$vol}) || ($Args::args{$vol} !~ /^$::REG_VNAME$/)) { Print::print_check_err( "Invalid volume argument (name and number only)"); } return 0; } sub get_vol { my $vol = shift; if ($Args::args{$vol} =~ /^($::REG_VNAME)$/) { return $1; } Print::print_err("Invalid volume ($vol)"); } 1; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/lib/Caseman.pm�������������������������������������������������������������������������0000644�0000765�0000024�00000406115�11105131407�015132� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Case Management methods, including the windows and functions to read the # config files # # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2001-2005 by Brian Carrier. All rights reserved # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package Caseman; # If the order of these views are changed, then the order of the main # function may have to be as well # Case Views $Caseman::CASE_NEW = 1; $Caseman::CASE_NEW_DOIT = 2; $Caseman::CASE_OPEN = 3; $Caseman::CASE_OPEN_LOG = 4; $Caseman::CASE_DETAILS = 5; # $Caseman::CASE_DEL = 6; my $CASE_MAX = 5; # Host Views $Caseman::HOST_ADD = 7; $Caseman::HOST_ADD_DOIT = 8; $Caseman::HOST_OPEN = 9; $Caseman::HOST_OPEN_LOG = 10; $Caseman::HOST_DETAILS = 11; # $Caseman::HOST_DEL = 12; my $HOST_MAX = 11; # Image Views $Caseman::IMG_ADD = 13; $Caseman::IMG_ADD_PREP = 14; $Caseman::IMG_ADD_DOIT = 15; $Caseman::VOL_OPEN = 16; $Caseman::VOL_OPEN_LOG = 17; $Caseman::VOL_DETAILS = 18; $Caseman::IMG_DEL = 19; $Caseman::VOL_MAKESTR = 20; $Caseman::VOL_MAKEBLKLS = 21; my $IMG_MAX = 21; # Module Variables # %vol2par - Volume to parent volume (vol to img, str to vol) # %vol2start - Starting sector of volume in image # %vol2end - ending sector of volume in image # %vol2cat - The big picture type of volume (part, disk, strings, blkls) # %vol2ftype - The file system type (fat, dos, ntfs etc.) # %vol2itype - The image file type (could be for a parent image) # %vol2dtype- the disk type # %mod2vol; # Mapping for image, given the strings or blkls # %vol2mnt; # Mapping for mount point, given the vol name # %vol2str; # Mapping for ASCII strings file, given the vol name # %vol2uni; # Mapping for Unicode strings file, given the vol name # %vol2blkls; # Mapping for blkls file, given the vol name # %vol2path - full file path of volume # %vol2sname - short name of volume sub main { # By default, show the case open window $Args::args{'view'} = $Args::enc_args{'view'} = $Caseman::CASE_OPEN unless (exists $Args::args{'view'}); Args::check_view(); my $view = Args::get_view(); # The only live function is for the open img if ($::LIVE == 1) { Args::check_inv(); if ($view == $Caseman::VOL_OPEN) { return vol_open(); } Args::check_vol('vol'); # Args::check_ftype(); # Args::check_mnt(); if ($view == $Caseman::VOL_OPEN_LOG) { return vol_open_log(); } else { Print::print_check_err( "Invalid Live Analysis Case Management View"); } return 0; } # Case functions if ($view <= $CASE_MAX) { if ($view == $Caseman::CASE_OPEN) { return case_open(); } elsif ($view == $Caseman::CASE_NEW) { return case_new(); } Args::check_case(); $::case_dir = "$::LOCKDIR/" . Args::get_case() . "/"; $::case_dir =~ s/\/\//\//g; if ($view == $Caseman::CASE_OPEN_LOG) { return case_open_log(); } elsif ($view == $Caseman::CASE_NEW_DOIT) { return case_new_doit(); } elsif ($view == $Caseman::CASE_DETAILS) { return case_details(); } } Args::check_case(); $::case_dir = "$::LOCKDIR/" . Args::get_case() . "/"; $::case_dir =~ s/\/\//\//g; # Host functions if ($view <= $HOST_MAX) { if ($view == $Caseman::HOST_OPEN) { return host_open(); } elsif ($view == $Caseman::HOST_ADD) { return host_add(); } Args::check_host(); $::host_dir = "$::case_dir" . Args::get_host() . "/"; $::host_dir =~ s/\/\//\//g; if ($view == $Caseman::HOST_ADD_DOIT) { return host_add_doit(); } Caseman::read_host_config(); if ($view == $Caseman::HOST_OPEN_LOG) { return host_open_log(); } elsif ($view == $Caseman::HOST_DETAILS) { return host_details(); } } Args::check_host(); $::host_dir = "$::case_dir" . Args::get_host() . "/"; $::host_dir =~ s/\/\//\//g; Caseman::read_host_config(); Args::check_inv(); if ($view <= $IMG_MAX) { if ($view == $Caseman::VOL_OPEN) { return vol_open(); } elsif ($view == $Caseman::IMG_ADD) { return img_add(); } elsif ($view == $Caseman::IMG_ADD_PREP) { return img_add_prep(); } elsif ($view == $Caseman::IMG_ADD_DOIT) { return img_add_doit(); } Args::check_vol('vol'); if ($view == $Caseman::VOL_OPEN_LOG) { return vol_open_log(); } elsif ($view == $Caseman::VOL_DETAILS) { return vol_details(); } # elsif ($view == $Caseman::IMG_DEL) { # return img_del(); # } elsif ($view == $Caseman::VOL_MAKESTR) { return vol_makestr(); } elsif ($view == $Caseman::VOL_MAKEBLKLS) { return vol_makeblkls(); } } Print::print_check_err("Invalid Case Management View"); } #################################################################### # General menu Functions sub print_menu_tabs { if ($::LIVE == 1) { print "<h2>Live Analysis Mode</h2>\n"; } print "<table width=\"600\" height=\"60\" background=\"$::YEL_PIX\" " . "border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tr>\n" . "<td align=\"center\" width=\"200\">"; my $view = Args::get_view(); # Case Gallery Tab if ($view == $Caseman::CASE_OPEN) { print "<img border=0 src=\"pict/menu_t_cg_cur.jpg\" " . "width=200 height=65 alt=\"Case Gallery (Current Mode)\">\n"; } elsif ($::LIVE == 1) { print "<img border=0 src=\"pict/menu_t_cg_org.jpg\" " . "width=200 height=65 alt=\"Case Gallery\">\n"; } else { print "<a href=\"$::PROGNAME?" . "mod=$::MOD_CASEMAN&view=$Caseman::CASE_OPEN\">" . "<img border=0 src=\"pict/menu_t_cg_link.jpg\" " . "width=200 height=65 alt=\"Case Gallery\"></a>\n"; } print "</td>\n" . "<td align=\"center\" width=\"200\">"; # Host Gallery Tab # Current if ($view == $Caseman::HOST_OPEN) { print "<img border=0 src=\"pict/menu_t_hg_cur.jpg\" " . "width=200 height=65 alt=\"Host Gallery (Current Mode)\">\n"; } # Link elsif (($view == $Caseman::VOL_OPEN) && ($::LIVE == 0)) { print "<a href=\"$::PROGNAME?" . "mod=$::MOD_CASEMAN&view=$Caseman::HOST_OPEN" . "&case=$Args::args{'case'}\">" . "<img border=0 src=\"pict/menu_t_hg_link.jpg\" " . "width=200 height=65 alt=\"Host Gallery\"></a>\n"; } # Non-link else { print "<img border=0 src=\"pict/menu_t_hg_org.jpg\" " . "width=200 height=65 alt=\"Host Gallery (Not Available)\">\n"; } print "</td>\n" . "<td align=\"center\" width=\"200\">"; # Host Manager Tab # Current if ($view == $Caseman::VOL_OPEN) { print "<img border=0 src=\"pict/menu_t_hm_cur.jpg\" " . "width=200 height=65 alt=\"Host Manager (Current Mode)\">\n"; } # non-link else { print "<img border=0 src=\"pict/menu_t_hm_org.jpg\" " . "width=200 height=65 alt=\"Host Manager (Not Available)\">\n"; } print "</td>\n</tr>\n" . "</table>\n"; } #################################################################### # Case Functions # if no args are passed, return case config using args{'case'}, # else use the case value passed # # Case config: # In case directory with case_name.case sub case_config_fname { if (scalar(@_) == 1) { my $c = shift; return "$::LOCKDIR/" . "$c/case.aut"; } else { return "$::LOCKDIR/" . "$Args::args{'case'}/case.aut"; } } # Read case config and save it to $Caseman::cvals sub read_case_config { return if ($::LIVE == 1); my $case; if (scalar(@_) == 1) { $case = shift; } else { $case = Args::get_case(); } my $fname = case_config_fname($case); %Caseman::cvals = (); open CONFIG, "<$fname" or die "Can't open case config file ($fname)"; while (<CONFIG>) { next if ((/^\#/) || (/^\s+$/)); s/^\s+//; s/\s+$//; $Caseman::cvals{$1} = Print::html_encode($2) if (/^(\S+)\s+(.*)$/); } close(CONFIG); $Caseman::cvals{'desc'} = "None Provided" unless (exists $Caseman::cvals{'desc'}); $Caseman::cvals{'created'} = "unknown" unless (exists $Caseman::cvals{'created'}); } sub case_new { Print::print_html_header("Create A New Case"); print <<EOF; <br> <br> <center> <img src=\"pict/menu_h_cnew.jpg\" alt=\"New Case\"> <br><br><br> <table width=\"600\" background=\"$::YEL_PIX\" cellspacing=\"0\" cellpadding=\"2\" border=0> <form action=\"$::PROGNAME\" method=\"get\"> <input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\"> <input type=\"hidden\" name=\"view\" value=\"$Caseman::CASE_NEW_DOIT\"> <tr> <td colspan=3 align=left> 1. <b>Case Name:</b> The name of this investigation. It can contain only letters, numbers, and symbols. </td> </tr> <tr> <td>&nbsp;&nbsp;</td> <td align=left colspan=2><input type=\"text\" name=\"case\"></td> </tr> <tr><td colspan=3>&nbsp;</td></tr> <tr> <td colspan=3 align=left> 2. <b>Description:</b> An optional, one line description of this case. </td> </tr> <tr> <td>&nbsp;&nbsp;</td> <td align=left colspan=2><input type=\"text\" name=\"desc\" size=32 maxlength=32></td> </tr> <tr><td colspan=3>&nbsp;</td></tr> <tr> <td colspan=3 align=left> 3. <b>Investigator Names:</b> The optional names (with no spaces) of the investigators for this case. </td> </tr> <tr> <td>&nbsp;</td> <td align=left><tt>a.</tt> <input type=\"text\" name=\"inv1\"></td> <td align=left><tt>b.</tt> <input type=\"text\" name=\"inv2\"></td> </tr> <tr> <td>&nbsp;</td> <td align=left><tt>c.</tt> <input type=\"text\" name=\"inv3\"></td> <td align=left><tt>d.</tt> <input type=\"text\" name=\"inv4\"></td> </tr> <tr> <td>&nbsp;</td> <td align=left><tt>e.</tt> <input type=\"text\" name=\"inv5\"></td> <td align=left><tt>f.</tt> <input type=\"text\" name=\"inv6\"></td> </tr> <tr> <td>&nbsp;</td> <td align=left><tt>g.</tt> <input type=\"text\" name=\"inv7\"></td> <td align=left><tt>h.</tt> <input type=\"text\" name=\"inv8\"></td> </tr> <tr> <td>&nbsp;</td> <td align=left><tt>i.</tt> <input type=\"text\" name=\"inv9\"></td> <td align=left><tt>j.</tt> <input type=\"text\" name=\"inv10\"></td> </tr> </table> <br><br> <table width=\"600\" cellspacing=\"0\" cellpadding=\"2\"> <tr> <td align=center> <input type=\"image\" src=\"pict/menu_b_cnew.jpg\" alt=\"Create Case\" width=\"176\" height=20 border=0> </td> </form> <td align=center> <form action=\"$::PROGNAME\" method=\"get\"> <input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\"> <input type=\"hidden\" name=\"view\" value=\"$Caseman::CASE_OPEN\"> <input type=\"image\" src=\"pict/menu_b_cancel.jpg\" alt=\"Cancel\" width=\"167\" height=20 border=0> </form> </td> <td align=center><a href=\"$::HELP_URL\" target=\"_blank\"> <img src=\"pict/menu_b_help.jpg\" alt=\"Help\" width=\"167\" height=20 border=0></a> </td> </tr> </table> EOF Print::print_html_footer(); return; } # Create the directory and case configuration file # Gets the input from CASE_NEW sub case_new_doit { Print::print_html_header("Creating Case: $Args::args{'case'}"); my $case = $Args::args{'case'}; print "<h3>Creating Case: <tt>$case</tt></h3>\n"; # Make the directory if (-d "$::case_dir") { # we can't send all of this to print_err, bc it doesn't want HTML print "Error: $::case_dir already exists<br>" . "Please remove the directory and its contents and try again" . "<p><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" . "view=$Caseman::CASE_OPEN\">" . "<img src=\"pict/but_ok.jpg\" alt=\"Ok\" " . "width=\"43\" height=20 border=\"0\"></a>\n"; Print::print_err("\n"); } unless (mkdir "$::case_dir", $::MKDIR_MASK) { Print::print_err("Error making directory $::case_dir: $!"); } print "Case directory (<tt>$::case_dir</tt>) created<br>\n"; Print::log_case_info("Case $case created"); my $fname = Caseman::case_config_fname(); open CASE_CONFIG, ">$fname" or die "Can't open case config: $fname"; print CASE_CONFIG "# Autopsy case config file\n" . "# Case: $case\n\n" . "created " . localtime() . "\n"; if ((exists $Args::args{'desc'}) && ($Args::args{'desc'} ne "")) { Print::print_err( "Invalid Description\n" . "Use the browser's back button to fix") if ($Args::args{'desc'} =~ /\n/); print CASE_CONFIG "desc $Args::args{'desc'}\n"; } print CASE_CONFIG "images $::IMGDIR\n"; print CASE_CONFIG "data $::DATADIR\n"; print CASE_CONFIG "log $::LOGDIR\n"; print CASE_CONFIG "reports $::REPDIR\n"; close CASE_CONFIG; print "Configuration file (<tt>$fname</tt>) created<br>\n"; my $iname = investig_fname(); open INVES, ">>$iname" or die "Can't open investigators file: $iname"; my @invs; if ( (exists $Args::args{'inv1'}) && ($Args::args{'inv1'} ne "") && ($Args::args{'inv1'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) { print INVES "$1\n"; push @invs, $1; } if ( (exists $Args::args{'inv2'}) && ($Args::args{'inv2'} ne "") && ($Args::args{'inv2'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) { print INVES "$1\n"; push @invs, $1; } if ( (exists $Args::args{'inv3'}) && ($Args::args{'inv3'} ne "") && ($Args::args{'inv3'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) { print INVES "$1\n"; push @invs, $1; } if ( (exists $Args::args{'inv4'}) && ($Args::args{'inv4'} ne "") && ($Args::args{'inv4'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) { print INVES "$1\n"; push @invs, $1; } if ( (exists $Args::args{'inv5'}) && ($Args::args{'inv5'} ne "") && ($Args::args{'inv5'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) { print INVES "$1\n"; push @invs, $1; } if ( (exists $Args::args{'inv6'}) && ($Args::args{'inv6'} ne "") && ($Args::args{'inv6'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) { print INVES "$1\n"; push @invs, $1; } if ( (exists $Args::args{'inv7'}) && ($Args::args{'inv7'} ne "") && ($Args::args{'inv7'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) { print INVES "$1\n"; push @invs, $1; } if ( (exists $Args::args{'inv8'}) && ($Args::args{'inv8'} ne "") && ($Args::args{'inv8'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) { print INVES "$1\n"; push @invs, $1; } if ( (exists $Args::args{'inv9'}) && ($Args::args{'inv9'} ne "") && ($Args::args{'inv9'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) { print INVES "$1\n"; push @invs, $1; } if ( (exists $Args::args{'inv10'}) && ($Args::args{'inv10'} ne "") && ($Args::args{'inv10'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) { print INVES "$1\n"; push @invs, $1; } close(INVES); Print::log_session_info("Case $case created"); print "<br><br>We must now create a host for this case.\n"; print "<form action=\"$::PROGNAME\" method=\"get\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::HOST_ADD\">\n" . "<input type=\"hidden\" name=\"case\" value=\"$case\">\n"; if (scalar @invs == 0) { print "<option hiddden name=\"inv\" value=\"unknown\">\n"; } else { print "<br><br>Please select your name from the list: " . "<select name=\"inv\" size=\"1\">\n"; foreach $i (@invs) { print "<option value=\"$i\">$i</option>\n"; } print "</select>\n"; } print "<br><br>" . "<input type=\"image\" src=\"pict/menu_b_hnew.jpg\" alt=\"Add New Host\" " . "height=20 border=\"0\"></form>\n"; Print::print_html_footer(); return; } # Open a Case # This provides a form with a list of options sub case_open { Print::print_html_header("Open A Case"); # Read the directories of the Evidence Locker into an array # Verify that there is a config file in the directory my @cases; opendir CASES, $::LOCKDIR or die "Can't open $::LOCKDIR directory: $!"; foreach my $c (readdir CASES) { next if (($c eq '.') || ($c eq '..')); my $cfile = Caseman::case_config_fname($c); push @cases, $c if ((-d "$::LOCKDIR/$c") && (-e "$cfile")); } closedir CASES; print "<br><br><center>"; # Were there any cases? if (scalar @cases == 0) { print "No cases exist in <tt>$::LOCKDIR</tt><br><br>\n" . "Select the New Case button below to make one<br>\n"; } else { print "Select the case to open or create a new one<br>\n"; print_menu_tabs(); print "<table width=\"600\" background=\"$::YEL_PIX\" " . " cellspacing=\"0\" cellpadding=\"2\" border=0>\n"; print "<form action=\"$::PROGNAME\" method=\"get\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::CASE_OPEN_LOG\">\n" . Args::make_hidden() . "<tr><th>Name</th>" . "<th>Description</th>" . "<td>&nbsp;</td></tr>\n"; my $first = 0; foreach my $c (@cases) { print "<tr><td align=\"left\">" . "<input type=\"radio\" name=\"case\" value=$c"; if ($first == 0) { print " CHECKED"; $first = 1; } print ">" . Print::html_encode($c) . "</td>"; Caseman::read_case_config($c); print "<td>$Caseman::cvals{'desc'}</td>" . "<td align=center>" . "<a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" . "view=$Caseman::CASE_DETAILS&case=$c\">" . "details</a></td>" . "</tr>\n"; } print "</table>\n"; } print "<br><br>" . "<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\">\n" . "<tr>\n"; # Print the OK button if there were cases if (scalar @cases != 0) { print "<td align=center>" . "<input type=\"image\" src=\"pict/menu_b_ok.jpg\" " . "width=167 height=20 alt=\"Ok\" border=0>" . "</form></td>\n\n"; } # Print a 'New Case' Button print "<td align=center>" . "<form action=\"$::PROGNAME\" method=\"get\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::CASE_NEW\">\n" . "<input type=\"image\" src=\"pict/menu_b_cnew.jpg\" " . "width=167 height=20 alt=\"New Case\" border=0>\n" . "</form></td>" . # Print a Menu Button "<td align=center>" . "<form action=\"$::PROGNAME\" method=\"get\">\n" . "<input type=\"image\" src=\"pict/menu_b_menu.jpg\" " . "width=167 height=20 alt=\"Main Menu\" border=0>\n" . "</form></td></tr></table>\n"; print "<table width=600 cellspacing=\"0\" cellpadding=\"2\">\n<tr>" . "<td>&nbsp;</td>\n" . "<td align=center width=200><a href=\"$::HELP_URL\" " . " target=\"_blank\">" . "<img src=\"pict/menu_b_help.jpg\" alt=\"Help\" " . "width=\"167\" height=20 border=0>" . "</a></td>" . "<td>&nbsp;</td>\n" . "</tr>\n" . "</table>"; Print::print_html_footer(); return; } # Log that a given case was opened and then proceed to open a host sub case_open_log { Print::log_session_info("Case $Args::args{'case'} opened"); Print::log_case_info("Case $Args::args{'case'} opened"); $Args::args{'view'} = $Args::enc_args{'view'} = $Caseman::HOST_OPEN; host_open(); } # Display Case Details sub case_details { Print::print_html_header("Details of $Args::args{'case'}"); read_case_config(); print "<br><br>" . "<center>" . "<img src=\"pict/menu_h_cdet.jpg\" alt=\"Case Details\">" . "<br><br><br>\n" . "<table width=\"600\" cellspacing=\"0\" background=\"$::YEL_PIX\" " . "cellpadding=\"2\" border=0>\n" . " <tr><td align=\"right\" width=300><b>Name:</b></td>" . "<td align=\"left\" width=300><tt>$Args::args{'case'}</tt></td></tr>\n" . # Description " <tr><td align=\"right\"><b>Description:</b></td>" . "<td align=\"left\"><tt>$Caseman::cvals{'desc'}</tt></td></tr>\n" . " <tr><td align=\"right\"><b>Created:</b></td>" . "<td align=\"left\"><tt>$Caseman::cvals{'created'}</tt></td></tr>\n"; # Display the valid investigators my @invs = read_invest(); my $cnt = 0; print " <tr><td colspan=\"2\">&nbsp;</td></tr>\n" if (scalar @invs > 0); foreach my $i (@invs) { if ($cnt == 0) { print " <tr><td align=\"right\"><b>Investigators:</b></td>"; $cnt++; } else { print " <tr><td>&nbsp;</td>"; } print "<td align=\"left\"><tt>" . Print::html_encode($i) . "</tt></td></tr>\n"; } print "</table>\n" . "<p><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&view=$Caseman::CASE_OPEN\">" . "<img src=\"pict/menu_b_ok.jpg\" alt=\"Ok\" " . "width=\"167\" height=20 border=\"0\"></a>"; Print::print_html_footer(); return 0; } #################################################################### # Host Functions # if no args are passed, return host config using args{'host'}, # else use the host value passed sub host_config_fname { if (scalar(@_) == 1) { my $h = shift; return "$::case_dir" . "$h/host.aut"; } else { return "$::host_dir" . "host.aut"; } } # Converts the original single image host config to the volume-based config sub convert_host_config { return if ($::LIVE == 1); my $host = Args::get_host(); Print::log_host_info("Converting host config files"); print STDERR "Converting host config file to new format\n"; # The file to convert my $cfile = host_config_fname(); unless (open(FILE, $cfile)) { Print::print_check_err("Error opening $cfile"); } my $tmpcfile = "$::host_dir" . "host-convert.aut"; unless (open(FILE_TMP, ">>$tmpcfile")) { Print::print_check_err("Error opening $tmpcfile"); } my $img_cnt = 0; my $vol_cnt = 0; $img2vol{'qazwsxedc'} = ""; # stores the image path to partition / file name $img2vol2{'qazwsxedc'} = ""; # stores the image path to file name (no partitions) while (<FILE>) { if ((/^\#/) || (/^\s+$/)) { print FILE_TMP $_; next; } # remove whitespace s/^\s+//; s/\s+$//; # normal file system image entry # # 'image images/hda1.dd openbsd /usr if (/^image\s+($::REG_IMG)\s+([\w\-]+)\s+([\w\-\_\.\/:\\]+)$/o) { my $i = $1; my $t = $2; my $r = $3; # Add trailing / to original mount point if needed if (($r !~ /.*?\/$/) && ($r !~ /.*?\\$/)) { $r .= '/'; } my $vnum = "vol" . $vol_cnt; my $inum = "img" . $img_cnt; $img2vol{$i} = $vnum; $img2vol2{$i} = $inum; print FILE_TMP "image $inum raw $i\n"; print FILE_TMP "part $vnum $inum 0 0 $t $r\n"; $img_cnt++; $vol_cnt++; } # swap # swap images/hda3.dd elsif (/^swap\s+($::REG_IMG)\s*$/o) { my $i = $1; my $vnum = "vol" . $vol_cnt; my $inum = "img" . $img_cnt; $img2vol{$i} = $vnum; $img2vol2{$i} = $inum; print FILE_TMP "image $inum raw $i\n"; print FILE_TMP "part $vnum $inum 0 0 swap\n"; $img_cnt++; $vol_cnt++; } # raw # raw images/hda3.dd elsif (/^raw\s+($::REG_IMG)\s*$/o) { my $i = $1; $img2vol{$i} = "vol" . $vol_cnt; $img2vol2{$i} = "img" . $img_cnt; print FILE_TMP "image img" . $img_cnt . " raw $i\n"; print FILE_TMP "part vol" . $vol_cnt . " img" . $img_cnt . " 0 0 raw\n"; $img_cnt++; $vol_cnt++; } # entry for a strings or blkls file # # strings data/hda1.str images/hda1.dd elsif (/^strings\s+($::REG_IMG)\s+($::REG_IMG)$/o) { my $i = $1; my $o = $2; if (exists $img2vol{$o}) { my $vname = $img2vol{$o}; print FILE_TMP "strings vol" . $vol_cnt . " $vname $i\n"; $img2vol{$i} = "vol" . $vol_cnt; $img2vol2{$i} = "vol" . $vol_cnt; } else { print STDERR "Error: Volume for strings $o not found<br>\n"; } $vol_cnt++; } # entry for a strings or blkls file # # unistrings data/hda1.str images/hda1.dd elsif (/^unistrings\s+($::REG_IMG)\s+($::REG_IMG)$/o) { my $i = $1; my $o = $2; if (exists $img2vol{$o}) { my $vname = $img2vol{$o}; print FILE_TMP "unistrings vol" . $vol_cnt . " $vname $i\n"; $img2vol{$i} = "vol" . $vol_cnt; $img2vol2{$i} = "vol" . $vol_cnt; } else { print STDERR "Error: Volume for unicode strings $o not found<br>\n"; } $vol_cnt++; } # blkls entry # blkls data/image.blkls [images/image.dd] elsif (/^blkls\s+($::REG_IMG)\s*($::REG_IMG)$/o) { my $i = $1; my $o = $2; $img2vol{$i} = "vol" . $vol_cnt; if (exists $img2vol{$o}) { my $vname = $img2vol{$o}; print FILE_TMP "blkls vol" . $vol_cnt . " $vname $i\n"; $img2vol{$i} = "vol" . $vol_cnt; $img2vol2{$i} = "vol" . $vol_cnt; } else { print STDERR "Error: Volume for blkls $o not found<br>\n"; } $vol_cnt++; } # body data/body.txt elsif (/^body\s+($::REG_IMG)$/o) { my $i = $1; print FILE_TMP "body vol" . $vol_cnt . " $i\n"; $img2vol{$i} = "vol" . $vol_cnt; $img2vol2{$i} = "vol" . $vol_cnt; $vol_cnt++; } # timeline data/timeline.txt elsif (/^timeline\s+($::REG_IMG)$/o) { my $i = $1; print FILE_TMP "timeline vol" . $vol_cnt . " $i\n"; $img2vol{$i} = "vol" . $vol_cnt; $img2vol2{$i} = "vol" . $vol_cnt; $vol_cnt++; } # timezone XYZ elsif (/^timezone\s+($::REG_ZONE_ARGS)$/o) { print FILE_TMP "$_\n"; } # timeskew XYZ elsif (/^timeskew\s+($::REG_SKEW)$/o) { print FILE_TMP "$_\n"; } # desc XYZ elsif (/^desc\s+(.*)$/) { print FILE_TMP "$_\n"; } # hash databases elsif (/^alert_db\s+'(.*)'$/) { print FILE_TMP "$_\n"; } elsif (/^exclude_db\s+'(.*)'$/) { print FILE_TMP "$_\n"; } else { my $msg = "Error: invalid entry in $cfile:$." . "\n" . "image path fs_type mnt_point\n" . "strings path orig_img\n" . "blkls path [orig_img]\n" . "body path\n" . "timeline path\n" . "timezone TZ\n" . "desc DESCRIPTION\n"; Print::print_check_err($msg); } } close(FILE); close(FILE_TMP); unless (rename $cfile, $cfile . ".bak") { print STDERR "Error backing up original host config file\n"; } unless (rename $tmpcfile, $cfile) { print STDERR "Error renaming new host config file\n"; } Notes::convert(\%img2vol); Hash::convert(\%img2vol2); } # reads host config file and sets global hash values for images and other sub read_host_config { if ($::LIVE == 1) { %Caseman::mod2vol = (); %Caseman::vol2str = (); %Caseman::vol2uni = (); %Caseman::vol2blkls = (); $Caseman::tz = ""; $Caseman::ts = 0; $Caseman::host_desc = ""; $Caseman::exclude_db = ""; $Caseman::alert_db = ""; return; } my $host = Args::get_host(); my $cfile = host_config_fname(); restart: unless (open(FILE, $cfile)) { Print::print_check_err("Error opening $cfile"); } %Caseman::vol2mnt = (); %Caseman::vol2ftype = (); %Caseman::vol2dtype = (); %Caseman::vol2cat = (); %Caseman::mod2vol = (); %Caseman::vol2str = (); %Caseman::vol2uni = (); %Caseman::vol2blkls = (); %Caseman::vol2par = (); %Caseman::vol2start = (); %Caseman::vol2end = (); $Caseman::vol2path = (); $Caseman::vol2sname = (); $Caseman::tz = ""; $Caseman::ts = 0; $Caseman::host_desc = ""; $Caseman::exclude_db = ""; $Caseman::alert_db = ""; while (<FILE>) { next if ((/^\#/) || (/^\s+$/)); # remove whitespace s/^\s+//; s/\s+$//; # old file system image entry # # 'image images/hda1.dd openbsd /usr if (/^image\s+($::REG_IMG)\s+([\w\-]+)\s+([\w\-\_\.\/:\\]+)$/o) { close(FILE); convert_host_config(); goto restart; } elsif ( /^image\s+($::REG_INAME)\s+($::REG_IMGTYPE)\s+($::REG_IMG_CONFIG)$/o ) { my $me = $1; my $t = $2; my $i = $3; unless ((-e "$::host_dir$i") || ((-l "$::host_dir$i") && (-e readlink "$::host_dir$i"))) { Print::print_check_err( "Error: image $i in ${host}.host:$. not found: " . "$::host_dir" . "$i \nEdit the config file and refresh your browser\n" . "(Or your version of Perl does not support large files)" ); } if (exists $Caseman::vol2path{$me}) { $Caseman::vol2path{$me} .= " \'$::host_dir" . "$i\'"; } else { $Caseman::vol2path{$me} = "\'$::host_dir" . "$i\'"; $Caseman::vol2sname{$me} = $i; $Caseman::vol2sname{$me} = $1 if ($i =~ /\/($::REG_FILE)$/); $Caseman::vol2par{$me} = ""; $Caseman::vol2cat{$me} = "image"; $Caseman::vol2itype{$me} = $t; $Caseman::vol2ftype{$me} = ""; $Caseman::vol2start{$me} = 0; $Caseman::vol2end{$me} = 0; } } elsif ( /^part\s+($::REG_VNAME)\s+($::REG_INAME)\s+(\d+)\s+(\d+)\s+($::REG_FTYPE)\s*([\w\-\_\.\/:\\]+)?$/o ) { my $par = $2; my $me = $1; my $s = $3; my $e = $4; my $t = $5; my $r = $6; # Not defined for swap and raw unless (exists $Fs::addr_unit{$t}) { Print::print_check_err( "Error: unknown type: $t in host config: $." . "\nEdit the file and refresh your browser"); } if (exists $Caseman::vol2itype{$par}) { $Caseman::vol2itype{$me} = $Caseman::vol2itype{$par}; } else { Print::print_check_err( "Error: Image $par for partition $me was not found in config: $." . "\nEdit the file and refresh your browser"); } $Caseman::vol2ftype{$me} = $t; $Caseman::vol2cat{$me} = "part"; $Caseman::vol2start{$me} = $s; $Caseman::vol2end{$me} = $e; # Add trailing / to original mount point if needed if ((defined $r) && ($r !~ /.*?\/$/) && ($r !~ /.*?\\$/)) { $r .= '/'; } $Caseman::vol2mnt{$me} = $r; $Caseman::vol2par{$me} = $par; $Caseman::vol2path{$me} = $Caseman::vol2path{$par}; $Caseman::vol2sname{$me} = $Caseman::vol2sname{$par} . "-" . $s . "-" . $e; } elsif (/^disk\s+($::REG_VNAME)\s+($::REG_INAME)\s+($::REG_FTYPE)?$/o) { my $par = $2; my $me = $1; my $t = $3; unless (exists $Vs::type{$t}) { Print::print_check_err( "Error: unknown volume system type: $t in host config: $." . "\nEdit the file and refresh your browser"); } if (exists $Caseman::vol2itype{$par}) { $Caseman::vol2itype{$me} = $Caseman::vol2itype{$par}; } else { Print::print_check_err( "Error: Image $par for disk $me was not found in config: $.\n" . "Edit the file and refresh your browser"); } $Caseman::vol2ftype{$me} = "raw"; $Caseman::vol2dtype{$me} = $t; $Caseman::vol2cat{$me} = "disk"; $Caseman::vol2start{$me} = 0; $Caseman::vol2end{$me} = 0; $Caseman::vol2mnt{$me} = ""; $Caseman::vol2par{$me} = $par; $Caseman::vol2path{$me} = $Caseman::vol2path{$par}; $Caseman::vol2sname{$me} = $Caseman::vol2sname{$par} . "-disk"; } # entry for a strings or blkls file # # strings data/hda1.str volX elsif (/^strings\s+($::REG_VNAME)\s+($::REG_VNAME)\s+($::REG_IMG)$/o) { my $i = $3; my $par = $2; my $me = $1; unless ((-e "$::host_dir$i") || ((-l "$::host_dir$i") && (-e readlink "$::host_dir$i"))) { Print::print_check_err("Error: strings file not found: " . "$::host_dir$i\nEdit host config in $::host_dir and refresh your browser" ); } unless (exists $Caseman::vol2cat{$par}) { Print::print_check_err( "Error: Volume $par for strings $me was not found in config: $." . "\nEdit the file and refresh your browser"); } $Caseman::vol2ftype{$me} = "strings"; $Caseman::vol2cat{$me} = "mod"; $Caseman::vol2itype{$me} = "raw"; $Caseman::mod2vol{$me} = $par; $Caseman::vol2str{$par} = $me; $Caseman::vol2par{$me} = $par; $Caseman::vol2path{$me} = "\'$::host_dir" . "$i\'"; $Caseman::vol2start{$me} = 0; $Caseman::vol2end{$me} = 0; $Caseman::vol2sname{$me} = $i; $Caseman::vol2sname{$me} = $1 if ($i =~ /\/($::REG_FILE)$/); } # entry for a strings or blkls file # # unistrings data/hda1.str volX elsif (/^unistrings\s+($::REG_VNAME)\s+($::REG_VNAME)\s+($::REG_IMG)$/o) { my $i = $3; my $par = $2; my $me = $1; unless ((-e "$::host_dir$i") || ((-l "$::host_dir$i") && (-e readlink "$::host_dir$i"))) { Print::print_check_err("Error: Unicode strings file not found: " . "$::host_dir$i\nEdit host config in $::host_dir and refresh your browser" ); } unless (exists $Caseman::vol2cat{$par}) { Print::print_check_err( "Error: Volume $par for unistrings $me was not found in config: $." . "\nEdit the file and refresh your browser"); } $Caseman::vol2ftype{$me} = "strings"; $Caseman::vol2cat{$me} = "mod"; $Caseman::vol2itype{$me} = "raw"; $Caseman::mod2vol{$me} = $par; $Caseman::vol2uni{$par} = $me; $Caseman::vol2par{$me} = $par; $Caseman::vol2path{$me} = "\'$::host_dir" . "$i\'"; $Caseman::vol2start{$me} = 0; $Caseman::vol2end{$me} = 0; $Caseman::vol2sname{$me} = $i; $Caseman::vol2sname{$me} = $1 if ($i =~ /\/($::REG_FILE)$/); } # blkls entry # blkls themname myname elsif ((/^blkls\s+($::REG_VNAME)\s+($::REG_VNAME)\s+($::REG_IMG)$/o) || (/^dls\s+($::REG_VNAME)\s+($::REG_VNAME)\s+($::REG_IMG)$/o)) { my $i = $3; my $par = $2; my $me = $1; unless ( (-e "$::host_dir$i") || ( (-l "$::host_dir$i") && (-e readlink "$::host_dir$i")) ) { Print::print_check_err("Error: blkls file not found: " . "$::host_dir$i \nEdit host config in $::host_dir and refresh your browser" ); } unless (exists $Caseman::vol2cat{$par}) { Print::print_check_err( "Error: Volume $par for blkls $me was not found in config: $." . "\nEdit the file and refresh your browser"); } $Caseman::vol2ftype{$me} = "blkls"; $Caseman::vol2cat{$me} = "mod"; $Caseman::vol2itype{$me} = "raw"; $Caseman::vol2mnt{$me} = ""; $Caseman::vol2par{$me} = $par; $Caseman::mod2vol{$me} = $par; $Caseman::vol2blkls{$par} = $me; $Caseman::vol2path{$me} = "\'$::host_dir" . "$i\'"; $Caseman::vol2start{$me} = 0; $Caseman::vol2end{$me} = 0; $Caseman::vol2sname{$me} = $i; $Caseman::vol2sname{$me} = $1 if ($i =~ /\/($::REG_FILE)$/); } # body data/body.txt elsif (/^body\s+($::REG_VNAME)\s+($::REG_IMG)$/o) { my $me = $1; my $i = $2; unless ((-e "$::host_dir$i") || ((-l "$::host_dir$i") && (-e readlink "$::host_dir$i"))) { Print::print_check_err("Error: body file not found: " . "$::host_dir$i <br>Edit host config in $::host_dir and refresh your browser" ); } $Caseman::vol2cat{$me} = "timeline"; $Caseman::vol2ftype{$me} = "body"; $Caseman::vol2itype{$me} = "raw"; $Caseman::vol2path{$me} = "\'$::host_dir" . "$i\'"; $Caseman::vol2start{$me} = 0; $Caseman::vol2end{$me} = 0; $Caseman::vol2sname{$me} = $i; $Caseman::vol2sname{$me} = $1 if ($i =~ /\/($::REG_FILE)$/); } # timeline data/timeline.txt elsif (/^timeline\s+($::REG_VNAME)\s+($::REG_IMG)$/o) { my $me = $1; my $i = $2; unless ((-e "$::host_dir$i") || ((-l "$::host_dir$i") && (-e readlink "$::host_dir$i"))) { Print::print_check_err("Error: timeline file not found: " . "$::host_dir$i \nEdit host config in $::host_dir and refresh your browser" ); } $Caseman::vol2cat{$me} = "timeline"; $Caseman::vol2ftype{$me} = "timeline"; $Caseman::vol2itype{$me} = "raw"; # We do not add the quotes to the path for timeline because it is opened only by the Perl code and it doesn't like the quotes $Caseman::vol2path{$me} = "$::host_dir" . "$i"; $Caseman::vol2start{$me} = 0; $Caseman::vol2end{$me} = 0; $Caseman::vol2sname{$me} = $i; $Caseman::vol2sname{$me} = $1 if ($i =~ /\/($::REG_FILE)$/); } # timezone XYZ elsif (/^timezone\s+($::REG_ZONE_ARGS)$/o) { $Caseman::tz = "\'$1\'"; } # timeskew XYZ elsif (/^timeskew\s+($::REG_SKEW)$/o) { $Caseman::ts = "\'$1\'"; } # desc XYZ elsif (/^desc\s+(.*)$/) { $Caseman::host_desc = Print::html_encode($1); } # hash databases elsif (/^alert_db\s+'($::REG_HASHDB)'$/) { $Caseman::alert_db = "$1"; } elsif (/^exclude_db\s+'($::REG_HASHDB)'$/) { $Caseman::exclude_db = "$1"; } else { my $msg = "Error: invalid entry in $cfile:$." . "\n" . "$_\n"; Print::print_check_err($msg); } } close(FILE); } # Add a new image entry to the host config and return its id sub add_img_host_config { my $type = shift; my $other = shift; my $id = shift; my $read = host_config_fname(); my $write = $read . "-" . rand(); unless (open(READ, "<$read")) { Print::print_check_err("Error opening $read"); } unless (open(WRITE, ">$write")) { Print::print_check_err("Error opening $write"); } my $maxcnt = 0; while (<READ>) { s/^\s+//; s/\s+$//; if (/^\w+\s+img(\d+)\s+.*$/) { $maxcnt = $1 if ($1 > $maxcnt); } print WRITE "$_\n"; } $maxcnt++; if ($id eq "") { $id = "img" . $maxcnt; } print WRITE "$type $id $other\n"; Print::log_host_info("Image added: $type $id $other"); close(READ); close(WRITE); unless (rename $write, $read) { print STDERR "Error renaming temp host config file\n"; } return $id; } # Add a new volume entry to the host config and return its id sub add_vol_host_config { my $type = shift; my $other = shift; my $read = host_config_fname(); my $write = $read . "-" . rand(); unless (open(READ, "<$read")) { Print::print_check_err("Error opening $read"); } unless (open(WRITE, ">$write")) { Print::print_check_err("Error opening $write"); } # We want to find the max count ... not just the unused # ones because we could end up reusing one and that could # mess up the notes my $maxcnt = 0; while (<READ>) { s/^\s+//; s/\s+$//; if (/^\w+\s+vol(\d+)\s+.*$/) { $maxcnt = $1 if ($1 > $maxcnt); } print WRITE "$_\n"; } $maxcnt++; print WRITE "$type vol" . $maxcnt . " $other\n"; Print::log_host_info("Volume added: $type vol" . $maxcnt . " $other"); close(READ); close(WRITE); unless (rename $write, $read) { print STDERR "Error renaming temp host config file\n"; } return "vol" . $maxcnt; } # Delete anentry from the host config # DOES NOT WORK RIGHT NOW sub del_host_config_BLAH { return; my $type = shift; my $other = shift; my $read = host_config_fname(); my $write = $read . "-" . rand(); unless (open(READ, "<$read")) { Print::print_check_err("Error opening $read"); } unless (open(WRITE, ">$write")) { Print::print_check_err("Error opening $write"); } while (<READ>) { s/^\s+//; s/\s+$//; print WRITE "$_\n" unless ((/^(\w+)\s+($::REG_IMG)/o) && ($2 eq $img) && ($1 ne 'desc') && ($1 ne 'timezone')); } if ($type ne "") { if (defined $ref) { print WRITE "$type $img $ref\n"; } else { print WRITE "$type $img\n"; } } close(READ); close(WRITE); unless (rename $write, $read) { print STDERR "Error renaming temp host config file\n"; } return; } # Given the image and md5, it is saved to the MD5.txt file and any other # references to the image are removed # # if $md5 is "", then nothing is written sub update_md5 { my $vol = shift; my $md5 = shift; $md5 =~ tr/[a-f]/[A-F]/; my $read = "$::host_dir/md5.txt"; my $write = $read . "-" . rand(); unless (open(WRITE, ">$write")) { Print::print_check_err("Error opening $write"); } if (-e "$read") { unless (open(READ, "<$read")) { Print::print_check_err("Error opening $read"); } while (<READ>) { s/^\s+//; s/\s+$//; print WRITE "$_\n" unless ((/^$::REG_MD5\s+($::REG_VNAME)/o) && ($1 eq $vol)); } close(READ); } print WRITE "$md5 $vol\n" if ($md5 ne ""); close(WRITE); unless (rename $write, $read) { print STDERR "Error renaming temp MD5 hash file\n"; } return; } sub host_add { Print::print_html_header("Add A New Host To $Args::args{'case'}"); print "<b>Case: </b> $Args::args{'case'}<br><br>\n"; print "<center>" . "<img src=\"pict/menu_h_hnew.jpg\" alt=\"Add Host\">" . "<br><br><br>\n"; print "<table width=\"600\" cellspacing=\"0\" background=\"$::YEL_PIX\" " . "cellpadding=\"2\" border=0>\n" . "<form action=\"$::PROGNAME\" method=\"get\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::HOST_ADD_DOIT\">\n" . Args::make_hidden() . "<tr><td colspan=\"2\">&nbsp;</td></tr>" . # Host name "<tr><td align=\"left\" colspan=2>1. <b>Host Name:</b> The name of the computer being investigated. It can contain only letters, numbers, and symbols.</td></tr>" . "<tr><td align=\"left\">&nbsp;&nbsp;&nbsp;</td>" . "<td align=\"left\"><input type=\"text\" name=\"host\" size=32 maxlength=32 value=\"host1\"></td></tr>\n" . # Description "<tr><td align=\"left\" colspan=2>2. <b>Description:</b> An optional one-line description or note about this computer.</td></tr>" . "<tr><td align=\"left\">&nbsp;&nbsp;&nbsp;</td>" . "<td align=\"left\">" . "<input type=\"text\" name=\"desc\" size=32 maxlength=32></td></tr>\n" . # Empty line "<tr><td colspan=\"2\">&nbsp;</td></tr>" . # Timezone "<tr><td align=\"left\" colspan=2>3. <b>Time zone:</b> An optional timezone value (i.e. EST5EDT). If not given, it defaults to the local setting. A list of time zones can be found in the help files.</td></tr>" . "<tr><td align=\"left\">&nbsp;&nbsp;&nbsp;</td>" . "<td align=\"left\">" . "<input type=\"text\" name=\"tz\" size=16 maxlength=64></td></tr>\n" . # Timeskew "<tr><td align=\"left\" colspan=2>4. <b>Timeskew Adjustment:</b> An optional value to describe how many seconds this computer's clock was out of sync. For example, if the computer was 10 seconds fast, then enter -10 to compensate.</td></tr>" . "<tr><td align=\"left\">&nbsp;&nbsp;&nbsp;</td>" . "<td align=\"left\">" . "<input type=\"text\" name=\"ts\" size=8 maxlength=16 value=\"0\">" . "</td></tr>\n" . # Spacer "<tr><td colspan=\"2\">&nbsp;</td></tr>" . # Alert "<tr><td align=\"left\" colspan=2>5. <b>Path of Alert Hash Database:</b> An optional hash database of known bad files.</td></tr>" . "<tr><td align=\"left\">&nbsp;&nbsp;&nbsp;</td>" . "<td align=\"left\">" . "<input type=\"text\" name=\"alert_db\" size=32 maxlength=512>" . "</td></tr>\n" . # Ignore "<tr><td align=\"left\" colspan=2>6. <b>Path of Ignore Hash Database:</b> An optional hash database of known good files.</td></tr>" . "<tr><td align=\"left\">&nbsp;&nbsp;&nbsp;</td>" . "<td align=\"left\">" . "<input type=\"text\" name=\"exclude_db\" size=32 maxlength=512>" . "</td></tr>\n" . # Spacer "<tr><td colspan=\"2\">&nbsp;</td></tr>" . "</table>\n"; if (exists $Args::args{'inv'}) { print "<input type=\"hidden\" name=\"inv\" value=\"$Args::args{'inv'}\">\n"; } # Ok Button print "<br><br><table width=\"600\" cellspacing=\"8\" cellpadding=\"2\">\n" . "<tr><td align=center>" . "<input type=\"image\" src=\"pict/menu_b_hnew.jpg\" " . "width=167 height=20 alt=\"Add Host\" border=0>\n" . "</form></td>\n" . # Cancel Button "<td align=center>" . "<form action=\"$::PROGNAME\" method=\"get\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::HOST_OPEN\">\n" . "<input type=\"hidden\" name=\"case\" value=\"$Args::args{'case'}\">\n" . "<input type=\"image\" src=\"pict/menu_b_cancel.jpg\" " . "alt=\"Cancel\" width=\"167\" height=20 border=0>\n" . "</form></td>\n" . # Help Button "<td align=center><a href=\"$::HELP_URL\" " . "target=\"_blank\">" . "<img src=\"pict/menu_b_help.jpg\" alt=\"Help\" " . "width=\"167\" height=20 border=0></a>" . "</td></tr>\n" . "</table>"; Print::print_html_footer(); return 0; } # Make the directories and config files for a host sub host_add_doit { Args::check_tz() if ((exists $Args::args{'tz'}) && ($Args::args{'tz'} ne "")); Args::check_ts(); Print::print_html_header( "Adding Host $Args::args{'host'} to $Args::args{'case'}"); print "<h3>Adding host: <tt>$Args::args{'host'}</tt> to " . "case <tt>$Args::args{'case'}</tt></h3>\n"; # Do some sanity checks before we start making the directories and such if ( (exists $Args::args{'alert_db'}) && ($Args::args{'alert_db'} ne "")) { unless ($Args::args{'alert_db'} =~ /^$::REG_HASHDB$/o) { print "Invalid Alert Database path\n" . "<p><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" . "view=$Caseman::HOST_ADD&case=$Args::args{'case'}\">" . "<img src=\"pict/but_ok.jpg\" alt=\"Ok\" " . "width=\"43\" height=20 border=\"0\"></a>\n"; return 1; } unless (-e "$Args::args{'alert_db'}") { print "Alert Database Not Found: $Args::args{'alert_db'}" . "<p><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" . "view=$Caseman::HOST_ADD&case=$Args::args{'case'}\">" . "<img src=\"pict/but_ok.jpg\" alt=\"Ok\" " . "width=\"43\" height=20 border=\"0\"></a>\n"; return 1; } } if ( (exists $Args::args{'exclude_db'}) && ($Args::args{'exclude_db'} ne "")) { unless ($Args::args{'exclude_db'} =~ /^$::REG_HASHDB$/o) { print "Invalid Exclude Database path\n" . "<p><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" . "view=$Caseman::HOST_ADD&case=$Args::args{'case'}\">" . "<img src=\"pict/but_ok.jpg\" alt=\"Ok\" " . "width=\"43\" height=20 border=\"0\"></a>\n"; return 1; } unless (-e "$Args::args{'exclude_db'}") { print "Exclude Database Not Found: $Args::args{'exclude_db'}" . "<p><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" . "view=$Caseman::HOST_ADD&case=$Args::args{'case'}\">" . "<img src=\"pict/but_ok.jpg\" alt=\"Ok\" " . "width=\"43\" height=20 border=\"0\"></a>\n"; return 1; } } # Make the directory if (-d "$::host_dir") { print "Error: $::host_dir already exists<br>" . "Please remove the directory and its contents and try again" . "<p><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" . "view=$Caseman::HOST_OPEN&case=$Args::enc_args{'case'}\">" . "<img src=\"pict/but_ok.jpg\" alt=\"Ok\" " . "width=\"43\" height=20 border=\"0\"></a>\n"; Print::print_err("\n"); } unless (mkdir "$::host_dir", $::MKDIR_MASK) { Print::print_err("Error making directory $::host_dir: $!"); } print "Host Directory (<tt>$::host_dir</tt>) created<p>\n"; Print::log_case_info("Host $Args::args{'host'} added to case"); # Images directory unless (mkdir "$::host_dir" . "$::IMGDIR", $::MKDIR_MASK) { rmdir "$::host_dir"; Print::print_err("Error making $::host_dir" . "$::IMGDIR"); } # Output Directory unless (mkdir "$::host_dir" . "$::DATADIR", $::MKDIR_MASK) { rmdir "$::host_dir" . "$::IMGDIR"; rmdir "$::host_dir"; Print::print_err("Error making $::host_dir" . "$::DATADIR"); } # Log Directory unless (mkdir "$::host_dir" . "$::LOGDIR", $::MKDIR_MASK) { rmdir "$::host_dir" . "$::DATADIR"; rmdir "$::host_dir" . "$::IMGDIR"; rmdir "$::host_dir"; Print::print_err("Error making $::host_dir" . "$::LOGDIR"); } # Reports directory unless (mkdir "$::host_dir" . "$::REPDIR", $::MKDIR_MASK) { rmdir "$::host_dir" . "$::LOGDIR"; rmdir "$::host_dir" . "$::DATADIR"; rmdir "$::host_dir" . "$::IMGDIR"; rmdir "$::host_dir"; Print::print_err("Error making $::host_dir" . "$::REPDIR"); } # Make a directory for mounting the image in loopback unless (mkdir "$::host_dir" . "mnt", $::MKDIR_MASK) { rmdir "$::host_dir" . "$::REPDIR"; rmdir "$::host_dir" . "$::LOGDIR"; rmdir "$::host_dir" . "$::DATADIR"; rmdir "$::host_dir" . "$::IMGDIR"; rmdir "$::host_dir"; Print::print_err("Error making $::host_dir" . "mnt"); } Print::log_host_info( "Host $Args::args{'host'} added to case $Args::args{'case'}"); # Create config file my $fname = Caseman::host_config_fname(); open HOST_CONFIG, ">$fname" or die "Can't open host config: $fname"; print HOST_CONFIG "# Autopsy host config file\n" . "# Case: $Args::args{'case'} Host: $Args::args{'host'}\n" . "# Created: " . localtime() . "\n\n"; if ((exists $Args::args{'desc'}) && ($Args::args{'desc'} ne "")) { Print::print_err( "Invalid Description\n" . "Use the browser's back button to fix") if ($Args::args{'desc'} =~ /\n/); print HOST_CONFIG "desc $Args::args{'desc'}\n"; } print HOST_CONFIG "timezone " . Args::get_tz() . "\n" if ((exists $Args::args{'tz'}) && ($Args::args{'tz'} ne "")); print HOST_CONFIG "timeskew " . Args::get_ts() . "\n"; if ( (exists $Args::args{'alert_db'}) && ($Args::args{'alert_db'} ne "")) { # Index it if it is not unless (-e "$Args::args{'alert_db'}-md5.idx") { print "Alert Database has not been indexed - it will be as an md5sum file<br>\n"; print "<hr>\n"; Hash::index_md5sum($Args::args{'alert_db'}); print "<hr>\n"; } # only print it if it was successful print HOST_CONFIG "alert_db \'$Args::args{'alert_db'}\'\n" if (-e "$Args::args{'alert_db'}-md5.idx"); } if ( (exists $Args::args{'exclude_db'}) && ($Args::args{'exclude_db'} ne "")) { # Index it if it is not unless (-e "$Args::args{'exclude_db'}-md5.idx") { print "Exclude Database has not been indexed - it will be as an md5sum file<br>\n"; print "<hr>\n"; Hash::index_md5sum($Args::args{'exclude_db'}); print "<hr>\n"; } # only print it if it was successful print HOST_CONFIG "exclude_db \'$Args::args{'exclude_db'}\'\n" if (-e "$Args::args{'exclude_db'}-md5.idx"); } close HOST_CONFIG; print "Configuration file (<tt>$fname</tt>) created<br><br>\n"; print "We must now import an image file for this host\n"; print "<br><br><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" . "view=$Caseman::HOST_OPEN_LOG&$Args::baseargs\">" . "<img src=\"pict/menu_b_inew.jpg\" alt=\"Add Image\" " . " height=20 border=\"0\"></a>\n"; Print::print_html_footer(); return 0; } # Open a host in the given case sub host_open { Print::print_html_header("Open Host In $Args::args{'case'}"); # Create an array of directories in the case, verifying that there is # a config file my @hosts; opendir HOSTS, $::case_dir or die "Can't open $::case_dir directory: $!"; foreach my $h (readdir HOSTS) { next if (($h eq '.') || ($h eq '..')); my $hfile = Caseman::host_config_fname($h); push @hosts, $h if ((-d "$::case_dir" . "$h") && (-e "$hfile")); } closedir HOSTS; print "<b>Case:</b> $Args::args{'case'}<br><br>\n"; print "<center>"; if (scalar @hosts == 0) { print "No hosts have been added to the case yet" . "<br><br>Select the Add Host button below to create one.<br>\n"; } else { print "Select the host to open or create a new one<br>\n"; print_menu_tabs(); print "<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\" " . "background=\"$::YEL_PIX\" border=0>\n"; print "<form action=\"$::PROGNAME\" method=\"get\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::HOST_OPEN_LOG\">\n" . Args::make_hidden() . "<tr><th>Name</th>" . "<th>Description</th><th>&nbsp;</th></tr>\n"; my $first = 0; foreach my $h (@hosts) { print "<tr><td align=\"left\">" . "<input type=\"radio\" name=\"host\" value=$h"; if ($first == 0) { print " CHECKED"; $first = 1; } print "> " . Print::html_encode($h) . " </td>"; my $fname = Caseman::host_config_fname($h); open CONFIG, "<$fname" or die "Can't open host config file ($fname)"; my $desc = "None Provided"; while (<CONFIG>) { s/^\s+//; s/\s+$//; if (/^desc\s+(.*)$/) { $desc = Print::html_encode($1); last; } } close CONFIG; print "<td align=left>$desc</td>" . "<td align=center>" . "<a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" . "view=$Caseman::HOST_DETAILS&$Args::baseargs&" . "host=$h\">details</a></td></tr>\n"; } print "</table>\n"; # Display pulldown of investigators my @invs = read_invest(); if (scalar @invs == 0) { print "<input type=\"hidden\" name=\"inv\" value=\"unknown\">\n"; } else { print "<br>Investigator (for reports only): "; my $cur_inv = ""; $cur_inv = $Args::args{'inv'} if (exists $Args::args{'inv'}); print "<select name=\"inv\" size=\"1\">\n"; if (($cur_inv eq "") && (scalar @invs != 1)) { print "<option value=\"\" selected>Select One" . "</option>\n"; } foreach my $i (@invs) { print "<option value=\"$i\""; print " selected" if ($cur_inv eq $i); print ">" . Print::html_encode($i) . "</option>\n"; } print "</select>\n"; } } print "<br><br><table width=\"600\" cellspacing=\"0\" cellpadding=\"2\">\n" . "<tr>\n"; # Make a table for the buttons. The table will either be 3 or 2 # entries wide, depending on if there is an 'Ok' button or not unless (scalar @hosts == 0) { print "<td align=center>" . "<input type=\"image\" src=\"pict/menu_b_ok.jpg\" " . "alt=\"Ok\" width=\"167\" height=20 border=0>\n" . "</form>\n</td>\n"; } # Add Host print "<td align=center>" . "<form action=\"$::PROGNAME\" method=\"get\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::HOST_ADD\">\n" . "<input type=\"hidden\" name=\"case\" value=\"$Args::args{'case'}\">\n" . "<input type=\"image\" src=\"pict/menu_b_hnew.jpg\" " . "alt=\"Add Host\" width=\"176\" height=20 border=0>\n" . "</form></td>" . # Close Button "<td align=center>" . "<form action=\"$::PROGNAME\" method=\"get\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::CASE_OPEN\">\n" . "<input type=\"image\" src=\"pict/menu_b_ccls.jpg\" " . "alt=\"Close Case\" width=\"176\" height=20 border=0>\n" . "</form></td></tr></table>\n"; print "<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\">\n" . "<tr><td>&nbsp;</td>" . "<td align=center><a href=\"$::HELP_URL\" " . " target=\"_blank\">" . "<img src=\"pict/menu_b_help.jpg\" alt=\"Help\" " . "width=\"167\" height=20 border=0>" . "</a></td><td>&nbsp;</td></tr>\n" . "</table>\n"; Print::print_html_footer(); return 0; } # Log that a given host was opened and then proceed to open an image sub host_open_log { unless ((exists $Args::args{'inv'}) && ($Args::args{'inv'} ne "")) { my @invs = read_invest(); if (scalar @invs == 0) { $Args::args{'inv'} = $Args::enc_args{'inv'} = 'unknown'; } else { Print::print_html_header("Missing Investigator"); print "<br>An investigator must be selected<p>\n" . "<form action=\"$::PROGNAME\" method=\"get\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::HOST_OPEN_LOG\">\n" . Args::make_hidden(); print "Select one of the following:"; print "<select name=\"inv\" size=\"1\">\n"; print "<option value=\"\" selected>Select One" . "</option>\n"; foreach my $i (@invs) { print "<option value=\"$i\">$i</option>\n"; } print "</select><p>\n" . "<input type=\"image\" src=\"pict/but_ok.jpg\" alt=\"Ok\" " . "width=43 height=20 border=\"0\">\n" . "</form>\n"; Print::print_html_footer(); return 0; } } Args::check_inv(); Print::log_case_info( "Host $Args::args{'host'} opened by $Args::args{'inv'}"); Print::log_host_info( "Host $Args::args{'host'} opened by $Args::args{'inv'}"); Print::log_host_inv("Host $Args::args{'host'} opened"); $Args::args{'view'} = $Args::enc_args{'view'} = $Caseman::VOL_OPEN; vol_open(); } # Provide details about the configuration of a host. This window is # a link from the HOST_OPEN window sub host_details { Print::print_html_header( "Details of $Args::args{'case'}:$Args::args{'host'}"); print "<b>Case: </b>$Args::args{'case'}<br><br>" . "<center>" . "<img src=\"pict/menu_h_hdet.jpg\" alt=\"Host Details\">" . "<br><br><br>\n" . "<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\" " . "background=\"$::YEL_PIX\" border=0>\n" . # Name "<tr><td align=\"right\" width=300><b>Name:</b></td>" . "<td align=\"left\" width=300><tt>$Args::args{'host'}</tt></td></tr>\n" . # Description "<tr><td align=\"right\"><b>Description:</b></td>" . "<td align=\"left\"><tt>" . (($Caseman::host_desc ne "") ? $Caseman::host_desc : "&nbsp;") . "</tt></td></tr>\n" . # Timezone "<tr><td align=\"right\"><b>Time zone: </b></td>" . "<td align=\"left\"><tt>$Caseman::tz</tt></td></tr>\n" . # Timeskew "<tr><td align=\"right\"><b>Timeskew:</b></td>" . "<td align=\"left\"><tt>$Caseman::ts</tt></td></tr>\n" . "<tr><td colspan=2>&nbsp;</td></tr>\n" . # Actual Directory "<tr><td align=\"right\"><b>Directory:</b></td>" . "<td align=\"left\"><tt>" . Print::html_encode($::host_dir) . "</tt></td></tr>\n" . "<tr><td colspan=2>&nbsp;</td></tr>\n" . # Alert Database "<tr><td align=\"right\"><b>Alert Hash Database:</b></td>" . "<td align=\"left\"><tt>" . (($Caseman::alert_db ne "") ? Print::html_encode($Caseman::alert_db) : "&nbsp;") . "</tt></td></tr>\n" . # Exclude Database "<tr><td align=\"right\"><b>Exclude Hash Database:</b></td>" . "<td align=\"left\"><tt>" . (($Caseman::exclude_db ne "") ? Print::html_encode($Caseman::exclude_db) : "&nbsp;") . "</tt></td></tr>\n" . "</table>\n"; # Final Button print "<br><br><form action=\"$::PROGNAME\" method=\"get\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::HOST_OPEN\">\n" . Args::make_hidden() . "<input type=\"image\" src=\"pict/menu_b_ok.jpg\" " . "alt=\"Ok\" width=\"167\" height=20 border=\"0\">\n</form>"; Print::print_html_footer(); return; } # Read the investigators file and return a sorted list sub read_invest { my $fname = investig_fname(); open INVES, "<$fname" or return; my @investigs; while (<INVES>) { chomp; s/^\s+//; s/\s+$//; push @investigs, $1 if (/^($::REG_INVESTIG)$/o); } close(INVES); sort { lc($a) cmp lc($b) } @investigs; } # File of investigators name in list sub investig_fname { return "$::case_dir" . "investigators.txt"; } #################################################################### # Image Functions # Types of modes for fname (i.e. can we overwrite it if it exists) my $FNAME_MODE_INIT = 0; my $FNAME_MODE_OVER = 1; my $MD5_NOTHING = 1; my $MD5_CALC = 2; my $MD5_ADD = 3; my $IMG_ADD_SYM = 1; my $IMG_ADD_COPY = 2; my $IMG_ADD_MOVE = 3; # Open an image that has been configured sub vol_open { Print::print_html_header( "Open Image In $Args::args{'case'}:$Args::args{'host'}"); print "<b>Case:</b> $Args::args{'case'}<br>\n"; print "<b>Host:</b> $Args::args{'host'}<br>\n"; print "<center>\n"; # the images have been loaded from reading the host config file in # autopsy_main if (scalar(keys %Caseman::vol2ftype) == 0) { print "No images have been added to this host yet<br><br>\n" . "Select the Add Image File button below to add one\n"; goto EGRESS; } if ($::LIVE == 1) { print "Select a volume to analyze.<br>\n"; } else { print "Select a volume to analyze or add a new image file.<br>\n"; } print_menu_tabs(); print "<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\" " . "background=\"$::YEL_PIX\" border=0>\n"; # We want to sort, so rearrange the hash my %mnt2vol; my %par2disk; # Cycle through each image we read from the host config foreach my $i (keys %Caseman::vol2cat) { if ($Caseman::vol2cat{$i} eq "disk") { $mnt2vol{"1disk--AUTOPSY--$i"} = $i; } elsif ($Caseman::vol2cat{$i} eq "part") { if ( ($Caseman::vol2ftype{$i} eq "raw") || ($Caseman::vol2ftype{$i} eq "swap")) { $mnt2vol{"2$Caseman::vol2ftype{$i}--AUTOPSY--$i"} = $i; } else { $mnt2vol{"2$Caseman::vol2mnt{$i}--AUTOPSY--$i"} = $i; } } } # sort via parent volume, then starting location, # and then mount point (which includes the name) my @mnt = sort { ($Caseman::vol2par{$mnt2vol{$a}} cmp $Caseman::vol2par{$mnt2vol{$b}}) or ($Caseman::vol2start{$mnt2vol{$a}} <=> $Caseman::vol2start{$mnt2vol{$b}}) or (lc($a) cmp lc($b)) } keys %mnt2vol; # It is possible to have only the blkls image and not the original # We need to search for those now because they will not be in the # list that we just made (which are arranged via mount point) my @orphan_blkls; # cycle through each image and check its type and original foreach my $k (keys %Caseman::vol2ftype) { if ( ($Caseman::vol2ftype{$k} eq "blkls") && (!exists $Caseman::mod2vol{$k})) { push @orphan_blkls, $k; } } print "<form action=\"$::PROGNAME\" method=\"get\" target=\"_top\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::VOL_OPEN_LOG\">\n" . Args::make_hidden() . "<tr><th>&nbsp;</th>" . "<th align=left>mount</th>" . "<th align=left>name</th>" . # vol name "<th align=left>fs type</th></tr>\n"; my $prev_par = ""; for (my $i = 0; $i <= $#mnt; $i++) { my $vol = $mnt2vol{$mnt[$i]}; if ($Caseman::vol2par{$vol} ne $prev_par) { print "<tr><td colspan=5><hr></td></tr>\n" if ($i != 0); $prev_par = $Caseman::vol2par{$vol}; } # Mount Point # If we have the dummy string at the end of the duplicate # entry, then take it off and print the original $mnt[$i] = $1 if ($mnt[$i] =~ /^\d(.*?)--AUTOPSY--$::REG_VNAME$/o); print "<tr>" . "<td><input type=\"radio\" name=\"vol\" value=$vol"; print " CHECKED" if ($i == 0); print "></td>" . "<td><tt>" . Print::html_encode($mnt[$i]) . "</tt></td>"; # image name and ftype print "<td><tt>$Caseman::vol2sname{$vol}</tt></td><td>$Caseman::vol2ftype{$vol}</td>"; if ($::LIVE == 0) { print "<td align=center><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" . "view=$Caseman::VOL_DETAILS&$Args::baseargs&" . "vol=$vol\">details</a></td>" . "</tr>\n"; } else { print "<td>&nbsp;</td></tr>\n"; } } # If we are done with the regular images and have some orphan # blkls images, print them my @sort = sort @orphan_blkls; for (my $i = 0; $i <= $#sort; $i++) { print "<tr><td>&nbsp;</td><td>&nbsp;</td><td>(<input type=\"radio\" name=\"vol\" " . "value=$sort[$i]"; print " CHECKED" if ($#mnt == 0); print "> unalloc)</td><td><tt>" . Print::html_encode($Caseman::vol2sname{$sort[$i]}) . "</tt></td><td>" . Print::html_encode($Caseman::vol2ftype{$sort[$i]}) . "</td></tr>\n"; } # Begin Button print "</table>\n"; EGRESS: print "<br><br>" . "<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\">\n"; # Ok Button if (scalar(keys %Caseman::vol2ftype) == 0) { print "<tr><td width=200>&nbsp;</td>\n"; } else { print "<tr><td align=center width=200>" . "<input type=\"image\" src=\"pict/menu_b_analyze.jpg\" " . "alt=\"Analyze\" width=\"167\" height=20 border=0>\n" . "</form></td>\n"; } # Image Add Button if ($::LIVE == 0) { print "<td align=center width=200>" . "<form action=\"$::PROGNAME\" method=\"get\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::IMG_ADD\">\n" . Args::make_hidden() . "<input type=\"image\" src=\"pict/menu_b_ifnew.jpg\" " . "alt=\"Add Image\" width=167 height=20 border=0></form></td>\n" . # Cancel Button "<td align=center width=200>" . "<form action=\"$::PROGNAME\" method=\"get\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::HOST_OPEN\">\n" . "<input type=\"hidden\" name=\"case\" value=\"$Args::args{'case'}\">\n" . "<input type=\"image\" src=\"pict/menu_b_hcls.jpg\" " . "width=167 height=20 alt=\"Close Host\" border=0>\n" . "</form></td></tr>"; } else { print "<td width=200>&nbsp;</td><td width=200>&nbsp;</td></tr>\n"; } # Help Button print "<td width=200>&nbsp;</td><td align=center width=200><a href=\"$::HELP_URL\" " . " target=\"_blank\">" . "<img src=\"pict/menu_b_help.jpg\" alt=\"Help\" " . "width=\"167\" height=20 border=0>" . "</a></td><td width=200>&nbsp;</td></tr>\n" . "</table>\n"; # Other features that can be done on a host if ($::LIVE == 0) { print "<hr><p>" . "<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\">\n" . "<tr>\n"; # Timeline of file activity print "<td align=\"center\" width=200>" . "<a href=\"$::PROGNAME?${Args::baseargs_novol}&" . "mod=$::MOD_TL&view=$Timeline::FRAME\">" . "<img border=0 " . "src=\"pict/menu_b_tl.jpg\" " . "width=\"167\" height=20 " . "alt=\"File Activity Timelines\"></a></td>\n"; # verify the integrity of the images print "<td align=\"center\" width=200>" . "<a href=\"$::PROGNAME?${Args::baseargs_novol}&" . "mod=$::MOD_HASH&view=$Hash::IMG_LIST_FR\">" . "<img border=0 " . "src=\"pict/menu_b_int.jpg\" " . "width=\"167\" height=20 " . "alt=\"Image Integrity\"></a></td>\n" . # Hashdatabases "<td align=\"center\" width=200>" . "<a href=\"$::PROGNAME?${Args::baseargs_novol}&" . "mod=$::MOD_HASH&view=$Hash::DB_MANAGER\">" . "<img border=0 " . "src=\"pict/menu_b_hashdb.jpg\" " . "width=\"167\" height=20 " . "alt=\"Hash Databases\"></a></td>\n" . "</tr></table>\n"; # Notes if ($::USE_NOTES == 1) { print "<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\">\n" . "<tr>\n" . "<td align=\"center\" width=300>" . "<a href=\"$::PROGNAME?${Args::baseargs_novol}&mod=$::MOD_NOTES&view=$Notes::READ_NORM\">" . "<img border=0 " . "src=\"pict/menu_b_note.jpg\" " . "width=\"167\" height=20 " . "alt=\"View Notes\"></a></td>\n" . "<td width=300 align=\"center\">" . "<a href=\"$::PROGNAME?${Args::baseargs_novol}&mod=$::MOD_NOTES&view=$Notes::READ_SEQ\">" . "<img border=0 " . "src=\"pict/menu_b_seq.jpg\" " . "width=\"167\" height=20 " . "alt=\"Event Sequencer\"></a></td>\n" . "</tr>\n" . "</table>\n"; } # If LIVE } else { print "<a href=\"./about\"><br>\n" . "<img src=\"pict/logo.jpg\" border=0 alt=\"Logo\"></a><br>\n"; } Print::print_html_footer(); return 0; } # Log in the host log that a given image was opened by what user # then open the main window sub vol_open_log { # These will be stopped in the func during LIVE Print::log_host_info( "Image $Args::args{'vol'} opened by $Args::args{'inv'}"); Print::log_host_inv("$Args::args{'vol'}: volume opened"); $Args::args{'mod'} = $Args::enc_args{'mod'} = $::MOD_FRAME; $Args::args{'view'} = $Args::enc_args{'view'} = $Frame::IMG_FRAME; Frame::main(); } # Menu to add a new image to the host # # The list of new images is determined by looking in the images directory # and seeing which is not yet configured # sub img_add { Print::print_html_header( "Add Image To $Args::args{'case'}:$Args::args{'host'}"); print "<b>Case:</b> $Args::args{'case'}<br>\n" . "<b>Host:</b> $Args::args{'host'}<br>\n"; print "<form action=\"$::PROGNAME\" method=\"get\" target=\"_top\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::IMG_ADD_PREP\">\n" . Args::make_hidden(); print <<EOF1; <center> <img src=\"pict/menu_h_inew.jpg\" alt=\"Add Image\"> <br><br><br> <table width=\"600\" cellpadding=\"2\" cellspacing=\"0\" background=\"$::YEL_PIX\" border=0> <tr> <td colspan=4>&nbsp;</td> </tr> <tr> <td align=left colspan=4> 1. <b>Location</b><br>Enter the full path (starting with <tt>/</tt>) to the image file.<br> If the image is split (either raw or EnCase), then enter '*' for the extension. </td> </tr> <tr> <td>&nbsp;&nbsp;</td> <td align=left colspan=3> <input type=\"text\" name=\"img_path\" size=36 maxlength=256> </td> </tr> <tr><td colspan=4>&nbsp;</td><tr> <tr> <td align=left colspan=4>2. <b>Type</b><br>Please select if this image file is for a disk or a single partition.</td> </tr> <tr> <td>&nbsp;&nbsp;</td> <td align=left> <input type=\"radio\" name=\"imgtype\" value="disk" CHECKED> Disk </td> <td align=left> <input type=\"radio\" name=\"imgtype\" value="volume"> Partition </td> <td align=left>&nbsp; </td> </tr> <tr><td colspan=4>&nbsp;</td><tr> <tr> <td align=left colspan=4>3. <b>Import Method</b><br>To analyze the image file, it must be located in the evidence locker. It can be imported from its current location using a symbolic link, by copying it, or by moving it. Note that if a system failure occurs during the move, then the image could become corrupt.</td> </tr> <tr> <td>&nbsp;&nbsp;</td> <td align=left> <input type=\"radio\" name=\"sort\" value=$IMG_ADD_SYM CHECKED> Symlink </td> <td align=left> <input type=\"radio\" name=\"sort\" value=$IMG_ADD_COPY> Copy </td> <td align=left> <input type=\"radio\" name=\"sort\" value=$IMG_ADD_MOVE> Move </td> </tr> <tr> <td colspan=4>&nbsp;</td> </tr> </table> <br> <table width=\"600\" cellspacing=\"0\" cellpadding=\"2\"> <tr> <td align=center colspan=2> <input type=\"image\" src=\"pict/menu_b_next.jpg\" alt=\"Next Step\" width=\"167\" height=20 border=0> </td> </tr> </form> EOF1 print "<tr><td colspan=2>&nbsp;</td></tr>\n" . "<td align=center>\n" . " <form action=\"$::PROGNAME\" method=\"get\">\n" . " <input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . " <input type=\"hidden\" name=\"view\" value=\"$Caseman::VOL_OPEN\">\n" . Args::make_hidden() . " <input type=\"image\" src=\"pict/menu_b_cancel.jpg\" " . "alt=\"Cancel\" width=\"167\" height=20 border=0></form>\n" . " </td>\n" . # HELP " <td align=center>\n" . " <a href=\"$::HELP_URL\" target=\"_blank\">\n" . " <img src=\"pict/menu_b_help.jpg\" alt=\"Help\" " . "width=\"167\" height=20 border=0></a>\n" . " </td>\n" . "</tr>\n" . "</table>\n"; Print::print_html_footer(); return 0; } # List the images from the glob - called from img_add_prep if spl_conf is not set sub img_add_split_conf { my $img_path = Args::get_img_path_wild(); my $img_type = $Args::args{'imgtype'}; print "<center><br><br><b>Split Image Confirmation</b><br><br>\n"; my @spl_img = glob($img_path); if (scalar(@spl_img) == 0) { print "No images were found at this location ($img_path)<br>\n" . "Use the back button and fix the path<br>\n"; return; } print <<EOF1; The following images will be added to the case.<br> If this is not the correct order, then you should change the naming convention.<br> Press the Next button at the bottom of the page if this is correct.<br><br> <table width=\"600\" cellpadding=\"2\" cellspacing=\"0\" background=\"$::YEL_PIX\" border=0> <tr> <td colspan=2>&nbsp;</td> </tr> EOF1 my $a = 0; foreach $i (@spl_img) { # We need to do this when we analyze the image, so do it here too to show # what will be analyzed $i = $1 if ($i =~ /^($::REG_IMG_PATH)$/); print "<tr><td align=\"center\">$a</td><td align=\"left\"><tt>$i</tt></td></tr>\n"; $a++; } my $vs = ""; $vs = "&vstype=$Args::args{'vstype'}" if (exists $Args::args{'vstype'}); # Print the Ok Button print "</table><br><br>\n" . "<table width=\"600\" cellpadding=\"2\" cellspacing=\"0\" border=0>" . "<tr><td width=\"300\" align=\"center\"><a href=\"$::PROGNAME?${Args::baseargs_novol}&" . "mod=$::MOD_CASEMAN&view=$Caseman::IMG_ADD_PREP&spl_conf=1&sort=$Args::args{'sort'}&" . "img_path=$img_path&imgtype=$Args::args{'imgtype'}$vs\">" . "<img src=\"pict/menu_b_next.jpg\" alt=\"Next\" " . "width=\"167\" height=20 border=0></a></td>\n" . "<td width=\"300\" align=\"center\"><a href=\"$::PROGNAME?${Args::baseargs_novol}&" . "mod=$::MOD_CASEMAN&view=$Caseman::IMG_ADD\">" . "<img src=\"pict/menu_b_cancel.jpg\" alt=\"cancel\" width=\"167\" height=\"20\" border=\"0\">" . "</a></td></tr></table>\n"; return 0; } # Run the autodetect stuff and get confirmation from the user sub img_add_prep { Args::check_img_path_wild(); Args::check_sort(); unless ((exists $Args::args{'imgtype'}) && ($Args::args{'imgtype'} =~ /^\w+$/)) { Print::print_check_err("Invalid image type"); } Print::print_html_header("Collecting details on new image file"); my $img_path = Args::get_img_path_wild(); my $img_type = $Args::args{'imgtype'}; my $spl_conf = 0; $spl_conf = 1 if ((exists $Args::args{'spl_conf'}) && ($Args::args{'spl_conf'} == 1)); # If we have a wildcard then it is a split image, so we verify it first and # then make a string of the images so we can test it. if ($img_path =~ /[\*\?]/) { if ($spl_conf == 0) { return img_add_split_conf(); } else { $img_tmp = ""; foreach my $i (glob($img_path)) { if ($i =~ /^($::REG_IMG_PATH)$/) { $img_tmp .= "\"$1\" "; } } $img_path = $img_tmp; } } else { unless ((-f $img_path) || (-d $img_path) || (-l $img_path) || (-b $img_path) || (-c $img_path)) { Print::print_err("Image file not found ($img_path)"); } $img_path = "\"$img_path\""; } # Get the image type local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/img_stat' -t $img_path"); my $itype = Exec::read_pipe_line(*OUT); if (defined $itype) { chomp $itype; $itype = $1 if ($itype =~ /^(\w+)$/); } else { print "The image format type could not be determined for this image file<br>\n"; return; } close(OUT); # The plan here is to collect the needed info and then we print it my $conflict = 0; my $cnt = 0; $start[0] = ""; $end[0] = ""; $type[0] = ""; $desc[0] = ""; $active[0] = ""; my $vstype = ""; my $vstype_flag = ""; my $mmls_out = ""; # Will contain output of mmls (if disk image) if ($img_type eq "disk") { my $out; if ( (exists $Args::args{'vstype'}) && ($Args::args{'vstype'} =~ /^(\w+)$/)) { $vstype = $Args::args{'vstype'}; $vstype_flag = "-t $vstype"; } # Get the type else { Exec::exec_pipe(*OUT, "'$::TSKDIR/mmstat' -i $itype $img_path"); $vstype = Exec::read_pipe_line(*OUT); close(OUT); chomp $vstype if (defined $vstype); if ( (!defined $vstype) || ($vstype =~ /^Error determining/) || ($vstype eq "") || (!exists $Vs::type{$vstype}) || ($vstype !~ /^\w+$/)) { print "<table><tr><td colspan=2><font color=\"$::DEL_COLOR[0]\">Warning:</font> Autopsy could not determine the volume system type for the disk image (i.e. the type of partition table).<br>\n" . "Please select the type from the list below or reclassify the image as a volume image instead of as a disk image.</td></tr>\n" . "<tr><td colspan=2>&nbsp;</td></tr>\n" . "<form action=\"$::PROGNAME\" method=\"get\" target=\"_top\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::IMG_ADD_PREP\">\n" . "<input type=\"hidden\" name=\"spl_conf\" value=\"1\">\n" . "<input type=\"hidden\" name=\"img_path\" value=\"$Args::args{'img_path'}\">\n" . "<input type=\"hidden\" name=\"sort\" value=\"$Args::enc_args{'sort'}\">\n" . Args::make_hidden() . "<tr><td>Disk Image <input type=\"radio\" name=\"imgtype\" value=\"disk\" CHECKED></td>\n" . "<td>Volume Image<input type=\"radio\" name=\"imgtype\" value=\"volume\"></td></tr>\n" . "<tr><td>Volume System Type (disk image only): <select name=\"vstype\">\n"; foreach my $vs (sort keys %Vs::type) { print "<option value=\"$vs\""; print " selected" if ($vs eq 'dos'); print ">${vs}</option>\n"; } print "</select></td>" . "<td>&nbsp;</td></tr>" . "<tr><td colspan=2>&nbsp;</td></tr>" . "</table><br><br>\n" . "<input type=\"image\" src=\"pict/menu_b_ok.jpg\" alt=\"Ok\" width=\"176\" height=20 border=0>" . "</form>\n"; return; } $vstype = $1 if ($vstype =~ /^(\w+)$/); $vstype_flag = "-t $vstype"; } # Run 'mmls' on the image Exec::exec_pipe(*OUT, "'$::TSKDIR/mmls' -a -i $itype -aM $vstype_flag -r $img_path"); # cycle through results and add each to table with file system type my $part_type = ""; while ($_ = Exec::read_pipe_line(*OUT)) { $mmls_out .= "$_"; # Save the line last if (/^Error determining partition/); if (/^\d+:\s+[\d:]+\s+(\d+)\s+(\d+)\s+\d+\s+(\S.*)$/) { $start[$cnt] = $1; $end[$cnt] = $2; $desc[$cnt] = $3; $active[$cnt] = 1; } elsif ((/^DOS Partition/) || (/^BSD Disk/) || (/^Sun VTOC/) || (/^MAC Partition/) || (/^GUID Partition/)) { $part_type = $_; #print "<tr><td colspan=7>&nbsp;</td></tr>\n"; #print "<tr><td colspan=7>$_</td></tr>\n"; next; } elsif (/^Sector:/) { #print "<tr><td colspan=7>$_</td></tr>\n"; next; } else { next; } # Skip the BSD partition for the full disk next if ( ($part_type =~ /^BSD Disk/) && ($start[$cnt] == 0) && ($desc[$cnt] =~ /^Unused/)); # Skip if this is an extended DOS partition next if ( ($part_type =~ /^DOS Partition/) && ($desc[$cnt] =~ /Extended \(/)); # Get rid of the leading 0s $start[$cnt] = $1 if ($start[$cnt] =~ /^0+([1-9]\d*)$/); $end[$cnt] = $1 if ($end[$cnt] =~ /^0+([1-9]\d*)$/); # Do we already have this partition? my $i; for ($i = 0; $i < $cnt; $i++) { next if ($active[$i] == 0); if ($start[$i] == $start[$cnt]) { $conflict = 1; if ($end[$i] == $end[$cnt]) { last; } #The previous was the BSD partition - skip it */ if ( ($desc[$i] =~ /^FreeBSD \(0xA5\)/) || ($desc[$i] =~ /^OpenBSD \(0xA6\)/) || ($desc[$i] =~ /^NetBSD \(0xA9\)/)) { $active[$i] = 0; # if the current one is the BSD partition for # the full partition/disk then skip it if ($desc[$cnt] =~ /^Unused /) { $active[$cnt] = 0; } } } # Do we start inside of another? if (($start[$i] > $start[$cnt]) && ($end[$i] < $start[$cnt])) { $conflict = 1; } # Do we end inside of another? elsif (($start[$i] < $end[$cnt]) && ($end[$i] > $end[$cnt])) { $conflict = 1; } } if (($end[$i] == $end[$cnt]) && ($i != $cnt)) { next; } local *OUT2; my $out2; # Run 'fstat -t' on the image Exec::exec_pipe(*OUT2, "'$::TSKDIR/fsstat' -o $start[$cnt] -i $itype -t $img_path"); $type[$cnt] = Exec::read_pipe_line(*OUT2); close(OUT2); if ( (!exists $type[$cnt]) || (!defined $type[$cnt]) || ($type[$cnt] =~ /^Cannot determine/) || ($type[$cnt] eq "")) { $type[$cnt] = "Unknown"; } chomp $type[$cnt]; $cnt++; } close(OUT); if ($conflict == 1) { print "<tr><td colspan=2><font color=\"$::DEL_COLOR[0]\">Warning:</font> Conflicts in the partitions were detected.<br>The full <tt>mmls</tt> output is given at the bottom of the page</td></tr>\n" . "<tr><td colspan=2>&nbsp;</td></tr>\n"; } } # If a volume, then run fsstat on it elsif ($img_type eq "volume") { # Run 'fstat -t' on the image Exec::exec_pipe(*OUT, "'$::TSKDIR/fsstat' -t -i $itype $img_path"); $type[0] = Exec::read_pipe_line(*OUT); close(OUT); if ( (!defined $type[0]) || ($type[0] =~ /^Cannot determine/) || ($type[0] eq "")) { $type[0] = "Unknown"; print "<font color=\"$::DEL_COLOR[0]\">Warning:</font> The file system type of the volume image file could not be determined.<br>\n" . "If this is a disk image file, return to the previous page and change the type.<br><br>\n"; } chomp $type[0]; $start[0] = 0; $end[0] = 0; $active[0] = 1; $desc[0] = $type[0]; $cnt++; close(OUT); } else { Print::print_err("Unknown image type: $img_type"); } my $sname = $img_path; $sname = "$::IMGDIR/" . "$1" if ($sname =~ /\/($::REG_FILE)\"$/); # Now that we have the information about the partitions and disks, print the fields print <<EOF1; <form action=\"$::PROGNAME\" method=\"get\" target=\"_top\"> <input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\"> <input type=\"hidden\" name=\"view\" value=\"$Caseman::IMG_ADD_DOIT\"> <input type=\"hidden\" name=\"img_path\" value=\"$Args::args{'img_path'}\"> <input type=\"hidden\" name=\"num_img\" value=\"$cnt\"> <input type=\"hidden\" name=\"sort\" value=\"$Args::enc_args{'sort'}\"> <center> <h3>Image File Details</h3> <table width=\"600\" cellpadding=\"2\" cellspacing=\"0\" background=\"$::YEL_PIX\" border=0> <tr> <td align=left colspan=4> <b>Local Name: </b> $sname </td> </tr> EOF1 # We do not currently offer integrity options for non-raw files if (($itype eq "raw") || ($itype eq "split")) { print <<EOF1b; <tr> <td align=left colspan=4> <b>Data Integrity: </b> An MD5 hash can be used to verify the integrity of the image. (With split images, this hash is for the full image file) </td> </tr> <tr> <td>&nbsp;&nbsp;</td> <td align=left colspan=3> <input type=\"radio\" name=\"do_md5\" value=\"$MD5_NOTHING\" CHECKED> <u>Ignore</u> the hash value for this image. </td> </tr> <tr> <td>&nbsp;&nbsp;</td> <td align=left colspan=3> <input type=\"radio\" name=\"do_md5\" value=\"$MD5_CALC\"> <u>Calculate</u> the hash value for this image. </td> </tr> <tr> <td>&nbsp;&nbsp;</td> <td align=left colspan=3> <input type=\"radio\" name=\"do_md5\" value=\"$MD5_ADD\"> <u>Add</u> the following MD5 hash value for this image: </td> </tr> <tr> <td>&nbsp;&nbsp;</td> <td align=left colspan=3>&nbsp;&nbsp;&nbsp;&nbsp; <input type=\"text\" name=\"md5\" size=36 maxlength=32> </td> </tr> <tr> <td>&nbsp;&nbsp;</td> <td align=left colspan=3>&nbsp;&nbsp;&nbsp;&nbsp; <input type=\"checkbox\" name=\"ver_md5\" value=\"1\"> &nbsp;Verify hash after importing? </td> </tr> EOF1b } else { print "<input type=\"hidden\" name=\"do_md5\" value=\"$MD5_NOTHING\">\n"; } print <<EOF1c; </table> <h3>File System Details</h3> <table width=\"600\" cellpadding=\"2\" cellspacing=\"0\" background=\"$::YEL_PIX\" border=0> <tr> <td colspan=2 align=left>Analysis of the image file shows the following partitions:</td> </tr> <tr> <td colspan=2>&nbsp;</td> </tr> EOF1c print Args::make_hidden(); print "<input type=\"hidden\" name=\"vstype\" value=\"$vstype\">\n" if ($vstype ne ""); my $idx = 1; my $ms_cnt = 0; my @ms_name = ("C:", "D:", "E:", "F:", "G:", "H:", "I:", "J:"); for (my $i = 0; $i < $cnt; $i++) { next if ($active[$i] == 0); print "<tr><td colspan=2><u>Partition $idx</u> (Type: $desc[$i])</td><tr>\n"; if ($cnt > 1) { print "<tr><td colspan=2>&nbsp;&nbsp;Add to case? " . "<input type=\"checkbox\" name=\"yes-${idx}\" value=1 CHECKED></td></tr>\n"; } else { print "<input type=\"hidden\" name=\"yes-${idx}\" value=1>\n"; } unless (($start[$i] == 0) && ($end[$i] == 0)) { print "<tr><td colspan=2>&nbsp;&nbsp;Sector Range: " . "$start[$i] to $end[$i]" . "</td></tr>\n"; } print "<input type=\"hidden\" name=\"start-${idx}\" value=\"$start[$i]\">" . "<input type=\"hidden\" name=\"end-${idx}\" value=\"$end[$i]\">\n" . "<tr><td>&nbsp;&nbsp;Mount Point: <input type=\"text\" name=\"mnt-${idx}\" size=\"6\""; if (($type[$i] =~ /^ntfs/) || ($type[$i] =~ /^fat/)) { print " value=\"$ms_name[$ms_cnt]\"" if ($ms_cnt < 8); $ms_cnt++; } elsif (($type[$i] =~ /^raw/) || ($type[$i] =~ /^swap/)) { print " value=\"N/A\""; } else { print " value=\"/$idx/\""; } print "></td>\n" . "<td>File System Type: <select name=\"ftype-${idx}\">\n"; foreach my $fs (@Fs::types) { print "<option value=\"$fs\""; print " selected" if ($fs eq $type[$i]); print ">${fs}</option>\n"; } # The following do not have 'metas' but should be in the list print "<option value=\"\">======</option>\n"; if ($type[$i] eq "Unknown") { print "<option value=\"raw\" selected>raw</option>\n"; } else { print "<option value=\"raw\">raw</option>\n"; } print "<option value=\"swap\">swap</option>\n" . "</select></td></tr>\n" . "<tr><td colspan=2>&nbsp;</td></tr>\n"; $idx++; } print "</table>\n"; print <<EOF2; <br><br> <table width=\"600\" cellspacing=\"0\" cellpadding=\"2\"> <tr> <td align=center> <input type=\"image\" src=\"pict/menu_b_add.jpg\" alt=\"Add\" width=\"176\" height=20 border=0> </td> </form> <td align=center> <form action=\"$::PROGNAME\" method=\"get\"> EOF2 print Args::make_hidden(); print <<EOF3; <input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\"> <input type=\"hidden\" name=\"view\" value=\"$Caseman::VOL_OPEN\"> <input type=\"image\" src=\"pict/menu_b_cancel.jpg\" alt=\"Cancel\" width=\"167\" height=20 border=0> </form> </td> <td align=center><a href=\"$::HELP_URL\" target=\"_blank\"> <img src=\"pict/menu_b_help.jpg\" alt=\"Help\" width=\"167\" height=20 border=0></a> </td> </tr> </table> EOF3 if ($img_type eq "disk") { print "</center><p>For your reference, the <tt>mmls</tt> output was the following:<br><pre>$mmls_out</pre>\n"; } Print::print_html_footer(); return 0; } # Add the image to the configuration by adding it to the host config file # and the md5.txt file if that data was provided sub img_add_doit { Args::check_num_img(); Args::check_img_path_wild(); Args::check_sort(); Args::check_do_md5(); my $num_img = Args::get_num_img(); my $img_path = Args::get_img_path_wild(); my $import_type = Args::get_sort(); Print::print_html_header("Add a new image to an Autopsy Case"); my $err = 0; my $add_num = 0; $start[0] = 0; $end[0] = 0; $ftype[0] = ""; $mnt[0] = ""; # We need a string with all images in it for the hashes and file system testing my $img_path_full; if ($img_path =~ /[\*\?]/) { $img_path_full = ""; foreach my $i (glob($img_path)) { if ($i =~ /^($::REG_IMG_PATH)$/) { $img_path_full .= "\"$1\" "; } } } else { $img_path_full = "\"$img_path\""; } # Get the image type local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/img_stat' -t $img_path_full"); my $itype = Exec::read_pipe_line(*OUT); if (defined $itype) { chomp $itype; $itype = $1 if ($itype =~ /^(\w+)$/); } else { print "The image format type could not be determined for this image file<br>\n"; return; } close(OUT); # Check the hash of the image if that is the plan my $do_md5 = Args::get_do_md5(); my $act_md5 = ""; unless ($do_md5 == $MD5_NOTHING) { # Do we need to calculate an MD5? if ( ($do_md5 == $MD5_CALC) || ( ($do_md5 == $MD5_ADD) && (exists $Args::args{'ver_md5'}) && ($Args::args{'ver_md5'} == 1)) ) { print "<p>Calculating MD5 (this could take a while)<br>\n"; $act_md5 = Hash::calc_md5_split($img_path_full); unless ($act_md5 =~ /^$::REG_MD5$/o) { print "Error calculating MD5: $act_md5<br>\n"; return 1; } print "Current MD5: <tt>$act_md5</tt><br>\n"; } # And md5 value was given so we can add it to the md5.txt file if (($do_md5 == $MD5_ADD) && (exists $Args::args{'md5'})) { my $md5 = $Args::args{'md5'}; unless ($md5 =~ /^$::REG_MD5$/o) { if ($md5 eq "") { print "MD5 value missing<br>\n"; } else { print "Invalid MD5 value (32 numbers or letters a-f)<br>\n"; } print "<p><a href=\"$::PROGNAME?" . "mod=$::MOD_CASEMAN&view=$Caseman::IMG_ADD&" . "$Args::baseargs\">" . "<img src=\"pict/menu_b_back.jpg\" border=\"0\" " . "width=\"167\" height=20 alt=\"Back\"></a>\n"; return 1; } $md5 =~ tr/[a-f]/[A-F]/; # They also want us to validate the MD5 if ( (exists $Args::args{'ver_md5'}) && ($Args::args{'ver_md5'} == 1)) { if ($act_md5 eq $md5) { print "Integrity Check Passed<br>\n"; Print::log_host_info("Integrity check passed on new image"); } else { print "<font color=\"$::DEL_COLOR[0]\">" . "Integrity Check Failed<br></font><br>\n" . "Provided: <tt>$md5</tt><br>\n" . "Image not added to case<br>\n"; Print::log_host_info("Integrity check failed on new image"); return 1; } } # set the act_md5 value to what was given and verified $act_md5 = $md5; } # We will add the MD5 to the config file after we get its ID } # Proces the image arguments to make sure they are all there and test the # file system type print "Testing partitions<br>\n"; for (my $i = 0; $i <= $num_img; $i++) { next unless ((exists $Args::args{"yes-" . $i}) && ($Args::args{"yes-" . $i} == 1)); if ( (exists $Args::args{"start-" . $i}) && ($Args::args{"start-" . $i} =~ /^(\d+)$/)) { $start[$add_num] = $1; } else { print "Missing starting address for partition $i<br>\n"; $err = 1; last; } if ( (exists $Args::args{"end-" . $i}) && ($Args::args{"end-" . $i} =~ /^(\d+)$/)) { $end[$add_num] = $1; } else { print "Missing ending address for partition $i<br>\n"; $err = 1; last; } if ( (exists $Args::args{"mnt-" . $i}) && ($Args::args{"mnt-" . $i} =~ /^($::REG_MNT)$/)) { $mnt[$add_num] = $1; } else { print "Missing mount point for partition $i<br>\n"; $err = 1; last; } if ( (exists $Args::args{"ftype-" . $i}) && ($Args::args{"ftype-" . $i} =~ /^($::REG_FTYPE)$/)) { $ftype[$add_num] = $1; } else { print "Missing file system type for partition $i<br>\n"; $err = 1; last; } # Test the File System if (($ftype[$add_num] ne 'swap') && ($ftype[$add_num] ne 'raw')) { local *OUT; my $out; # Run 'fsstat' and see if there is any output - else there was # an error and the data went to STDERR Exec::exec_pipe(*OUT, "'$::TSKDIR/fsstat' -o $start[$add_num] -i $itype -f $ftype[$add_num] $img_path_full" ); unless (read(OUT, $out, 1)) { print "<p>Partition $i is not a <tt>$ftype[$add_num]</tt> file system<br>\n"; $err = 1; last; } close(OUT); } $add_num++; } # Go back if we got an error if ($err == 1) { print "Use the browser's back button to fix the data<br>\n"; return 1; } ################################################## # Copy the images and add them to the config file if ($import_type == $IMG_ADD_SYM) { Print::print_err("ERROR: /bin/ln missing") unless (-x '/bin/ln'); print "Linking image(s) into evidence locker<br>\n"; } elsif ($import_type == $IMG_ADD_COPY) { Print::print_err("ERROR: /bin/cp missing") unless (-x '/bin/cp'); print "Copying image(s) into evidence locker (this could take a little while)<br>\n"; } elsif ($import_type == $IMG_ADD_MOVE) { Print::print_err("ERROR: /bin/mv missing") unless (-x '/bin/mv'); print "Moving image(s) into evidence locker<br>\n"; } else { Print::print_err("Invalid Import Type: $import_type\n"); } my $imgid = ""; foreach my $i (glob($img_path)) { # remove the tainting $i = $1 if ($i =~ /^($::REG_IMG_PATH)$/); # Deterine the local (target) name my $img = ""; if ($i =~ /\/($::REG_FILE)$/) { $img = "$::IMGDIR/$1"; } else { Print::print_err("Error Parsing Image Path ($i)\n"); } # Get the full path of the destination my $img_dst = "$::host_dir" . "$img"; if ((-e "$img_dst") || (-l "$img_dst")) { Print::print_err( "An image by the same name already exists in the Host directory ($img)\n" . "Use the browser's back button to fix the name or delete the existing file." ); } my $orig_size = (stat("$i"))[7]; # Copy, Move, or link it if ($import_type == $IMG_ADD_SYM) { Print::log_host_info( "Sym Linking image $img_path into $Args::args{'case'}:$Args::args{'host'}" ); Exec::exec_sys("/bin/ln -s '$i' '$img_dst'"); } elsif ($import_type == $IMG_ADD_COPY) { Print::log_host_info( "Copying image $img_path into $Args::args{'case'}:$Args::args{'host'}" ); Exec::exec_sys("/bin/cp '$i' '$img_dst'"); } elsif ($import_type == $IMG_ADD_MOVE) { Print::log_host_info( "Moving image $img_path into $Args::args{'case'}:$Args::args{'host'}" ); Exec::exec_sys("/bin/mv '$i' '$img_dst'"); } my $new_size = (stat("$img_dst"))[7]; if ($new_size != $orig_size) { Print::print_err( "Original image size ($orig_size) is not the same as the destination size ($new_size)" ); } # Add the disk and partition images to the config file $imgid = Caseman::add_img_host_config("image", "$itype $img", $imgid); } print "Image file added with ID <tt>$imgid</tt><br>\n"; # AFM files have raw files that we also need to copy # This approach is not the best, since it may copy more than # is needed if ($itype eq "afm") { my $afm_base_path = ""; if ($img_path =~ /^(.*?)\.afm/i) { $afm_base_path = $1; $afm_base_path .= ".[0-9][0-9][0-9]"; } else { Print::print_err( "Error parsing out base name of AFM file $img_path"); } print "BASE: $afm_base_path<br>\n"; my $copied = 0; foreach my $i (glob($afm_base_path)) { $copied++; # remove the tainting $i = $1 if ($i =~ /^($::REG_IMG_PATH)$/); # Deterine the local (target) name my $img = ""; if ($i =~ /\/($::REG_FILE)$/) { $img = "$::IMGDIR/$1"; } else { Print::print_err("Error Parsing Image Path ($i)\n"); } # Get the full path of the destination my $img_dst = "$::host_dir" . "$img"; if ((-e "$img_dst") || (-l "$img_dst")) { Print::print_err( "An image by the same name already exists in the Host directory ($img) (AFM import)\n" . "Use the browser's back button to fix the name or delete the existing file." ); } my $orig_size = (stat("$i"))[7]; # Copy, Move, or link it if ($import_type == $IMG_ADD_SYM) { Print::log_host_info( "Sym Linking image $img_path into $Args::args{'case'}:$Args::args{'host'}" ); Exec::exec_sys("/bin/ln -s '$i' '$img_dst'"); } elsif ($import_type == $IMG_ADD_COPY) { Print::log_host_info( "Copying image $img_path into $Args::args{'case'}:$Args::args{'host'}" ); Exec::exec_sys("/bin/cp '$i' '$img_dst'"); } elsif ($import_type == $IMG_ADD_MOVE) { Print::log_host_info( "Moving image $img_path into $Args::args{'case'}:$Args::args{'host'}" ); Exec::exec_sys("/bin/mv '$i' '$img_dst'"); } my $new_size = (stat("$img_dst"))[7]; if ($new_size != $orig_size) { Print::print_err( "Original image size ($orig_size) is not the same as the destination size ($new_size) after AFM import" ); } } if ($copied == 0) { Print::print_err( "No AFM raw files were found with the same base name and a numeric extension" ); } else { print "$copied AFM raw files imported<br>\n"; } } Caseman::update_md5("$imgid", "$act_md5") unless (($do_md5 == $MD5_NOTHING) || ($imgid eq "")); # Add a disk entry if the image is of a disk unless (($add_num == 1) && ($end[0] == 0) && ($start[0] == 0)) { unless ((exists $Args::args{'vstype'}) && ($Args::args{'vstype'} =~ /^(\w+)$/)) { Print::print_err("Missing Volume System Type"); } my $vstype = $Args::args{'vstype'}; my $diskid = Caseman::add_vol_host_config("disk", "$imgid $vstype"); print "<p>Disk image (type $vstype) added with ID <tt>$diskid</tt>\n"; } # Add the file system / partition entries for (my $i = 0; $i < $add_num; $i++) { my $volid = Caseman::add_vol_host_config("part", "$imgid $start[$i] $end[$i] $ftype[$i] $mnt[$i]"); print "<p>Volume image ($start[$i] to $end[$i] - $ftype[$i] - $mnt[$i]) added with ID <tt>$volid</tt>\n"; } print <<EOF; <p> <center> <table width=600> <tr> <td width=300 align=center> <a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&view=$Caseman::VOL_OPEN&${Args::baseargs_novol}\"> <img src=\"pict/menu_b_ok.jpg\" alt=\"Ok\" width=\"167\" height=20 border=\"0\"> </a> </td> <td width=300 align=center> <a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&view=$Caseman::IMG_ADD&${Args::baseargs_novol}\"> <img src=\"pict/menu_b_inew.jpg\" alt=\"Ok\" width=\"167\" height=20 border=\"0\"> </a> </td> </tr> </table> </center> EOF Print::print_html_footer(); return 0; } # Display details of image based on config values # provides links to remove the config of the image and to get the file # system details sub vol_details { Print::print_html_header("Details of $Args::args{'vol'}"); Args::get_unitsize(); my $vol = Args::get_vol('vol'); my $mnt = $Caseman::vol2mnt{$vol}; my $ftype = $Caseman::vol2ftype{$vol}; print "<center>" . "<img src=\"pict/menu_h_idet.jpg\" alt=\"Image Details\">" . "<br><br><br>\n" . "<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\" " . "background=\"$::YEL_PIX\" border=0>\n" . " <tr><td colspan=\"2\">&nbsp;</td></tr>\n" . # Name " <tr><td align=\"right\" width=\"300\"><b>Name:</b></td>" . "<td align=\"left\"><tt>$Caseman::vol2sname{$vol}</tt></td></tr>\n" . "<tr><td align=\"right\" width=\"300\"><b>Volume Id:</b></td>" . "<td align=\"left\"><tt>$vol</tt></td></tr>\n" . "<tr><td align=\"right\" width=\"300\"><b>Parent Volume Id:</b></td>" . "<td align=\"left\"><tt>$Caseman::vol2par{$vol}</tt></td></tr>\n" . "<tr><td align=\"right\" width=\"300\"><b>Image File Format:</b></td>" . "<td align=\"left\"><tt>$Caseman::vol2itype{$vol}</tt></td></tr>\n" # Mount . " <tr><td align=\"right\"><b>Mounting Point:</b></td>" . "<td align=\"left\"><tt>$mnt</tt></td></tr>\n" . # Type " <tr><td align=\"right\"><b>File System Type:</b></td>" . "<td align=\"left\"><tt>$ftype</tt></td></tr>\n"; # Host Directory print " <tr><td colspan=\"2\">&nbsp;</td></tr>\n" # Strings File . " <tr><td colspan=2 align=\"center\"><b>External Files</b></td></tr>\n" . " <tr><td align=\"right\"><b>ASCII Strings:</b></td>" . "<td align=\"left\"><tt>" . ( (exists $Caseman::vol2str{$vol}) ? $Caseman::vol2sname{$Caseman::vol2str{$vol}} : "&nbsp;" ) . "</tt></td></tr>\n" . # Unicode Strings File " <tr><td align=\"right\"><b>Unicode Strings:</b></td>" . "<td align=\"left\"><tt>" . ( (exists $Caseman::vol2uni{$vol}) ? $Caseman::vol2sname{$Caseman::vol2uni{$vol}} : "&nbsp;" ) . "</tt></td></tr>\n"; if (($ftype ne "raw") && ($ftype ne "swap")) { # blkls file print " <tr><td align=\"right\"><b>Unallocated $Fs::addr_unit{$ftype}s:</b></td>" . "<td align=\"left\"><tt>" . ( (exists $Caseman::vol2blkls{$vol}) ? $Caseman::vol2sname{$Caseman::vol2blkls{$vol}} : "&nbsp;" ) . "</tt></td></tr>\n"; # Strings of blkls print " <tr><td align=\"right\"><b>ASCII Strings of Unallocated:</b></td>" . "<td align=\"left\"><tt>" . ( ( (exists $Caseman::vol2blkls{$vol}) && (exists $Caseman::vol2str{$Caseman::vol2blkls{$vol}}) ) ? $Caseman::vol2sname{$Caseman::vol2str{$Caseman::vol2blkls{$vol}}} : "&nbsp;" ) . "</tt></td></tr>\n"; # Unicodde Strings of blkls print " <tr><td align=\"right\"><b>Unicode Strings of Unallocated:</b></td>" . "<td align=\"left\"><tt>" . ( ( (exists $Caseman::vol2blkls{$vol}) && (exists $Caseman::vol2uni{$Caseman::vol2blkls{$vol}}) ) ? $Caseman::vol2sname{$Caseman::vol2uni{$Caseman::vol2blkls{$vol}}} : "&nbsp;" ) . "</tt></td></tr>\n"; } print " <tr><td colspan=\"2\">&nbsp;</td></tr>\n" . "</table>\n<a name=\"extract\"\n"; # Section for Strings file and 'blkls' file if ( (!(exists $Caseman::vol2str{$vol})) || (!(exists $Caseman::vol2uni{$vol})) || (!(exists $Caseman::vol2blkls{$vol})) || ( (exists $Caseman::vol2blkls{$vol}) && ( (!(exists $Caseman::vol2str{$Caseman::vol2blkls{$vol}})) || (!(exists $Caseman::vol2uni{$Caseman::vol2blkls{$vol}}))) ) ) { print "<hr><table width=600>\n<tr>"; } # Strings File if ( (!(exists $Caseman::vol2str{$vol})) || (!(exists $Caseman::vol2uni{$vol}))) { print "<td align=\"center\" width=280><h3>Extract Strings of<br>Entire Volume</h3>" . "Extracting the ASCII and Unicode strings from a file system will " . "make keyword searching faster.<br><br>\n" . "<form action=\"$::PROGNAME\" method=\"get\">\n" . "Generate MD5? " . "<input type=\"checkbox\" name=\"md5\" value=\"1\" CHECKED><br><br>" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::VOL_MAKESTR\">\n" . "<input type=\"hidden\" name=\"vol\" value=\"$Args::args{'vol'}\">\n" . Args::make_hidden(); if (!(exists $Caseman::vol2str{$vol})) { print "ASCII: <input type=\"checkbox\" name=\"str\" value=\"1\" CHECKED> \n"; } if (!(exists $Caseman::vol2uni{$vol})) { print " Unicode: <input type=\"checkbox\" name=\"uni\" value=\"1\" CHECKED>\n"; } print "<br><br><input type=\"image\" src=\"pict/srch_b_str.jpg\" " . "alt=\"Extract Strings\" border=\"0\">\n</form></td>\n" . "<td width=40>&nbsp;</td>\n"; } if (($ftype eq 'blkls') || ($ftype eq 'swap') || ($ftype eq 'raw')) { # Place holder for types that have no notion of unallocated } # Unallocated Space File elsif (!(exists $Caseman::vol2blkls{$vol})) { print "<td align=\"center\" width=280><h3>Extract Unallocated $Fs::addr_unit{$ftype}s</h3>" . "Extracting the unallocated data in a file system allows " . "more focused keyword searches and data recovery.<br><br>\n" . "(Note: This Does Not Include Slack Space)<br>\n" . "<form action=\"$::PROGNAME\" method=\"get\">\n"; print "Generate MD5? " . "<input type=\"checkbox\" name=\"md5\" value=\"1\" CHECKED><br><br>" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::VOL_MAKEBLKLS\">\n" . "<input type=\"hidden\" name=\"vol\" value=\"$Args::args{'vol'}\">\n" . Args::make_hidden() . "<input type=\"image\" src=\"pict/srch_b_un.jpg\" " . "alt=\"Extract Unallocated Data\" border=\"0\">\n<br></form>\n"; } # strings of 'blkls' elsif ((!(exists $Caseman::vol2str{$Caseman::vol2blkls{$vol}})) || (!(exists $Caseman::vol2uni{$Caseman::vol2blkls{$vol}}))) { print "<td align=\"center\" width=280><h3>Extract Strings of<br>Unallocated $Fs::addr_unit{$ftype}s</h3>" . "Extracting the ASCII strings from the unallocated data will make " . "keyword searching faster.<br><br>\n" . "<form action=\"$::PROGNAME\" method=\"get\">\n" . "Generate MD5? " . "<input type=\"checkbox\" name=\"md5\" value=\"1\" CHECKED><br><br>" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::VOL_MAKESTR\">\n" . "<input type=\"hidden\" name=\"vol\" value=\"$Caseman::vol2blkls{$vol}\">\n" . "<input type=\"hidden\" name=\"fname_mode\" value=\"$FNAME_MODE_INIT\">\n" . Args::make_hidden(); if (!(exists $Caseman::vol2str{$Caseman::vol2blkls{$vol}})) { print "ASCII: <input type=\"checkbox\" name=\"str\" value=\"1\" CHECKED> \n"; } if (!(exists $Caseman::vol2uni{$Caseman::vol2blkls{$vol}})) { print " Unicode: <input type=\"checkbox\" name=\"uni\" value=\"1\" CHECKED>\n"; } print "<br><br><input type=\"image\" src=\"pict/srch_b_str.jpg\" " . "alt=\"Extract Strings\" border=\"0\">\n</form></td>\n"; } if ( (!(exists $Caseman::vol2str{$vol})) || (!(exists $Caseman::vol2uni{$vol})) || (!(exists $Caseman::vol2blkls{$vol})) || ( (exists $Caseman::vol2blkls{$vol}) && ( (!(exists $Caseman::vol2str{$Caseman::vol2blkls{$vol}})) || (!(exists $Caseman::vol2uni{$Caseman::vol2blkls{$vol}}))) ) ) { print "</tr></table><hr>\n"; } print "<p>" . "<table width=\"400\" cellspacing=\"0\" cellpadding=\"2\">\n" . # Ok "<tr><td align=center width=200>" . "<form action=\"$::PROGNAME\" method=\"get\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::VOL_OPEN\">\n" . Args::make_hidden() . "<input type=\"image\" src=\"pict/menu_b_close.jpg\" " . "alt=\"Close\" width=\"167\" height=20 border=0></form></td>\n"; print "<td align=center width=200>"; if (($ftype ne "raw") && ($ftype ne "swap")) { # File System Details print "<form action=\"$::PROGNAME\" method=\"get\" target=\"_blank\">\n" . Args::make_hidden() . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_FRAME\">\n" . "<input type=\"hidden\" name=\"submod\" value=\"$::MOD_FS\">\n" . "<input type=\"hidden\" name=\"vol\" value=\"$vol\">\n" . "<input type=\"image\" src=\"pict/menu_b_fs.jpg\" " . "width=167 height=20 " . "alt=\"File System\" border=0></form></td>\n"; } else { print "&nbsp;</td>\n"; } # Remove Image # THis was removed 12/03 because it causes problems because the image still # exists and config entries and ... it becomes a mess # print # "<td align=center width=200>". # "<form action=\"$::PROGNAME\" method=\"get\">\n". # "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n". # "<input type=\"hidden\" name=\"view\" value=\"$Caseman::IMG_DEL\">\n". # Args::make_hidden(). # "<input type=\"hidden\" name=\"vol\" value=\"$Args::args{'vol'}\">\n". # "<input type=\"hidden\" name=\"mnt\" value=\"$Args::args{'mnt'}\">\n". # "<input type=\"image\" src=\"pict/menu_b_rem.jpg\" ". # "width=167 height=20 alt=\"Remove\" border=0></form>". # "</td>\n". # "</tr></table>\n"; Print::print_html_footer(); return 0; } # remove the config files sub img_del { Args::check_vol('vol'); # Args::check_ftype(); Print::print_html_header( "Removing Configuration Settings for $Args::args{'vol'}"); Caseman::del_host_config("", $Args::args{'vol'}, ""); Caseman::update_md5($Args::args{'vol'}, ""); print "Settings for <tt>$Args::args{'vol'}</tt> removed from " . "<tt>$Args::args{'case'}:$Args::args{'host'}</tt>.\n" . "<p>NOTE: The actual file still exists in the host directory.\n"; print "<p><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" . "view=$Caseman::VOL_OPEN&${Args::baseargs_novol}\">" . "<img src=\"pict/but_ok.jpg\" alt=\"Ok\" " . "width=\"43\" height=20 border=\"0\"></a>\n"; Print::print_html_footer(); return 0; } # Make a strings -t d file for the image to decrease the search time # Can make both ASCII and Unicode strings files sub vol_makestr { Print::print_html_header("Extracting Strings"); my $ascii = 0; my $uni = 0; my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; if ((exists $Args::args{'str'}) && ($Args::args{'str'} == 1)) { if (exists $Caseman::vol2str{$vol}) { Print::print_err( "Image already has an ASCII strings file: $Caseman::vol2sname{$vol}" ); } $ascii = 1; } if ((exists $Args::args{'uni'}) && ($Args::args{'uni'} == 1)) { if (exists $Caseman::vol2uni{$vol}) { Print::print_err( "Image already has a Unicode strings file: $Caseman::vol2sname{$vol}" ); } $uni = 1; } if (($uni == 0) && ($ascii == 0)) { goto str_egress; } my $base_name = $Caseman::vol2sname{$vol}; if ($ascii == 1) { my $fname_rel = "$::DATADIR/${base_name}-$ftype.asc"; my $fname = "$::host_dir" . "$fname_rel"; if (-e "$fname") { my $i = 1; $i++ while (-e "$::host_dir" . "$::DATADIR/" . "${base_name}-$ftype-$i.asc"); $fname_rel = "$::DATADIR/${base_name}-$ftype-$i.asc"; $fname = "$::host_dir" . "$fname_rel"; } print "Extracting ASCII strings from <tt>$Caseman::vol2sname{$vol}</tt><br>\n"; Print::log_host_inv( "$Caseman::vol2sname{$vol}: Saving ASCII strings to $fname_rel"); local *OUT; my $hit_cnt = 0; $SIG{ALRM} = sub { if (($hit_cnt++ % 5) == 0) { print "+"; } else { print "-"; } alarm(5); }; alarm(5); if ($ftype eq "blkls") { Exec::exec_pipe(*OUT, "'$::TSKDIR/srch_strings' -a -t d $img > '$fname'"); } elsif ((($ftype eq "raw") || ($ftype eq "swap")) && ($Caseman::vol2end{$vol} != 0)) { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkls' -e -f $ftype -i $imgtype $img " . $Caseman::vol2start{$vol} . "-" . $Caseman::vol2end{$vol} . " | '$::TSKDIR/srch_strings' -a -t d > '$fname'"); } else { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkls' -e -f $ftype -o $offset -i $imgtype $img | '$::TSKDIR/srch_strings' -a -t d > '$fname'" ); } alarm(0); $SIG{ALRM} = 'DEFAULT'; print $_ while ($_ = Exec::read_pipe_line(*OUT)); close(OUT); print "<br>\n" if ($hit_cnt != 0); # Verify that it worked unless (open(STR, "$fname")) { print( "Error opening $fname<br>\n" . "Either an error occurred while generating the file or " . "no ASCII strings exist<br>"); goto str_uni; } # append to config my $strvol = Caseman::add_vol_host_config("strings", "$vol $fname_rel"); print "Host configuration file updated<br>"; $Caseman::vol2ftype{$strvol} = "strings"; $Caseman::mod2vol{$strvol} = $vol; $Caseman::vol2str{$vol} = $strvol; $Caseman::vol2cat{$strvol} = "mod"; $Caseman::vol2itype{$strvol} = "raw"; $Caseman::vol2par{$strvol} = $vol; $Caseman::vol2path{$strvol} = "$::host_dir" . "$fname_rel"; $Caseman::vol2start{$strvol} = 0; $Caseman::vol2end{$strvol} = 0; $Caseman::vol2sname{$strvol} = $fname_rel; # Calculate MD5 if ((exists $Args::args{'md5'}) && ($Args::args{'md5'} == 1)) { print "Calculating MD5 Value<br><br>\n"; my $m = Hash::int_create_wrap($strvol); print "MD5 Value: <tt>$m</tt><br><br>\n"; } } str_uni: if ($uni == 1) { my $fname_rel = "$::DATADIR/${base_name}-$ftype.uni"; my $fname = "$::host_dir" . "$fname_rel"; if (-e "$fname") { my $i = 1; $i++ while (-e "$::host_dir" . "$::DATADIR/" . "${base_name}-$ftype-$i.uni"); $fname_rel = "$::DATADIR/${base_name}-$ftype-$i.uni"; $fname = "$::host_dir" . "$fname_rel"; } print "<hr>\n" if ($ascii == 1); print "Extracting Unicode strings from <tt>$Caseman::vol2sname{$vol}</tt><br>\n"; Print::log_host_inv( "$Caseman::vol2sname{$vol}: Saving Unicode strings to $fname_rel"); local *OUT; my $hit_cnt = 0; $SIG{ALRM} = sub { if (($hit_cnt++ % 5) == 0) { print "+"; } else { print "-"; } alarm(5); }; alarm(5); if ($ftype eq "blkls") { Exec::exec_pipe(*OUT, "'$::TSKDIR/srch_strings' -a -t d -e l $img > '$fname'"); } elsif ((($ftype eq "raw") || ($ftype eq "swap")) && ($Caseman::vol2end{$vol} != 0)) { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkls' -e -f $ftype -i $imgtype $img " . $Caseman::vol2start{$vol} . "-" . $Caseman::vol2end{$vol} . " | '$::TSKDIR/srch_strings' -a -t d -e l > '$fname'"); } else { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkls' -e -f $ftype -o $offset -i $imgtype $img | '$::TSKDIR/srch_strings' -a -t d -e l > '$fname'" ); } alarm(0); $SIG{ALRM} = 'DEFAULT'; print $_ while ($_ = Exec::read_pipe_line(*OUT)); close(OUT); print "<br>\n" if ($hit_cnt != 0); # Verify that it worked unless (open(STR, "$fname")) { print "Error opening $fname<br>\n" . "Either an error occurred while generating the file or " . "no Unicode strings exist"; goto str_egress; } # append to config my $strvol = Caseman::add_vol_host_config("unistrings", "$vol $fname_rel"); print "Host configuration file updated<br>"; $Caseman::vol2ftype{$strvol} = "strings"; $Caseman::mod2vol{$strvol} = $vol; $Caseman::vol2uni{$vol} = $strvol; $Caseman::vol2cat{$strvol} = "mod"; $Caseman::vol2itype{$strvol} = "raw"; $Caseman::vol2par{$strvol} = $vol; $Caseman::vol2path{$strvol} = "$::host_dir" . "$fname_rel"; $Caseman::vol2start{$strvol} = 0; $Caseman::vol2end{$strvol} = 0; $Caseman::vol2sname{$strvol} = $fname_rel; # Calculate MD5 if ((exists $Args::args{'md5'}) && ($Args::args{'md5'} == 1)) { print "Calculating MD5 Value<br><br>\n"; $m = Hash::int_create_wrap($strvol); print "MD5 Value: <tt>$m</tt><br><br>\n"; } } str_egress: my $dest_vol = $vol; # We need to return with a real image to VOL_DETAILS so check the mod $dest_vol = $Caseman::mod2vol{$vol} if (exists $Caseman::mod2vol{$vol}); print "<hr><a href=\"$::PROGNAME?$Args::baseargs_novol&mod=$::MOD_CASEMAN&" . "view=$Caseman::VOL_DETAILS&vol=$dest_vol\" target=_top>Image Details</a><p>\n"; print "<a href=\"$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_KWSRCH&$Args::baseargs\"" . " target=\"_top\">Keyword Search</a>\n"; Print::print_html_footer(); return 0; } sub vol_makeblkls { Print::print_html_header("Extracting Unallocated Space"); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $base_name = $Caseman::vol2sname{$vol}; $base_name = $1 if ($base_name =~ /^(.*?)\.dd$/); my $fname_rel = "$::DATADIR/${base_name}-$ftype.unalloc"; my $fname = "$::host_dir" . "$fname_rel"; if (-e "$::host_dir" . "$fname_rel") { my $i = 1; $i++ while (-e "$::host_dir" . "$::DATADIR/" . "${base_name}-$ftype-$i.unalloc"); $fname_rel = "$::DATADIR/${base_name}-$ftype-$i.unalloc"; $fname = "$::host_dir" . "$fname_rel"; } Print::log_host_inv( "$Args::args{'vol'}: Saving unallocated data to $fname_rel"); print "Extracting unallocated data from <tt>$Caseman::vol2sname{$vol}</tt><br>\n"; local *OUT; my $hit_cnt = 0; $SIG{ALRM} = sub { if (($hit_cnt++ % 5) == 0) { print "+"; } else { print "-"; } alarm(5); }; alarm(5); Exec::exec_pipe(*OUT, "'$::TSKDIR/blkls' -f $ftype -o $offset -i $imgtype $img > '$fname'"); alarm(0); $SIG{ALRM} = 'DEFAULT'; print "$_" while ($_ = Exec::read_pipe_line(*OUT)); close(OUT); print "<br>\n" if ($hit_cnt != 0); # append to config my $blklsvol = Caseman::add_vol_host_config("blkls", "$vol $fname_rel"); print "Host configuration file updated<br>"; $Caseman::vol2ftype{$blklsvol} = "blkls"; $Caseman::mod2vol{$blklsvol} = $vol; $Caseman::vol2blkls{$vol} = $blklsrvol; $Caseman::vol2cat{$blklsvol} = "mod"; $Caseman::vol2itype{$blklsvol} = "raw"; $Caseman::vol2par{$blklsvol} = $vol; $Caseman::vol2path{$blklsvol} = "$::host_dir" . "$fname_rel"; $Caseman::vol2start{$blklsvol} = 0; $Caseman::vol2end{$blklsvol} = 0; $Caseman::vol2sname{$blklsvol} = $fname_rel; # Calculate MD5 if ((exists $Args::args{'md5'}) && ($Args::args{'md5'} == 1)) { print "Calculating MD5 Value<br>\n"; my $m = Hash::int_create_wrap($blklsvol); print "MD5 Value: <tt>$m</tt><br><br>\n"; } print "<a href=\"$::PROGNAME?$Args::baseargs&mod=$::MOD_CASEMAN&" . "view=$Caseman::VOL_DETAILS\" target=_top>Image Details</a><p>\n"; print "<a href=\"$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_KWSRCH&$Args::baseargs_novol&" . "vol=$fname_rel\" target=\"_top\">Keyword Search</a>\n"; Print::print_html_footer(); return 0; } 1; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/lib/Data.pm����������������������������������������������������������������������������0000644�0000765�0000024�00000071735�11070040246�014443� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Data / Content layer functions # # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2001-2005 by Brian Carrier. All rights reserved # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package Data; $Data::FRAME = 1; $Data::ENTER = 2; $Data::CONT = 3; $Data::CONT_MENU = 4; $Data::CONT_MENU_FR = 5; $Data::REPORT = 6; $Data::LIST = 7; $Data::EXPORT = 8; $Data::BLANK = 9; # Display types that use the sort variable $Data::SORT_ASC = 0; $Data::SORT_HEX = 1; $Data::SORT_STR = 2; # Types of block numbers $Data::ADDR_DD = 0; $Data::ADDR_BLKLS = 1; sub main { # By default, show the main frame $Args::args{'view'} = $Args::enc_args{'view'} = $Data::FRAME unless (exists $Args::args{'view'}); Args::check_view(); my $view = Args::get_view(); # Check Basic Args Args::check_vol('vol'); # These windows don't need the data unit address if ($view == $Data::FRAME) { return frame(); } elsif ($view == $Data::ENTER) { return enter(); } elsif ($view == $Data::LIST) { return list(); } elsif ($view == $Data::BLANK) { return blank(); } # These windows do need the data unit address Args::check_block(); if ($view == $Data::CONT) { return content(); } elsif ($view == $Data::CONT_MENU) { return content_menu(); } elsif ($view == $Data::CONT_MENU_FR) { return content_menu_frame(); } elsif ($view == $Data::REPORT) { return report(); } elsif ($view == $Data::EXPORT) { return export(); } else { Print::print_check_err("Invalid Data View"); } } # Generate the 2 frames for block browsing sub frame { Print::print_html_header_frameset("Data Browse on $Args::args{'vol'}"); print "<frameset cols=\"20%,80%\">\n"; # Data Contents if (exists $Args::args{'block'}) { my $len = Args::get_len(); print "<frame src=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::ENTER&" . "$Args::baseargs&block=$Args::enc_args{'block'}\">\n" . "<frame src=\"$::PROGNAME?" . "mod=$::MOD_DATA&view=$Data::CONT_MENU_FR&" . "block=$Args::enc_args{'block'}&$Args::baseargs&len=$len\" " . "name=\"content\">\n</frameset>\n"; } else { print "<frame src=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::ENTER&" . "$Args::baseargs\">\n" . "<frame src=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::BLANK&" . "$Args::baseargs\" name=\"content\">\n</frameset>\n"; } Print::print_html_footer_frameset(); return 0; } # Frame to enter the data into sub enter { Print::print_html_header(""); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $bs = Args::get_unitsize(); print "<form action=\"$::PROGNAME\" method=\"get\" " . "target=\"content\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_DATA\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$Data::CONT_MENU_FR\">\n" . "<input type=\"hidden\" name=\"vol\" value=\"$vol\">\n" . Args::make_hidden() . # Address "<b>$Fs::addr_unit{$ftype} Number:</b><br>&nbsp;&nbsp;&nbsp;&nbsp;" . "<input type=\"text\" name=\"block\" size=12 maxlength=12"; print " value=\"$Args::enc_args{'block'}\"" if (exists $Args::args{'block'}); print ">\n"; # Number of units print "<p><b>Number of $Fs::addr_unit{$ftype}" . "s:</b>" . "<br>&nbsp;&nbsp;&nbsp;&nbsp;" . "<input type=\"text\" name=\"len\" value=\"1\" size=6 maxlength=6>\n"; print "<p><b>$Fs::addr_unit{$ftype} Size:</b>" . "&nbsp;$bs\n"; # blkls images do not get to select this # if (($ftype ne 'blkls') && ($ftype ne 'swap') && ($ftype ne 'raw')) { if ($Fs::is_fs{$ftype} == 1) { print "<p><b>Address Type:</b><br>&nbsp;&nbsp;&nbsp;&nbsp;" . "<select name=\"btype\" size=1>\n" . "<option value=\"$Data::ADDR_DD\" selected>Regular (dd)</option>\n" . "<option value=\"$Data::ADDR_BLKLS\">Unallocated (blkls)</option>\n" . "</select>\n"; } else { print "<input type=\"hidden\" name=\"btype\" value=\"$Data::ADDR_DD\">\n"; } # Lazarus print "<p><b>Lazarus Addr:</b> " . "<input type=\"checkbox\" name=\"btype2\">\n" . "<p><input type=\"image\" src=\"pict/but_view.jpg\" " . "width=45 height=22 alt=\"View\" border=\"0\">\n" . "</form>\n"; print "<hr><p>" . "<a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::LIST&$Args::baseargs\" target=\"content\">" . "<img src=\"pict/but_alloc_list.jpg\" border=\"0\" " . "width=113 height=20 alt=\"Allocation List\"></a><br>\n" if ($Fs::is_fs{$ftype} == 1); # unless (($ftype eq 'blkls') || ($ftype eq 'swap') || ($ftype eq 'raw')); # If there is a blkls image, then provide a button for it if (($ftype ne 'blkls') && (exists $Caseman::vol2blkls{$vol})) { print "<form action=\"$::PROGNAME\" method=\"get\" target=\"_top\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_FRAME\">\n" . "<input type=\"hidden\" name=\"submod\" value=\"$::MOD_DATA\">\n" . "<input type=\"hidden\" name=\"vol\" value=\"$Caseman::vol2blkls{$vol}\">\n" . Args::make_hidden() . "<p><input type=\"image\" src=\"pict/srch_b_lun.jpg\" " . "alt=\"Load Unallocated Image\" border=\"0\">\n<br></form>\n"; } # If we are using a blkls image, then give a button for the original elsif (($ftype eq 'blkls') && (exists $Caseman::mod2vol{$vol})) { print "<form action=\"$::PROGNAME\" method=\"get\" target=\"_top\">\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_FRAME\">\n" . "<input type=\"hidden\" name=\"submod\" value=\"$::MOD_DATA\">\n" . "<input type=\"hidden\" name=\"vol\" value=\"$Caseman::mod2vol{$vol}\">\n" . Args::make_hidden() . "<p><input type=\"image\" src=\"pict/srch_b_lorig.jpg\" " . "alt=\"Load Original Image\" border=\"0\">\n<br></form>\n"; } Print::print_html_footer(); return 0; } # generate frame for block content sub content_menu_frame { Print::print_html_header_frameset(""); my $sort = $Data::SORT_ASC; $sort = $1 if ((exists $Args::args{'sort'}) && ($Args::args{'sort'} =~ /^(\d+)$/)); my $len = Args::get_len(); if ($len == 0) { Print::print_err("Invalid length: 0"); } my $blk; my $ifind = Args::get_ifind(); # off is 1 if a lazarus block number as they are off by one my $off = 0; $off = -1 if (exists $Args::args{'btype2'}); # Do we need to convert from blkls value to dd value ? if ( (exists $Args::args{'btype'}) && ($Args::args{'btype'} == $Data::ADDR_BLKLS)) { my $vol = Args::get_vol('vol'); my $b = Args::get_block() + $off; my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/blkcalc' -f $ftype -u $b -o $offset -i $imgtype $img"); $blk = Exec::read_pipe_line(*OUT); close(OUT); $blk = "Error getting block" if ((!defined $blk) || ($blk eq "")); if ($blk !~ /^\d+$/) { print "$blk\n"; return 1; } } else { $blk = Args::get_block() + $off; } print "<frameset rows=\"25%,75%\">\n" . "<frame src=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::CONT_MENU&$Args::baseargs" . "&block=$blk&sort=$sort&len=$len&ifind=$ifind\">\n" . "<frame src=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::CONT&$Args::baseargs" . "&block=$blk&sort=$sort&len=$len\" name=\"cont2\">\n" . "</frameset>"; Print::print_html_footer_frameset(); return 0; } sub print_ifind { my $block = Args::get_block(); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; Print::log_host_inv( "$Caseman::vol2sname{$vol}: Finding $Fs::meta_str{$ftype} for data unit $block" ); local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/ifind' -f $ftype -d $block -o $offset -i $imgtype $img"); my $meta = Exec::read_pipe_line(*OUT); close(OUT); $meta = "Error getting meta address" if ((!defined $meta) || ($meta eq "")); if ($meta =~ /^($::REG_META)$/o) { $meta = $1; my $tmpr = $Caseman::vol2mnt{$vol}; print "<b>Pointed to by $Fs::meta_str{$ftype}:</b> " . "<a href=\"$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_META&$Args::baseargs&" . "meta=$meta\" target=\"_top\">$meta</a><br>\n"; print "<b>Pointed to by file:</b>\n"; Exec::exec_pipe(*OUT, "'$::TSKDIR/ffind' -f $ftype -a -o $offset -i $imgtype $img $meta"); while ($_ = Exec::read_pipe_line(*OUT)) { chop; # Make it red if it is deleted if (/^(\*)\s+\/*(.*)$/) { Print::print_output("<tt><font color=\"$::DEL_COLOR[0]\">" . Print::html_encode(${tmpr} . ${2}) . "</font></tt> (deleted)<br>\n"); } # If it starts with a '/' then it must be a file elsif (/^\/(.*)$/) { Print::print_output("<tt>" . Print::html_encode(${tmpr} . ${1}) . "</tt><br>\n"); } # this must be an error else { Print::print_output(Print::html_encode($_) . "<br>\n"); } } close(OUT); } else { print "$meta\n"; } } # Generate index for block content sub content_menu { Print::print_html_header(""); my $block = Args::get_block(); my $prev = $block - 1; my $next = $block + 1; my $sort = Args::get_sort(); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $ifind = Args::get_ifind(); my $len = Args::get_len(); my $bs = Args::get_unitsize(); if ($len == 0) { Print::print_err("Invalid length: 0"); } print "<center>"; my $url = "$::PROGNAME?mod=$::MOD_DATA&view=$Data::CONT_MENU_FR&" . "$Args::baseargs&sort=$sort&len=$len" . "&ifind=$ifind"; # Next and Previous pointers print "<table cellspacing=\"0\" cellpadding=\"2\">\n" . "<tr>\n"; # Previous if ($prev < $Fs::first_addr{$ftype}) { print "<td align=\"right\">&nbsp;</td>\n"; } else { print "<td align=\"right\">" . "<a href=\"$url&block=$prev\" target=\"_parent\">\n" . "<img src=\"pict/but_prev.jpg\" alt=\"previous\" " . "width=\"89\" height=20 border=\"0\"></a></td>\n"; } # Next print "<td align=\"left\"><a href=\"$url&block=$next\"" . " target=\"_parent\">" . "<img src=\"pict/but_next.jpg\" alt=\"next\" " . "width=\"89\" height=20 border=\"0\"></a></td>\n</tr>\n"; print "<tr><td align=\"right\"><a href=\"$::PROGNAME?" . "mod=$::MOD_DATA&view=$Data::EXPORT&$Args::baseargs&" . "block=$block&len=$len\">" . "<img src=\"pict/but_export.jpg\" border=\"0\" alt=\"Export\" " . "width=123 height=20></a></td>\n"; if ($::USE_NOTES == 1) { print "<td align=\"left\">" . "<a href=\"$::PROGNAME?mod=$::MOD_NOTES&view=$Notes::ENTER_DATA&$Args::baseargs&block=$block&len=$len\" " . "target=\"_blank\">" . "<img src=\"pict/but_addnote.jpg\" border=\"0\" " . "width=\"89\" height=20 alt=\"Add Note\"></a></td>\n"; } else { print "<td align=\"left\">&nbsp;</td>\n"; } print "</tr></table>\n"; # Display formats print "<table cellspacing=\"0\" cellpadding=\"2\">\n" . "<tr><td>ASCII ("; if ($sort == $Data::SORT_ASC) { print "display - "; } else { print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::CONT_MENU_FR&" . "$Args::baseargs&" . "sort=$Data::SORT_ASC&block=$block&len=$len\" target=\"_parent\">" . "display</a> - \n"; } print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::REPORT&" . "$Args::baseargs&sort=$Data::SORT_ASC" . "&block=$block&len=$len\" target=\"_blank\">report</a>)</td>\n" . "<td>*</td>\n"; print "<td>Hex ("; if ($sort == $Data::SORT_HEX) { print "display - "; } else { print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::CONT_MENU_FR&" . "$Args::baseargs&" . "sort=$Data::SORT_HEX&block=$block&len=$len\" target=\"_parent\">" . "display</a> - \n"; } print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::REPORT&" . "$Args::baseargs&sort=$Data::SORT_HEX" . "&block=$block&len=$len\" target=\"_blank\">report</a>)</td>\n" . "<td>*</td>\n"; print "<td>ASCII Strings ("; if ($sort == $Data::SORT_STR) { print "display - "; } else { print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::CONT_MENU_FR&" . "$Args::baseargs&" . "sort=$Data::SORT_STR&block=$block&len=$len\" target=\"_parent\">" . "display</a> - \n"; } print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::REPORT&" . "$Args::baseargs&sort=$Data::SORT_STR" . "&block=$block&len=$len\" target=\"_blank\">report</a>)</td>\n" . "</tr></table>\n"; # Special case for 'blkls' b.c. we need to specify original data unit size local *OUT; if ($ftype eq 'blkls') { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkcat' -f $ftype -u $bs -o $offset -i $imgtype $img $block | '$::FILE_EXE' -z -b -" ); } else { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkcat' -f $ftype -o $offset -i $imgtype $img $block | '$::FILE_EXE' -z -b -" ); } my $file_type = Exec::read_pipe_line(*OUT); close(OUT); $file_type = "Error getting file type" if ((!defined $file_type) || ($file_type eq "")); print "<b>File Type:</b> $file_type<br></center>\n"; if ($len == 1) { print "<b>$Fs::addr_unit{$ftype}:</b> $block<br>\n"; } else { my $end = $block + $len - 1; print "<b>$Fs::addr_unit{$ftype}" . "s:</b> $block-$end<br>\n"; } if ($Fs::is_fs{$ftype} == 1) { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkstat' -f $ftype -o $offset -i $imgtype $img $block" ); my $cnt = 0; while ($_ = Exec::read_pipe_line(*OUT)) { if ($_ =~ /((Not )?Allocated)/) { print "<font color=\"$::DEL_COLOR[0]\">" if (defined $2); print "<b>Status:</b> $1<br>"; print "</font>" if (defined $2); } elsif ($_ =~ /Group: (\d+)/) { print "<b>Group:</b> $1<br>\n"; } $cnt++; } close(OUT); if ($cnt == 0) { print "Invalid $Fs::addr_unit{$ftype} address<br>\n"; return; } # Make ifind an option $url = "$::PROGNAME?mod=$::MOD_DATA&view=$Data::CONT_MENU&" . "$Args::baseargs&sort=$sort&len=$len&block=$block"; if ($ifind == 0) { print "<a href=\"$url&ifind=1\">Find Meta Data Address</a><br>\n"; } else { print "<a href=\"$url&ifind=0\">Hide Meta Data Address</a><br>\n"; print_ifind(); } } # Option to view original if it exists if ( ($ftype eq 'blkls') && (exists $Caseman::mod2vol{$vol})) { print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&" . "view=$Data::CONT_MENU_FR&${Args::baseargs_novol}" . "&vol=$Caseman::mod2vol{$vol}&" . "block=$block&sort=$sort&len=$len&btype=$Data::ADDR_BLKLS\" " . "target=\"_parent\">View Original</a><br>\n"; } Print::print_html_footer(); return 0; } #Display actual block content sub content { Args::check_sort(); Print::print_text_header(); my $sort = Args::get_sort(); my $block = Args::get_block(); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $len = Args::get_len(); my $bs = Args::get_unitsize(); my $range = ""; if ($len == 0) { print "Invalid length: 0\n"; exit(1); } elsif ($len == 1) { $range = "$Fs::addr_unit{$ftype} $block"; } else { my $end = $block + $len - 1; $range = "$Fs::addr_unit{$ftype}" . "s $block-$end"; } my $str = "Contents of $range in $Caseman::vol2sname{$vol}\n\n\n"; my $log_str = "contents of $range"; my $usize_str = ""; $usize_str = " -u $bs " if ($ftype eq 'blkls'); local *OUT; if ($sort == $Data::SORT_HEX) { print "Hex " . $str; Print::log_host_inv( "$Caseman::vol2sname{$vol}: Displaying Hex $log_str"); Exec::exec_pipe(*OUT, "'$::TSKDIR/blkcat' -f $ftype $usize_str -h -o $offset -i $imgtype $img $block $len" ); } elsif ($sort == $Data::SORT_ASC) { print "ASCII " . $str; Print::log_host_inv( "$Caseman::vol2sname{$vol}: Displaying ASCII $log_str"); Exec::exec_pipe(*OUT, "'$::TSKDIR/blkcat' -f $ftype $usize_str -a -o $offset -i $imgtype $img $block $len" ); } elsif ($sort == $Data::SORT_STR) { print "ASCII String " . $str; Print::log_host_inv( "$Caseman::vol2sname{$vol}: Displaying string $log_str"); Exec::exec_pipe(*OUT, "'$::TSKDIR/blkcat' -f $ftype $usize_str -o $offset -i $imgtype $img $block $len | '$::TSKDIR/srch_strings' -a" ); } print $_ while ($_ = Exec::read_pipe_data(*OUT, 512)); close(OUT); Print::print_text_footer(); return 0; } sub report { Args::check_sort(); my $sort = Args::get_sort(); my $vol = Args::get_vol('vol'); my $block = Args::get_block(); my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $len = Args::get_len(); my $type; if ($len == 0) { print("Invalid length: 0"); exit(1); } my $bs = Args::get_unitsize(); my $usize_str = ""; $usize_str = " -u $bs " if ($ftype eq 'blkls'); Print::print_text_header("$vol" . "-" . "$Fs::addr_unit{$ftype}" . "$Args::args{'block'}" . ".txt"); if ($sort == $Data::SORT_ASC) { Print::log_host_inv( "$Caseman::vol2sname{$vol}: Generating ASCII report on data unit $block" ); $type = "ascii"; } elsif ($sort == $Data::SORT_STR) { Print::log_host_inv( "$Caseman::vol2sname{$vol}: Generating ASCII strings report on data unit $block" ); $type = "string"; } elsif ($sort == $Data::SORT_HEX) { Print::log_host_inv( "$Caseman::vol2sname{$vol}: Generating hex report on data unit $block" ); $type = "hex"; } else { print "\n\n"; print "invalid sort value"; return 1; } print " Autopsy $type $Fs::addr_unit{$ftype} Report\n\n" . "-" x 70 . "\n" . " GENERAL INFORMATION\n\n"; if ($len == 1) { print "$Fs::addr_unit{$ftype}: $Args::args{'block'}\n"; } else { my $end = $block + $len - 1; print "$Fs::addr_unit{$ftype}" . "s: $Args::args{'block'}-$end\n"; } print "$Fs::addr_unit{$ftype} Size: $bs\n"; # if (($ftype ne 'blkls') && ($ftype ne 'raw') && ($ftype ne 'swap')) { if ($Fs::is_fs{$ftype} == 1) { local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/ifind' -f $ftype -d $block -o $offset -i $imgtype $img" ); my $meta = Exec::read_pipe_line(*OUT); close(OUT); $meta = "Error getting meta address" if ((!defined $meta) || ($meta eq "")); if ($meta =~ /^($::REG_META)$/o) { my $tmpi = $1; print "\nPointed to by $Fs::meta_str{$ftype}: $tmpi\n"; my $tmpr = $Caseman::vol2mnt{$vol}; print "Pointed to by files:\n"; Exec::exec_pipe(*OUT, "'$::TSKDIR/ffind' -f $ftype -a -o $offset -i $imgtype $img $tmpi" ); while ($_ = Exec::read_pipe_line(*OUT)) { chop; if (/^(\*)\s+\/*(.*)$/) { Print::print_output( " $tmpr$2 (deleted)\n"); } elsif (/^\/(.*)$/) { Print::print_output( " $tmpr$1\n"); } else { Print::print_output(" $_\n"); } } close(OUT); } else { print "Not allocated to any meta data structures\n"; } } # not blkls Exec::exec_pipe(*OUT, "'$::TSKDIR/blkcat' -f $ftype $usize_str -o $offset -i $imgtype $img $block $len | '$::MD5_EXE'" ); my $md5 = Exec::read_pipe_line(*OUT); close(OUT); $md5 = "Error getting md5" if ((!defined $md5) || ($md5 eq "")); chop $md5; print "MD5 of raw $Fs::addr_unit{$ftype}: $md5\n"; if ($sort == $Data::SORT_HEX) { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkcat' -f $ftype $usize_str -h -o $offset -i $imgtype $img $block $len | '$::MD5_EXE'" ); } elsif ($sort == $Data::SORT_ASC) { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkcat' -f $ftype $usize_str -a -o $offset -i $imgtype $img $block $len | '$::MD5_EXE'" ); } elsif ($sort == $Data::SORT_STR) { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkcat' -f $ftype $usize_str -o $offset -i $imgtype $img $block $len | '$::TSKDIR/srch_strings' -a | '$::MD5_EXE'" ); } $md5 = Exec::read_pipe_line(*OUT); close(OUT); $md5 = "Error getting md5" if ((!defined $md5) || ($md5 eq "")); chop $md5; print "MD5 of $type output: $md5\n"; print "\nImage: $Caseman::vol2path{$vol}\n"; if (($Caseman::vol2start{$vol} == 0) && ($Caseman::vol2end{$vol} == 0)) { print "Offset: Full image\n"; } elsif ($Caseman::vol2end{$vol} == 0) { print "Offset: $Caseman::vol2start{$vol} to end\n"; } else { print "Offset: $Caseman::vol2start{$vol} to $Caseman::vol2end{$vol}\n"; } print "File System Type: $ftype\n"; my $date = localtime(); print "\nDate Generated: $date\n" . "Investigator: $Args::args{'inv'}\n" . "-" x 70 . "\n" . " CONTENT\n\n"; if ($sort == $Data::SORT_HEX) { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkcat' -f $ftype $usize_str -h -o $offset -i $imgtype $img $block $len" ); } elsif ($sort == $Data::SORT_ASC) { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkcat' -f $ftype $usize_str -a -o $offset -i $imgtype $img $block $len" ); } elsif ($sort == $Data::SORT_STR) { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkcat' -f $ftype $usize_str -o $offset -i $imgtype $img $block $len | '$::TSKDIR/srch_strings' -a" ); } Print::print_output($_) while ($_ = Exec::read_pipe_data(*OUT, 512)); close(OUT); print "\n" . "-" x 70 . "\n" . " VERSION INFORMATION\n\n" . "Autopsy Version: $::VER\n"; print "The Sleuth Kit Version: " . ::get_tskver() . "\n"; Print::print_text_footer(); return 0; } # # Display the block allocation list # sub list { Print::print_html_header("Block Allocation List"); my $BLKLS_GAP = 500; my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $min = 0; $min = Args::get_min() if (exists $Args::args{'min'}); my $max = $min + $BLKLS_GAP - 1; # set fmin to the minimum for the file system my $fmin = $min; $fmin = $Fs::first_addr{$ftype} if ($min < $Fs::first_addr{$ftype}); Print::log_host_inv( "$Caseman::vol2sname{$vol}: Block Allocation List for $min to $max"); print "<center><H2>$Fs::addr_unit{$ftype}: $min - $max</H2>"; my $tmp; if ($min - $BLKLS_GAP >= 0) { $tmp = $min - $BLKLS_GAP; print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::LIST&" . "$Args::baseargs&min=$tmp\">" . "<img src=\"pict/but_prev.jpg\" alt=\"previous\" " . "width=\"89\" height=20 border=\"0\"></a> "; } $tmp = $min + $BLKLS_GAP; print " <a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::LIST&" . "$Args::baseargs&min=$tmp\">" . "<img src=\"pict/but_next.jpg\" alt=\"next\" " . "width=\"89\" height=20 border=\"0\"></a><br>"; print "</center>\n"; local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/blkls' -el -f $ftype -o $offset -i $imgtype $img $fmin-$max" ); while ($_ = Exec::read_pipe_line(*OUT)) { if (/^(\d+)\|([af])/) { print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&" . "view=$Data::CONT_MENU_FR&$Args::baseargs&block=$1\">" . "$1:</a> "; if ($2 eq "a") { print "allocated<br>\n"; } else { print "<font color=\"$::DEL_COLOR[0]\">free</font><br>\n"; } } } close(OUT); print "<center>\n"; if ($min - $BLKLS_GAP >= 0) { $tmp = $min - $BLKLS_GAP; print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::LIST&" . "$Args::baseargs&min=$tmp\">" . "<img src=\"pict/but_prev.jpg\" alt=\"previous\" " . "width=\"89\" height=20 border=\"0\"></a> "; } $tmp = $min + $BLKLS_GAP; print " <a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::LIST&" . "$Args::baseargs&min=$tmp\">" . "<img src=\"pict/but_next.jpg\" alt=\"next\" " . "width=\"89\" height=20 border=\"0\"></a><br>"; print "</center>\n"; Print::print_html_footer(); return 0; } sub export { my $block = Args::get_block(); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $len = Args::get_len(); my $bs = Args::get_unitsize(); Print::print_oct_header( "$vol" . "-" . "$Fs::addr_unit{$ftype}" . "$block" . ".raw"); Print::log_host_inv( "$Caseman::vol2sname{$vol}: Saving contents of data unit $block (unit size: $bs number: $len)" ); local *OUT; if ($ftype eq 'blkls') { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkcat' -f $ftype -u $bs -o $offset -i $imgtype $img $block $len" ); } else { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkcat' -f $ftype -o $offset -i $imgtype $img $block $len" ); } print "$_" while ($_ = Exec::read_pipe_data(*OUT, 512)); close(OUT); Print::print_oct_footer(); return 0; } # Blank Page sub blank { Print::print_html_header("Data Unit Blank Page"); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; print "<center><h3>Data Unit Mode</h3><br>\n" . "Here you can view the contents of any $Fs::addr_unit{$ftype} in the file system.<br>\n" . "Enter the address in the field on the left.\n"; Print::print_html_footer(); return 0; } �����������������������������������autopsy-2.24/lib/define.pl��������������������������������������������������������������������������0000644�0000765�0000024�00000001522�11355002261�015007� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# $VER = '2.24'; $HTTP_NL = "\x0a"; $notes_file = ""; $PICTDIR = "$INSTALLDIR/pict/"; $SANITIZE_TAG = 'AutopsySanitized'; $SANITIZE_PICT = 'sanitized.jpg'; $PROGNAME = 'autopsy'; # Default directory names $MKDIR_MASK = 0775; $IMGDIR = 'images'; $DATADIR = 'output'; $LOGDIR = 'logs'; $REPDIR = 'reports'; # Colors $BACK_COLOR = "#CCCC99"; $BACK_COLOR_TABLE = "#CCCCCC"; $DEL_COLOR[0] = "red"; $DEL_COLOR[1] = "#800000"; # used when meta data structure has been reallocated $NORM_COLOR = ""; $LINK_COLOR = "blue"; $YEL_PIX = "pict/back_pix.jpg"; %m2d = ( "Jan", 1, "Feb", 2, "Mar", 3, "Apr", 4, "May", 5, "Jun", 6, "Jul", 7, "Aug", 8, "Sep", 9, "Oct", 10, "Nov", 11, "Dec", 12 ); @d2m = ( "", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ); 1; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/lib/Exec.pm����������������������������������������������������������������������������0000644�0000765�0000024�00000005132�11070040246�014442� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Functions that wrap the execution of tools so that they are logged # # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2001-2005 by Brian Carrier. All rights reserved # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package Exec; # exec_pipe(HANDLE, CMD); sub exec_pipe { my $handle = shift(@_); my $cmd = shift(@_); die "Can't open pipe for exec_pipe" unless defined(my $pid = open($handle, '-|')); if ($pid) { return $handle; } else { $| = 1; Print::log_host_inv_exec("$cmd"); exec("$cmd") or die "Can't exec program: $!"; } } sub read_pipe_line { my $handle = shift(@_); my $out; # for (my $i = 0; ($len = read ($handle, $$buf, $size)) && (!defined $len); $i++) { for (my $i = 0; $i < 100; $i++) { $out = <$handle>; return $out if (defined $out); } return $out; } sub read_pipe_data { my $handle = shift(@_); my $size = shift(@_); my $out; my $len; for ( my $i = 0; ($len = read($handle, $out, $size)) && (!defined $len) && ($i < 100); $i++ ) { } return $out; } sub exec_sys { my $cmd = shift(@_); Print::log_host_inv_exec("$cmd"); system($cmd); return; } 1; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/lib/File.pm����������������������������������������������������������������������������0000644�0000765�0000024�00000214015�11355002261�014440� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # File name layer functions # # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2001-2005 by Brian Carrier. All rights reserved # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Updated 1/15 package File; # If the order of these views are changed, then the checks in main # must be as well $File::BLANK = 0; $File::FRAME = 1; $File::DIR_LIST = 2; $File::FILE_LIST_DIR = 3; $File::FILE_LIST_FILE = 4; $File::FILE_LIST_DEL = 5; $File::FILE_LIST = 6; $File::CONT = 7; $File::CONT_FR = 8; $File::CONT_MENU = 9; $File::REPORT = 10; $File::EXPORT = 11; $File::MD5LIST = 12; $File::CONT_IMG = 13; $File::REC_NO = 0; $File::REC_YES = 1; sub main { # By default, show the main frame $Args::args{'view'} = $Args::enc_args{'view'} = $File::FRAME unless (exists $Args::args{'view'}); Args::check_view(); my $view = Args::get_view(); if ($view == $File::BLANK) { blank(); return 0; } # Check Basic Args Args::check_vol('vol'); # These windows don't need the meta data address if ($view < $File::FILE_LIST) { if ($view == $File::FRAME) { return frame(); } Args::check_dir(); if ($view == $File::DIR_LIST) { return dir_list(); } elsif ($view == $File::FILE_LIST_DIR) { return file_list_dir(); } elsif ($view == $File::FILE_LIST_DEL) { return file_list_del(); } elsif ($view == $File::FILE_LIST_FILE) { return file_list_file(); } } # These windows need the meta data address Args::check_dir(); Args::check_meta('meta'); if ($view < $File::REPORT) { if ($view == $File::FILE_LIST) { return file_list(); } elsif ($view == $File::CONT) { return content(); } elsif ($view == $File::CONT_FR) { return content_fr(); } elsif ($view == $File::CONT_MENU) { return content_menu(); } } else { if ($view == $File::REPORT) { return report(); } elsif ($view == $File::EXPORT) { return export(); } elsif ($view == $File::MD5LIST) { return md5list(); } elsif ($view == $File::CONT_IMG) { return content_img(); } } Print::print_check_err("Invalid File View"); } # Sorting and display types my $FIL_SORT_ASC = 0; my $FIL_SORT_STR = 1; my $FIL_SORT_HEX = 2; # Methods of sorting the file listings my $SORT_DTYPE = 0; # type according to dentry my $SORT_ITYPE = 1; # type according to meta my $SORT_NAME = 2; my $SORT_MOD = 3; my $SORT_ACC = 4; my $SORT_CHG = 5; my $SORT_CRT = 6; my $SORT_SIZE = 7; my $SORT_GID = 8; my $SORT_UID = 9; my $SORT_META = 10; my $SORT_DEL = 11; my $DIRMODE_SHOW = 1; my $DIRMODE_NOSHOW = 2; # # Make the three frames and fill them in # sub frame { my $vol = Args::get_vol('vol'); my $mnt = $Caseman::vol2mnt{$vol}; my $ftype = $Caseman::vol2ftype{$vol}; # If we were not given the meta, then look up the root unless (exists $Args::args{'meta'}) { $Args::args{'meta'} = $Args::enc_args{'meta'} = $Fs::root_meta{$ftype}; } unless (exists $Args::args{'dir'}) { $Args::enc_args{'dir'} = $Args::args{'dir'} = "/"; } Args::check_meta('meta'); Args::check_dir(); my $meta = Args::get_meta('meta'); my $dir = Args::get_dir(); Print::print_html_header_frameset("$mnt$dir on $Args::args{'vol'}"); my $sort = $SORT_NAME; $sort = $Args::args{'sort'} if (exists $Args::args{'sort'}); my $dirmode = $DIRMODE_NOSHOW; $dirmode = $Args::args{'dirmode'} if (exists $Args::args{'dirmode'}); print "<frameset cols=\"175,*\">\n"; # Directory Listing on Left my $url = "$::PROGNAME?$Args::baseargs&dir=$dir&" . "sort=$sort&dirmode=$dirmode"; print "<frame src=\"$url&mod=$::MOD_FILE&view=$File::DIR_LIST\">\n"; # File frameset on right print "<frameset rows=\"50%,50%\">\n"; # File Listings on top print "<frame src=\"$url&mod=$::MOD_FILE&view=$File::FILE_LIST&meta=$meta\" " . "name=\"list\">\n"; # File Contents print "<frame src=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::BLANK&" . "$Args::baseargs\" name=\"content\">\n" . "</frameset>\n" . "</frameset>\n"; Print::print_html_footer_frameset(); return 0; } # # Print the directory names for the lhs frame and other # Search forms # sub dir_list { Args::check_sort(); Args::check_dirmode(); Print::print_html_header(""); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $sort = Args::get_sort(); my $dirmode = Args::get_dirmode(); my $mnt = $Caseman::vol2mnt{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $lcldir = ""; my $prev_plus = ""; # previous number of '+' directory spacers my $prev_fname = ""; my $prev_meta = ""; # Field to enter a directory into: print "<p><form action=\"$::PROGNAME\" method=\"get\" target=\"list\">\n" . "<center><b>Directory Seek</b></center><br>" . "Enter the name of a directory that you want to view.<br>" . "<tt>$mnt</tt>" . "<input type=\"text\" name=\"dir\" size=24 maxlength=100>\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_FILE\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$File::FILE_LIST_DIR\">\n" . "<input type=\"hidden\" name=\"vol\" value=\"$vol\">\n" . "<input type=\"hidden\" name=\"sort\" value=\"$Args::args{'sort'}\">\n" . "<input type=\"hidden\" name=\"dirmode\" value=\"$Args::args{'dirmode'}\">\n" . Args::make_hidden() . # View Button "<br><input type=\"image\" src=\"pict/but_view.jpg\" " . "width=45 height=22 alt=\"View\" border=\"0\"></form>\n"; # Field to enter a name into: print "<hr><p><form action=\"$::PROGNAME\" method=\"get\" target=\"list\">\n" . "<center><b>File Name Search</b></center><br>" . "Enter a Perl regular expression for the file names you want to find.<br><br>\n" . "<input type=\"text\" name=\"dir\" size=24 maxlength=100>\n" . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_FILE\">\n" . "<input type=\"hidden\" name=\"view\" value=\"$File::FILE_LIST_FILE\">\n" . "<input type=\"hidden\" name=\"vol\" value=\"$Args::args{'vol'}\">\n" . "<input type=\"hidden\" name=\"sort\" value=\"$Args::args{'sort'}\">\n" . "<input type=\"hidden\" name=\"dirmode\" value=\"$Args::args{'dirmode'}\">\n" . Args::make_hidden() . "<br>\n" . # Search Button "<input type=\"image\" src=\"pict/but_search.jpg\" " . "width=61 height=22 alt=\"Search\" border=\"0\"></form>\n"; print "<p><hr><p>\n"; my $base_url = "$::PROGNAME?$Args::baseargs&sort=$sort"; # All deleted files button print "<a href=\"$base_url&mod=$::MOD_FILE&view=$File::FILE_LIST_DEL&" . "dir=&dirmode=$dirmode\" target=\"list\">" . "<img border=\"0\" src=\"pict/file_b_alldel.jpg\" width=\"127\" " . "alt=\"Show All Deleted Files\">" . "</a><p>\n"; # The dirmode arg shows if we should expand the whole directory listing # or not if ($dirmode == $DIRMODE_NOSHOW) { print "<a href=\"$base_url&mod=$::MOD_FILE&view=$File::FRAME&" . "dirmode=$DIRMODE_SHOW\" target=\"_parent\">" . "<img src=\"pict/file_b_expand.jpg\" alt=\"Expand All Directories\" " . "border=\"0\"></a><p><hr>\n"; return; } else { print "<a href=\"$base_url&mod=$::MOD_FILE&view=$File::FRAME&" . "dirmode=$DIRMODE_NOSHOW\" target=\"_parent\">" . "<img src=\"pict/file_b_hide.jpg\" alt=\"Hide All Directories\" " . "border=\"0\"></a><p><hr>\n"; } $base_url .= "&dirmode=$dirmode"; Print::log_host_inv("$Args::args{'vol'}: List of all directories"); # We need to maintain state to create dir and this is done by # counting the + marks. local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/fls' -f $ftype -ruD -o $offset -i $imgtype $img"); # Print root my $url = "$base_url&mod=$::MOD_FILE&view=$File::FILE_LIST&" . "meta=$Fs::root_meta{$ftype}&dir="; print "<p><a href=\"$url\" target=\"list\">$mnt</a><br>\n"; while ($_ = Exec::read_pipe_line(*OUT)) { if ( /^(\*)?(\+*)\s*[\-d]\/[\-d]\s*(\d+)\-?\d*\-?\d*\s*(\(realloc\))?:\t(.+)$/ ) { my $del = $1; my $plus = $2; my $meta = $3; my $re = $4; my $fname = $5; # Adjust the dir value using the '++' values to determine # how "deep" we are unless ($prev_plus eq $plus) { # are we in 1 more if ($plus eq $prev_plus . '+') { $lcldir .= ($prev_fname . "/"); } # we are back (at least one) elsif (defined $plus) { my @dirs = split('/', $lcldir); my $idx = -1; $lcldir = ""; while (($idx = index($plus, '+', $idx + 1)) != -1) { $lcldir .= ($dirs[$idx] . "/"); } } } $prev_plus = $plus; $prev_fname = $fname; $prev_meta = $meta; $url = "$base_url&mod=$::MOD_FILE&view=$File::FILE_LIST&" . "meta=$meta&dir=" . Args::url_encode($lcldir . $fname . "/"); print "<font color=\"$::DEL_COLOR[0]\">" if defined $del; print "+$plus<a href=\"$url\" target=\"list\"><tt>/" . Print::html_encode($fname) . "</tt></a><br>\n"; print "</font>" if defined $del; } } close(OUT); Print::print_html_footer(); return 0; }; # end of FIL_DIR # Print the files and directories for the upper rhs frame # These can be sorted in any format # # We need to find a way to cache this data # sub file_list { Args::check_sort(); Args::check_dirmode(); my $vol = Args::get_vol('vol'); my $sort = Args::get_sort(); my $ftype = $Caseman::vol2ftype{$vol}; my $meta = Args::get_meta('meta'); my $mnt = $Caseman::vol2mnt{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $fname = "$mnt$Args::args{'dir'}"; $fname =~ s/\/\//\//g; my $sp = "&nbsp;&nbsp;"; Print::print_html_header("Entries in $fname"); my (@itype, @dtype, @name, @mod, @acc, @chg, @crt, @size, @gid, @uid, @meta); my (@dir, @entry, @del, @realloc, @meta_int); my $tz = ""; $tz = "-z '$Caseman::tz'" unless ("$Caseman::tz" eq ""); Print::log_host_inv( "$Caseman::vol2sname{$vol}: Directory listing of $fname ($meta)"); local *OUT; # execute command Exec::exec_pipe(*OUT, "'$::TSKDIR/fls' -f $ftype -la $tz -s $Caseman::ts -o $offset -i $imgtype $img $meta" ); # Make the big table, small table, and start the current directory my $iurl = "$::PROGNAME?$Args::baseargs&dirmode=$Args::enc_args{'dirmode'}&sort=$sort"; # base number of columns in table my $cols = 15; $cols += 2 if ($Fs::has_ctime{$ftype}); $cols += 2 if ($Fs::has_crtime{$ftype}); $cols += 2 if ($Fs::has_mtime{$ftype}); print <<EOF1; <!-- Big Table --> <table cellspacing=\"0\" cellpadding=\"2\" border=0> <!-- Small Table --> <tr> <td colspan=$cols> <table border=0 align=\"left\" cellspacing=\"0\" cellpadding=\"2\" width=500> <tr> <td colspan=2><b>Current Directory:</b> <tt> <a href=\"${iurl}&mod=$::MOD_FILE&view=$File::FILE_LIST&meta=$Fs::root_meta{$ftype}&dir=\">$mnt</a>&nbsp; EOF1 # Each file in the path will get its own link $iurl .= "&mod=$::MOD_FILE&view=$File::FILE_LIST_DIR"; my $path = ""; my @dir_split = split('/', $Args::args{'dir'}); while (scalar @dir_split > 1) { my $d = shift @dir_split; next if ($d eq ''); $path .= "$d/"; print " <a href=\"${iurl}&dir=$path\">/${d}/</a>&nbsp;\n"; } print " /$dir_split[0]/&nbsp;\n" if (scalar @dir_split == 1); print " </tt></td>\n" . " </tr>\n"; # Add Note Button $iurl = "&$Args::baseargs&dir=$Args::enc_args{'dir'}&meta=$Args::enc_args{'meta'}"; if ($::USE_NOTES == 1) { print <<EOF2; <tr> <td width=\"100\" align=left> <a href=\"$::PROGNAME?mod=$::MOD_NOTES&view=$Notes::ENTER_FILE$iurl\" target=\"_blank\"> <img border=\"0\" src=\"pict/but_addnote.jpg\" width=\"89\" height=20 alt=\"Add Note About Directory\"> </a> </td> EOF2 } # Generate MD5 List Button print <<EOF3; <td width=\"206\" align=left> <a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::MD5LIST$iurl\" target=\"_blank\"> <img border=\"0\" src=\"pict/file_b_md5list.jpg\" width=\"206\" alt=\"Generate list of MD5 values\"> </a> </td> </tr> <!-- END of Little Table --> </table> </td> </tr> <tr> <td colspan=$cols><hr></td> </tr> EOF3 # Make the Table and Headers my $url = "$::PROGNAME?mod=$::MOD_FILE&view=$File::FRAME&" . "$Args::baseargs&meta=$Args::enc_args{'meta'}" . "&dir=$Args::enc_args{'dir'}&dirmode=$Args::enc_args{'dirmode'}"; print "<tr valign=\"MIDDLE\" " . "background=\"$::YEL_PIX\">\n"; # Print the Headers - If the sorting mode is set to it, then don't # make it a link and print a different button if ($sort == $SORT_DEL) { print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<img border=\"0\" " . "src=\"pict/file_h_del_cur.jpg\" " . "width=\"49\" height=20 " . "alt=\"Deleted Files\">" . "</td>\n"; } else { $iurl = $url . "&sort=$SORT_DEL"; print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<a href=\"$iurl\" target=\"_parent\">" . "<img border=\"0\" " . "src=\"pict/file_h_del_link.jpg\" " . "width=\"28\" height=20 " . "alt=\"Deleted Files\">" . "</a></td>\n"; } # type only gets one column for two 'types' print " <td background=\"$::YEL_PIX\">$sp</td>\n" . " <th align=\"center\" background=\"$::YEL_PIX\">" . "&nbsp;&nbsp;Type&nbsp;&nbsp;<br>"; if ($sort == $SORT_DTYPE) { print "dir"; } else { $iurl = $url . "&sort=$SORT_DTYPE"; print "<a href=\"$iurl\" target=\"_parent\">dir</a>"; } print "&nbsp;/&nbsp;"; if ($sort == $SORT_ITYPE) { print "in</th>\n"; } else { $iurl = $url . "&sort=$SORT_ITYPE"; print "<a href=\"$iurl\" target=\"_parent\">in</a></th>\n"; } print " <td background=\"$::YEL_PIX\">$sp</td>\n"; if ($sort == $SORT_NAME) { print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<img border=\"0\" " . "src=\"pict/file_h_nam_cur.jpg\" " . "width=\"76\" height=20 " . "alt=\"File Name\">" . "</td>\n"; } else { $iurl = $url . "&sort=$SORT_NAME"; print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<a href=\"$iurl\" target=\"_parent\">" . "<img border=\"0\" " . "src=\"pict/file_h_nam_link.jpg\" " . "width=\"50\" height=20 " . "alt=\"File Name\">" . "</a></td>\n"; } print " <td background=\"$::YEL_PIX\">$sp</td>\n"; # Modified / Written if ($Fs::has_mtime{$ftype}) { if ($sort == $SORT_MOD) { print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<img border=\"0\" " . "src=\"pict/file_h_wr_cur.jpg\" " . "width=\"89\" height=20 " . "alt=\"Modified/Written Time\">" . "</td>\n"; } else { $iurl = $url . "&sort=$SORT_MOD"; print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<a href=\"$iurl\" target=\"_parent\">" . "<img border=\"0\" " . "src=\"pict/file_h_wr_link.jpg\" " . "width=\"60\" height=20 " . "alt=\"Modified/Written Time\">" . "</a></td>\n"; } print " <td background=\"$::YEL_PIX\">$sp</td>\n"; } # Accessed if ($sort == $SORT_ACC) { print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<img border=\"0\" " . "src=\"pict/file_h_acc_cur.jpg\" " . "width=\"90\" height=20 " . "alt=\"Access Time\">" . "</td>\n"; } else { $iurl = $url . "&sort=$SORT_ACC"; print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<a href=\"$iurl\" target=\"_parent\">" . "<img border=\"0\" " . "src=\"pict/file_h_acc_link.jpg\" " . "width=\"66\" height=20 " . "alt=\"Access Time\">" . "</a></td>\n"; } print " <td background=\"$::YEL_PIX\">$sp</td>\n"; # Change if ($Fs::has_ctime{$ftype}) { if ($sort == $SORT_CHG) { print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<img border=\"0\" " . "src=\"pict/file_h_chg_cur.jpg\" " . "width=\"90\" height=20 " . "alt=\"Change Time\">" . "</td>\n"; } else { $iurl = $url . "&sort=$SORT_CHG"; print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<a href=\"$iurl\" target=\"_parent\">" . "<img border=\"0\" " . "src=\"pict/file_h_chg_link.jpg\" " . "width=\"62\" height=20 " . "alt=\"Change Time\">" . "</a></td>\n"; } print " <td background=\"$::YEL_PIX\">$sp</td>\n"; } # Create if ($Fs::has_crtime{$ftype}) { if ($sort == $SORT_CRT) { print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<img border=\"0\" " . "src=\"pict/file_h_cre_cur.jpg\" " . "width=\"84\" height=20 " . "alt=\"Create Time\">" . "</td>\n"; } else { $iurl = $url . "&sort=$SORT_CRT"; print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<a href=\"$iurl\" target=\"_parent\">" . "<img border=\"0\" " . "src=\"pict/file_h_cre_link.jpg\" " . "width=\"59\" height=20 " . "alt=\"Create Time\">" . "</a></td>\n"; } print " <td background=\"$::YEL_PIX\">$sp</td>\n"; } # Size if ($sort == $SORT_SIZE) { print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<img border=\"0\" " . "src=\"pict/file_h_siz_cur.jpg\" " . "width=\"53\" height=20 " . "alt=\"Size\">" . "</td>\n"; } else { $iurl = $url . "&sort=$SORT_SIZE"; print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<a href=\"$iurl\" target=\"_parent\">" . "<img border=\"0\" " . "src=\"pict/file_h_siz_link.jpg\" " . "width=\"31\" height=20 " . "alt=\"Size\">" . "</a></td>\n"; } print " <td background=\"$::YEL_PIX\">$sp</td>\n"; # UID if ($sort == $SORT_UID) { print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<img border=\"0\" " . "src=\"pict/file_h_uid_cur.jpg\" " . "width=\"49\" height=20 " . "alt=\"UID\">" . "</td>\n"; } else { $iurl = $url . "&sort=$SORT_UID"; print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<a href=\"$iurl\" target=\"_parent\">" . "<img border=\"0\" " . "src=\"pict/file_h_uid_link.jpg\" " . "width=\"27\" height=20 " . "alt=\"UID\">" . "</a></td>\n"; } print " <td background=\"$::YEL_PIX\">$sp</td>\n"; # GID if ($sort == $SORT_GID) { print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<img border=\"0\" " . "src=\"pict/file_h_gid_cur.jpg\" " . "width=\"49\" height=20 " . "alt=\"GID\">" . "</td>\n"; } else { $iurl = $url . "&sort=$SORT_GID"; print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<a href=\"$iurl\" target=\"_parent\">" . "<img border=\"0\" " . "src=\"pict/file_h_gid_link.jpg\" " . "width=\"28\" height=20 " . "alt=\"GID\">" . "</a></td>\n"; } print " <td background=\"$::YEL_PIX\">$sp</td>\n"; # meta if ($sort == $SORT_META) { print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<img border=\"0\" " . "src=\"pict/file_h_meta_cur.jpg\" " . "width=\"62\" height=20 " . "alt=\"Meta\">" . "</td>\n"; } else { $iurl = $url . "&sort=$SORT_META"; print " <td align=\"left\" background=\"$::YEL_PIX\">" . "<a href=\"$iurl\" target=\"_parent\">" . "<img border=\"0\" " . "src=\"pict/file_h_meta_link.jpg\" " . "width=\"41\" height=20 " . "alt=\"Meta\">" . "</a></td>\n"; } print "</tr>\n"; my $cnt = 0; my %seen; # sort fls into arrays while ($_ = Exec::read_pipe_line(*OUT)) { if ( /^($::REG_MTYPE)\/($::REG_MTYPE)\s*(\*?)\s*($::REG_META)(\(realloc\))?:\t(.+?)\t($::REG_DATE)\t($::REG_DATE)\t($::REG_DATE)\t($::REG_DATE)\t(\d+)\t(\d+)\t(\d+)$/o ) { my $lcldir = $Args::args{'dir'}; $dtype[$cnt] = $1; $itype[$cnt] = $2; $del[$cnt] = $3; $meta[$cnt] = $4; $realloc[$cnt] = ""; $realloc[$cnt] = $5 if (defined $5); $name[$cnt] = $6; $mod[$cnt] = $7; $acc[$cnt] = $8; $chg[$cnt] = $9; $crt[$cnt] = $10; $size[$cnt] = $11; $gid[$cnt] = $12; $uid[$cnt] = $13; if ($meta[$cnt] =~ /^(\d+)(-\d+(-\d+)?)?$/) { $meta_int[$cnt] = $1; } else { $meta_int[$cnt] = $meta[$cnt]; } # See if we have already seen this file yet if (exists $seen{"$name[$cnt]-$meta[$cnt]"}) { my $prev_cnt = $seen{"$name[$cnt]-$meta[$cnt]"}; # If we saw it while it was deleted, & it # is now undel, then update it if ( ($del[$cnt] eq "") && ($del[$prev_cnt] eq '*')) { $del[$prev_cnt] = $del[$cnt]; } next; # Add it to the seen list } else { $seen{"$name[$cnt]-$meta[$cnt]"} = $cnt; } # We must adjust the dir for directories if ($itype[$cnt] eq 'd') { # special cases for .. and . if ($name[$cnt] eq '..') { my @dirs = split('/', $lcldir); my $i; $lcldir = ""; for ($i = 0; $i < $#dirs; $i++) { $lcldir .= ($dirs[$i] . '/'); } } elsif ($name[$cnt] ne '.') { $lcldir .= ($name[$cnt] . '/'); } $name[$cnt] .= '/'; } else { $lcldir .= $name[$cnt]; } # format the date so that the time and time zone are on the # same line $mod[$cnt] = "$1&nbsp;$2" if ($mod[$cnt] =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); $acc[$cnt] = "$1&nbsp;$2" if ($acc[$cnt] =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); $chg[$cnt] = "$1&nbsp;$2" if ($chg[$cnt] =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); $crt[$cnt] = "$1&nbsp;$2" if ($crt[$cnt] =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); $dir[$cnt] = Args::url_encode($lcldir); $entry[$cnt] = $cnt; $cnt++; } # We missed it for some reason else { print "<tr><td colspan=10>Error Parsing File (Invalid Characters?):<br>$_</td></tr>\n"; } } close(OUT); if ($cnt == 0) { print "</table>\n<center>No Contents</center>\n"; return 0; } # Sort the above array based on the sort argument my @sorted; # an array of indices if ($sort == $SORT_DTYPE) { @sorted = sort { $dtype[$a] cmp $dtype[$b] or lc($name[$a]) cmp lc($name[$b]) } @entry; } elsif ($sort == $SORT_ITYPE) { @sorted = sort { $itype[$a] cmp $itype[$b] or lc($name[$a]) cmp lc($name[$b]) } @entry; } elsif ($sort == $SORT_NAME) { @sorted = sort { lc($name[$a]) cmp lc($name[$b]) } @entry; } elsif ($sort == $SORT_MOD) { @sorted = sort { $mod[$a] cmp $mod[$b] or lc($name[$a]) cmp lc($name[$b]) } @entry; } elsif ($sort == $SORT_ACC) { @sorted = sort { $acc[$a] cmp $acc[$b] or lc($name[$a]) cmp lc($name[$b]) } @entry; } elsif ($sort == $SORT_CHG) { @sorted = sort { $chg[$a] cmp $chg[$b] or lc($name[$a]) cmp lc($name[$b]) } @entry; } elsif ($sort == $SORT_CRT) { @sorted = sort { $crt[$a] cmp $crt[$b] or lc($name[$a]) cmp lc($name[$b]) } @entry; } elsif ($sort == $SORT_SIZE) { @sorted = sort { $size[$a] <=> $size[$b] or lc($name[$a]) cmp lc($name[$b]) } @entry; } elsif ($sort == $SORT_UID) { @sorted = sort { $uid[$a] <=> $uid[$b] or lc($name[$a]) cmp lc($name[$b]) } @entry; } elsif ($sort == $SORT_GID) { @sorted = sort { $gid[$a] <=> $gid[$b] or lc($name[$a]) cmp lc($name[$b]) } @entry; } elsif ($sort == $SORT_META) { @sorted = sort { $meta_int[$a] <=> $meta_int[$b] or lc($name[$a]) cmp lc($name[$b]) } @entry; } elsif ($sort == $SORT_DEL) { @sorted = sort { $del[$b] cmp $del[$a] or lc($name[$a]) cmp lc($name[$b]) } @entry; } # print them based on sorting my $row = 0; foreach my $i (@sorted) { my $url; my $target; my $color; my $lcolor; if ($del[$i] eq '*') { $color = "<font color=\"" . $::DEL_COLOR[$realloc[$i] ne ""] . "\">"; $lcolor = $color; } else { $color = "<font color=\"$::NORM_COLOR\">"; $lcolor = "<font color=\"$::LINK_COLOR\">"; } # directories have different targets and view values if ($itype[$i] eq 'd') { $target = "list"; $url = "$::PROGNAME?mod=$::MOD_FILE&view=$File::FILE_LIST&" . "$Args::baseargs&meta=$meta_int[$i]" . "&sort=$sort&dir=$dir[$i]&dirmode=$Args::enc_args{'dirmode'}"; } else { $target = "content"; $url = "$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT_FR&" . "$Args::baseargs&meta=$meta[$i]" . "&sort=$sort&dir=$dir[$i]&dirmode=$Args::enc_args{'dirmode'}"; if ($del[$i] eq '*') { $url .= "&recmode=$File::REC_YES"; } else { $url .= "&recmode=$File::REC_NO"; } } if (($row % 2) == 0) { print "<tr valign=\"TOP\" bgcolor=\"$::BACK_COLOR\">\n <td align=\"center\">"; } else { print "<tr valign=\"TOP\" bgcolor=\"$::BACK_COLOR_TABLE\">\n <td align=\"center\">"; } print "<img src=\"pict/file_b_check.jpg\" border=\"0\">\n" if ($del[$i] eq '*'); print "</td>\n" . " <td>$sp</td>\n" . " <td align=\"center\">${color}$dtype[$i]&nbsp;/&nbsp;$itype[$i]</td>\n" . " <td>$sp</td>\n"; # for valid files and directories make a link # Special rule for $OrphanFiles directory and HFS directories, which have a size of 0 if ( ($meta_int[$i] >= $Fs::first_meta{$ftype}) && (($size[$i] > 0) || (($name[$i] =~ /^\$Orphan/) && ($itype[$i] eq 'd')) || (($ftype =~ /hfs/) && ($itype[$i] eq 'd'))) && ( ($itype[$i] eq 'r') || ($itype[$i] eq 'd') || ($itype[$i] eq 'v')) ) { print " <td><a href=\"$url\" target=\"$target\">$lcolor"; } else { print " <td>$color"; } print "<tt>" . Print::html_encode($name[$i]) . "</tt></td>\n" . " <td>$sp</td>\n"; print " <td>${color}$mod[$i]</td>\n" . " <td>$sp</td>\n" if ($Fs::has_mtime{$ftype}); print " <td>${color}$acc[$i]</td>\n" . " <td>$sp</td>\n"; print " <td>${color}$chg[$i]</td>\n" . " <td>$sp</td>\n" if ($Fs::has_ctime{$ftype}); print " <td>${color}$crt[$i]</td>\n" . " <td>$sp</td>\n" if ($Fs::has_crtime{$ftype}); print " <td>${color}$size[$i]</td>\n" . " <td>$sp</td>\n" . " <td>${color}$uid[$i]</td>\n" . " <td>$sp</td>\n" . " <td>${color}$gid[$i]</td>\n" . " <td>$sp</td>\n"; # for a valid meta, make a link to meta browsing mode if ($meta_int[$i] >= $Fs::first_meta{$ftype}) { my $iurl = "$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_META&$Args::baseargs&meta=$meta[$i]"; print "<td><a href=\"$iurl\" target=\"_top\">$lcolor"; } else { print "<td>$color"; } print "$meta[$i]</a> $realloc[$i]</td>\n</tr>\n"; $row++; } print "</table>\n"; Print::print_html_footer(); return 0; }; #end of FIL_LIST # This takes a directory name as an argument and converts it to # the meta value and calls FIL_LIST # # The meta value can be anything when this is run, it will be # overwritten sub file_list_dir { my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $dir = Args::get_dir(); my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; Print::log_host_inv( "$Args::args{'vol'}: Finding meta data address for $dir"); # Use 'ifind -n' to get the meta data address for the given name local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/ifind' -f $ftype -n '$dir' -o $offset -i $imgtype $img"); my $meta; while ($_ = Exec::read_pipe_line(*OUT)) { $meta = $1 if (/^($::REG_META)$/); } close(OUT); Print::print_check_err("Error finding meta data address for $dir") unless (defined $meta); Print::print_check_err("Error finding meta data address for $dir: $meta") unless ($meta =~ /^$::REG_META$/); # Verify it is a directory with istat Exec::exec_pipe(*OUT, "'$::TSKDIR/istat' -f $ftype -o $offset -i $imgtype $img $meta"); while ($_ = Exec::read_pipe_line(*OUT)) { # This is a directory if ( (/mode:\s+d/) || (/File Attributes: Directory/) || (/^Flags:.*?Directory/)) { close(OUT); # Set the meta variables $Args::enc_args{'meta'} = $Args::args{'meta'} = $meta; $Args::args{'dir'} .= "/" unless ($Args::args{'dir'} =~ /.*?\/$/); $Args::enc_args{'dir'} .= "/" unless ($Args::enc_args{'dir'} =~ /.*?\/$/); # List the directory contents file_list(); return 0; } } close(OUT); # This is not a directory, so just give a link Print::print_html_header(""); my $meta_int = $meta; $meta_int = $1 if ($meta_int =~ /(\d+)-\d+(-\d+)?/); my $recmode = $File::REC_NO; local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/ils' -f $ftype -e -o $offset -i $imgtype $img $meta_int"); while ($_ = Exec::read_pipe_line(*OUT)) { chop; next unless ($_ =~ /^$meta/); if ($_ =~ /^$meta\|f/) { $recmode = $File::REC_YES; } elsif ($_ =~ /^$meta\|a/) { $recmode = $File::REC_NO; } else { Print::print_err("Error parsing ils output: $_"); } } close(OUT); print <<EOF; <tt>$dir</tt> ( <a href=\"$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_META&$Args::baseargs&meta=$meta&recmode=$recmode\" target=\"_top\"> meta $meta</a>) is not a directory. <p> <a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT_FR&$Args::baseargs&meta=$meta&dir=$dir&recmode=$recmode\" target=\"content\"> <img src=\"pict/but_viewcont.jpg\" height=20 width=123 alt=\"view contents\" border=\"0\"> </a> EOF Print::print_html_footer(); return 1; } # List the files that meet a certain pattern sub file_list_file { Args::check_sort(); Args::check_dirmode(); Args::check_dir(); my $vol = Args::get_vol('vol'); my $mnt = $Caseman::vol2mnt{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $ftype = $Caseman::vol2ftype{$vol}; my $meta = $Fs::root_meta{$ftype}; my $sort = Args::get_sort(); my $dirmode = Args::get_dirmode(); my $dir = Args::get_dir(); Print::print_html_header( "Filtered files on $Caseman::vol2sname{$vol} $mnt"); my $tz = ""; $tz = "-z '$Caseman::tz'" unless ("$Caseman::tz" eq ""); my $sp = "&nbsp;&nbsp;"; Print::log_host_inv( "$Caseman::vol2sname{$vol}: Listing all files with $dir"); local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/fls' -f $ftype -lpr $tz -s $Caseman::ts -o $offset -i $imgtype $img $meta" ); print "<b>All files with \'<tt>$dir</tt>\' in the name</b><p>\n" . "<a href=\"$::PROGNAME?$Args::baseargs&dirmode=$Args::enc_args{'dirmode'}" . "&sort=$sort&mod=$::MOD_FILE&view=$File::FILE_LIST" . "&meta=$Fs::root_meta{$ftype}&dir=\">" . "<img border=\"0\" src=\"pict/file_b_allfiles.jpg\" width=\"112\" " . "alt=\"Show All Files\"></a>\n" . "<hr>" . "<table cellspacing=\"0\" cellpadding=\"2\" border=0>\n" . "<tr valign=\"MIDDLE\" align=\"left\" " . "background=\"$::YEL_PIX\">\n"; # deleted print "<td align=\"left\">" . "<img border=\"0\" src=\"pict/file_h_del_link.jpg\" " . "width=\"28\" height=20 alt=\"Deleted Files\">" . "</td>\n" . "<td>$sp</td>\n"; # Type print "<th align=\"center\">&nbsp;&nbsp;Type&nbsp&nbsp;<br>" . "dir&nbsp;/&nbsp;in</th>" . "<td>$sp</td>\n"; # Name print " <td><img border=\"0\" " . "src=\"pict/file_h_nam_link.jpg\" " . "width=\"50\" height=20 " . "alt=\"File Name\">" . "</td>\n" . "<td>$sp</td>\n"; # Mod / Written if ($Fs::has_mtime{$ftype}) { print " <td><img border=\"0\" " . "src=\"pict/file_h_wr_link.jpg\" " . "width=\"60\" " . "alt=\"Written Time\">" . "</td>\n" . "<td>$sp</td>\n"; } # Access print " <td><img border=\"0\" " . "src=\"pict/file_h_acc_link.jpg\" " . "width=\"66\" height=20 " . "alt=\"Access Time\">" . "</td>\n" . "<td>$sp</td>\n"; # Change if ($Fs::has_ctime{$ftype}) { print " <td><img border=\"0\" " . "src=\"pict/file_h_chg_link.jpg\" " . "width=\"62\" " . "alt=\"Change Time\">" . "</td>\n" . "<td>$sp</td>\n"; } # Create if ($Fs::has_crtime{$ftype}) { print " <td><img border=\"0\" " . "src=\"pict/file_h_cre_link.jpg\" " . "width=\"59\" " . "alt=\"Create Time\">" . "</td>\n" . "<td>$sp</td>\n"; } # Size print " <td><img border=\"0\" " . "src=\"pict/file_h_siz_link.jpg\" " . "width=\"31\" height=20 " . "alt=\"Size\">" . "</td>\n" . "<td>$sp</td>\n"; # UID print " <td><img border=\"0\" " . "src=\"pict/file_h_uid_link.jpg\" " . "width=\"27\" height=20 " . "alt=\"UID\">" . "</td>\n" . "<td>$sp</td>\n"; # GID print " <td><img border=\"0\" " . "src=\"pict/file_h_gid_link.jpg\" " . "width=\"28\" height=20 " . "alt=\"GID\">" . "</td>\n" . "<td>$sp</td>\n"; # Meta print " <td><img border=\"0\" " . "src=\"pict/file_h_meta_link.jpg\" " . "width=\"41\" height=20 " . "alt=\"Meta\">" . "</td>\n" . "<td>$sp</td>\n"; my $row = 0; while ($_ = Exec::read_pipe_line(*OUT)) { if ( /^($::REG_MTYPE)\/($::REG_MTYPE)\s*(\*?)\s*($::REG_META)(\(realloc\))?:\t(.+?)\t($::REG_DATE)\t($::REG_DATE)\t($::REG_DATE)\t($::REG_DATE)\t(\d+)\t(\d+)\t(\d+)$/o ) { # We have to remove the / from the beginning of the file name so # save all values so they aren't lost my $dt = $1; my $it = $2; my $d = $3; my $i = $4; my $r = 0; $r = 1 if (defined $5); my $n = $6; my $m = $7; my $a = $8; my $c = $9; my $cr = $10; my $s = $11; my $g = $12; my $u = $13; if ($n =~ /^\/(.*)/) { $n = $1; } my $p = ""; my $f = $n; if ($n =~ /^(.+?)\/([^\/]+)$/) { $p = $1; $f = $2; } next unless ($f =~ /$dir/i); my $enc_n = Args::url_encode($n); my $iurl = "$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_META&$Args::baseargs&meta=$i"; my $i_int = $i; $i_int = $1 if ($i =~ /(\d+)-\d+-\d+/); if (($row % 2) == 0) { print "<tr valign=\"TOP\" bgcolor=\"$::BACK_COLOR\">\n"; } else { print "<tr valign=\"TOP\" bgcolor=\"$::BACK_COLOR_TABLE\">\n"; } print "<td align=\"left\">\n"; my $color; my $lcolor; if ($d eq '*') { $color = "<font color=\"" . $::DEL_COLOR[$r] . "\">"; $lcolor = $color; print "<img src=\"pict/file_b_check.jpg\" border=\"0\">\n"; } else { $color = "<font color=\"$::NORM_COLOR\">"; $lcolor = "<font color=\"$::LINK_COLOR\">"; print "&nbsp;"; } print "</td><td>$sp</td>"; print "<td align=\"center\">$color" . "$dt&nbsp;/&nbsp;$it</td>" . "<td>$sp</td>\n"; if ($it eq 'd') { my $url = "$::PROGNAME?mod=$::MOD_FILE&" . "view=$File::FILE_LIST&$Args::baseargs&meta=$i" . "&sort=$sort&dir=$enc_n&dirmode=$dirmode"; print "<td>"; if ($i_int >= $Fs::first_meta{$ftype}) { print "<a href=\"$url\" target=\"_self\">$lcolor"; } else { print "$color"; } print "<tt>" . Print::html_encode($mnt . $n) . "</tt></td>" . "<td>$sp</td>\n"; } else { my $url = "$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT_FR&" . "$Args::baseargs&meta=$i&sort=$sort&dir=$enc_n"; if ($d eq '*') { $url .= "&recmode=$File::REC_YES"; } else { $url .= "&recmode=$File::REC_NO"; } print "<td>"; if (($i_int >= $Fs::first_meta{$ftype}) && ($it eq 'r')) { print "<a href=\"$url\" target=\"content\">$lcolor"; } else { print "$color"; } print "<tt>$mnt$n</tt></td>" . "<td>$sp</td>\n"; } $m = "$1&nbsp;$2" if ($m =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); $a = "$1&nbsp;$2" if ($a =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); $c = "$1&nbsp;$2" if ($c =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); $cr = "$1&nbsp;$2" if ($cr =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); print "<td>$color$m</td>" . "<td>$sp</td>\n" if ($Fs::has_mtime{$ftype}); print "<td>$color$a</td>" . "<td>$sp</td>\n"; print "<td>$color$c</td>" . "<td>$sp</td>\n" if ($Fs::has_ctime{$ftype}); print "<td>$color$cr</td>" . "<td>$sp</td>\n" if ($Fs::has_crtime{$ftype}); print "<td>$color$s</td>" . "<td>$sp</td>\n" . "<td>$color$g</td>" . "<td>$sp</td>\n" . "<td>$color$u</td>" . "<td>$sp</td>\n"; print "<td>"; if ($i_int >= $Fs::first_meta{$ftype}) { print "<a href=\"$iurl\" target=\"_top\">"; print "$lcolor$i</a>"; } else { print "$color$i"; } print " (realloc)" if $r; print "</td></tr>\n"; } else { print "Error Parsing File (invalid characters?)<br>: $_\n<br>"; } $row++; } close(OUT); print "</table>\n"; print "<center>No files found with that pattern</center>\n" if ($row == 0); Print::print_html_footer(); return 0; } # display deleted files only # # Sorting should be added to this sub file_list_del { Args::check_sort(); Args::check_dirmode(); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $mnt = $Caseman::vol2mnt{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $meta = $Fs::root_meta{$ftype}; my $sort = Args::get_sort(); my $dirmode = Args::get_dirmode(); Print::print_html_header("Deleted files on $Caseman::vol2sname{$vol} $mnt"); my $tz = ""; $tz = "-z '$Caseman::tz'" unless ("$Caseman::tz" eq ""); my $sp = "&nbsp;&nbsp;"; Print::log_host_inv("$Caseman::vol2sname{$vol}: Listing all deleted files"); local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/fls' -f $ftype -ldr $tz -s $Caseman::ts -o $offset -i $imgtype $img $meta" ); print "<b>All Deleted Files</b><p><hr>" . "<table cellspacing=\"0\" cellpadding=\"2\" border=0>\n" . "<tr valign=\"MIDDLE\" align=\"left\" " . "background=\"$::YEL_PIX\">\n"; # Type print "<th align=\"center\">&nbsp;&nbsp;Type&nbsp&nbsp;<br>" . "dir&nbsp;/&nbsp;in</th>" . "<td>$sp</td>\n"; # Name print " <td><img border=\"0\" " . "src=\"pict/file_h_nam_link.jpg\" " . "width=\"50\" height=20 " . "alt=\"File Name\">" . "</td>\n" . "<td>$sp</td>\n"; # Mod / Written if ($Fs::has_mtime{$ftype}) { print " <td><img border=\"0\" " . "src=\"pict/file_h_wr_link.jpg\" " . "width=\"60\" " . "alt=\"Written Time\">" . "</td>\n" . "<td>$sp</td>\n"; } # Access print " <td><img border=\"0\" " . "src=\"pict/file_h_acc_link.jpg\" " . "width=\"66\" height=20 " . "alt=\"Access Time\">" . "</td>\n" . "<td>$sp</td>\n"; # Change if ($Fs::has_ctime{$ftype}) { print " <td><img border=\"0\" " . "src=\"pict/file_h_chg_link.jpg\" " . "width=\"62\" " . "alt=\"Change Time\">" . "</td>\n" . "<td>$sp</td>\n"; } # Create if ($Fs::has_crtime{$ftype}) { print " <td><img border=\"0\" " . "src=\"pict/file_h_cre_link.jpg\" " . "width=\"59\" " . "alt=\"Create Time\">" . "</td>\n" . "<td>$sp</td>\n"; } # Size print " <td><img border=\"0\" " . "src=\"pict/file_h_siz_link.jpg\" " . "width=\"31\" height=20 " . "alt=\"Size\">" . "</td>\n" . "<td>$sp</td>\n"; # UID print " <td><img border=\"0\" " . "src=\"pict/file_h_uid_link.jpg\" " . "width=\"27\" height=20 " . "alt=\"UID\">" . "</td>\n" . "<td>$sp</td>\n"; # GID print " <td><img border=\"0\" " . "src=\"pict/file_h_gid_link.jpg\" " . "width=\"28\" height=20 " . "alt=\"GID\">" . "</td>\n" . "<td>$sp</td>\n"; # Meta print " <td><img border=\"0\" " . "src=\"pict/file_h_meta_link.jpg\" " . "width=\"41\" height=20 " . "alt=\"Meta\">" . "</td>\n" . "<td>$sp</td>\n"; my $row = 0; while ($_ = Exec::read_pipe_line(*OUT)) { if ( /^($::REG_MTYPE)\/($::REG_MTYPE)\s*(\*?)\s*($::REG_META)(\(realloc\))?:\t(.+?)\t($::REG_DATE)\t($::REG_DATE)\t($::REG_DATE)\t($::REG_DATE)\t(\d+)\t(\d+)\t(\d+)$/o ) { # We have to remove the / from the beginning of the file name so # save all values so they aren't lost my $dt = $1; my $it = $2; my $d = $3; my $i = $4; my $r = 0; $r = 1 if (defined $5); my $n = $6; my $m = $7; my $a = $8; my $c = $9; my $cr = $10; my $s = $11; my $g = $12; my $u = $13; if ($n =~ /^\/(.*)/) { $n = $1; } my $enc_n = Args::url_encode($n); my $iurl = "$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_META&$Args::baseargs&meta=$i"; my $i_int = $i; $i_int = $1 if ($i =~ /(\d+)-\d+-\d+/); if (($row % 2) == 0) { print "<tr valign=\"TOP\" bgcolor=\"$::BACK_COLOR\">\n"; } else { print "<tr valign=\"TOP\" bgcolor=\"$::BACK_COLOR_TABLE\">\n"; } print "<td align=\"center\"><font color=\"$::DEL_COLOR[$r]\">" . "$dt&nbsp;/&nbsp;$it</td>" . "<td>$sp</td>\n"; if ($it eq 'd') { my $url = "$::PROGNAME?mod=$::MOD_FILE&" . "view=$File::FILE_LIST&$Args::baseargs&meta=$i" . "&sort=$sort&dir=$enc_n&dirmode=$dirmode"; print "<td>"; if ($i_int >= $Fs::first_meta{$ftype}) { print "<a href=\"$url\" target=\"_self\">"; } print "<font color=\"$::DEL_COLOR[$r]\"><tt>" . Print::html_encode($mnt . $n) . "</tt></td>" . "<td>$sp</td>\n"; } else { my $url = "$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT_FR&" . "$Args::baseargs&meta=$i&sort=$sort&dir=$enc_n" . "&recmode=$File::REC_YES"; print "<td>"; if (($i_int >= $Fs::first_meta{$ftype}) && ($it eq 'r')) { print "<a href=\"$url\" target=\"content\">"; } print "<font color=\"$::DEL_COLOR[$r]\"><tt>" . Print::html_encode($mnt . $n) . "</tt></td>" . "<td>$sp</td>\n"; } $m = "$1&nbsp;$2" if ($m =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); $a = "$1&nbsp;$2" if ($a =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); $c = "$1&nbsp;$2" if ($c =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); $cr = "$1&nbsp;$2" if ($cr =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); print "<td><font color=\"$::DEL_COLOR[$r]\">$m</td>" . "<td>$sp</td>\n" if ($Fs::has_mtime{$ftype}); print "<td><font color=\"$::DEL_COLOR[$r]\">$a</td>" . "<td>$sp</td>\n"; print "<td><font color=\"$::DEL_COLOR[$r]\">$c</td>" . "<td>$sp</td>\n" if ($Fs::has_ctime{$ftype}); print "<td><font color=\"$::DEL_COLOR[$r]\">$cr</td>" . "<td>$sp</td>\n" if ($Fs::has_crtime{$ftype}); print "<td><font color=\"$::DEL_COLOR[$r]\">$s</td>" . "<td>$sp</td>\n" . "<td><font color=\"$::DEL_COLOR[$r]\">$g</td>" . "<td>$sp</td>\n" . "<td><font color=\"$::DEL_COLOR[$r]\">$u</td>" . "<td>$sp</td>\n"; print "<td>"; if ($i_int >= $Fs::first_meta{$ftype}) { print "<a href=\"$iurl\" target=\"_top\">"; } print "<font color=\"$::DEL_COLOR[$r]\">$i</a>"; print " (realloc)" if $r; print "</td></tr>\n"; } else { print "Error Parsing File (invalid characters?)<br>: $_\n<br>"; } $row++; } close(OUT); print "</table>\n"; print "<center>None</center>\n" if ($row == 0); Print::print_html_footer(); return 0; } # Content Frame # This creates two frames for the lower rhs frame # sub content_fr { Print::print_html_header_frameset(""); my $meta = Args::get_meta('meta'); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; print "<frameset rows=\"65,*\">\n"; my $recmode = $File::REC_NO; if (exists $Args::enc_args{'recmode'}) { $recmode = $Args::enc_args{'recmode'}; } else { # We need to get the allocation status of this structure my $meta_int = $meta; $meta_int = $1 if ($meta_int =~ /(\d+)-\d+(-\d+)?/); local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/ils' -f $ftype -e -o $offset -i $imgtype $img $meta_int" ); while ($_ = Exec::read_pipe_line(*OUT)) { chop; next unless ($_ =~ /^$meta/); if ($_ =~ /^$meta\|f/) { $recmode = $File::REC_YES; } elsif ($_ =~ /^$meta\|a/) { $recmode = $File::REC_NO; } else { Print::print_check_err("Error parsing ils output: $_"); } } } close(OUT); # Get the file type so we can show the thumb nails automatically if ($recmode == $File::REC_YES) { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype -r -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" ); } else { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" ); } my $apptype = Exec::read_pipe_line(*OUT); close(OUT); $apptype = "Error getting file type" if ((!defined $apptype) || ($apptype eq "")); # The menu for the different viewing options print "<frame src=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT_MENU&" . "$Args::baseargs&dir=$Args::enc_args{'dir'}" . "&meta=$Args::enc_args{'meta'}&sort=$FIL_SORT_ASC&recmode=$recmode\">\n"; # Print the image thumbnail if (($apptype =~ /image data/) || ($apptype =~ /PC bitmap data/)) { print "<frame src=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT_IMG" . "&$Args::baseargs&dir=$Args::enc_args{'dir'}" . "&meta=$Args::enc_args{'meta'}" . "&sort=$FIL_SORT_ASC&recmode=$recmode\" name=\"cont2\">\n</frameset>"; } else { # Where the actual content will be displayed print "<frame src=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT" . "&$Args::baseargs&dir=$Args::enc_args{'dir'}" . "&meta=$Args::enc_args{'meta'}" . "&sort=$FIL_SORT_ASC&recmode=$recmode\" name=\"cont2\">\n</frameset>"; } Print::print_html_footer_frameset(); return 0; } # This is the index for the lower rhs frame # Choose the content display type here sub content_menu { Args::check_sort(); Args::check_recmode(); Print::print_html_header(""); my $meta = Args::get_meta('meta'); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $recmode = Args::get_recmode(); # Get the file type if ($recmode == $File::REC_YES) { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype -r -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" ); } else { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" ); } my $apptype = Exec::read_pipe_line(*OUT); close(OUT); $apptype = "Error getting file type" if ((!defined $apptype) || ($apptype eq "")); # We already have the path in the content window below, so save space # print "<center><tt>$mnt$Args::args{'dir'}</tt>\n"; print "<center>\n"; my $url = "&$Args::baseargs&dir=$Args::enc_args{'dir'}" . "&meta=$Args::enc_args{'meta'}&recmode=$recmode"; # Print the options for output display print "<table cellspacing=\"0\" cellpadding=\"2\">\n<tr>\n" . "<td>ASCII (<a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT&" . "sort=$FIL_SORT_ASC$url\" target=\"cont2\">display</a> - " . "<a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::REPORT&" . "sort=$FIL_SORT_ASC$url\" target=\"_blank\">report</a>)</td>\n" . "<td>*</td>\n" . "<td>Hex (" . "<a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT&" . "sort=$FIL_SORT_HEX$url\" target=\"cont2\">display</a> - " . "<a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::REPORT&" . "sort=$FIL_SORT_HEX$url\" target=\"_blank\">report</a>)</td>\n" . "<td>*</td>\n" . "<td>ASCII Strings (" . "<a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT&" . "sort=$FIL_SORT_STR$url\" target=\"cont2\">display</a> - " . "<a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::REPORT&" . "sort=$FIL_SORT_STR$url\" target=\"_blank\">report</a>)</td>\n" . "<td>*</td>\n" . "<td><a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::EXPORT&$url\">" . "Export</a></td>\n"; # if the file is either image or HTML, then let them view it if ( ($apptype =~ /image data/) || ($apptype =~ /PC bitmap data/)) { print "<td>*</td>\n<td><a href=\"$::PROGNAME?" . "mod=$::MOD_FILE&view=$File::CONT_IMG$url\"" . "target=\"cont2\">View</a></td>\n"; } elsif ($apptype =~ /HTML document text/) { print "<td>*</td>\n<td><a href=\"$::PROGNAME?" . "mod=$::MOD_APPVIEW&view=$Appview::CELL_FRAME$url\"" . "target=\"_blank\">View</a></td>\n"; } print "<td>*</td>\n" . "<td><a href=\"$::PROGNAME?mod=$::MOD_NOTES&view=$Notes::ENTER_FILE$url\" target=\"_blank\">" . "Add Note</a></td>\n" if ($::USE_NOTES == 1); print "</tr></table>\n"; print "File Type: $apptype\n"; print "<br><font color=\"$::DEL_COLOR[0]\">Deleted File Recovery Mode</font>\n" if ($recmode == $File::REC_YES); print "</center>\n"; Print::print_html_footer(); return 0; } # # Display the actual content here # # NOTE: This has a media type of raw text # sub content { Args::check_sort(); Args::check_recmode(); Print::print_text_header(); my $sort = Args::get_sort(); my $meta = Args::get_meta('meta'); my $vol = Args::get_vol('vol'); my $mnt = $Caseman::vol2mnt{$vol}; my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $recflag = ""; $recflag = " -r " if (Args::get_recmode() == $File::REC_YES); my $fname = "$mnt$Args::args{'dir'}"; $fname =~ s/\/\//\//g; local *OUT; if ($sort == $FIL_SORT_ASC) { Print::log_host_inv( "$Caseman::vol2sname{$vol}: Viewing $fname ($meta) as ASCII"); Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta" ); print "Contents Of File: $fname\n\n\n"; Print::print_output($_) while ($_ = Exec::read_pipe_data(*OUT, 1024)); close(OUT); } elsif ($sort == $FIL_SORT_HEX) { Print::log_host_inv( "$Caseman::vol2sname{$vol}: Viewing $fname ($meta) as Hex"); Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta" ); print "Hex Contents Of File: $fname\n\n\n"; my $offset = 0; while ($_ = Exec::read_pipe_data(*OUT, 1024)) { Print::print_hexdump($_, $offset * 1024); $offset++; } close(OUT); } elsif ($sort == $FIL_SORT_STR) { Print::log_host_inv( "$Caseman::vol2sname{$vol}: Viewing $fname ($meta) as strings"); Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta | '$::TSKDIR/srch_strings' -a" ); print "ASCII String Contents Of File: $fname\n\n\n\n"; Print::print_output($_) while ($_ = Exec::read_pipe_line(*OUT)); close(OUT); } Print::print_text_footer(); return 0; } sub content_img { Print::print_html_header("image content"); my $vol = Args::get_vol('vol'); my $mnt = $Caseman::vol2mnt{$vol}; my $fname = "$mnt$Args::args{'dir'}"; $fname =~ s/\/\//\//g; my $url = "&$Args::baseargs&meta=$Args::enc_args{'meta'}" . "&dir=$Args::enc_args{'dir'}&" . "cell_mode=2&recmode=$Args::enc_args{'recmode'}"; print "<tt>$fname</tt><br><br>\n" . "<table><tr>\n" . "<td width=250 align=\"center\">" . "<b>Thumbnail:</b><br>" . "<img src=\"$::PROGNAME?mod=$::MOD_APPVIEW&view=$Appview::CELL_CONT${url}\" width=\"200\"></td>\n" . "<td valign=top>" . "<a href=\"$::PROGNAME?mod=$::MOD_APPVIEW&view=$Appview::CELL_CONT${url}\" " . "target=_blank>View Full Size Image</a><br>\n</td>\n" . "</tr></table>\n"; Print::print_html_footer(); return 0; } # Export the contents of a file sub export { my $meta = Args::get_meta('meta'); my $vol = Args::get_vol('vol'); my $mnt = $Caseman::vol2mnt{$vol}; my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $fname = "$mnt$Args::args{'dir'}"; $fname =~ s/\/\//\//g; my $recflag = ""; $recflag = " -r " if ( (exists $Args::enc_args{'recmode'}) && ($Args::enc_args{'recmode'} == $File::REC_YES)); Print::log_host_inv( "$Caseman::vol2sname{$vol}: Saving contents of $fname ($meta)"); local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta" ); # We can't trust the mnt and dir values (since there # could be bad ASCII values, so only allow basic chars into name $fname =~ tr/a-zA-Z0-9\_\-\@\,/\./c; $fname = $1 if ($fname =~ /^\.(.*)$/); Print::print_oct_header("$vol-${fname}"); print "$_" while ($_ = Exec::read_pipe_data(*OUT, 1024)); Print::print_oct_footer(); return 0; } # Display a report for a file # This is intended to have its own window # sub report { Args::check_sort(); my $sort = Args::get_sort(); my $vol = Args::get_vol('vol'); my $meta = Args::get_meta('meta'); my $mnt = $Caseman::vol2mnt{$vol}; my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $type; my $fname = "$mnt$Args::args{'dir'}"; $fname =~ s/\/\//\//g; my $tz = ""; $tz = "-z '$Caseman::tz'" unless ("$Caseman::tz" eq ""); my $recflag = ""; $recflag = " -r " if ( (exists $Args::enc_args{'recmode'}) && ($Args::enc_args{'recmode'} == $File::REC_YES)); # We can't trust the mnt and dir values (since there # could be bad ASCII values, so only allow basic chars into name $fname =~ tr/a-zA-Z0-9\_\-\@\,/\./c; $fname = $1 if ($fname =~ /^\.+(.*)$/); $fname = $1 if ($fname =~ /^(.*?)\.+$/); Print::print_text_header("filename=$Args::args{'vol'}-${fname}.txt"); $fname = "$mnt$Args::args{'dir'}"; if ($sort == $FIL_SORT_ASC) { Print::log_host_inv( "$Caseman::vol2sname{$vol}: Generating ASCII report for $fname ($meta)" ); $type = "ASCII"; } elsif ($sort == $FIL_SORT_HEX) { Print::log_host_inv( "$Args::args{'vol'}: Generating Hex report for $fname ($meta)"); $type = "Hex"; } elsif ($sort == $FIL_SORT_STR) { Print::log_host_inv( "$Args::args{'vol'}: Generating ASCII strings report for $fname ($meta)" ); $type = "string"; } else { print "\n\ninvalid sort value"; return 1; } # NOTE: There is a space in the beginning of the separator lines in # order to make clear@stamper.itconsult.co.uk time stamping happy # I think it confuses the lines that begin at the lhs with PGP # headers and will remove the second line. # print " Autopsy $type Report\n\n" . "-" x 70 . "\n" . " GENERAL INFORMATION\n\n" . "File: $fname\n"; # Calculate the MD5 value local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta | '$::MD5_EXE'" ); my $md5 = Exec::read_pipe_line(*OUT); close(OUT); $md5 = "Error getting MD5 Value" if ((!defined $md5) || ($md5 eq "")); chomp $md5; if ($recflag eq "") { print "MD5 of file: $md5\n"; } else { print "MD5 of recovered file: $md5\n"; } if ($::SHA1_EXE ne "") { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta | '$::SHA1_EXE'" ); my $sha1 = Exec::read_pipe_line(*OUT); close(OUT); $sha1 = "Error getting SHA-1 Value" if ((!defined $sha1) || ($sha1 eq "")); chomp $sha1; if ($recflag eq "") { print "SHA-1 of file: $sha1\n"; } else { print "SHA-1 of recovered file: $sha1\n"; } } if ($sort == $FIL_SORT_STR) { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta | '$::TSKDIR/srch_strings' -a | '$::MD5_EXE'" ); $md5 = Exec::read_pipe_line(*OUT); close(OUT); $md5 = "Error getting MD5 Value" if ((!defined $md5) || ($md5 eq "")); chomp $md5; print "MD5 of ASCII strings: $md5\n"; if ($::SHA1_EXE ne "") { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta | '$::TSKDIR/srch_strings' -a | '$::SHA1_EXE'" ); $sha1 = Exec::read_pipe_line(*OUT); close(OUT); $sha1 = "Error getting SHA-1 Value" if ((!defined $sha1) || ($sha1 eq "")); chomp $sha1; print "SHA-1 of ASCII strings: $sha1\n"; } } print "\nImage: $Caseman::vol2path{$vol}\n"; if (($Caseman::vol2start{$vol} == 0) && ($Caseman::vol2end{$vol} == 0)) { print "Offset: Full image\n"; } elsif ($Caseman::vol2end{$vol} == 0) { print "Offset: $Caseman::vol2start{$vol} to end\n"; } else { print "Offset: $Caseman::vol2start{$vol} to $Caseman::vol2end{$vol}\n"; } print "File System Type: $ftype\n"; my $date = localtime(); print "\nDate Generated: $date\n" . "Investigator: $Args::args{'inv'}\n\n" . "-" x 70 . "\n" . " META DATA INFORMATION\n\n"; # Get the meta details Exec::exec_pipe(*OUT, "'$::TSKDIR/istat' -f $ftype $tz -s $Caseman::ts -o $offset -i $imgtype $img $meta" ); print $_ while ($_ = Exec::read_pipe_line(*OUT)); close(OUT); # File Type Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" ); my $apptype = Exec::read_pipe_line(*OUT); close(OUT); $apptype = "Error getting file type" if ((!defined $apptype) || ($apptype eq "")); print "\nFile Type: $apptype"; print "\n" . "-" x 70 . "\n"; if ($sort == $FIL_SORT_ASC) { print " CONTENT (Non-ASCII data may not be shown)\n\n"; } else { print " CONTENT\n\n"; } if ($sort == $FIL_SORT_ASC) { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta" ); Print::print_output($_) while ($_ = Exec::read_pipe_data(*OUT, 1024)); close(OUT); } elsif ($sort == $FIL_SORT_HEX) { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta" ); my $offset = 0; while ($_ = Exec::read_pipe_data(*OUT, 1024)) { Print::print_hexdump($_, $offset * 1024); $offset++; } close(OUT); } elsif ($sort == $FIL_SORT_STR) { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta | '$::TSKDIR/srch_strings' -a" ); Print::print_output($_) while ($_ = Exec::read_pipe_line(*OUT)); close(OUT); } print "\n" . "-" x 70 . "\n" . " VERSION INFORMATION\n\n" . "Autopsy Version: $::VER\n"; print "The Sleuth Kit Version: " . ::get_tskver() . "\n"; Print::print_text_footer(); return 0; } # Generate the MD5 value for every file in a given directory and save # them to a text file sub md5list { my $vol = Args::get_vol('vol'); my $meta = Args::get_meta('meta'); my $mnt = $Caseman::vol2mnt{$vol}; my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $fname = "$mnt$Args::args{'dir'}"; $fname = 'root' if ($fname eq '/'); $fname =~ s/\/\//\//g; # We can't trust the mnt and dir values (since there # could be bad ASCII values, so only allow basic chars into name $fname =~ tr/a-zA-Z0-9\_\-\@\,/\./c; # remove .'s at beginning and end $fname = $1 if ($fname =~ /^\.+(.*)$/); $fname = $1 if ($fname =~ /^(.*?)\.+$/); Print::print_text_header("filename=$fname.md5"); $fname = "$mnt$Args::args{'dir'}"; $fname =~ s/\/\//\//g; local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/fls' -f $ftype -Fu -o $offset -i $imgtype $img $meta"); print "MD5 Values for files in $fname ($Caseman::vol2sname{$vol})\n\n"; while ($_ = Exec::read_pipe_line(*OUT)) { # area for allocated files if ( (/r\/[\w\-]\s+([\d\-]+):\s+(.*)$/) || (/-\/r\s+([\d\-]+):\s+(.*)$/)) { my $in = $1; my $name = $2; local *OUT_MD5; Exec::exec_pipe(*OUT_MD5, "'$::TSKDIR/icat' -f $ftype -r -o $offset -i $imgtype $img $in | '$::MD5_EXE'" ); my $md5out = Exec::read_pipe_line(*OUT_MD5); $md5out = "Error calculating MD5" if ((!defined $md5out) || ($md5out eq "")); chomp $md5out; print "$md5out\t" . Print::html_encode($name) . "\n"; close(OUT_MD5); } elsif (/[\w\-]\/[\w\-]\s+([\d\-]+):\s+(.*)$/) { # ignore, non-file types such as sockets or symlinks that do not have # MD5 values that make sense } # Hmmmm else { print "Error parsing file (invalid characters?): $_\n"; } } close(OUT); Print::print_text_footer(); return 0; } # Blank Page sub blank { Print::print_html_header(""); print "<br><center><h3>File Browsing Mode</h3><br>\n" . "<p>In this mode, you can view file and directory contents.</p>\n" . "<p>File contents will be shown in this window.<br>\n" . "More file details can be found using the Metadata link at the end of the list (on the right).<br>\n" . "You can also sort the files using the column headers</p>\n"; Print::print_html_footer(); return 0; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/lib/Filesystem.pm����������������������������������������������������������������������0000644�0000765�0000024�00000012076�11070040246�015707� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # File system layer functions # # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2001-2005 by Brian Carrier. All rights reserved # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Updated 1/13 package Filesystem; $Filesystem::STATS = 0; sub main { # By default, show the main window $Args::args{'view'} = $Args::enc_args{'view'} = $Filesystem::STATS unless (exists $Args::args{'view'}); Args::check_view(); my $view = Args::get_view(); # Check Basic Args Args::check_vol('vol'); # These windows don't need the meta data address if ($view == $Filesystem::STATS) { return stats(); } else { Print::print_check_err("Invalid File System View"); } } sub stats_disk { Print::print_html_header("Disk Status"); my $vol = Args::get_vol('vol'); my $img = $Caseman::vol2path{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $offset = $Caseman::vol2start{$vol}; my $dtype = $Caseman::vol2dtype{$vol}; # Run 'mmls' on the image Exec::exec_pipe(*OUT, "'$::TSKDIR/mmls' -o $offset -i $imgtype -t $dtype -r $img"); # cycle through results and add each to table with file system type print "<center><h3>Disk Image Details</h3></center>\n"; print "<b>PARTITION INFORMATION</b><p>\n"; while ($_ = Exec::read_pipe_line(*OUT)) { print "<tt>$_</tt><br>\n"; } return 0; } ############ FILE SYSTEM ################## sub stats { my $vol = Args::get_vol('vol'); return stats_disk() if ($Caseman::vol2cat{$vol} eq "disk"); Print::print_html_header("File System Status"); my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; Print::log_host_inv( "$Caseman::vol2sname{$vol}: Displaying file system details"); print "<center><h3>General File System Details</h3></center><p>\n"; my $fat = 0; local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/fsstat' -f $ftype -o $offset -i $imgtype $img"); while ($_ = Exec::read_pipe_line(*OUT)) { if (/\-\-\-\-\-\-\-\-\-\-/) { # Ignore these and print them ahead of the headers } # need the space to prevent NTFS STD_INFORMATION from triggering it elsif (/ INFORMATION/) { print "<hr><b>$_</b><p>\n"; } elsif (($ftype =~ /fat/) && ($_ =~ /FAT CONTENTS/)) { print "<hr><b>$_</b><p>\n"; # Set the flag if we reach the FAT $fat = 1; } # Special case for FAT # We will be giving hyperlinks in the FAT table dump elsif ($fat == 1) { # Ignore the divider if (/\-\-\-\-\-\-\-\-\-\-/) { print "$_<br>"; next; } if (/^((\d+)\-\d+\s+\((\d+)\)) \-\> ([\w]+)$/) { my $full = $1; my $blk = $2; my $len = $3; my $next = $4; # Print the tag so that other FAT entries can link to it print "<a name=\"$blk\">\n"; print "<a href=\"$::PROGNAME?$Args::baseargs&mod=$::MOD_FRAME&submod=$::MOD_DATA&" . "block=$blk&len=$len\" target=\"_top\">$full</a> -> "; if ($next eq 'EOF') { print "EOF<br>\n"; } else { print "<a href=\"#$next\">$next</a><br>\n"; } } else { $fat = 0; print "$_<br>"; } } else { print "$_<br>"; } } close(OUT); Print::print_html_footer(); return 0; } 1; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autopsy-2.24/lib/Frame.pm���������������������������������������������������������������������������0000644�0000765�0000024�00000023646�11070040246�014622� 0����������������������������������������������������������������������������������������������������ustar �carrier�������������������������staff������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Functions to create the tabs and frame of the main browsing mode # # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2001-2005 by Brian Carrier. All rights reserved # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package Frame; $Frame::IMG_FRAME = 0; $Frame::IMG_TABS = 1; $Frame::IMG_BLANK = 2; sub main { Args::check_vol('vol'); # By default, show the main frame $Args::args{'view'} = $Args::enc_args{'view'} = $Frame::IMG_FRAME unless (exists $Args::args{'view'}); Args::check_view(); my $view = Args::get_view(); if ($view == $Frame::IMG_FRAME) { vol_browse_frame(); } elsif ($view == $Frame::IMG_TABS) { vol_browse_tabs(); } elsif ($view == $Frame::IMG_BLANK) { vol_browse_blank(); } else { Print::print_check_err("Invalid Frame View"); } return 0; } # create the frame for the tabs on top and the generic message on the bottom sub vol_browse_frame { Print::print_html_header_frameset( "$Args::args{'case'}:$Args::args{'host'}:$Args::args{'vol'}"); my $submod = $::MOD_FRAME; $submod = Args::get_submod() if (exists $Args::args{'submod'}); # Print the rest of the frames my $str = ""; my $view = ""; if ($submod == $::MOD_FILE) { $str .= "&meta=$Args::args{'meta'}" if (exists $Args::args{'meta'}); $str .= "&dir=$Args::args{'dir'}" if (exists $Args::args{'dir'}); $str .= "&sort=$Args::args{'sort'}" if (exists $Args::args{'sort'}); $str .= "&dmode=$Args::args{'dmode'}" if (exists $Args::args{'dmode'}); } elsif ($submod == $::MOD_DATA) { $str .= "&block=$Args::args{'block'}" if (exists $Args::args{'block'}); $str .= "&len=$Args::args{'len'}" if (exists $Args::args{'len'}); } elsif ($submod == $::MOD_META) { $str .= "&meta=$Args::args{'meta'}" if (exists $Args::args{'meta'}); } elsif ($submod == $::MOD_FRAME) { $view = "&view=$Frame::IMG_BLANK"; } print <<EOF; <frameset rows=\"40,*\"> <frame src=\"$::PROGNAME?mod=$::MOD_FRAME&view=$Frame::IMG_TABS&$Args::baseargs&submod=$submod\"> <frame src=\"$::PROGNAME?mod=$submod$view&$Args::baseargs$str\"> </frameset> <NOFRAMES> <center> Autopsy requires a browser that supports frames. </center> EOF Print::print_html_footer_frameset(); return 0; } # Display a message when the image is opened (below the tabs) sub vol_browse_blank { Print::print_html_header("Main Message"); print <






To start analyzing this volume, choose an analysis mode from the tabs above. EOF Print::print_html_footer(); return 0; } sub vol_browse_tabs { Args::check_submod(); Print::print_html_header_tabs("Mode Tabs"); my $submod = Args::get_submod(); my $vol = Args::get_vol('vol'); my $special = 0; $special = 1 unless (($Caseman::vol2cat{$vol} eq "part") && ($Fs::is_fs{$Caseman::vol2ftype{$vol}} == 1)); # if ( ($Caseman::vol2ftype{$vol} eq "strings") # || ($Caseman::vol2ftype{$vol} eq "blkls") # || ($Caseman::vol2ftype{$vol} eq "swap") # || ($Caseman::vol2ftype{$vol} eq "raw")); print "
\n"; # Files print "\n" . "\n" . "\n" . "\n" . "\n" . "\n" . "\n"; # Close print "\n"; print "
"; if ($special == 0) { print ""; # Current if ($submod == $::MOD_FILE) { print ""; } # Link else { print ""; } } # non-link else { print ""; } # Search print ""; print ""; if ($submod == $::MOD_KWSRCH) { print ""; } else { print ""; } # File Type print ""; if (($special == 0) && ($::LIVE == 0)) { print ""; # Current if ($submod == $::MOD_APPSORT) { print ""; } else { print ""; } } else { print ""; } # Image Details print ""; if (($special == 0) || ($Caseman::vol2cat{$vol} eq "disk")) { print ""; if ($submod == $::MOD_FS) { print ""; } else { print ""; } } else { print ""; } # Meta Data print ""; if ($special == 0) { print ""; if ($submod == $::MOD_META) { print ""; } else { print ""; } } else { print ""; } # Data Units print ""; print ""; # Current if ($submod == $::MOD_DATA) { print ""; } # Link else { print ""; } # Help - set to current mode print "" . "" . "" . "" . "" . "
\n"; Print::print_html_footer_tabs(); return 0; } autopsy-2.24/lib/Fs.pm0000644000076500000240000001232511070763703014142 0ustar carrierstaff# package Fs; $Fs::types[0] = "ext"; $Fs::types[1] = "fat"; $Fs::types[2] = "ntfs"; $Fs::types[3] = "ufs"; $Fs::types[4] = "iso9660"; $Fs::types[5] = "-----"; $Fs::types[6] = "fat12"; $Fs::types[7] = "fat16"; $Fs::types[8] = "fat32"; $Fs::types[9] = "bsdi"; $Fs::types[10] = "freebsd"; $Fs::types[11] = "openbsd"; $Fs::types[12] = "solaris"; $Fs::types[13] = "hfs"; # These need to be updated as The Sleuth Kit supports more file systems # # addr_unit contains the addressable unit per filesystem type # first_meta contains the first usable meta address on a system # root_meta is the meta address for the root directory (diff than # first on ntfs) $Fs::addr_unit{'disk'} = 'Sector'; $Fs::first_addr{'disk'} = 0; $Fs::is_fs{'disk'} = 0; $Fs::addr_unit{'blkls'} = 'Unit'; $Fs::first_addr{'blkls'} = 0; $Fs::is_fs{'blkls'} = 0; # raw $Fs::addr_unit{'raw'} = 'Unit'; $Fs::first_addr{'raw'} = 0; $Fs::is_fs{'raw'} = 0; # Swap $Fs::addr_unit{'swap'} = 'Unit'; $Fs::first_addr{'swap'} = 0; $Fs::is_fs{'swap'} = 0; # BSDI $Fs::first_meta{'bsdi'} = $Fs::root_meta{'bsdi'} = 2; $Fs::first_addr{'bsdi'} = 0; $Fs::addr_unit{'bsdi'} = 'Fragment'; $Fs::has_ctime{'bsdi'} = 1; $Fs::has_crtime{'bsdi'} = 0; $Fs::has_mtime{'bsdi'} = 1; $Fs::meta_str{'bsdi'} = "Inode"; $Fs::is_fs{'bsdi'} = 1; # FreeBSD $Fs::first_meta{'freebsd'} = $Fs::root_meta{'freebsd'} = 2; $Fs::first_addr{'freebsd'} = 0; $Fs::addr_unit{'freebsd'} = 'Fragment'; $Fs::has_ctime{'freebsd'} = 1; $Fs::has_crtime{'freebsd'} = 0; $Fs::has_mtime{'freebsd'} = 1; $Fs::meta_str{'freebsd'} = "Inode"; $Fs::is_fs{'freebsd'} = 1; # OpenBSD $Fs::first_meta{'openbsd'} = $Fs::root_meta{'openbsd'} = 2; $Fs::first_addr{'openbsd'} = 0; $Fs::addr_unit{'openbsd'} = 'Fragment'; $Fs::has_ctime{'openbsd'} = 1; $Fs::has_crtime{'openbsd'} = 0; $Fs::has_mtime{'openbsd'} = 1; $Fs::meta_str{'openbsd'} = "Inode"; $Fs::is_fs{'openbsd'} = 1; # Solaris $Fs::first_meta{'solaris'} = $Fs::root_meta{'solaris'} = 2; $Fs::first_addr{'solaris'} = 0; $Fs::addr_unit{'solaris'} = 'Fragment'; $Fs::has_ctime{'solaris'} = 1; $Fs::has_crtime{'solaris'} = 0; $Fs::has_mtime{'solaris'} = 1; $Fs::meta_str{'solaris'} = "Inode"; $Fs::is_fs{'solaris'} = 1; # UFS $Fs::first_meta{'ufs'} = $Fs::root_meta{'ufs'} = 2; $Fs::first_addr{'ufs'} = 0; $Fs::addr_unit{'ufs'} = 'Fragment'; $Fs::has_ctime{'ufs'} = 1; $Fs::has_crtime{'ufs'} = 0; $Fs::has_mtime{'ufs'} = 1; $Fs::meta_str{'ufs'} = "Inode"; $Fs::is_fs{'ufs'} = 1; # Linux $Fs::first_meta{'linux-ext2'} = $Fs::root_meta{'linux-ext2'} = 2; $Fs::first_addr{'linux-ext2'} = 0; $Fs::addr_unit{'linux-ext2'} = 'Fragment'; $Fs::has_ctime{'linux-ext2'} = 1; $Fs::has_crtime{'linux-ext2'} = 0; $Fs::has_mtime{'linux-ext2'} = 1; $Fs::meta_str{'linux-ext2'} = "Inode"; $Fs::is_fs{'linux-ext2'} = 1; $Fs::first_meta{'linux-ext3'} = $Fs::root_meta{'linux-ext3'} = 2; $Fs::first_addr{'linux-ext3'} = 0; $Fs::addr_unit{'linux-ext3'} = 'Fragment'; $Fs::has_ctime{'linux-ext3'} = 1; $Fs::has_crtime{'linux-ext3'} = 0; $Fs::has_mtime{'linux-ext3'} = 1; $Fs::meta_str{'linux-ext3'} = "Inode"; $Fs::is_fs{'linux-ext3'} = 1; $Fs::first_meta{'ext'} = $Fs::root_meta{'ext'} = 2; $Fs::first_addr{'ext'} = 0; $Fs::addr_unit{'ext'} = 'Fragment'; $Fs::has_ctime{'ext'} = 1; $Fs::has_crtime{'ext'} = 0; $Fs::has_mtime{'ext'} = 1; $Fs::meta_str{'ext'} = "Inode"; $Fs::is_fs{'ext'} = 1; # FAT $Fs::first_meta{'fat'} = $Fs::first_meta{'fat12'} = $Fs::first_meta{'fat16'} = $Fs::first_meta{'fat32'} = 1; $Fs::root_meta{'fat'} = $Fs::root_meta{'fat12'} = $Fs::root_meta{'fat16'} = $Fs::root_meta{'fat32'} = 2; $Fs::first_addr{'fat'} = $Fs::first_addr{'fat12'} = $Fs::first_addr{'fat16'} = $Fs::first_addr{'fat32'} = 0; $Fs::addr_unit{'fat'} = $Fs::addr_unit{'fat12'} = $Fs::addr_unit{'fat16'} = $Fs::addr_unit{'fat32'} = 'Sector'; $Fs::has_ctime{'fat'} = $Fs::has_ctime{'fat12'} = $Fs::has_ctime{'fat16'} = $Fs::has_ctime{'fat32'} = 0; $Fs::has_crtime{'fat'} = $Fs::has_crtime{'fat12'} = $Fs::has_crtime{'fat16'} = $Fs::has_crtime{'fat32'} = 1; $Fs::has_mtime{'fat'} = $Fs::has_mtime{'fat12'} = $Fs::has_mtime{'fat16'} = $Fs::has_mtime{'fat32'} = 1; $Fs::meta_str{'fat'} = $Fs::meta_str{'fat12'} = $Fs::meta_str{'fat16'} = $Fs::meta_str{'fat32'} = "Dir Entry"; $Fs::is_fs{'fat'} = $Fs::is_fs{'fat12'} = $Fs::is_fs{'fat16'} = $Fs::is_fs{'fat32'} = 1; # NTFS $Fs::first_meta{'ntfs'} = 0; $Fs::root_meta{'ntfs'} = 5; $Fs::first_addr{'ntfs'} = 0; $Fs::addr_unit{'ntfs'} = 'Cluster'; $Fs::has_ctime{'ntfs'} = 1; $Fs::has_crtime{'ntfs'} = 1; $Fs::has_mtime{'ntfs'} = 1; $Fs::meta_str{'ntfs'} = "MFT Entry"; $Fs::is_fs{'ntfs'} = 1; # ISO9660 $Fs::first_meta{'iso9660'} = $Fs::root_meta{'iso9660'} = 0; $Fs::first_addr{'iso9660'} = 0; $Fs::addr_unit{'iso9660'} = 'Block'; $Fs::has_ctime{'iso9660'} = 0; $Fs::has_crtime{'iso9660'} = 1; $Fs::has_mtime{'iso9660'} = 0; $Fs::meta_str{'iso9660'} = "Directory Entry"; $Fs::is_fs{'iso9660'} = 1; # HFS $Fs::first_meta{'hfs'} = $Fs::root_meta{'hfs'} = 2; $Fs::first_addr{'hfs'} = 0; $Fs::addr_unit{'hfs'} = 'Block'; $Fs::has_ctime{'hfs'} = 1; $Fs::has_crtime{'hfs'} = 1; $Fs::has_mtime{'hfs'} = 1; $Fs::meta_str{'hfs'} = "Record"; $Fs::is_fs{'hfs'} = 1; autopsy-2.24/lib/Hash.pm0000644000076500000240000007030011070040246014440 0ustar carrierstaff# # Hash database and calculation functions # # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2001-2008 by Brian Carrier. All rights reserved # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package Hash; $Hash::DB_MANAGER = 1; $Hash::DB_LOOKUP = 2; $Hash::DB_INDEX = 3; $Hash::IMG_VERIFY = 4; $Hash::IMG_CALC = 5; $Hash::IMG_LIST_FR = 6; $Hash::IMG_LIST = 7; $Hash::BLANK = 8; sub main { return if ($::LIVE == 1); Args::check_view(); my $view = Args::get_view(); if ($view == $Hash::BLANK) { blank(); return 0; } elsif ($view == $Hash::DB_MANAGER) { return db_manager(); } elsif ($view == $Hash::DB_LOOKUP) { return db_lookup(); } elsif ($view == $Hash::DB_INDEX) { return db_index(); } elsif ($view == $Hash::IMG_LIST_FR) { return img_list_fr(); } elsif ($view == $Hash::IMG_LIST) { return img_list(); } Args::check_vol('vol'); if ($view == $Hash::IMG_CALC) { return img_calc(); } elsif ($view == $Hash::IMG_VERIFY) { return img_verify(); } else { Print::print_check_err("Invalid Hash View"); } } sub index_md5sum { my $db = shift; local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/hfind' -i md5sum '$db'"); while ($_ = Exec::read_pipe_line(*OUT)) { print "$_
\n"; } close(OUT); } sub index_nsrl { local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/hfind' -i nsrl-md5 '$::NSRLDB'"); while ($_ = Exec::read_pipe_line(*OUT)) { print "$_
\n"; } close(OUT); } # Manager/status Window from HOST Manager sub db_manager { Print::print_html_header("Hash Database Manager"); print < To edit the location of the databases, you must manually edit the host.aut file in the host directory.
\"Alert

Overview
These files are known to be bad and are the ones that you want to know about if they are in the image you are analyzing. For example, this database would include hashes of known attacker tools, rootkits, or photographs. EOF print "

Details
\n"; if ($Caseman::alert_db eq "") { print "Location: Not Configured
\n"; } elsif (-e "$Caseman::alert_db") { print "Location: $Caseman::alert_db
\n"; if (-e "$Caseman::alert_db" . "-md5.idx") { print "Status: MD5 Index File Exists
\n"; } else { print "Status: Database has not been MD5 indexed
\n"; } # Index Button print "

" . "\"Index" . "\n"; # Lookup Button if (-e "$Caseman::alert_db" . "-md5.idx") { print "

Lookup
" . "

" . "\n" . "\n" . "\n" . Args::make_hidden() . "\n\n" . "\n" . "\n
Enter MD5 Value: " . "" . "\n" . "
\n" . "
"; } } else { print "Location: $Caseman::alert_db
\n" . "ERROR: Database not found
\n"; } print <
\"Ignore

Overview
These files are known to be good and are the ones that you can ignore if they are found in the image you are analyzing. For example, this database would include hashes of known system binaries and other documents that you do not want to waste time on when running 'sorter' or files that you want to confirm were not modified by an attacker. EOF2 print "

Details
\n"; if ($Caseman::exclude_db eq "") { print "Location: Not Configured
\n"; } elsif (-e "$Caseman::exclude_db") { print "Location: $Caseman::exclude_db
\n"; if (-e "$Caseman::exclude_db" . "-md5.idx") { print "Status: MD5 Index File Exists
\n"; } else { print "Status: Database has not been MD5 indexed
\n"; } # Index Button print "

" . "\"Index" . "\n"; # Lookup Button if (-e "$Caseman::exclude_db" . "-md5.idx") { print "

Lookup
" . "

" . "\n" . "\n" . "\n" . Args::make_hidden() . "\n\n" . "\n" . "\n
Enter MD5 Value: " . "" . "\n" . "
\n" . "
"; } } else { print "Location: $Caseman::exclude_db
\n" . "ERROR: Database not found
\n"; } print <
\"NSRL

Overview
These files are known to be good and bad. It is currently difficult to distinguish between known good and known bad, but the NSRL is used in Autopsy to ignore all known files. EOF3 print "

Details
\n"; if ($::NSRLDB eq "") { print "Location: Not Configured
\n"; } elsif (-e "$::NSRLDB") { print "Location: $::NSRLDB
\n"; if (-e "$::NSRLDB" . "-md5.idx") { print "Status: MD5 Index File Exists
\n"; } else { print "Status: Database has not been MD5 indexed
\n"; } # Index Button print "

" . "\"Index" . "\n"; # Lookup Button if (-e "$::NSRLDB" . "-md5.idx") { print "

Lookup
" . "

" . "\n" . "\n" . "\n" . Args::make_hidden() . "\n\n" . "\n" . "\n
Enter MD5 Value: " . "" . "\n" . "
\n" . "
"; } } else { print "Location: $::NSRLDB
\n" . "ERROR: Database not found
\n"; } print <
\"Close\" \"Help\"
EOF4 Print::print_html_footer(); return 0; } sub db_index { Print::print_html_header("Hash Database Indexing"); if ( (exists $Args::args{'hash_exclude'}) && ($Args::args{'hash_exclude'} == 1) && ($Caseman::exclude_db ne "")) { Print::log_host_info("Exclude Database Re-Indexed"); print "
Exclude Database Indexing

\n"; index_md5sum($Caseman::exclude_db); } if ( (exists $Args::args{'hash_alert'}) && ($Args::args{'hash_alert'} == 1) && ($Caseman::alert_db ne "")) { Print::log_host_info("Alert Database Re-Indexed"); print "


Alert Database Indexing

\n"; index_md5sum($Caseman::alert_db); } if ( (exists $Args::args{'hash_nsrl'}) && ($Args::args{'hash_nsrl'} == 1) && ($::NSRLDB ne "")) { Print::log_host_info("NSRL Database Re-Indexed"); print "


NSRL Database Indexing

\n"; index_nsrl(); } print "

Indexing Complete
\n" . "


\n\n" . "\"Hash\n"; Print::print_html_footer(); return 0; } # Lookup hashes in database sub db_lookup { Print::print_html_header("Hash Database Lookup"); unless ((exists $Args::args{'md5'}) && ($Args::args{'md5'} =~ /^$::REG_MD5$/o)) { Print::print_err("Invalid MD5 Argument"); } if ( (exists $Args::args{'hash_nsrl'}) && ($Args::args{'hash_nsrl'} == 1) && ($::NSRLDB ne "")) { print "


NSRL Lookup

\n"; if (-e "$::NSRLDB") { local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/hfind' '$::NSRLDB' $Args::args{'md5'}"); print "$_
\n" while ($_ = Exec::read_pipe_line(*OUT)); close(OUT); Print::log_host_inv("NSRL Lookup ($Args::args{'md5'})"); } else { print "NSRL Database Missing
\n"; Print::log_host_inv( "NSRL Lookup ($Args::args{'md5'}) - Database Missing"); } } if ( (exists $Args::args{'hash_exclude'}) && ($Args::args{'hash_exclude'} == 1) && ($Caseman::exclude_db ne "")) { print "


Exclude Database Lookup

\n"; if (-e "$Caseman::exclude_db") { local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/hfind' '$Caseman::exclude_db' $Args::args{'md5'}"); print "$_
\n" while ($_ = Exec::read_pipe_line(*OUT)); close(OUT); Print::log_host_inv("Exclude Database Lookup ($Args::args{'md5'})"); } else { print "Exclude Database Missing
\n"; Print::log_host_inv( "Exclude Database Lookup ($Args::args{'md5'}) - Database Missing" ); } } if ( (exists $Args::args{'hash_alert'}) && ($Args::args{'hash_alert'} == 1) && ($Caseman::alert_db ne "")) { print "


Alert Database Lookup

\n"; if (-e "$Caseman::alert_db") { local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/hfind' '$Caseman::alert_db' $Args::args{'md5'}"); print "$_
\n" while ($_ = Exec::read_pipe_line(*OUT)); close(OUT); Print::log_host_inv("Alert Database Lookup ($Args::args{'md5'})"); } else { print "Alert Database Missing
\n"; Print::log_host_inv( "Alert Database Lookup ($Args::args{'md5'}) - Database Missing" ); } } print "


\n" . "If any of the hash databases need to be re-indexed, use the " . "Hash Database Manager

" . "\n" . "\"Hash\n"; Print::print_html_footer(); return 0; } ############ INTEGRITY CHECKS ################## # Special view for printing integrity check menu # We show any file that we have a reference for # pass the md5 hash (from md5.txt) and then the sorted array sub int_menu_print { my %md5s = %{$_[0]}; my @sort = @{$_[1]}; for (my $i = 0; $i <= $#sort; $i++) { print "$Caseman::vol2sname{$sort[$i]}\n"; # It already exists, so make verify button if (exists $md5s{$sort[$i]}) { print "$md5s{$sort[$i]}" . "

\n" . "\n" . Args::make_hidden() . "\n" . "\n" . "\n" . "
\n"; } # we currenly only support integrity for raw and split image formats elsif (($Caseman::vol2itype{$sort[$i]} ne "raw") && ($Caseman::vol2itype{$sort[$i]} ne "split")) { print "Integrity checks for image type $Caseman::vol2itype{$sort[$i]} not yet supported\n"; } # Generate New button else { print " " . "
\n" . "\n" . Args::make_hidden() . "\n" . "\n" . "\n" . "
\n"; } } return; } # Create a frame with two rows, one with the list of images to check # and then the bottom actually does it. sub img_list_fr { Print::print_html_header_frameset( "$Args::args{'case'}:$Args::args{'host'} Integrity Check"); print "\n"; # Block List print "\n" . "\n" . "\n"; Print::print_html_footer_frameset(); return 0; } # Reads the MD5 file to fill in the MENU list for the integrity # check mode sub img_list { Print::print_html_header("Image Integrity Menu"); my %md5s; my @blkls; my @str; my @img; my @body; my @tl; # Read the known values if the file exists if (open(FILE, "$::host_dir" . "/md5.txt")) { # Read the md5 values into a hash while () { s/^\s+//; s/\s+$//; if (/($::REG_MD5)\s+(.*)/o) { $md5s{"$2"} = $1; $md5s{"$2"} =~ tr/[a-f]/[A-F]/; } else { print "Error reading line $. of md5.txt: $_
\n"; return 1; } } close(FILE); } # sort the images into the different types foreach my $k (keys %Caseman::vol2cat) { if ($Caseman::vol2cat{$k} eq "image") { push @img, $k; } elsif ($Caseman::vol2ftype{$k} eq "blkls") { push @blkls, $k; } elsif ($Caseman::vol2ftype{$k} eq "strings") { push @str, $k; } elsif ($Caseman::vol2ftype{$k} eq "body") { push @body, $k; } elsif ($Caseman::vol2ftype{$k} eq "timeline") { push @tl, $k; } } print "
"; # image files if (scalar @img > 0) { print "\n"; my @sort = sort { $a cmp $b } @img; int_menu_print(\%md5s, \@sort); } # Unallocated (blkls) images if (scalar @blkls > 0) { print "\n" . "\n"; my @sort = sort { $a cmp $b } @blkls; int_menu_print(\%md5s, \@sort); } # Strings files (of blkls or fs images) if (scalar @str > 0) { print "\n" . "\n"; my @sort = sort { $a cmp $b } @str; int_menu_print(\%md5s, \@sort); } # timeline body files if (scalar @body > 0) { print "\n" . "\n"; my @sort = sort { $a cmp $b } @body; int_menu_print(\%md5s, \@sort); } # timeline files if (scalar @tl > 0) { print "\n" . "\n"; my @sort = sort { $a cmp $b } @tl; int_menu_print(\%md5s, \@sort); } print <

" . "\"Image" . "
 
" . "\"Unallocated" . "
 
" . "\"Strings" . "
 
" . "\"Timeline" . "
 
" . "\"Timelines\"" . "
\"close\" \"Refresh\" \"Help\"
EOF Print::print_html_footer(); return 0; } # Pass the relative path (images/xyz) of the file. The MD5 is # returned (or NULL) (in all caps) sub lookup_md5 { my $vol = shift; my $md5 = ""; my $md5_file = "$::host_dir/md5.txt"; if (-e "$md5_file") { unless (open(FILE, $md5_file)) { print "Error opening $md5_file
\n"; return ""; } while () { s/^\s+//; s/\s+$//; if (/($::REG_MD5)\s+(.*)/o) { my $m = $1; if ($2 =~ /$vol$/) { $md5 = $m; $md5 =~ tr/[a-f]/[A-F]/; last; } } else { print "Error reading line $. of $md5_file: $_
\n"; return ""; } } close(FILE); } return $md5; } sub img_verify { Print::print_html_header("Image Integrity Check"); my $vol = Args::get_vol('vol'); my $md5 = lookup_md5($vol); if ($md5 eq "") { print "The MD5 value of $Caseman::vol2sname{$vol} was not found
" . "It can be calculated by pressing the button below." . "

\n
\n" . "\n" . "\n" . "\n" . Args::make_hidden() . "\n
"; return 1; } Print::log_host_inv("$Caseman::vol2sname{$vol}: Checking image integrity"); print "Original MD5: $md5
\n"; # We have the original value, now get the new one my $img = $Caseman::vol2path{$vol}; my $cur; if ($Caseman::vol2itype{$vol} eq "split") { $cur = calc_md5_split($img); } else { $cur = calc_md5($img); } if ($cur =~ /^$::REG_MD5$/o) { print "Current MD5: $cur

\n"; if ($cur eq $md5) { print "Pass
\n"; Print::log_host_inv( "$Caseman::vol2sname{$vol}: Image integrity check PASSED"); } else { print "Fail: Restore from backup" . "
\n"; Print::log_host_inv( "$Caseman::vol2sname{$vol}: Image integrity check FAILED"); } Print::print_html_footer(); return 0; } else { print "$cur
\n"; Print::print_html_footer(); return 1; } } # Calculate the MD5 value of a file (given the full path) # return the value in upper case # This one supports only single files - not split volumes sub calc_md5 { my $img = shift; my $hit_cnt = 0; $SIG{ALRM} = sub { if (($hit_cnt++ % 5) == 0) { print "+"; } else { print "-"; } alarm(5); }; alarm(5); local *OUT; Exec::exec_pipe(*OUT, "'$::MD5_EXE' $img"); alarm(0); $SIG{ALRM} = 'DEFAULT'; print "
\n" if ($hit_cnt > 0); my $out = Exec::read_pipe_line(*OUT); close(OUT); $out = "Error calculating MD5" if ((!defined $out) || ($out eq "")); if ($out =~ /^($::REG_MD5)\s+/) { my $m = $1; $m =~ tr/[a-f]/[A-F]/; return $m; } else { return $out; } } # Same as the version above, but this one can do split images # it fails though if the file is not a multiple of 512 sub calc_md5_split { my $img = shift; my $hit_cnt = 0; $SIG{ALRM} = sub { if (($hit_cnt++ % 5) == 0) { print "+"; } else { print "-"; } alarm(5); }; alarm(5); local *OUT; # We use the blkls method so that we can handle split images Exec::exec_pipe(*OUT, "'$::TSKDIR/blkls' -f raw -e $img | '$::MD5_EXE'"); alarm(0); $SIG{ALRM} = 'DEFAULT'; print "
\n" if ($hit_cnt > 0); my $out = Exec::read_pipe_line(*OUT); close(OUT); $out = "Error calculating MD5" if ((!defined $out) || ($out eq "")); if ($out =~ /^($::REG_MD5)\s+/) { my $m = $1; $m =~ tr/[a-f]/[A-F]/; return $m; } else { return $out; } } # Pass it the full path and the short name # and it adds it to md5.txt and returns the MD5 sub int_create_wrap { my $vol = shift; my $img = $Caseman::vol2path{$vol}; my $m; if ( (exists $Caseman::vol2itype{$vol}) && ($Caseman::vol2itype{$vol} eq "split")) { $m = calc_md5_split($img); } else { $m = calc_md5($img); } Caseman::update_md5($vol, $m) if ($m =~ /^$::REG_MD5$/o); return $m; } sub img_calc { Print::print_html_header("Image Integrity Creation"); my $vol = Args::get_vol('vol'); print "Calculating MD5 value for $Caseman::vol2sname{$vol}
\n"; Print::log_host_inv("$Caseman::vol2sname{$vol}: Calculating MD5 value"); my $m = int_create_wrap($vol); print "MD5: $m
\n"; print "
Value saved to host file

\n"; Print::print_html_footer(); return 0; } # Conver the 'image' format to the 'volume' format # Make one central file sub convert { my %img2vol = %{shift()}; Print::log_host_info("Converting format of MD5 hash files"); # Get out of here if there are no hash files return 0 unless ((-e "$::host_dir" . "$::IMGDIR" . "/md5.txt") || (-e "$::host_dir" . "$::DATADIR" . "/md5.txt")); # We are going ot make a single file my $md5_file_new = "$::host_dir" . "/md5.txt"; open MD5_NEW, ">$md5_file_new" or die "Can't open writing file: $md5_file_new"; # Read the md5s for the image directory my $md5_file = "$::host_dir" . "$::IMGDIR" . "/md5.txt"; if (open(FILE, $md5_file)) { # Read the md5 values into a hash while () { s/^\s+//; s/\s+$//; if (/($::REG_MD5)\s+(.*)/o) { my $md5 = $1; my $img = $2; unless (exists $img2vol{$img}) { print STDERR "Error finding image during hash file conversion: $img. Skipping\n"; next; } my $vol = $img2vol{$img}; print MD5_NEW "$md5 $vol\n"; } else { print MD5_NEW "$_"; } } close(FILE); rename $md5_file, $md5_file . ".bak"; } # Now do the data directory $md5_file = "$::host_dir" . "$::DATADIR" . "/md5.txt"; if (open(FILE, $md5_file)) { # Read the md5 values into a hash while () { s/^\s+//; s/\s+$//; if (/($::REG_MD5)\s+(.*)/o) { my $md5 = $1; my $img = $2; unless (exists $img2vol{$img}) { print STDERR "Error finding image during hash file conversion: $img. Skipping\n"; next; } my $vol = $img2vol{$img}; print MD5_NEW "$md5 $vol\n"; } else { print MD5_NEW "$_"; } } close(FILE); rename $md5_file, $md5_file . ".bak"; } close(MD5_NEW); return 0; } # Blank Page sub blank { Print::print_html_header(""); print "\n"; Print::print_html_footer(); return 0; } autopsy-2.24/lib/Kwsrch.pm0000644000076500000240000007620611335317414015041 0ustar carrierstaff# # Keyword search mode # # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2001-2005 by Brian Carrier. All rights reserved # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package Kwsrch; require 'search.pl'; $Kwsrch::ENTER = 1; $Kwsrch::RESULTS_FR = 2; $Kwsrch::RUN = 3; $Kwsrch::LOAD = 4; $Kwsrch::BLANK = 5; my $IMG_DETAILS = 0x80; sub main { # By default, show the main frame $Args::args{'view'} = $Args::enc_args{'view'} = $Kwsrch::ENTER unless (exists $Args::args{'view'}); Args::check_view(); my $view = Args::get_view(); if ($view == $Kwsrch::BLANK) { blank(); return 0; } # Check Basic Args Args::check_vol('vol'); # These windows don't need the meta data address if ($view == $Kwsrch::ENTER) { return enter(); } elsif ($view == $Kwsrch::RESULTS_FR) { return results_fr(); } elsif ($view == $Kwsrch::RUN) { return run(); } elsif ($view == $Kwsrch::LOAD) { return load(); } else { Print::print_check_err("Invalid Keyword Search View"); } } my $CASE_INSENS = 1; my $CASE_SENS = 0; my $REG_EXP = 1; my $STRING = 0; # Form to enter search data sub enter { my $vol = Args::get_vol('vol'); Print::print_html_header("Search on $Caseman::vol2sname{$vol}"); my $ftype = $Caseman::vol2ftype{$vol}; if ($ftype eq 'blkls') { print "

Keyword Search of Unallocated Space

\n"; } elsif ($ftype eq 'swap') { print "

Keyword Search of swap partition

\n"; } elsif ($ftype eq 'raw') { print "

Keyword Search of raw data

\n"; } elsif ($Caseman::vol2cat{$vol} eq "disk") { print "

Keyword Search of disk

\n"; } else { print "

Keyword Search of Allocated and Unallocated Space

\n"; } # @@@ Fix this - caused by writing all results to a file if ($::LIVE == 1) { Print::print_err( "Keyword searching is temporarily not available during live analysis mode" ); } print "
\n" . "Enter the keyword string or expression to search for:


\n" . Args::make_hidden() . "\n" . "\n" . "\n"; print "\n" . "" . "\n" . "\n" . "
" . "ASCII \n" . "Unicode
" . "Case Insensitive\n" . "grep Regular Expression
\n" . "\n
\n"; if ($::LIVE == 0) { print "\n"; # If we are a non-blkls image and one exists - make a button to load it if (($ftype ne 'blkls') && (exists $Caseman::vol2blkls{$vol})) { print "\n"; } # If we are a blkls and the original exists - make a button to load it elsif (($ftype eq 'blkls') && (exists $Caseman::mod2vol{$vol})) { print "\n"; } # Strings Button if ( (!(exists $Caseman::vol2str{$vol})) || (!(exists $Caseman::vol2uni{$vol}))) { my $dest_vol = $vol; $dest_vol = $Caseman::mod2vol{$vol} if exists($Caseman::mod2vol{$vol}); print "\n"; } # Unallocated Space Button if ( ($Fs::is_fs{$ftype}) && (!(exists $Caseman::vol2blkls{$vol}))) { print "\n"; } print "
" . "
\n" . "\n" . "\n" . "\n" . Args::make_hidden() . "\n
" . "
\n" . "\n" . "\n" . "\n" . Args::make_hidden() . "\n
" . "
\n" . "\n" . "\n" . "\n" . Args::make_hidden() . "\n
" . "
\n" . "\n" . "\n" . "\n" . Args::make_hidden() . "\n
\n"; } print "" . "Regular Expression Cheat Sheet\n

\n"; print "

NOTE: The keyword search runs " . "grep on the image.
\n" . "A list of what will and " . "what will not be found is available " . "here.
\n"; # Section for previous searches if ($::LIVE == 0) { my $srch_name = get_srch_fname(0); if (-e $srch_name) { print "


Previous Searches

\n" . "\n"; my $row_idx = 0; # Cycle through the files for (my $srch_idx = 0;; $srch_idx++) { $srch_name = get_srch_fname($srch_idx); last unless (-e $srch_name); # Open the file to get the string and count unless (open(SRCH, "$srch_name")) { print "Error opening search file: $srch_name\n"; return 1; } my $prev_str = ""; my $prev_cnt = 0; while () { unless (/^(\d+)\|(.*?)?\|(.*)$/) { print "Error pasing header of search file: $srch_name\n"; return 1; } $prev_cnt = $1; $prev_str = $3; if (length($prev_str) > 32) { $prev_str = substr($prev_str, 0, 32); $prev_str .= "..."; } last; } close(SRCH); print "\n" if ($row_idx == 0); print " \n"; $row_idx = 0; } else { $row_idx++; } } print "
\n" . "
\n" . "\n" . "\n" . "\n" . "\n" . Args::make_hidden(); print "" . "
\n"; if ($row_idx == 3) { print "
\n"; } } # Predefined expressions from search.pl print "

Predefined Searches

\n"; print "\n"; my $row_idx = 0; my $r; foreach $r (keys %Kwsrch::auto_srch) { $Kwsrch::auto_srch_reg{$r} = 0 unless (defined $Kwsrch::auto_srch_reg{$r}); $Kwsrch::auto_srch_csense{$r} = 1 unless (defined $Kwsrch::auto_srch_csense{$r}); print "\n" if ($row_idx == 0); # @@@ Make a unicode option in predefined print " \n"; if ($row_idx == 3) { print "\n"; $row_idx = 0; } else { $row_idx++; } } print "
\n" . "
\n" . "\n" . "\n" . "\n" . "\n" . "\n" . Args::make_hidden(); if ($Kwsrch::auto_srch_reg{$r} == 1) { print "\n"; } if ($Kwsrch::auto_srch_csense{$r} == 0) { print "\n"; } print "
\n" . "
\n"; Print::print_html_footer(); return 0; } # MAIN WITH RESULTS # Page that makes frame with the results on left and data units on right sub results_fr { my $vol = Args::get_vol('vol'); # A string was given for a new search if (exists $Args::args{'str'}) { Args::check_str(); Print::print_html_header_frameset( "Search on $Caseman::vol2sname{$vol} for $Args::args{'str'}"); print "\n"; my $srch_case = ""; $srch_case = "&srch_case=$Args::args{'srch_case'}" if (exists $Args::args{'srch_case'}); my $regexp = ""; $regexp = "®exp=$Args::args{'regexp'}" if (exists $Args::args{'regexp'}); my $ascii = ""; $ascii = "&ascii=$Args::args{'ascii'}" if (exists $Args::args{'ascii'}); my $unicode = ""; $unicode = "&unicode=$Args::args{'unicode'}" if (exists $Args::args{'unicode'}); # Block List print "\n"; } elsif (exists $Args::args{'srchidx'}) { Args::check_srchidx(); Print::print_html_header_frameset( "Search on $Caseman::vol2sname{$vol} for Index $Args::args{'srchidx'}" ); print "\n"; # Block List print "\n"; } # Block Contents print "\n" . "\n"; Print::print_html_footer_frameset(); return 0; } # Find an empty file to save the keyword searches to sub find_srch_file { my $vol = Args::get_vol('vol'); my $out_name = "$::host_dir" . "$::DATADIR/$Caseman::vol2sname{$vol}"; my $i; for ($i = 0; -e "${out_name}-${i}.srch"; $i++) { } return "${out_name}-${i}.srch"; } # Pass the index # return the full path of the file returned sub get_srch_fname { my $idx = shift; my $vol = Args::get_vol('vol'); return "$::host_dir" . "$::DATADIR" . "/$Caseman::vol2sname{$vol}-${idx}.srch"; } sub load { Args::check_srchidx(); Print::print_html_header(""); if ($::LIVE == 1) { print "Searches cannot be loaded during live analysis
\n"; return 1; } my $srch_name = get_srch_fname($Args::args{'srchidx'}); print "New Search\n

"; print_srch_results($srch_name); Print::print_html_footer(); return 0; } # performs actual search, saves hits to file, and calls method to print sub run { Args::check_str(); Print::print_html_header(""); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $orig_str = Args::get_str(); my $grep_str = $orig_str; # we will escape some values in the grep ver # Check for a search string if ($orig_str eq "") { print "You must enter a string value to search
\n"; print "New Search\n

"; return 1; } my $log = ""; # Log entry string my $ascii = 0; my $unicode = 0; if ((exists $Args::args{'ascii'}) && ($Args::args{'ascii'} == 1)) { $ascii = 1; $log .= "ASCII, "; } if ((exists $Args::args{'unicode'}) && ($Args::args{'unicode'} == 1)) { $unicode = 1; $log .= "Unicode, "; } if (($ascii == 0) && ($unicode == 0)) { print "You must choose either ASCII or Unicode to search
\n"; print "New Search\n

"; return 1; } my $grep_flag = ""; # Flags to pass to grep # Check if search is case insensitive my $case = 0; if ( (exists $Args::args{'srch_case'}) && ($Args::args{'srch_case'} == $CASE_INSENS)) { $grep_flag = "-i"; $case = 1; $log .= "Case Insensitive "; } # Check if search is a regular expression my $regexp = 0; if ((exists $Args::args{'regexp'}) && ($Args::args{'regexp'} == $REG_EXP)) { $grep_flag .= " -E"; $regexp = 1; $log .= "Regular Expression "; } # if not a reg-exp, we need to escape some special values that # 'grep' will misinterpret else { $grep_str =~ s/\\/\\\\/g; # \ $grep_str =~ s/\./\\\./g; # . $grep_str =~ s/\[/\\\[/g; # [ $grep_str =~ s/\^/\\\^/g; # ^ $grep_str =~ s/\$/\\\$/g; # $ $grep_str =~ s/\*/\\\*/g; # * # We need to add ' to end begin and end of the search as well if ($grep_str =~ /\'/) { $grep_str =~ s/\'/\\\'/g; # ' $grep_str = "'$grep_str'"; } $grep_str =~ s/^\-/\\\-/; # starting with - (mistakes for an arg) } Print::log_host_inv( "$Caseman::vol2sname{$vol}: ${log}search for $grep_str"); # Get the addressable unit of image my $bs = Args::get_unitsize(); # $norm_str is normalized to find the "hit" in the output my $norm_str = $orig_str; # make this lowercase if we are doing case insens $norm_str =~ tr/[A-Z]/[a-z]/ if ($case == 1); my $norm_str_len = length($norm_str); # array to pass to printing method my @results; my $name_uni = ""; my $name_asc = ""; # round 0 is for ASCII and 1 is for Unicode for (my $i = 0; $i < 2; $i++) { next if (($i == 0) && ($ascii == 0)); next if (($i == 1) && ($unicode == 0)); @results = (); local *OUT; my $hit_cnt = 0; $SIG{ALRM} = sub { if (($hit_cnt++ % 5) == 0) { print "+"; } else { print "-"; } alarm(5); }; alarm(5); if ($i == 0) { print "Searching for ASCII: "; } else { print "Searching for Unicode: "; } # if the string is less than 4 chars, then it will not be in the # strings file so it will be searched for the slow way if (length($orig_str) < 4) { my $ltmp = length($orig_str); if ($i == 0) { if ( (($ftype eq "raw") || ($ftype eq "swap")) && ($Caseman::vol2end{$vol} != 0)) { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkls' -e -f $ftype -i $imgtype $img " . $Caseman::vol2start{$vol} . "-" . $Caseman::vol2end{$vol} . " | '$::TSKDIR/srch_strings' -a -t d -$ltmp | '$::GREP_EXE' $grep_flag '$grep_str'" ); } else { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkls' -e -f $ftype -o $offset -i $imgtype $img | '$::TSKDIR/srch_strings' -a -t d -$ltmp | '$::GREP_EXE' $grep_flag '$grep_str'" ); } } else { if ( (($ftype eq "raw") || ($ftype eq "swap")) && ($Caseman::vol2end{$vol} != 0)) { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkls' -e -f $ftype -i $imgtype $img " . $Caseman::vol2start{$vol} . "-" . $Caseman::vol2end{$vol} . " | '$::TSKDIR/srch_strings' -a -t d -e l -$ltmp | '$::GREP_EXE' $grep_flag '$grep_str'" ); } else { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkls' -e -f $ftype -o $offset -i $imgtype $img | '$::TSKDIR/srch_strings' -a -t d -e l -$ltmp | '$::GREP_EXE' $grep_flag '$grep_str'" ); } } } # Use the strings file if it exists elsif (($i == 0) && (defined $Caseman::vol2str{$vol})) { my $str_vol = $Caseman::vol2path{$Caseman::vol2str{$vol}}; Exec::exec_pipe(*OUT, "'$::GREP_EXE' $grep_flag '$grep_str' $str_vol"); } elsif (($i == 1) && (defined $Caseman::vol2uni{$vol})) { my $str_vol = $Caseman::vol2path{$Caseman::vol2uni{$vol}}; Exec::exec_pipe(*OUT, "'$::GREP_EXE' $grep_flag '$grep_str' $str_vol"); } # Run strings on the image first and then grep that else { if ($i == 0) { if ( (($ftype eq "raw") || ($ftype eq "swap")) && ($Caseman::vol2end{$vol} != 0)) { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkls' -e -f $ftype -i $imgtype $img " . $Caseman::vol2start{$vol} . "-" . $Caseman::vol2end{$vol} . " | '$::TSKDIR/srch_strings' -a -t d | '$::GREP_EXE' $grep_flag '$grep_str'" ); } else { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkls' -e -f $ftype -o $offset -i $imgtype $img | '$::TSKDIR/srch_strings' -a -t d | '$::GREP_EXE' $grep_flag '$grep_str'" ); } } else { if ( (($ftype eq "raw") || ($ftype eq "swap")) && ($Caseman::vol2end{$vol} != 0)) { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkls' -e -f $ftype -i $imgtype $img " . $Caseman::vol2start{$vol} . "-" . $Caseman::vol2end{$vol} . " | '$::TSKDIR/srch_strings' -a -t d -e l | '$::GREP_EXE' $grep_flag '$grep_str'" ); } else { Exec::exec_pipe(*OUT, "'$::TSKDIR/blkls' -e -f $ftype -o $offset -i $imgtype $img | '$::TSKDIR/srch_strings' -a -t d -e l | '$::GREP_EXE' $grep_flag '$grep_str'" ); } } } alarm(0); $SIG{ALRM} = 'DEFAULT'; # Cycle through the results and put them in an array while ($_ = Exec::read_pipe_line(*OUT)) { # Parse out the byte offset and hit string if (/^\s*(\d+)\s+(.+)$/) { my $off = $1; my $hit_str_orig = $2; my $idx = 0; # Make a copy that we can modify & play with my $hit_str = $hit_str_orig; $hit_str =~ tr/[A-Z]/[a-z]/ if ($case == 1); # How long was the string that we hit? my $hit_str_len = length($hit_str); # I'm not sure how to find a grep re in the hit yet, so # for now we do not get the exact offset if ($regexp) { my $b = int($off / $bs); my $o = int($off % $bs); # $hit =~ s/\n//g; push @results, "${b}|${o}|"; next; } # There could be more than one keyword in the string # so cycle through all of them my $psize = scalar(@results); while (($idx = index($hit_str, $norm_str, $idx)) > -1) { # The summary of the hit starts 5 chars before it my $sum_min = $idx - 5; $sum_min = 0 if ($sum_min < 0); # Goto 5 after, if there is still space my $sum_max = $idx + $norm_str_len + 5; $sum_max = $hit_str_len if ($sum_max > $hit_str_len); my $sum_hit = substr($hit_str_orig, $sum_min, $sum_max - $sum_min); # remove new lines $sum_hit =~ s/\n/ /g; # The actual offset for Unicode is 2 bytes per char my $tmpidx = $idx; $tmpidx *= 2 if ($i == 1); my $b = int(($off + $tmpidx) / $bs); my $o = int(($off + $tmpidx) % $bs); push @results, "${b}|${o}|$sum_hit"; # advance index to find next hit $idx++; } # If we did not find a term, then just print what # was found-this occurs bc index does not find it # sometimes. if ($psize == scalar(@results)) { my $b = int($off / $bs); my $o = int($off % $bs); # $hit =~ s/\n//g; push @results, "${b}|${o}|"; next; } } # A negative offset is common on FreeBSD with large images elsif (/^\s*(\-\d+):?\s*(.+)$/) { print "ERROR: Negative byte offset ($1) Your version of " . "strings likely does not support large files: $2
\n"; } else { print "Error parsing grep result: $_
\n"; } } close(OUT); print " Done
"; my $cnt = scalar(@results); my $srch_name = ""; if ($::LIVE == 0) { print "Saving: "; # Find a file to save the results to $srch_name = find_srch_file(); unless (open(IDX, ">$srch_name")) { print "Error opening $srch_name\n"; return (1); } # Print the header if ($i == 0) { print IDX "$cnt|${grep_flag}|${orig_str}|ascii\n"; $name_asc = $srch_name; } else { print IDX "$cnt|${grep_flag}|${orig_str}|unicode\n"; $name_uni = $srch_name; } for (my $a = 0; $a < $cnt; $a++) { print IDX "$results[$a]\n"; } close(IDX); print " Done
\n"; } if ($i == 0) { print "$cnt hits"; print "- link to results" if ($cnt > 0); print "
\n"; } else { print "$cnt hits"; print "- link to results" if ($cnt > 0); print "
\n"; } print "


\n"; } print "New Search\n

"; if ($::LIVE == 0) { if ($ascii == 1) { print_srch_results($name_asc); } if ($unicode == 1) { print_srch_results($name_uni); } } Print::print_html_footer(); return 0; } # Args are search string, grep flags, and array of hits sub print_srch_results { if (scalar(@_) != 1) { print "Missing Args for print_srch_results()\n"; return 1; } my $srch_name = shift; my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $addr_str = $Fs::addr_unit{$ftype}; unless (open(SRCH, "$srch_name")) { print "Error opening search file: $srch_name\n"; return 1; } my @results; my $grep_str = ""; my $grep_flag = ""; my $cnt = 0; my $type = 0; # ASCII iis 0 and Unicode is 1 my $prev = -1; while () { # The first line is a header if ($. == 1) { if (/^(\d+)\|(.*?)?\|(.*)$/) { $cnt = $1; $grep_flag = $2; $grep_str = $3; $type = 0; } else { print "Error pasing header of search file: $srch_name\n"; close(SRCH); return 1; } if ($grep_str =~ /^(.*?)\|unicode$/) { $grep_str = $1; $type = 1; } elsif ($grep_str =~ /^(.*?)\|ascii$/) { $grep_str = $1; } my $grep_str_html = Print::html_encode($grep_str); print "


\n"; if ($type == 0) { print "\n"; } else { print "\n"; } if ($cnt == 0) { print "$grep_str_html was not found
\n"; } elsif ($cnt == 1) { print "1 occurrence of $grep_str_html was found
\n"; } else { print "$cnt occurrences of $grep_str_html were found
\n"; } print "Search Options:
\n"; if ($type == 0) { print "  ASCII
\n"; } else { print "  Unicode
\n"; } if ($grep_flag =~ /\-i/) { print "  Case Insensitive
\n"; } else { print "  Case Sensitive
\n"; } if ($grep_flag =~ /\-E/) { print "  Regular Expression
\n"; } print "
\n"; if ($cnt > 1000) { print "There were more than 1000 hits.
\n"; print "Please revise the search to a managable amount.\n"; print "

The $cnt hits can be found in: $srch_name
\n"; close(SRCH); return 0; } next; } unless (/^(\d+)\|(\d+)\|(.*)?$/) { print "Error parsing results: $_\n"; close(SRCH); return 1; } my $blk = $1; my $off = $2; my $str = $3; if ($blk != $prev) { my $url = "$::PROGNAME?mod=$::MOD_DATA&view=$Data::CONT_MENU_FR&$Args::baseargs&block=$blk"; print "
\n$addr_str $blk (
Hex - " . "" . "Ascii"; print " - Original" if ( ($ftype eq 'blkls') && (exists $Caseman::mod2vol{$vol})); print ")
"; $prev = $blk; } my $occ = $. - 1; if ($str ne "") { $str = Print::html_encode($str); print "$occ: $off ($str)
\n"; } else { print "$occ: $off
\n"; } } close(SRCH); return 0; } # Blank Page sub blank { Print::print_html_header(""); print "\n"; Print::print_html_footer(); return 0; } 1; autopsy-2.24/lib/Main.pm0000644000076500000240000002301411070040246014441 0ustar carrierstaff# # Main.pm # Autopsy Forensic Browser # # This file requires The Sleuth Kit # www.sleuthkit.org # # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2001-2005 by Brian Carrier. All rights reserved # # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # use lib './'; use strict; use Appsort; use Appview; use Args; use Caseman; use Data; use Exec; use File; use Filesystem; use Frame; use Fs; use Hash; use Kwsrch; use Meta; use Notes; use Print; use Timeline; use Vs; require 'conf.pl'; require 'define.pl'; # Get rid of insecure settings $ENV{PATH} = ""; delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; # Formats for regular expressions # Year.Mon.Day Hr:Min:Sec (TZ) $::REG_DAY = '\d\d\d\d\-\d\d\-\d\d'; $::REG_TIME = '\d\d:\d\d:\d\d'; $::REG_ZONE_ARGS = '[\w\+\-\/\_]+'; $::REG_ZONE2 = '\([\w\+\- ]*\)'; $::REG_DATE = "$::REG_DAY" . '\s+' . "$::REG_TIME" . '\s+' . "$::REG_ZONE2"; $::REG_FTYPE = '[\w\-]+'; $::REG_SKEW = '[\+\-]?\d+'; $::REG_MTYPE = '[\?bcdflprsvw-]'; # Type according to meta data $::REG_FILE = '[\w\-\_\.]+'; $::REG_CASE = $::REG_FILE; $::REG_HOST = '[\w\-\_\.]+'; $::REG_INVESTIG = '[\w]+'; $::REG_IMG = "$::REG_FILE" . '/' . "$::REG_FILE"; $::REG_IMG_PATH = '/[\w\-\_\.\/]+'; $::REG_IMG_PATH_WILD = '/[\w\-\_\.\/]+\*?'; $::REG_IMG_CONFIG = '[\w\-\_\.\/ ]+'; $::REG_FNAME = $::REG_FILE; $::REG_MNT = '[\w\-\_\.\/\:\\\\]+'; $::REG_SEQ_FILE = '[\w\s\-\_\.\/\:\\\\]+'; $::REG_HASHDB = '[\w\-\_\.\,\/]+'; $::REG_IMGTYPE = '[\w\,]+'; $::REG_INAME = '[\w]+'; $::REG_VNAME = '[\w]+'; $::REG_META = '[\d-]+'; $::REG_MD5 = '[0-9a-fA-F]{32,32}'; $::HELP_URL = "help/index.html"; # host_dir and case_dir will end with a '/' $::host_dir = ""; $::case_dir = ""; ################## NEW STUFF ########################## # MODULES # If the values of these are changed, or if new modules are added, # Then the below pseudo-binary sort algorithm must be changed as well $::MOD_CASEMAN = 0; $::MOD_FRAME = 1; $::MOD_FILE = 2; $::MOD_META = 3; $::MOD_KWSRCH = 4; $::MOD_DATA = 5; $::MOD_TL = 6; $::MOD_FS = 7; $::MOD_APPSORT = 8; $::MOD_NOTES = 9; $::MOD_HASH = 10; $::MOD_APPVIEW = 11; # Main Menu # # Display the title page sub welcome { Print::print_html_header_javascript("Autopsy Forensic Browser"); print "

\n"; # This problem has not been seen with the 1 second delay if ((0) && ($] >= 5.008)) { print "

Warning: You are using Perl v5.8.
\n" . " Some buffer problems have been reported with Autopsy and Perl 5.8 " . "where output is not shown.
\n" . "Perl 5.6 should be used if available.\n" . "If data is missing, reload the page


\n"; } print < Autopsy Forensic Browser $::VER   Logo   http://www.sleuthkit.org/autopsy/   \"Open \"New \"Help\" EOF Print::print_html_footer_javascript(); return 0; } sub get_tskver { local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/fls' -V"); my $ver = Exec::read_pipe_line(*OUT); $ver = $1 if ($ver =~ /^The Sleuth Kit ver (.*)$/); close(OUT); return $ver; } # This function is called by the code in the 'autopy' file. # This will check for the basic module arguments and then host # and case accordingly. The main function of each of the modules # is called from here. Each of the modules will have to take care # of the detailed argument checking. sub main { # Parse arguments my $lcl_args = shift; Args::parse_args($lcl_args); # When autopsy is first run, no mod or arguments are given. unless (exists $Args::args{'mod'}) { # if we are not in live analysis mode, display the usual screen if ($::LIVE == 0) { return welcome(); } else { # If we are in live analysis mode, open up the window to select # and image and supply basic host and case values. $Args::args{'mod'} = $Args::enc_args{'mod'} = $::MOD_CASEMAN; $Args::args{'view'} = $Args::enc_args{'view'} = $Caseman::VOL_OPEN; $Args::args{'case'} = $Args::enc_args{'case'} = "live"; $Args::args{'host'} = $Args::enc_args{'host'} = "local"; $Args::args{'inv'} = $Args::enc_args{'inv'} = "unknown"; } } Args::check_mod(); my $module = Args::get_mod(); Args::make_baseargs(); # For live analysis, we need to change the regular expression # for images because it can be a full path (to /dev/xxxxxxx) $::REG_IMG = '/[\w\-\_\.\/]+' if ($::LIVE == 1); # The Case Management module is handled seperately because # it may not have the host and case values if ($module == $::MOD_CASEMAN) { return Caseman::main(); } # Check the minimum arguments Args::check_case(); Args::check_host(); # Set the case and host variables if ($::LIVE == 0) { $::case_dir = "$::LOCKDIR/" . Args::get_case() . "/"; $::case_dir =~ s/\/\//\//g; $::host_dir = "$::case_dir" . Args::get_host() . "/"; $::host_dir =~ s/\/\//\//g; } else { $::host_dir = ""; $::case_dir = ""; } Caseman::read_host_config(); # This is a partial binary sort method to reduce the number of checks # 0 < mod < 6 if ($module < $::MOD_TL) { # 0 < mod < 4 if ($module < $::MOD_KWSRCH) { # mod == 1 if ($module == $::MOD_FRAME) { return Frame::main(); } # mod == 2 elsif ($module == $::MOD_FILE) { return File::main(); } # mod == 3 elsif ($module == $::MOD_META) { return Meta::main(); } } # 4 <= mod < 6 else { # mod == 4 if ($module == $::MOD_KWSRCH) { return Kwsrch::main(); } # mod == 5 elsif ($module == $::MOD_DATA) { return Data::main(); } } } # 6 <= mod else { # 6 <= mod < 9 if ($module < $::MOD_NOTES) { # mod == 6 if ($module == $::MOD_TL) { return Timeline::main(); } # mod == 7 elsif ($module == $::MOD_FS) { return Filesystem::main(); } # mod == 8 elsif ($module == $::MOD_APPSORT) { return Appsort::main(); } } # 9 <= mod else { # mod == 9 if ($module == $::MOD_NOTES) { return Notes::main(); } # mod == 10 elsif ($module == $::MOD_HASH) { return Hash::main(); } # mod == 11 elsif ($module == $::MOD_APPVIEW) { return Appview::main(); } # New modules can be added here } } Print::print_check_err("Invalid Module"); } 1; autopsy-2.24/lib/Meta.pm0000644000076500000240000006046611355002261014460 0ustar carrierstaff# # Metadata mode # # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2001-2005 by Brian Carrier. All rights reserved # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Updated 1/13 package Meta; $Meta::FRAME = 0; $Meta::ENTER = 1; $Meta::STATS = 2; $Meta::EXPORT = 3; $Meta::FFIND = 4; $Meta::LIST = 5; $Meta::REPORT = 6; $Meta::BLANK = 7; sub main { # By default, show the main frame $Args::args{'view'} = $Args::enc_args{'view'} = $Meta::FRAME unless (exists $Args::args{'view'}); Args::check_view(); my $view = Args::get_view(); # Check Basic Args Args::check_vol('vol'); # These windows don't need the meta data address if ($view == $Meta::FRAME) { return frame(); } elsif ($view == $Meta::ENTER) { return enter(); } elsif ($view == $Meta::LIST) { return list(); } elsif ($view == $Meta::BLANK) { return blank(); } # These windows do need the meta data address Args::check_meta('meta'); if ($view == $Meta::STATS) { return stats(); } elsif ($view == $Meta::FFIND) { return findfile(); } Args::check_recmode(); if ($view == $Meta::EXPORT) { return export(); } elsif ($view == $Meta::REPORT) { return report(); } else { Print::print_check_err("Invalid Meta View"); } } # Print the two frames sub frame { my $vol = Args::get_vol('vol'); Print::print_html_header_frameset( "Meta Data Browse on $Caseman::vol2sname{$vol}"); print "\n"; # Print the frame where an addres can be entered and a frame for the # contents if (exists $Args::enc_args{'meta'}) { print "\n" . "\n\n"; } else { print "\n" . "\n\n"; } Print::print_html_footer_frameset(); return 0; } # Generate the frame to enter the data into sub enter { Print::print_html_header(""); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; # Address print "
\n" . "$Fs::meta_str{$ftype} Number:
    " . "\n" . "\n" . "\n" . "\n" . Args::make_hidden() . # View Button "

\n"; # Allocation List print "

" . "" . "\"Allocation" . "\n"; Print::print_html_footer(); return 0; } # Display the contents of meta sub stats { Print::print_html_header(""); my $meta = Args::get_meta('meta'); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $tz = ""; $tz = "-z '$Caseman::tz'" unless ("$Caseman::tz" eq ""); Print::log_host_inv( "$Caseman::vol2sname{$vol}: Displaying details of $Fs::meta_str{$ftype} $meta" ); my $meta_int = $meta; $meta_int = $1 if ($meta =~ /^(\d+)-\d+(-\d)?/); my $prev = $meta_int - 1; my $next = $meta_int + 1; # We need to get the allocation status of this structure my $recmode = $File::REC_NO; local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/ils' -f $ftype -e -o $offset -i $imgtype $img $meta_int"); while ($_ = Exec::read_pipe_line(*OUT)) { chop; next unless ($_ =~ /^$meta_int/); if ($_ =~ /^$meta_int\|f/) { $recmode = $File::REC_YES; } elsif ($_ =~ /^$meta_int\|a/) { $recmode = $File::REC_NO; } else { Print::print_err("Error parsing ils output: $_"); } } close(OUT); print "

\n"; print "" . "\"previous\"\n" unless ($prev < $Fs::first_meta{$ftype}); print "" . "\"next\"\n
"; # Report print "\n" . "\n"; # View (File Mode) print "\n"; # Export print ""; # Notes print "" if ($::USE_NOTES == 1); print "
" . "\"report\"" . "" . "\"view" . "" . "\"export\"" . "" . "\"Add" . "
\n
\n"; my $tmpr = $Caseman::vol2mnt{$vol}; if ($ftype =~ /fat/) { print "Search for File Name

"; } else { print "Pointed to by file:
\n"; local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/ffind' -f $ftype -a -o $offset -i $imgtype $img $meta"); my $cnt = 0; while ($_ = Exec::read_pipe_line(*OUT)) { chop; if (/^(\*)\s+\/*(.*)$/) { Print::print_output("" . Print::html_encode($tmpr . $2) . " (deleted)

\n"); } elsif (/^\/(.*)$/) { Print::print_output("" . Print::html_encode($tmpr . $1) . "

\n"); } else { Print::print_output(Print::html_encode($_) . "

\n"); } $cnt++; } close(OUT); if ($cnt == 0) { print "
Invalid $Fs::meta_str{$ftype} value

\n"; return; } } if ($recmode == $File::REC_YES) { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype -r -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" ); } else { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" ); } my $file_type = Exec::read_pipe_line(*OUT); close(OUT); $file_type = "Error getting file type" if ((!defined $file_type) || ($file_type eq "")); if ($recmode == $File::REC_YES) { print "File Type (Recovered):
$file_type
\n"; } else { print "File Type:
$file_type

\n"; } # MD5 Value if ($recmode == $File::REC_YES) { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype -r -o $offset -i $imgtype $img $meta | '$::MD5_EXE'" ); } else { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype -o $offset -i $imgtype $img $meta | '$::MD5_EXE'" ); } my $md5out = Exec::read_pipe_line(*OUT); close(OUT); $md5out = "Error getting MD5" if ((!defined $md5out) || ($md5out eq "")); chomp $md5out; if ($recmode == $File::REC_YES) { print "MD5 of recovered content:
$md5out

\n"; } else { print "MD5 of content:
$md5out

\n"; } # Hash Database Lookups if ( ( ($::NSRLDB ne "") || ($Caseman::alert_db ne "") || ($Caseman::exclude_db ne "") ) && ($md5out =~ /^$::REG_MD5$/o) ) { print "
\n" . Args::make_hidden() . "\n" . "\n" . "\n" . "\n"; if ($::NSRLDB ne "") { print "\n"; } if ($Caseman::alert_db ne "") { print "\n"; } if ($Caseman::exclude_db ne "") { print "\n"; } print "
" . "" . "NSRL" . "" . "Alert Database" . "" . "Exclude Database" . "" . "
\n
\n"; } # SHA-1 Value if ($::SHA1_EXE ne "") { if ($recmode == $File::REC_YES) { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype -r -o $offset -i $imgtype $img $meta | '$::SHA1_EXE'" ); } else { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype -o $offset -i $imgtype $img $meta | '$::SHA1_EXE'" ); } my $sha1out = Exec::read_pipe_line(*OUT); close(OUT); $sha1out = "Error getting SHA-1" if ((!defined $sha1out) || ($sha1out eq "")); chomp $sha1out; if ($recmode == $File::REC_YES) { print "SHA-1 of recovered content:
$sha1out

\n"; } else { print "SHA-1 of content:
$sha1out

\n"; } } # istat output print "Details:

\n"; my $mode = 0; # set to 1 when showing blocks my $force = 0; # set to 1 if size of meta is 0 my @output; if (exists($Args::args{'force'})) { my $f = Args::get_force(); Exec::exec_pipe(*OUT, "'$::TSKDIR/istat' -f $ftype $tz -s $Caseman::ts -B $f -o $offset -i $imgtype $img $meta" ); } else { Exec::exec_pipe(*OUT, "'$::TSKDIR/istat' -f $ftype $tz -s $Caseman::ts -o $offset -i $imgtype $img $meta" ); } while ($_ = Exec::read_pipe_line(*OUT)) { if ($mode == 1) { if (/^Indirect Blocks/) { print "$_
\n"; next; } elsif (/^Recover/) { print "$_
\n"; next; } elsif (/^Type: (\S+) \((\d+\-\d+)\) (.*)$/) { print "$1 (" . "$2) $3
\n"; next; } my $blk; foreach $blk (split(/ /, $_)) { if ($blk =~ /^\d+$/) { print "$blk "; } else { print "$blk "; } } print "
\n"; } else { if (/^Not Allocated$/) { print "$_
\n"; } else { print "$_
\n"; } $mode = 1 if (/^Direct Blocks|^Sectors/); $mode = 1 if (/^Attributes:/); # HFS gets messed up without ":" $mode = 1 if (/^Data Fork Blocks:/); if ((/^size: (\d+)/) && ($1 == 0)) { $force = 1; } } } close(OUT); # display a text box to force X number of blocks to be displayed if ($force == 1) { print "
\n" . Args::make_hidden() . "\n" . "\n" . "\n" . "\n"; print "Enter number of $Fs::addr_unit{$ftype}s to display: \n"; print " (because the size is 0)\n
\n"; } Print::print_html_footer(); return 0; } sub findfile { Print::print_html_header("Find File"); my $meta = Args::get_meta('meta'); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $tmpr = $Caseman::vol2mnt{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; print "Pointed to by file:
\n"; local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/ffind' -f $ftype -a -o $offset -i $imgtype $img $meta"); while ($_ = Exec::read_pipe_line(*OUT)) { chop; if (/(\*)\s+\/*(.*)/) { Print::print_output("" . Print::html_encode($tmpr . $2) . " (deleted)
\n"); } elsif (/^\/(.*)$/) { Print::print_output( "" . Print::html_encode($tmpr . $1) . "
\n"); } else { Print::print_output(Print::html_encode($_) . "
\n"); } } close(OUT); Print::print_html_footer(); return 0; } sub export { my $meta = Args::get_meta('meta'); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $recmode = Args::get_recmode(); Print::log_host_inv( "$Caseman::vol2sname{$vol}: Saving contents of $Fs::meta_str{$ftype} $meta" ); Print::print_oct_header("$vol" . "-meta" . "$meta" . ".raw"); local *OUT; if ($recmode == $File::REC_YES) { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype -r -o $offset -i $imgtype $img $meta"); } else { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype -o $offset -i $imgtype $img $meta"); } print "$_" while ($_ = Exec::read_pipe_data(*OUT, 512)); close(OUT); Print::print_oct_footer(); } sub report { my $meta = Args::get_meta('meta'); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $recmode = Args::get_recmode(); my $tz = ""; $tz = "-z '$Caseman::tz'" unless ("$Caseman::tz" eq ""); Print::log_host_inv( "$Caseman::vol2sname{$vol}: Generating report for $Fs::meta_str{$ftype} $meta" ); Print::print_text_header("filename=$vol-meta$meta.txt"); print " Autopsy $Fs::meta_str{$ftype} Report\n\n" . "-" x 70 . "\n" . " GENERAL INFORMATION\n\n" . "$Fs::meta_str{$ftype}: $Args::args{'meta'}\n"; print "Pointed to by file(s):\n"; my $tmpr = $Caseman::vol2mnt{$vol}; local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/ffind' -f $ftype -a -o $offset -i $imgtype $img $meta"); while ($_ = Exec::read_pipe_line(*OUT)) { chop; if (/^(\*)\s+\/*(.*)$/) { Print::print_output( " ${tmpr}${2} (deleted)\n"); } elsif (/^\/(.*)$/) { Print::print_output(" ${tmpr}${1}\n"); } else { Print::print_output(" $_\n"); } } close(OUT); Exec::exec_pipe(*OUT, "'$::TSKDIR/istat' -f $ftype $tz -s $Caseman::ts -o $offset -i $imgtype $img $meta | '$::MD5_EXE'" ); my $md5 = Exec::read_pipe_line(*OUT); close(OUT); $md5 = "Error getting MD5 Value" if ((!defined $md5) || ($md5 eq "")); chop $md5; print "MD5 of istat output: $md5\n"; if ($::SHA1_EXE ne "") { Exec::exec_pipe(*OUT, "'$::TSKDIR/istat' -f $ftype $tz -s $Caseman::ts -o $offset -i $imgtype $img $meta | '$::SHA1_EXE'" ); my $sha1 = Exec::read_pipe_line(*OUT); close(OUT); $sha1 = "Error getting SHA-1 Value" if ((!defined $sha1) || ($sha1 eq "")); chop $sha1; print "SHA-1 of istat output: $sha1\n"; } print "\nImage: $Caseman::vol2path{$vol}\n"; if (($Caseman::vol2start{$vol} == 0) && ($Caseman::vol2end{$vol} == 0)) { print "Offset: Full image\n"; } elsif ($Caseman::vol2end{$vol} == 0) { print "Offset: $Caseman::vol2start{$vol} to end\n"; } else { print "Offset: $Caseman::vol2start{$vol} to $Caseman::vol2end{$vol}\n"; } print "File System Type: $ftype\n"; my $date = localtime(); print "\nDate Generated: $date\n" . "Investigator: $Args::args{'inv'}\n\n" . "-" x 70 . "\n" . " META DATA INFORMATION\n\n"; Exec::exec_pipe(*OUT, "'$::TSKDIR/istat' -f $ftype $tz -s $Caseman::ts -o $offset -i $imgtype $img $meta" ); while ($_ = Exec::read_pipe_line(*OUT)) { print $_; } close(OUT); if ($recmode == $File::REC_YES) { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype -r -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" ); } else { Exec::exec_pipe(*OUT, "'$::TSKDIR/icat' -f $ftype -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" ); } my $file_type = Exec::read_pipe_line(*OUT); close(OUT); $file_type = "Error getting file type" if ((!defined $file_type) || ($file_type eq "")); print "\nFile Type: $file_type"; print "\n" . "-" x 70 . "\n" . " VERSION INFORMATION\n\n" . "Autopsy Version: $::VER\n"; print "The Sleuth Kit Version: " . ::get_tskver() . "\n"; Print::print_text_footer(); return 0; } # Display the meta Allocation Table sub list { my $ILS_GAP = 500; my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $min = 0; $min = Args::get_min() if (exists $Args::args{'min'}); my $max = $min + $ILS_GAP - 1; # Because we can not use metas 0 and 1 for most FS, set fmin to the # minimum for this fs my $fmin = $min; $fmin = $Fs::first_meta{$ftype} if ($min < $Fs::first_meta{$ftype}); Print::print_html_header( "$Fs::meta_str{$ftype} Allocation List $fmin -> $max"); Print::log_host_inv( "$Caseman::vol2sname{$vol}: $Fs::meta_str{$ftype} Allocation List for $min to $max" ); print "

$Fs::meta_str{$ftype}: $fmin - $max

"; # Display next and previous links my $tmp; if ($min > $Fs::first_meta{$ftype}) { $tmp = $min - $ILS_GAP; print "" . "\"previous\" "; } $tmp = $min + $ILS_GAP; print " " . "\"next\"
"; print "
\n"; # The list local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/ils' -e -s $Caseman::ts -f $ftype -o $offset -i $imgtype $img $fmin-$max" ); while ($_ = Exec::read_pipe_line(*OUT)) { if (/^($::REG_META)\|([af])\|\d+\|\d+\|\d+\|\d+\|\d+\|/o) { print "" . "$1: "; if ($2 eq "a") { print "allocated
\n"; } else { print "free
\n"; } } } close(OUT); # Display next and previous links print "
\n"; if ($min > $Fs::first_meta{$ftype}) { $tmp = $min - $ILS_GAP; print "" . "\"previous\" "; } $tmp = $min + $ILS_GAP; print " " . "\"next\"
"; print "
\n"; Print::print_html_footer(); return 0; } # Blank Page sub blank { Print::print_html_header("Metadata Blank Page"); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; print "

Metadata Mode


\n" . "Here you can view the details about any $Fs::meta_str{$ftype} in the file system.
\n" . "These are the data structures that store the file details.
\n" . "Enter the address in the field on the left.\n"; Print::print_html_footer(); return 0; } autopsy-2.24/lib/Notes.pm0000644000076500000240000010756711303263416014672 0ustar carrierstaff# # Notes and sequencer functions # # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2001-2005 by Brian Carrier. All rights reserved # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package Notes; use POSIX; $Notes::ENTER_FILE = 1; $Notes::ENTER_DATA = 2; $Notes::WRITE_FILE = 3; $Notes::WRITE_DATA = 4; $Notes::WRITE_SEQ_MAN = 5; $Notes::READ_NORM = 6; $Notes::READ_SEQ = 7; sub main { # There is no default for Notes Args::check_view(); Print::print_check_error("Notes option is not enabled") if ($::USE_NOTES == 0); my $view = Args::get_view(); if ($view == $Notes::ENTER_FILE) { return enter_file(); } elsif ($view == $Notes::ENTER_DATA) { return enter_data(); } elsif ($view == $Notes::WRITE_FILE) { return write_file(); } elsif ($view == $Notes::WRITE_DATA) { return write_data(); } elsif ($view == $Notes::WRITE_SEQ_MAN) { return write_seq_man(); } elsif ($view == $Notes::READ_NORM) { return read_norm(); } elsif ($view == $Notes::READ_SEQ) { return read_seq(); } else { Print::print_check_err("Invalid Notes View"); } } sub investig_notes_fname { return "$::host_dir" . "$::LOGDIR/$Args::args{'inv'}.notes"; } sub investig_seq_notes_fname { return "$::host_dir" . "$::LOGDIR/$Args::args{'inv'}.seq.notes"; } # window where user can enter a normal and sequencer note for a file # or meta data structure. sub enter_file { Args::check_vol('vol'); Args::check_meta('meta'); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $mnt = $Caseman::vol2mnt{$vol}; my $meta = Args::get_meta('meta'); # A file will have a 'dir' argument and a meta structure will not if (exists $Args::args{'dir'}) { my $fname = "$mnt$Args::args{'dir'}"; Print::print_html_header("Notes for file $fname"); print "
Enter a note for $fname ($meta):" . "

\n"; } else { Print::print_html_header("Notes for $Fs::meta_str{$ftype} $meta"); print "
Enter a note for $Fs::meta_str{$ftype} $meta:" . "

\n"; } print "A note works like a bookmark and allows you to later find this data more easily.

\n"; # Setup the form print "
\n" . "
\n" . "\n" . "\n" . "\n" . "\n" . Args::make_hidden(); print "\n" if (exists $Args::args{'dir'}); # Option to add a normal note print "\n" . " Add a Standard Note
\n"; # Sequencer notes - which requires the MAC times for the files if ("$Caseman::tz" ne "") { $ENV{TZ} = $Caseman::tz; POSIX: tzset(); } my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $meta_int = $meta; $meta_int = $1 if ($meta_int =~ /^(\d+)-\d+(-\d+)?$/); local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/ils' -s $Caseman::ts -f $ftype -e -o $offset -i $imgtype $img $meta_int" ); # Get the fourth line my $tmp = Exec::read_pipe_line(*OUT); $tmp = Exec::read_pipe_line(*OUT); $tmp = Exec::read_pipe_line(*OUT); $tmp = Exec::read_pipe_line(*OUT); close(OUT); unless ((defined $tmp) && ($tmp =~ /^$::REG_META\|\w\|\d+\|\d+\|(\d+)\|(\d+)\|(\d+)\|/o)) { Print::print_err("Error parsing 'ils' output"); } my $mtime = $1; my $atime = $2; my $ctime = $3; $mtime = localtime($mtime); $atime = localtime($atime); $ctime = localtime($ctime); # Print the Times print "

Add a Sequencer Event:

\n" . "A sequencer event will be sorted based on the time so that event reconstruction will be easier

\n" . "" . "  M-Time ($mtime)
\n" . "" . "  A-Time ($atime)
\n" . "" . "  C-Time ($ctime)


\n"; # The OK Button print "
\n
\n"; Print::print_html_footer(); return 0; } # data unit comment sub enter_data { Args::check_vol('vol'); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $block = Args::get_block(); my $len = Args::get_len(); Print::print_html_header("Notes for $Fs::addr_unit{$ftype} $block"); print "
Enter a note for $Fs::addr_unit{$ftype} $block

\n" . "A note works like a bookmark and allows you to later find this data more easily.

\n" . "
\n" . "
\n" . "\n" . "\n" . "\n" . "\n" . "\n" . "\n" . Args::make_hidden() . "
\n
\n"; Print::print_html_footer(); return 0; } # Write the note to the note file sub write_data { Args::check_vol('vol'); Args::check_block(); Args::check_len(); Args::check_note(); Print::print_html_header("Write a note"); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $img_sh = $Caseman::vol2sname{$vol}; my $block = Args::get_block(); my $len = Args::get_len(); Print::log_host_inv( "$img_sh: Creating note for $Fs::addr_unit{$ftype} $block"); my $notes_file = investig_notes_fname(); open NOTES, ">>$notes_file" or die "Can't open log: $notes_file"; print "Note added to $notes_file:

\n\n"; # Date my $tmp = localtime(); print NOTES "$tmp\n"; print "$tmp
\n"; print NOTES "Volume: $vol $Fs::addr_unit{$ftype}: $block Len: $len\n"; print "Volume: $vol $Fs::addr_unit{$ftype}: $block Len: $len
\n"; # The actual notes and a line at the bottom print NOTES "\n$Args::args{'note'}\n\n" . "-" x 70 . "\n"; print "

".Print::html_encode($Args::args{'note'})."

"; close(NOTES); print "


\n" . "You can view the notes from the Host Manager View

" . "" . "\"View\n"; Print::print_html_footer(); return 0; } sub write_file { Args::check_vol('vol'); Args::check_meta('meta'); Args::check_note(); # Get rid of carriage returns that Netscape adds $Args::args{'note'} =~ tr/\r//d; my $vol = Args::get_vol('vol'); my $mnt = $Caseman::vol2mnt{$vol}; my $ftype = $Caseman::vol2ftype{$vol}; my $img_sh = $Caseman::vol2sname{$vol}; my $meta = Args::get_meta('meta'); my $img = $Caseman::vol2path{$vol}; my $offset = $Caseman::vol2start{$vol}; my $imgtype = $Caseman::vol2itype{$vol}; my $fname = ""; my $type = ""; if (exists $Args::args{'dir'}) { $Args::args{'dir'} .= "/" if ($Args::args{'dir'} eq ""); $fname = "$mnt$Args::args{'dir'}"; if (($Args::args{'dir'} =~ /\/$/) || ($Args::args{'dir'} eq "")) { Print::log_host_inv( "$img_sh: Creating note for directory $fname ($meta)"); $type = "dir"; } else { Print::log_host_inv( "$img_sh: Creating note for file $fname ($meta)"); $type = "file"; } } else { Print::log_host_inv( "$img_sh: Creating note for $Fs::meta_str{$ftype} $meta"); $type = "$Fs::meta_str{$ftype}"; } Print::print_html_header("Writing a note / event"); # Get the times for the meta # Set the timezone to the host zone if ("$Caseman::tz" ne "") { $ENV{TZ} = "$Caseman::tz"; POSIX::tzset(); } my $meta_int = $meta; $meta_int = $1 if ($meta_int =~ /^(\d+)-\d+(-\d+)?$/); local *OUT; Exec::exec_pipe(*OUT, "'$::TSKDIR/ils' -s $Caseman::ts -f $ftype -e -o $offset -i $imgtype $img $meta_int" ); # Skip to the fourth line my $tmp = Exec::read_pipe_line(*OUT); $tmp = Exec::read_pipe_line(*OUT); $tmp = Exec::read_pipe_line(*OUT); $tmp = Exec::read_pipe_line(*OUT); unless ((defined $tmp) && ($tmp =~ /^$::REG_META\|\w\|\d+\|\d+\|(\d+)\|(\d+)\|(\d+)\|/o)) { Print::print_err("Error parsing 'ils' output"); } my $mtime = $1; my $atime = $2; my $ctime = $3; close(OUT); # Create a "normal" note if ((exists $Args::args{'norm_note'}) && ($Args::args{'norm_note'} == 1)) { my $notes_file = investig_notes_fname(); open NOTES, ">>$notes_file" or die "Can't open log: $notes_file"; print "Note added to $notes_file:

\n\n"; # Date my $tmp = localtime(); print NOTES "$tmp\n"; print "$tmp\n"; # We have a file name if ($fname ne "") { if ($type eq 'dir') { print NOTES "Directory: $fname\n"; print "Directory: $fname
\n"; } else { print NOTES "File: $fname\n"; print "File: $fname
\n"; } } if ($meta ne "") { print NOTES "Volume: $vol Meta: $meta\n"; print "Volume: $vol Meta: $meta
\n"; } print NOTES "M-time: " . localtime($mtime) . "\n"; print "M-time: " . localtime($mtime) . "
\n"; print NOTES "A-time: " . localtime($atime) . "\n"; print "A-time: " . localtime($atime) . "
\n"; print NOTES "C-time: " . localtime($ctime) . "\n"; print "C-time: " . localtime($ctime) . "
\n"; # The actual notes and a line at the bottom print NOTES "\n$Args::args{'note'}\n\n" . "-" x 70 . "\n"; print "

".Print::html_encode($Args::args{'note'})."

"; close(NOTES); } # Create a sequencer event - if there are any unless (((exists $Args::args{'mtime'}) && ($Args::args{'mtime'} == 1)) || ((exists $Args::args{'atime'}) && ($Args::args{'atime'} == 1)) || ((exists $Args::args{'ctime'}) && ($Args::args{'ctime'} == 1))) { print "


\n" . "You can view the notes from the Host Manager View

" . "" . "\"View\n"; Print::print_html_footer(); return 0; } # Get rid of the carriage returns $Args::args{'note'} =~ s/\n/
/gs; my $notes_file = investig_seq_notes_fname(); open NOTES, ">>$notes_file" or die "Can't open log: $notes_file"; if ((exists $Args::args{'mtime'}) && ($Args::args{'mtime'} == 1)) { my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($mtime); $year += 1900; $mon += 1; $mday = "0$mday" if ($mday < 10); $hour = "0$hour" if ($hour < 10); $min = "0$min" if ($min < 10); $sec = "0$sec" if ($sec < 10); print NOTES "'$year','$mon','$mday','$hour','$min','$sec'," . "'$Args::args{'host'}','$vol','$fname','$meta',''," . "'$type','[M-Time]$Args::args{'note'}'\n"; Print::log_host_inv( "$img_sh: M-Time note added for meta $Args::args{'meta'}"); print "M-Time sequence event added
\n"; } if ((exists $Args::args{'atime'}) && ($Args::args{'atime'} == 1)) { my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($atime); $year += 1900; $mon += 1; $mday = "0$mday" if ($mday < 10); $hour = "0$hour" if ($hour < 10); $min = "0$min" if ($min < 10); $sec = "0$sec" if ($sec < 10); print NOTES "'$year','$mon','$mday','$hour','$min','$sec'," . "'$Args::args{'host'}','$vol','$fname','$meta',''," . "'$type','[A-Time]$Args::args{'note'}'\n"; Print::log_host_inv( "$img_sh: A-Time note added for meta $Args::args{'meta'}"); print "A-Time sequence event added
\n"; } if ((exists $Args::args{'ctime'}) && ($Args::args{'ctime'} == 1)) { my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($ctime); $year += 1900; $mon += 1; $mday = "0$mday" if ($mday < 10); $hour = "0$hour" if ($hour < 10); $min = "0$min" if ($min < 10); $sec = "0$sec" if ($sec < 10); print NOTES "'$year','$mon','$mday','$hour','$min','$sec'," . "'$Args::args{'host'}','$vol','$fname','$meta',''," . "'$type','[C-Time]$Args::args{'note'}'\n"; Print::log_host_inv( "$img_sh: C-Time note added for meta $Args::args{'meta'}"); print "C-Time sequence event added
\n"; } close(NOTES); print "


\n" . "You can view the notes and events from the Host Manager View

"; if ((exists $Args::args{'norm_note'}) && ($Args::args{'norm_note'} == 1)) { print "" . "\"View\n"; } print "" . "\"Event\n"; Print::print_html_footer(); return 0; } # Display the contents of the "normal" notes file sub read_norm { Print::print_html_header("Contents of Notes File"); my $notes_file = investig_notes_fname(); Print::log_host_inv("Viewing contents of notes file ($notes_file)"); if ((!(-e "$notes_file")) || (-z "$notes_file")) { print "No notes have been entered yet.
\n" . "They can be entered using the Add Note link within each analysis mode.
\n"; return; } open NOTES, "<$notes_file" or die "Can't open log: $notes_file"; my $file = ""; my $dir = ""; print "\n" . "\n\n
\n"; my $row = 0; # This will need to change whenever the log format changes while () { # we need to extract mnt from here $file = $1 if (/^File: (.*)$/); $dir = $1 if (/^Directory: (.*)$/); # Reset the $file if we are at the end of the current note if (/^\-+$/) { $file = ""; $dir = ""; if (($row++ % 2) == 0) { print "
\n"; } else { print "
\n"; } } else { print Print::html_encode($_); } if (/^Volume: ($::REG_VNAME) Meta: ([0-9\-]+)/o) { $vol = $1; $meta = $2; next unless (exists $Caseman::vol2cat{$vol}); # file note if ($file ne "") { # extract the prepended mnt value my $mnt = $Caseman::vol2mnt{$vol}; my $fname = ""; $fname = $1 if ($file =~ /^$mnt\/?(.*)$/); print "" . "\"view\"
\n"; } # directory note elsif ($dir ne "") { # extract the prepended mnt value my $mnt = $Caseman::vol2mnt{$vol}; my $fname = ""; $fname = $1 if ($dir =~ /^$mnt\/?(.*)$/); print "" . "\"view\"
\n"; } # meta note else { print "" . "\"view\"
\n"; } } # block note elsif (/^Volume: ($::REG_VNAME) \w+: ([0-9]+) Len: (\d+)/o) { $vol = $1; $blk = $2; $len = $3; next unless (exists $Caseman::vol2cat{$vol}); print "" . "\"view\"
\n"; } } print "
\n"; # Ok and refresh buttons print "

\n" . "
\n" . "" . "\"close\"\n" . "\n" . "" . "\"refresh\"\n" . "
\n"; close(NOTES); Print::print_html_footer(); return 0; } ######################################################################### # Sequencer Code # Write a sequence event that was manually entered sub write_seq_man { Args::check_note(); Print::print_html_header("Writing Sequencer Event"); # Get rid of carriage returns that Netscape adds $Args::args{'note'} =~ tr/\r//d; $Args::args{'note'} =~ s/\n/
/gs; if ($Args::args{'note'} eq "") { print( "A comment must be given for the event
\n" . "

" . ""); Print::print_err("\n"); } # Check the args and add them to the final string that will be written my $str = ""; unless ((exists $Args::args{'year'}) && ($Args::args{'year'} =~ /^(\d\d\d\d)$/)) { Print::print_err("Invalid year"); } $str .= "'$1',"; unless ((exists $Args::args{'mon'}) && ($Args::args{'mon'} =~ /^(\d\d?)$/)) { Print::print_err("Invalid month"); } $str .= "'$1',"; unless ((exists $Args::args{'day'}) && ($Args::args{'day'} =~ /^(\d\d?)$/)) { Print::print_err("Invalid day"); } $str .= "'$1',"; unless ((exists $Args::args{'hour'}) && ($Args::args{'hour'} =~ /^(\d\d?)$/)) { Print::print_err("Invalid hour"); } $str .= "'$1',"; unless ((exists $Args::args{'min'}) && ($Args::args{'min'} =~ /^(\d\d?)$/)) { Print::print_err("Invalid min"); } $str .= "'$1',"; unless ((exists $Args::args{'sec'}) && ($Args::args{'sec'} =~ /^(\d\d?)$/)) { Print::print_err("Invalid sec"); } $str .= "'$1',"; # There are no image, meta, file name, or data unit for this type $str .= "'$Args::args{'host'}','','','','',"; unless ((exists $Args::args{'src'}) && ($Args::args{'src'} =~ /^(\w+)$/)) { Print::print_err("Invalid src"); } $str .= "'$1','$Args::args{'note'}'\n"; # Write the string to the notes file my $notes_file = investig_seq_notes_fname(); open NOTES, ">>$notes_file" or die "Can't open log: $notes_file"; print NOTES $str; close(NOTES); # Send a message to the user print "Event Added to Sequencer file:

\n" . "$::d2m[$Args::args{'mon'}] $Args::args{'day'}, $Args::args{'year'} " . "$Args::args{'hour'}:$Args::args{'min'}:$Args::args{'sec'}

\n" . Print::html_encode($Args::args{'note'})."
\n" . "

" . "\"Ok\"\n"; Print::print_html_footer(); return 0; } # View the sequencer file sub read_seq { Print::print_html_header("Event Sequencer"); print "

\n" . "

Event Sequencer

\n"; my $cnt = 0; my @entry; my ( @year, @mon, @day, @hour, @min, @sec, @host, @vol, @fname, @meta, @data, @type, @note ); # Read the sequencer file into arrays that will be sorted my $notes_file = investig_seq_notes_fname(); if (-e $notes_file) { open NOTES, "$notes_file" or die "Can't open log: $notes_file"; while () { unless ( /^'?(\d+)'?,'?(\d+)'?,'?(\d+)'?,'?(\d+)'?,'?(\d+)'?,'?(\d+)'?,'?($::REG_HOST)'?,'?($::REG_VNAME)?'?,'?(.*?)'?,'?($::REG_META)?'?,'?(\d+)?'?,'?([\w\s]+)'?,'?(.*?)'?$/ ) { Print::print_err("Error parsing sequence event entry: $_"); } $year[$cnt] = $1; $mon[$cnt] = $2; $day[$cnt] = $3; $hour[$cnt] = $4; $min[$cnt] = $5; $sec[$cnt] = $6; $host[$cnt] = $7; $vol[$cnt] = $8; $fname[$cnt] = ""; $fname[$cnt] = $9 if (defined $9); $meta[$cnt] = ""; $meta[$cnt] = $10 if (defined $10); $data[$cnt] = ""; $data[$cnt] = $11 if (defined $11); $type[$cnt] = $12; $note[$cnt] = $13; $entry[$cnt] = $cnt; $cnt++; } close(NOTES); # Sort the values by date, source, and then note my @sorted = sort { $year[$a] <=> $year[$b] or $mon[$a] <=> $mon[$b] or $day[$a] <=> $day[$b] or $hour[$a] <=> $hour[$b] or $min[$a] <=> $min[$b] or $sec[$a] <=> $sec[$b] or lc($type[$a]) cmp lc($type[$b]) or lc($note[$a]) cmp lc($note[$b]) } @entry; # Table and header print "\n" . "\n" . "\n" . "\n" . "\n"; # Cycle through the sorted events my $row = 0; foreach my $i (@sorted) { # Alternate row colors if (($row % 2) == 0) { print "\n"; } else { print "\n"; } # Date & Time print "" . "\n"; # Print the actual note $note[$i] = Print::html_encode($note[$i]); $note[$i] = " " if ($note[$i] eq ""); print "\n"; $row++; } print "
Date & TimeSourceEvent & Note
\n" . "$::d2m[$mon[$i]] $day[$i], $year[$i]" . " $hour[$i]:$min[$i]:$sec[$i]\n"; # If there is as name, then we will show it # @@@ Why does an error message come up from here: # Use of uninitialized value in string ne at if ($fname[$i] ne "") { if ( (exists $vol[$i]) && (defined $vol[$i]) && ($vol[$i] ne "") && (exists $Caseman::vol2mnt{$vol[$i]}) && (exists $meta[$i])) { # extract the prepended mnt value my $mnt = $Caseman::vol2mnt{$vol[$i]}; my $fname = ""; $fname = $1 if ($fname[$i] =~ /^$mnt\/?(.*)$/); # Check if it is a directory if ($type[$i] eq 'dir') { print "\n" . "$fname[$i]\n"; } else { print "\n" . "$fname[$i]\n"; } } else { print "$fname[$i]\n"; } } # Display the meta value if there was no name elsif (($vol[$i] ne "") && (defined $meta[$i]) && ($meta[$i] ne "")) { my $ftype = $Caseman::vol2ftype{$vol[$i]}; # Include a link if we can if (exists $Caseman::vol2mnt{$vol[$i]}) { print "\n" . "$Fs::meta_str{$ftype}: $meta[$i]\n"; } else { print "$Fs::meta_str{$ftype}: $meta[$i]\n"; } } # Otherwise, just give the source type else { print "$type[$i]\n"; } print "$note[$i]
\n"; } # End of if file exists else { print "No events currently exist
\n"; } # Ok and refresh buttons print "

\n" . "
\n" . "" . "\"close\"\n" . "\n" . "" . "\"refresh\"\n" . "
\n"; # Manually add a new event print "


\n" . "Add a New Event

\n" . "
\n" . "
\n" . "\n" . "\n" . Args::make_hidden(); # Month print "\n" . "\n"; # Type print "\n" . "\n"; print "
\n"; print "

Date: " . "\n"; # Day print " \n"; # Year $prev = 1900 + (localtime())[5]; $prev = $Args::args{'year'} if ((exists $Args::args{'year'}) && ($Args::args{'year'} =~ /^\d+$/)); print " \n"; # Hour print "  \n"; # Min print ":\n"; # Sec print ":

 
Event Source:
 
\n
\n"; Print::print_html_footer(); return 0; } # Conver the 'image' format to the 'volume' format sub convert { my %img2vol = %{shift()}; my @invs = Caseman::read_invest(); if (scalar @invs == 0) { push @invs, "unknown"; } foreach $i (@invs) { my $notes_file = "$::host_dir" . "$::LOGDIR/$i.notes"; if ((!(-e "$notes_file")) || (-z "$notes_file")) { next; } Print::log_host_info( "Converting format of notes file for $i ($notes_file)"); open NOTES, "<$notes_file" or die "Can't open log: $notes_file"; my $notes_file_new = $notes_file . ".new"; open NOTES_NEW, ">$notes_file_new" or die "Can't open writing log: $notes_file_new"; while () { if (/Image: ($::REG_IMG)\s+(.*)$/) { my $img = $1; my $addr = $2; unless (exists $img2vol{$img}) { print STDERR "Error finding image during notes conversion: $img. Not converting\n"; next; } my $vol = $img2vol{$img}; # Convert old description to last versions $addr =~ s/Inode:/Meta:/; print NOTES_NEW "Volume: $vol $addr\n"; } else { print NOTES_NEW $_; } } close(NOTES); close(NOTES_NEW); rename $notes_file, $notes_file . ".bak"; rename $notes_file_new, $notes_file; } # NOw do sequence notes foreach $i (@invs) { my $notes_file = "$::host_dir" . "$::LOGDIR/$i.seq.notes"; if ((!(-e "$notes_file")) || (-z "$notes_file")) { next; } open NOTES, "$notes_file" or die "Can't open log: $notes_file"; $notes_file_new = $notes_file . ".new"; open NOTES_NEW, ">$notes_file_new" or die "Can't open log for updating: $notes_file_new"; while () { # No image in entry if (/^'\d+','\d+','\d+','\d+','\d+','\d+','$::REG_HOST','','/) { print NOTES_NEW $_; } elsif ( /^('\d+','\d+','\d+','\d+','\d+','\d+','$::REG_HOST',')($::REG_IMG)(','.*)$/ ) { my $pre = $1; my $img = $2; my $post = $3; unless (exists $img2vol{$img}) { print STDERR "Error finding image during notes conversion: $img. Not converting\n"; next; } my $vol = $img2vol{$img}; print NOTES_NEW $pre . $vol . $post . "\n"; } else { print NOTES_NEW "$_"; return; } } close(NOTES); close(NOTES_NEW); rename $notes_file, $notes_file . ".bak"; rename $notes_file_new, $notes_file; } return 0; } autopsy-2.24/lib/Print.pm0000644000076500000240000002510011316755454014670 0ustar carrierstaffpackage Print; # # Utilities to print information # # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2001-2005 by Brian Carrier. All rights reserved # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Escape HTML entities # Converts \n to
\n sub html_encode { my $text = shift; $text =~ s/&/&/gs; $text =~ s//>/gs; $text =~ s/\"/"/gs; $text =~ s/\n/
\n/gs; # @@@ LEADING SPACES and TABS # while ($text =~ s/^( )*\t/"$1    "/eig) {} # while ($text =~ s/^( )* /"$1 "/eig) {} return $text; } # remove control chars from printout # this does not escape HTML entities, so you can pass this HTML code sub print_output { my $out = shift; print "$out"; while (my $out = shift) { foreach $_ (split(//, $out)) { if ( ($_ eq "\n") || ($_ eq "\r") || ($_ eq "\f") || ($_ eq "\t")) { print "$_"; } elsif ((ord($_) < 0x20) && (ord($_) >= 0x00)) { print "^" . ord($_); } else { print "$_"; } } } } # Added to provide output in hexdump format # function gets called on a per-icat basis, # The offset value is the byte offset that this data # starts at, since the File.pm code calls it in 1024 # byte chunks) sub print_hexdump { my $out = shift; # data to output my $offset = shift; # starting byte offset in file my $buf = ""; foreach $i (split(//, $out)) { my $idx = $offset % 16; if ($idx == 0) { printf("%08X: ", $offset); } printf("%02X", ord($i)); if (($idx % 2) == 1) { printf(" "); } $buf[$idx] = $i; if ($idx == 15) { print " "; for (my $j = 0; $j < 16; $j++) { if ($buf[$j] =~ m/[ -~]/) { print $buf[$j]; } else { print "."; } $buf[$j] = 0; } print "\n"; } $offset++; } # print out last line if < 16 bytes long my $l = $offset % 16; if ($l) { my $t = (16 - $l) * 2 + (16 - $l) / 2; for (my $j = 0; $j < $t; $j++) { print " "; } print " "; for (my $j = 0; $j < $l; $j++) { if ($buf[$j] =~ m/[ -~]/) { print $buf[$j]; } else { print "."; } } print "\n"; } } ############################################ # # HTTP/HTML Headers and Footers # The page that makes the frameset does not have a body statement # This routine is used to make the minimum required header statements sub print_html_header_frameset { my $text = shift; print "Content-Type: text/html; charset=utf-8$::HTTP_NL$::HTTP_NL"; my $time = localtime(); print < $text EOF } sub print_html_footer_frameset { print "\n\n" . "$::HTTP_NL$::HTTP_NL"; } # Create the header information with the body tag sub print_html_header { print_html_header_frameset(shift); print "\n\n"; print "\n"; } sub print_html_footer { print "\n\n\n" . "$::HTTP_NL$::HTTP_NL"; } # Print the header with the margins set to 0 so that the tab buttons # are flush with the edges of the frame sub print_html_header_tabs { print_html_header_frameset(shift); print "\n\n"; print "\n"; $is_body = 1; } sub print_html_footer_tabs { print "\n\n\n" . "$::HTTP_NL$::HTTP_NL"; } # Header for front page to warn about java script sub print_html_header_javascript { my $text = shift; print "Content-Type: text/html; charset=utf-8$::HTTP_NL$::HTTP_NL"; my $time = localtime(); # The write line has to stay on one line print < $text EOF } sub print_html_footer_javascript { print "\n\n\n" . "$::HTTP_NL$::HTTP_NL"; } # For raw text outputs (Pass the name of a file if it is being saved) sub print_text_header { print "Content-Type: text/plain; charset=utf-8$::HTTP_NL"; if (scalar @_ > 0) { my $fname = shift(); print "Content-Disposition: inline; " . "filename=$fname;$::HTTP_NL"; } print "$::HTTP_NL"; } sub print_text_footer { print "$::HTTP_NL$::HTTP_NL"; } # For forced save outputs sub print_oct_header { print "Content-Type: application/octet-stream$::HTTP_NL"; if (scalar @_ > 0) { my $fname = shift(); print "Content-Disposition: inline; " . "filename=$fname;$::HTTP_NL"; } print "$::HTTP_NL"; } sub print_oct_footer { } # Error message that is used when an HTTP/HTML header is needed # This escapes the characters that chould be HTML entities. # it will also replace \n with
and other things that html_encode() # can do. Do not send arbitrary HTML to this function. sub print_check_err { print_html_header(""); print html_encode(shift()) . "
\n"; print_html_footer(); sleep(1); exit 1; } # Error message when header already exists # This escapes the characters that chould be HTML entities. # it will also replace \n with
and other things that html_encode() # can do. Do not send arbitrary HTML to this function. sub print_err { print html_encode(shift()) . "
\n"; sleep(1); print_html_footer(); exit 1; } ################################################################## # # Logging # # sub investig_log_fname { return "" unless (defined $::host_dir && $::host_dir ne ""); return "" unless (exists $Args::args{'inv'} && $Args::args{'inv'} ne ""); return "$::host_dir" . "$::LOGDIR/$Args::args{'inv'}.log"; } sub investig_exec_log_fname { return "" unless (defined $::host_dir && $::host_dir ne ""); return "" unless (exists $Args::args{'inv'} && $Args::args{'inv'} ne ""); return "$::host_dir" . "$::LOGDIR/$Args::args{'inv'}.exec.log"; } sub host_log_fname { return "" unless (defined $::host_dir && $::host_dir ne ""); return "$::host_dir" . "$::LOGDIR/host.log"; } sub case_log_fname { return "" unless (defined $::case_dir && $::case_dir ne ""); return "$::case_dir" . "case.log"; } # Log data to the investigators specific log file sub log_host_inv { return unless ($::USE_LOG == 1); my $str = shift; chomp $str; my $date = localtime; my $fname = investig_log_fname(); return if ($fname eq ""); open HOSTLOG, ">>$fname" or die "Can't open log: $fname"; print HOSTLOG "$date: $str\n"; close(HOSTLOG); return; } sub log_host_inv_exec { return unless ($::USE_LOG == 1); my $str = shift; chomp $str; my $date = localtime; my $fname = investig_exec_log_fname(); return if ($fname eq ""); open HOSTLOG, ">>$fname" or die "Can't open log: $fname"; print HOSTLOG "$date: $str\n"; close(HOSTLOG); return; } # log data to the general log file for the host sub log_host_info { return unless ($::USE_LOG == 1); my $str = shift; chomp $str; my $date = localtime; my $fname = host_log_fname(); return if ($fname eq ""); open HOSTLOG, ">>$fname" or die "Can't open log: $fname"; print HOSTLOG "$date: $str\n"; close(HOSTLOG); return; } sub log_case_info { return unless ($::USE_LOG == 1); my $str = shift; chomp $str; my $date = localtime; my $fname = case_log_fname(); return if ($fname eq ""); open CASELOG, ">>$fname" or die "Can't open log: $fname"; print CASELOG "$date: $str\n"; close(CASELOG); return; } sub log_session_info { return unless ($::USE_LOG == 1); my $str = shift; chomp $str; my $date = localtime; my $lname = "autopsy.log"; open AUTLOG, ">>$::LOCKDIR/$lname" or die "Can't open log: $lname"; print AUTLOG "$date: $str\n"; close(AUTLOG); return; } 1; autopsy-2.24/lib/search.pl0000644000076500000240000000327511070040246015030 0ustar carrierstaff# # This file contains pre-defined search strings. A button for each will # be displayed in the Search Mode. # # The $auto_srch{} hash is filled in with the search string # The index into the hash is the name of the search. # # For example, $auto_srch{'foo'} = "bar"; would search for the string # bar # # If the search is case sensitive, then set $auto_srch_csense to 1 (this # is the default value if not specified. Set to 0 for insensitive # # If the search is a regular expression, set $auto_srch_reg to 1, else # 0 (the default) # # # If you develop patterns that you think will be useful to others, email # them to me and I will include them in the next version (carrier@sleuthkit.org) # # Date / syslog search of month and date $auto_srch{'Date'} = "((jan)|(feb)|(mar)|(apr)|(may)|(june?)|(july?)|(aug)|(sept?)|(oct)|(nov)|(dec))([[:space:]]+[[:digit:]])?"; $auto_srch_reg{'Date'} = 1; $auto_srch_csense{'Date'} = 0; # IP Address $auto_srch{'IP'} = '[0-2]?[[:digit:]]{1,2}\.[0-2]?[[:digit:]]{1,2}\.[0-2]?[[:digit:]]{1,2}\.[0-2]?[[:digit:]]{1,2}'; $auto_srch_reg{'IP'} = 1; $auto_srch_csense{'IP'} = 0; # SSN in the pattern of 123-12-1234 - from Jerry Shenk $auto_srch{'SSN1'} = '[0-9][0-9][0-9]\-[0-9]]0-9]\-[0-9][0-9][0-9][0-9]'; $auto_srch_reg{'SSN1'} = 1; $auto_srch_csense{'SSN1'} = 0; # SSN in the pattern of 123121234 - from Jerry Shenk $auto_srch{'SSN2'} = '[0-9][0-9][0-9][0-9]]0-9][0-9][0-9][0-9][0-9]'; $auto_srch_reg{'SSN2'} = 1; $auto_srch_csense{'SSN2'} = 0; # CC # - from Jerry Shenk $auto_srch{'CC'} = '[0-9][0-9][0-9][0-9]]0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]]0-9]'; $auto_srch_reg{'CC'} = 1; $auto_srch_csense{'CC'} = 0; # This must be the last value 1; autopsy-2.24/lib/Timeline.pm0000644000076500000240000013346111070040246015333 0ustar carrierstaff# # Timeline functions # # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2001-2005 by Brian Carrier. All rights reserved # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package Timeline; use POSIX; # needed for tzset # Changing the order of this may affect the main function ordering $Timeline::BLANK = 0; $Timeline::FRAME = 1; $Timeline::TABS = 2; $Timeline::BODY_ENTER = 3; $Timeline::BODY_RUN = 4; $Timeline::TL_ENTER = 5; $Timeline::TL_RUN = 6; $Timeline::VIEW_FR = 7; $Timeline::VIEW_MENU = 8; $Timeline::VIEW_IDX = 9; $Timeline::VIEW_SUM = 10; $Timeline::VIEW = 11; # Types of modes for fname (i.e. can we overwrite it if it exists) my $FNAME_MODE_INIT = 0; my $FNAME_MODE_OVER = 1; sub main { return if ($::LIVE == 1); # By default, show the main frame $Args::args{'view'} = $Args::enc_args{'view'} = $Timeline::FRAME unless (exists $Args::args{'view'}); Args::check_view(); my $view = Args::get_view(); if ($view < $Timeline::VIEW_FR) { if ($view == $Timeline::BLANK) { return blank(); } elsif ($view == $Timeline::FRAME) { return frame(); } elsif ($view == $Timeline::TABS) { return tabs(); } elsif ($view == $Timeline::BODY_ENTER) { return body_enter(); } elsif ($view == $Timeline::BODY_RUN) { return body_run(); } elsif ($view == $Timeline::TL_ENTER) { return tl_enter(); } elsif ($view == $Timeline::TL_RUN) { return tl_run(); } } else { if ($view == $Timeline::VIEW_FR) { return view_fr(); } elsif ($view == $Timeline::VIEW_MENU) { return view_menu(); } elsif ($view == $Timeline::VIEW_IDX) { return view_idx(); } elsif ($view == $Timeline::VIEW_SUM) { return view_sum(); } elsif ($view == $Timeline::VIEW) { return view(); } } Print::print_check_err("Invalid Timeline View"); } # Call the appropriate function based on the value of sort sub frame { Print::print_html_header_frameset( "Timeline: $Args::args{'case'}:$Args::args{'host'}"); print "\n"; my $submod = $Timeline::BLANK; $submod = Args::get_submod() if (exists $Args::args{'submod'}); # Listing print "\n"; my $str = ""; # Contents if ($submod == $Timeline::BLANK) { print "\n\n"; return; } elsif ($submod == $Timeline::TL_ENTER) { $str .= "&body=$Args::args{'body'}" if (exists $Args::args{'body'}); } elsif ($submod == $Timeline::VIEW_FR) { $str .= "&tl=$Args::args{'tl'}" if (exists $Args::args{'tl'}); } print "\n\n"; Print::print_html_footer_frameset(); return 0; } # The tabs / button images in timeline view sub tabs { Args::check_submod(); Print::print_html_header_tabs("Timeline Mode Tabs"); my $submod = Args::get_submod(); print "
\n"; # Create Datafile print "\n" . "\n" . "\n" . "\n"; } else { print "\n"; } # Help - set to current submod print "\n"; # Close print "\n" . "
" . ""; if ($submod == $Timeline::BODY_ENTER) { print "\n"; } else { print "\n"; } print "" . ""; # Create Timeline if ($submod == $Timeline::TL_ENTER) { print "\n"; } else { print "\n"; } print "" . ""; # View Timeline if (($submod == $Timeline::VIEW_FR) || ($submod == $Timeline::VIEW_MENU)) { print "\n"; } else { print "\n"; } # Notes print ""; if ($::USE_NOTES == 1) { print "" . "" . "" . "" . "" . "
\n"; Print::print_html_footer_tabs(); return 0; } sub body_enter { Print::print_html_header("Enter Data to Make Body File"); my $i; my %mnt2img; # Cycle through each image we read from fsmorgue foreach $i (keys %Caseman::vol2mnt) { next unless ($Caseman::vol2cat{$i} eq "part"); next if ( ($Caseman::vol2ftype{$i} eq "swap") || ($Caseman::vol2ftype{$i} eq "raw")); $mnt2vol{"$Caseman::vol2mnt{$i}--$i"} = $i; } # sort via parent volume, then starting location, and then mount point (which includes the name) my @mnt = sort { ($Caseman::vol2par{$mnt2vol{$a}} cmp $Caseman::vol2par{$mnt2vol{$b}}) or ($Caseman::vol2start{$mnt2vol{$a}} <=> $Caseman::vol2start{$mnt2vol{$b}}) or (lc($a) cmp lc($b)) } keys %mnt2vol; print "
\n" . "\n" . "\n" . Args::make_hidden() . "

Here we will process the file system images, collect the temporal data, and save the data to a single file." . "

1. Select one or more of the following images to collect data from:\n" . ""; for (my $i = 0; $i <= $#mnt; $i++) { my $vol = $mnt2vol{$mnt[$i]}; print "" . "\n"; } print "
" . "$Caseman::vol2mnt{$vol}$Caseman::vol2sname{$vol}$Caseman::vol2ftype{$vol}

2. Select the data types to gather:
\n" . "" . "" . "" . "
" . "Allocated Files" . "Unallocated Files
\n" . "

3. Enter name of output file (body):
" . "$::DATADIR/" . "\n" . "\n" . "

4. Generate MD5 Value? " . ""; print "

\n"; Print::print_html_footer(); return 0; } sub body_run { Args::check_fname(); Args::check_fname_mode(); Print::print_html_header("Make Body File"); my $fname_rel = Args::get_fname_rel(); my $fname = Args::get_fname(); my $fname_mode = $Args::args{'fname_mode'}; if ((-e "$fname") && ($FNAME_MODE_INIT == $fname_mode)) { print "File Already Exists: $fname_rel\n"; my $hidden = Args::make_hidden(); $hidden .= "\n" . "\n"; my $i; foreach $i (%Caseman::vol2mnt) { $hidden .= "\n" if (exists $Args::args{$i}); } $hidden .= "\n" if (exists $Args::args{'al_file'}); $hidden .= "\n" if (exists $Args::args{'unal_file'}); $hidden .= "\n" if (exists $Args::args{'md5'}); # Make a new name print "
\n" . "New Name: " . "\n"; # Overwrite it print "
" . "\n" . "$hidden" . "\n" . "
\n" . "
\n" . "\n" . "\n" . "$hidden" . "
"; return 0; } # we will be appending to the file so we should del it now if (-e "$fname") { unlink($fname); } my $log_files = ""; my $log_type = ""; # What kind of data are we collecting? my $al_file = 0; if (exists $Args::args{'al_file'}) { $al_file = $Args::args{'al_file'}; $log_type .= "Allocated Files"; } my $unal_file = 0; if (exists $Args::args{'unal_file'}) { $unal_file = $Args::args{'unal_file'}; $log_type .= ", " if ($log_type ne ""); $log_type .= "Unallocated Files"; } if (($unal_file == 0) && ($al_file == 0)) { print "No data types were selected. You must select at least one.
\n"; return 1; } my $tz = ""; $tz = "-z '$Caseman::tz'" unless ("$Caseman::tz" eq ""); my $i; my $found = 0; local *OUT; # Analyze each image - the image names are passed as an argument foreach $i (keys %Caseman::vol2mnt) { if (exists $Args::args{$i}) { $found = 1; my $ftype = $Caseman::vol2ftype{$i}; my $img = $Caseman::vol2path{$i}; my $offset = $Caseman::vol2start{$i}; my $imgtype = $Caseman::vol2itype{$i}; my $mnt = $Caseman::vol2mnt{$i}; $log_files .= ", " if ($log_files ne ""); $log_files .= "$i"; if (($al_file) && ($unal_file)) { print "Running fls -r -m on $i
\n"; Exec::exec_pipe(*OUT, "'$::TSKDIR/fls' $tz -s $Caseman::ts -m '$mnt' -f $ftype -r -o $offset -i $imgtype $img >> '$fname'" ); print "$_
\n" while ($_ = Exec::read_pipe_line(*OUT)); close(OUT); } elsif ($al_file) { print "Running fls -ru -m on $i
\n"; Exec::exec_pipe(*OUT, "'$::TSKDIR/fls' $tz -s $Caseman::ts -m '$mnt' -f $ftype -ru -o $offset -i $imgtype $img >> '$fname'" ); print "$_
\n" while ($_ = Exec::read_pipe_line(*OUT)); close(OUT); } elsif ($unal_file) { print "Running fls -rd -m on $i
\n"; Exec::exec_pipe(*OUT, "'$::TSKDIR/fls' $tz -s $Caseman::ts -m '$mnt' -f $ftype -rd -o $offset -i $imgtype $img >> '$fname'" ); print "$_
\n" while ($_ = Exec::read_pipe_line(*OUT)); close(OUT); } } } unless ($found) { print "No images were given for analysis. At least one must be selected.
\n"; return 1; } Print::log_host_inv( "Saving timeline data for $log_type for $log_files to $fname_rel"); # append to host config my $bod_vol = Caseman::add_vol_host_config("body", $fname_rel); $Caseman::vol2cat{$bod_vol} = "timeline"; $Caseman::vol2ftype{$bod_vol} = "body"; $Caseman::vol2itype{$bod_vol} = "raw"; $Caseman::vol2path{$bod_vol} = $fname; $Caseman::vol2start{$bod_vol} = 0; $Caseman::vol2end{$bod_vol} = 0; $Caseman::vol2sname{$bod_vol} = $fname_rel; print "
Body file saved to $fname

\n" . "Entry added to host config file

\n"; # Calculate MD5 if ((exists $Args::args{'md5'}) && ($Args::args{'md5'} == 1)) { print "Calculating MD5 Value

\n"; my $m = Hash::int_create_wrap($bod_vol); print "MD5 Value: $m

\n"; } print "

The next step is to sort the data into a timeline." . "

\n" . "\n" . "\n" . "\n" . "\n" . Args::make_hidden() . "\n
\n"; Print::print_html_footer(); return 0; } my $OTYPE_NORM = 1; my $OTYPE_HOURLY = 2; my $OTYPE_DAILY = 3; sub tl_enter { Print::print_html_header("Enter data for timeline"); my @body; # Find the body files if we will be looking for them unless ((exists $Args::args{'body'}) && (exists $Caseman::vol2cat{$Args::args{'body'}})) { foreach my $k (keys %Caseman::vol2cat) { if ( ($Caseman::vol2cat{$k} eq "timeline") && ($Caseman::vol2ftype{$k} eq "body")) { push @body, $k; } } if (scalar(@body) == 0) { print "There are currently no body files " . "for this host.
You must create the intermediate " . "data file before you can perform this step
\n" . "

" . "\"Ok\"" . "\n"; return 1; } } print "Now we will sort the data and save it to a timeline.

\n" . "

\n" . "\n" . "\n" . Args::make_hidden() . "1. Select the data input file (body):\n" . ""; # if the body file was specified then just print it if (exists $Args::args{'body'}) { print "\n"; } else { my @body_sort = sort { lc($a) cmp lc($b) } @body; my $chk = " CHECKED"; for (my $i = 0; $i <= $#body_sort; $i++) { print "\n"; $chk = ""; } } my $cur_mon = 1 + (localtime())[4]; my $cur_year = 1900 + (localtime())[5]; # STARTING DATE print "
" . "$Caseman::vol2sname{$Args::args{'body'}}
$Caseman::vol2sname{$body_sort[$i]}
\n" . "

2. Enter the starting date:
\n" . "None:
" . "Specify: " . "" . "" . "\n"; # END DATE print "

3. Enter the ending date:
\n" . "None:
\n" . "Specify: \n" . "\n" . "" . "\n"; # FILE NAME print "

4. Enter the file name to save as:
" . "$::DATADIR/
\n" . "\n"; # Get only the UNIX images - since only they have /etc/passwd and group my @unix_imgs; my $root_vol = ""; foreach my $i (keys %Caseman::vol2ftype) { my $f = $Caseman::vol2ftype{$i}; next unless (($f =~ /^ext/) || ($f =~ /^ufs/) || ($f =~ /^linux/) || ($f =~ /bsd$/) || ($f =~ /^solaris$/) || ($f =~ /^bsdi$/)); push @unix_vols, $i; # Keep a reference to an image with '/' as the mounting point $root_vol = $i if ($Caseman::vol2mnt{$i} eq '/'); } my $cnt = 5; if (scalar @unix_vols > 0) { print "

$cnt. Select the UNIX image that contains the /etc/passwd and /etc/group files:
\n"; $cnt++; print "\n"; } print "

$cnt. Choose the output format:
\n"; $cnt++; print "  Tabulated (normal)
\n" . "  Comma delimited with hourly summary
\n" . "  Comma delimited with daily summary
\n"; print "

$cnt. Generate MD5 Value? "; $cnt++; print "\n"; # Create Button print "

\n

\n"; Print::print_html_footer(); return 0; } sub tl_run { Args::check_fname(); Args::check_body(); Args::check_sort(); Print::print_html_header("Make Timeline"); my $body = Args::get_body(); my $fname = Args::get_fname(); my $fname_rel = Args::get_fname_rel(); my $otype = Args::get_sort(); my $fname_mode = $Args::args{'fname_mode'}; if ((-e "$fname") && ($FNAME_MODE_INIT == $fname_mode)) { print "File Already Exists: $fname_rel
\n"; my $hidden = "" . Args::make_hidden(); $hidden .= "\n" if (exists $Args::args{'st_none'}); $hidden .= "\n" if (exists $Args::args{'st_year'}); $hidden .= "\n" if (exists $Args::args{'st_day'}); $hidden .= "\n" if (exists $Args::args{'st_mon'}); $hidden .= "\n" if (exists $Args::args{'end_none'}); $hidden .= "\n" if (exists $Args::args{'end_year'}); $hidden .= "\n" if (exists $Args::args{'end_day'}); $hidden .= "\n" if (exists $Args::args{'end_mon'}); $hidden .= "\n" if (exists $Args::args{'tz'}); $hidden .= "\n" if (exists $Args::args{'pw_vol'}); $hidden .= "\n" if (exists $Args::args{'md5'}); $hidden .= "\n" if (exists $Args::args{'sort'}); # Make a new name print "
\n" . "New Name: " . "\n"; # Overwrite it print "
" . "\n" . "\n" . "\n" . "$hidden\n" . "\n" . "
\n" . "
\n" . "\n" . "\n" . "\n" . "\n" . "$hidden\n" . "
"; return 0; } my $mon; my $day; my $year; my $date = ""; # Get the start date unless ((exists $Args::args{'st_none'}) && ($Args::args{'st_none'} == 1)) { if (exists $Args::args{'st_mon'}) { Args::check_st_mon(); $mon = Args::get_st_mon(); if (($mon < 1) || ($mon > 12)) { print("Invalid starting month\n"); return 1; } if ($mon < 10) { $mon = "0" . $mon; } } if (exists $Args::args{'st_year'}) { Args::check_st_year(); $year = Args::get_st_year(); if (($year < 1970) || ($year > 2020)) { print("Invalid starting year\n"); return 1; } } if ( (exists $Args::args{'st_day'}) && ($Args::args{'st_day'} =~ /^(\d\d?)$/)) { $day = $1; if (($day < 1) || ($day > 31)) { print("Invalid starting day\n"); return 1; } if ($day < 10) { $day = "0" . $day; } } else { print("Invalid start day\n"); return 1; } $date = "$year-$mon-$day"; } unless ((exists $Args::args{'end_none'}) && ($Args::args{'end_none'} == 1)) { if ($date eq "") { print "Begin date must be given if ending date is given
"; return 1; } if ( (exists $Args::args{'end_mon'}) && ($Args::args{'end_mon'} =~ /^(\d\d?)$/)) { $mon = $1; if (($mon < 1) || ($mon > 12)) { print("Invalid end month\n"); return 1; } if ($mon < 10) { $mon = "0" . $mon; } } else { print("Invalid end month\n"); return 1; } if ( (exists $Args::args{'end_year'}) && ($Args::args{'end_year'} =~ /^(\d\d\d\d)$/)) { $year = $1; if (($year < 1970) || ($year > 2020)) { print("Invalid ending year\n"); return 1; } } else { print("Invalid end year\n"); return 1; } if ( (exists $Args::args{'end_day'}) && ($Args::args{'end_day'} =~ /^(\d\d?)$/)) { $day = $1; if (($day < 1) || ($day > 31)) { print("Invalid end day\n"); return 1; } if ($day < 10) { $day = "0" . $day; } } else { print("Invalid end day\n"); return 1; } $date .= "..$year-$mon-$day"; } # temp strings for the password and group files my $pw_tmp = ""; my $gr_tmp = ""; my $mac_args = ""; my $log = ""; local *OUT; # Password and Group Files if ((exists $Args::args{'pw_vol'}) && ($Args::args{'pw_vol'} ne "")) { Args::check_vol('pw_vol'); my $pw_vol = Args::get_vol('pw_vol'); my $ftype = $Caseman::vol2ftype{$pw_vol}; my $img = $Caseman::vol2path{$pw_vol}; my $offset = $Caseman::vol2start{$pw_vol}; my $imgtype = $Caseman::vol2itype{$pw_vol}; $log .= "Password & Group File ($pw_vol) "; # Get the passwd file meta and copy the file Exec::exec_pipe(*OUT, "'$::TSKDIR/ifind' -f $ftype -n 'etc/passwd' -o $offset -i $imgtype $img" ); my $pwi = Exec::read_pipe_line(*OUT); close(OUT); $pwi = "Error getting meta for passwd" if ((!defined $pwi) || ($pwi eq "")); # Do the Taint Checking if ($pwi =~ /^($::REG_META)$/) { $pwi = $1; $log .= "Password Meta Address ($pwi) "; # Find a temp name that we can call it my $i; for ($i = 0;; $i++) { unless (-e "$fname.pw-$i") { $pw_tmp = "$fname.pw-$i"; last; } } Exec::exec_sys( "'$::TSKDIR/icat' -f $ftype -o $offset -i $imgtype $img $pwi > '$pw_tmp'" ); $mac_args .= " -p \'$pw_tmp\' "; } else { print( "Error finding /etc/passwd meta in $Caseman::vol2sname{$pw_vol} ($pwi)
" ); Print::log_host_inv( "$Caseman::vol2sname{$pw_vol}: /etc/passwd file not found for timeline" ); } # Get the group file meta and copy the file Exec::exec_pipe(*OUT, "'$::TSKDIR/ifind' -f $ftype -n 'etc/group' -o $offset -i $imgtype $img" ); my $gri = Exec::read_pipe_line(*OUT); close(OUT); $gri = "Error getting meta for group" if ((!defined $gri) || ($gri eq "")); # Do the Taint Checking if ($gri =~ /^($::REG_META)$/) { $gri = $1; $log .= "Group Meta Address ($gri) "; # Find a temp name that we can call it my $i; for ($i = 0;; $i++) { unless (-e "$fname.gr-$i") { $gr_tmp = "$fname.gr-$i"; last; } } Exec::exec_sys( "'$::TSKDIR/icat' -f $ftype -o $offset -i $imgtype $img $gri > '$gr_tmp'" ); $mac_args .= " -g \'$gr_tmp\' "; } else { print( "Error finding /etc/group meta in $Caseman::vol2sname{$pw_vol} ($gri)
" ); Print::log_host_inv( "$Caseman::vol2sname{$pw_vol}: /etc/group file not found for timeline" ); } } if ($date eq "") { print "Creating Timeline using all dates (Time Zone: $Caseman::tz)
\n"; Print::log_host_inv( "$Caseman::vol2sname{$body}: Creating timeline using all dates (TZ: $Caseman::tz) ${log}to $fname_rel" ); } else { print "Creating Timeline for $date (Time Zone: $Caseman::tz)
\n"; Print::log_host_inv( "$Caseman::vol2sname{$body}: Creating timeline for $date (TZ: $Caseman::tz) ${log}to $fname_rel" ); } my $tz = ""; $tz = "-z '$Caseman::tz'" unless ("$Caseman::tz" eq ""); # mactime needs the path to run the 'date' command $ENV{PATH} = "/bin:/usr/bin"; local *OUT; if ($otype == $OTYPE_NORM) { Exec::exec_pipe(*OUT, "LANG=C LC_ALL=C '$::TSKDIR/mactime' -b $Caseman::vol2path{$body} $tz -i day '${fname}.sum' $mac_args $date > '$fname'" ); } elsif ($otype == $OTYPE_HOURLY) { Exec::exec_pipe(*OUT, "LANG=C LC_ALL=C '$::TSKDIR/mactime' -b $Caseman::vol2path{$body} $tz -d -i hour '${fname}.sum' $mac_args $date > '$fname'" ); } elsif ($otype == $OTYPE_DAILY) { Exec::exec_pipe(*OUT, "LANG=C LC_ALL=C '$::TSKDIR/mactime' -b $Caseman::vol2path{$body} $tz -d -i day '${fname}.sum' $mac_args $date > '$fname'" ); } else { Print::print_err("Unknown output type"); } print "$_
\n" while ($_ = Exec::read_pipe_line(*OUT)); close(OUT); $ENV{PATH} = ""; # Remove the password and group files unlink("$pw_tmp") if ($pw_tmp ne ""); unlink("$gr_tmp") if ($gr_tmp ne ""); print "
Timeline saved to $fname

\n"; # append to fsmorgue if a normal timeline if ($otype == $OTYPE_NORM) { my $tl_vol = Caseman::add_vol_host_config("timeline", $fname_rel); print "Entry added to host config file

\n"; $Caseman::vol2cat{$tl_vol} = "timeline"; $Caseman::vol2ftype{$tl_vol} = "timeline"; $Caseman::vol2itype{$tl_vol} = "raw"; $Caseman::vol2path{$tl_vol} = "$fname"; $Caseman::vol2start{$tl_vol} = 0; $Caseman::vol2end{$tl_vol} = 0; $Caseman::vol2sname{$tl_vol} = $fname_rel; # Calculate MD5 if ((exists $Args::args{'md5'}) && ($Args::args{'md5'} == 1)) { print "Calculating MD5 Value

\n"; my $m = Hash::int_create_wrap($tl_vol); print "MD5 Value: $m

\n"; } print "
\n" . "\n" . "\n" . "\n" . "\n" . Args::make_hidden() . "\n
\n" . "(NOTE: It is easier to view the timeline in a text editor than here)"; } else { print "Comma delimited files cannot be viewed from within Autopsy.
\n" . "Open it in a spreadsheet or other data processing tool.
\n"; } Print::print_html_footer(); return 0; } sub view_menu { Print::print_html_header("View Timeline Menu"); my @tl; # Find the timelines in the images hash foreach my $k (keys %Caseman::vol2cat) { if ( ($Caseman::vol2cat{$k} eq "timeline") && ($Caseman::vol2ftype{$k} eq "timeline")) { push @tl, $k; } } if (scalar(@tl) == 0) { print "There are currently no timeline files in the " . "host config file.
One must first be created before you " . "can view it
\n"; print "

" . "\"Ok\"" . "\n"; return 1; } print "

\n" . "\n" . "\n" . Args::make_hidden() . "1. Select the timeline file:\n" . "\n"; my @tl_sort = sort { lc($a) cmp lc($b) } @tl; for (my $i = 0; $i <= $#tl_sort; $i++) { print "\n"; } print "
$Caseman::vol2sname{$tl_sort[$i]}
\n" . "\n
\n"; Print::print_html_footer(); return 0; } sub view_fr { Args::check_tl(); Print::print_html_header_frameset(""); my $tl_vol = Args::get_tl(); my $tl = $Caseman::vol2path{$tl_vol}; my $url = ""; unless (exists $Args::args{'st_mon'}) { unless (open(TL, $tl)) { print("Error opening $tl"); return (1); } my $beg_mon; my $beg_year; my $cnt = 0; while () { $cnt++; if (/^(?:\w\w\w )?(\w\w\w)\s+\d\d\s+(\d\d\d\d)\s+\d\d:\d\d:\d\d/) { $url = "tl=$tl_vol&st_mon=$::m2d{$1}&st_year=$2"; } last; } close(TL); if ($cnt == 0) { print "Empty timeline
\n"; return 1; } if ($url eq "") { print "Invalid Timeline
\n"; return 1; } } else { $url = "tl=$tl_vol&st_mon=$Args::enc_args{'st_mon'}&" . "st_year=$Args::enc_args{'st_year'}"; } print "\n" . "\n" . "\n"; Print::print_html_footer(); return 0; } sub view_idx { Args::check_st_mon(); Args::check_st_year(); Args::check_tl(); Print::print_html_header("View Timeline Index"); my $mon = Args::get_st_mon(); my $year = Args::get_st_year(); my $tl_vol = Args::get_tl(); my $tl = $Caseman::vol2path{$tl_vol}; print "
"; my $url = "$::PROGNAME?$Args::baseargs&mod=$::MOD_TL&view=$Timeline::VIEW_FR&" . "tl=$tl_vol"; # Next and Previous pointers my $pyear = $year; my $pmon = $mon - 1; if ($pmon == 0) { $pmon = 12; $pyear--; } print "\n" . "\n" . "\n"; if (-e "${tl}.sum") { print "\n" . "\n"; } my $nyear = $year; my $nmon = $mon + 1; if ($nmon == 13) { $nmon = 1; $nyear++; } print "
" . "" . "<- $::d2m[$pmon] $pyear " . "Summary " . "" . "$::d2m[$nmon] $nyear ->
\n"; # Make a form to enter the next month and year to show. # it defaults to the current location print "
\n" . "\n" . "\n" . "\n" . Args::make_hidden() . "\n" . "" . "" . "\n" . "
" . "" . "" . "
\n"; Print::print_html_footer(); return 0; } # Display the contents of the summary file (hits per day) and show # it as hits per month sub view_sum { Args::check_tl(); Print::print_html_header("View Timeline Summary"); my $tl_vol = Args::get_tl(); my $tl = $Caseman::vol2path{$tl_vol}; $tl .= ".sum"; open(TL, "<$tl") or die "Can not open $tl"; my $url = "$::PROGNAME?$Args::baseargs&mod=$::MOD_TL&" . "view=$Timeline::VIEW_FR&tl=$tl_vol"; print "

This page provides a monthly summary of activity.
" . "Each day that has activity is noted with the number of events
\n"; my $p_year = ""; my $p_mon = ""; print "

\n"; while () { my @a = split(/ /, $_); next unless (scalar(@a) == 5); my $mon = $::m2d{$a[1]}; my $year = $a[3]; $year = $1 if ($year =~ /^(\d{4,4}):$/); if (($p_year ne $year) || ($p_mon ne $mon)) { print "\n"; $p_year = $year; $p_mon = $mon; } print "" . "\n"; } print "
" . "" . "$a[1] $year
  $a[0]$a[1]$a[2]$year($a[4])
\n"; close(TL); Print::print_html_footer(); return 0; } # display a given month of the timeline sub view { Args::check_tl(); Args::check_st_mon(); Args::check_st_year(); my $tl_vol = Args::get_tl(); my $tl = $Caseman::vol2path{$tl_vol}; my $st_mon = Args::get_st_mon(); my $st_year = Args::get_st_year(); Print::print_html_header("View $st_mon, $st_year of Timeline"); unless (open(TL, "$tl")) { print("Error opening $tl"); return (1); } Print::log_host_inv( "$Args::args{'tl'}: Viewing timeline for $::d2m[$st_mon] $st_year"); print "\n"; # zone identifies if we should be printing or not my $zone = 0; my $row = 0; while () { if ( /^(?:(\w\w\w\s+)?(\w\w\w\s+\d\d\s+\d\d\d\d)\s+(\d\d:\d\d:\d\d))?\s+(\d+)\s+([macb\.]+)\s+([-\/\?\w]+)\s+([\d\w\/]+)\s+([\d\w\/]+)\s+($::REG_META)\s+(.*)$/o ) { my $day = ""; $day = $1 if (defined $1); my $date = ""; $date = $2 if (defined $2); my $time = ""; $time = $3 if (defined $3); my $sz = $4; my $mac = $5; my $p = $6; my $u = $7; my $g = $8; my $i = $9; my $f = $10; # we must break this down to see if we can skip it or not if ($date ne "") { if ($date =~ /^(\w\w\w)\s+\d\d\s+(\d\d\d\d)$/) { if ($2 < $st_year) { next; } elsif (($2 == $st_year) && ($::m2d{$1} < $st_mon)) { next; } elsif ($2 > $st_year) { last; } elsif (($2 == $st_year) && ($::m2d{$1} > $st_mon)) { last; } else { $zone = 1; } } } # we need to print this entry if ($zone) { # the deleted meta entries screw up in HTML $f = "<$1 >" if ($f =~ /^<(.*?)>$/); if (($row % 2) == 0) { print "\n"; } else { print "\n"; } print "" . "" . "\n"; $row++; } } else { print "Error parsing timeline: " . Print::html_encode($_) . "
\n"; } } close(TL); print "
$day $date $time$sz$mac$p$u$g$i" . Print::html_encode($f) . "
"; Print::print_html_footer(); return 0; } # Blank Page sub blank { Print::print_html_header(""); print "

File Activity Timelines

\n" . "Here you can create a timeline of file activity.
\n" . "This process requires two steps:

\n" . "1. Create Data File from file system data  ->" . "  2. Create Timeline from the data file\n" . "

Use the tabs above to start.\n"; Print::print_html_footer(); return 0; } autopsy-2.24/lib/Vs.pm0000644000076500000240000000030511070040246014143 0ustar carrierstaffpackage Vs; # These need to be updated as The Sleuth Kit supports more volume systems $Vs::type{'dos'} = 1; $Vs::type{'bsd'} = 1; $Vs::type{'gpt'} = 1; $Vs::type{'mac'} = 1; $Vs::type{'sun'} = 1; autopsy-2.24/Makefile0000644000076500000240000000105111070040246014106 0ustar carrierstaffall: @sh ./configure conf.pl: @sh ./configure live: conf.pl ./make-live-cd indent: cd lib; perltidy -b *.pm *.pl cd base; perltidy -b autopsy.base clean: rm -f ./autopsy rm -f ./make-live-cd rm -f ./conf.pl rm -f ./config.tmp rm -f ./config2.tmp rm -rf ./live-cd/ rm -f ./lib/*.bak rm -f ./base/*.bak find . -name ".DS_Store" | xargs rm -f find . -type f -perm +g+x,o+x,u+x | xargs chmod -x grep "curtskver=" ./configure grep "VER" ./lib/define.pl find . -name ".*" | grep -v perltidy release: find . -name "CVS" | xargs rm -rf autopsy-2.24/man/0000755000076500000240000000000011355002266013232 5ustar carrierstaffautopsy-2.24/man/man1/0000755000076500000240000000000011355002266014066 5ustar carrierstaffautopsy-2.24/man/man1/autopsy.10000755000076500000240000001013611070040246015652 0ustar carrierstaff.TH AUTOPSY 1 "MAR 2005" "User Manuals" .SH NAME autopsy \- Autopsy Forensic Browser .SH SYNOPSIS .B autopsy [-c] [-C] [-d .I evid_locker .B ] [-i device filesystem mnt .B ] [-p .I port .B ] .I [addr] .SH DESCRIPTION By default, .B autopsy starts the Autopsy Forensic Browser server on port 9999 and and accepts connections from the localhost. If .I -p port is given, then the server opens on that port and if .I addr is given, then connections are only accepted from that host. When the .I -i argument is given, then autopsy goes into live analysis mode. The arguments are as follows: .IP "-c" Force the program to use cookies even for localhost. .IP "-C" Force the program to not use cookies even for remote hosts. .IP "-d evid_locker" Directory where cases and hosts are stored. This overrides the .B LOCKDIR value in .I conf.pl. The path must be a full path (i.e. start with /). .IP "-i device filesystem mnt" Specify the information for the live analysis mode. This can be specified as many times as needed. The .I device field is for the raw file system device, the .I filesystem field is for the file system type, and the .I mnt field is for the mounting point of the file system. .IP "-p port" TCP port for server to listen on. .IP addr IP address or host name of where investigator is located. If localhost is used, then 'localhost' must be used in the URL. If you use the actual hostname or IP, it will be rejected. .PP When started, the program will display a URL to paste into an HTML browser. The browser must support frames and forms. The Autopsy Forensic Browser will allow an investigator to analyze images generated by .BR dd(1) for evidence. The program allows the images to be analyzed by browsing files, blocks, inodes, or by searching the blocks. The program also generates Autopsy reports that include collection time, investigators name, and MD5 hash values. .SH VARIABLES The following variables can be set in .I conf.pl. .I USE_STIMEOUT .RS When set to 1 (default is 0), the server will exit after .B STIMEOUT seconds of inactivity (default is 3600). This setting is recommended if cookies are not used. .RE .I BASEDIR .RS Directory where cases and forensic images are located. The images must have simple names with only letters, numbers, '_', '-', and '.'. (See FILES). .RE .I TSKDIR .RS Directory where The Sleuth Kit binaries are located. .RE .I NSRLDB .RS Location of the NIST National Software Reference Library (NSRL). .RE .I INSTALLDIR .RS Directory where Autopsy was installed. .RE .I GREP_EXE .RS Location of .BR grep(1) binary. .RE .I STRINGS_EXE .RS Location of .BR strings(1) binary. .RE .SH FILES .I Evidence Locker .RS The Evidence Locker is where all cases and hosts will be saved to. It is a directory that will have a directory for each case. Each case directory will have a directory for each host. .RE .I /case.aut .RS This file is the case configuration file for the case. It contains the description of the case and default subdirectories for the hosts. .RE .I /investigators.txt .RS This file contains the list of investigators that will use this case. These are used for logging only, not authentication. .RE .I /host.aut .RS This file is where the host configuration details are saved. It is similar to the 'fsmorgue' file from previous versions of Autopsy. It has an entry for each file in the host and contains the host description. .RE .I md5.txt .RS Some directories will have this file in it. It contains MD5 values for important files in the directory. This makes it easy to validate the integrity of images. .SH EXAMPLE # ./autopsy -p 8888 10.1.34.19 .SH "SEE ALSO" .BR dd (1), .BR fls (1), .BR ffind (1), .BR ifind (1), .BR grep (1), .BR icat (1) .BR md5 (1), .BR strings (1), .SH REQUIREMENTS The Autopsy Forensic Browser requires .B The Sleuth Kit .SH HISTORY .BR "autopsy" " first appeared in " "Autopsy" " v1.0." .SH LICENSE This software is distributed under the GNU Public License. .SH AUTHOR Brian Carrier Send documentation updates to autopsy-2.24/pict/0000755000076500000240000000000011355002265013415 5ustar carrierstaffautopsy-2.24/pict/back_pix.jpg0000644000076500000240000000046111070040246015673 0ustar carrierstaffJFIFddDucky<Adobed       K ?nCautopsy-2.24/pict/but_addnote.jpg0000644000076500000240000000246411070040246016410 0ustar carrierstaffJFIFddDucky<Adobed       Y!1TA"SQa#q!1QRSAaq"B2 ?pCYb!".ՀjmUz(>K-B{җsbAumƍNiU&\\p/jo( ˂ nO|)Ϋݵwnυ8ѻj6|wf}[Kr,2%G1 xj5Z\(i곏wnRnOS#"vŵ4Ήh3ѡXWD 'r>UڻF[gœ|ݵte|)ƍQH`(MO;8wc7Qe:u$,V@s&Mɝ$-H`R5=UOϝ+2,HnInZS%wJ4*]B}F@N?aB# Eyq_[ݾd>Ud}\)mc| 5鋼>QQ>t(ӏg:bTiρF}A1w*4YqQPGL]8(o"#PHBWȃڥQ1aoautopsy-2.24/pict/but_alloc_list.jpg0000644000076500000240000000347411070040246017121 0ustar carrierstaffJFIFddDucky<Adobed       q!1"d%Q2Aaqb#B3!b#1Aa"Qq2B ?ۏd ?(fv#_qp*juoؒKIBHRR^R F&uDV HInZZP_G wW:<&+;qYmU.xQPhTM~+YJu 4PIh3#cBd1j]ki^mvv۫})v֕Lo]m͂\ˍ8BEUWJEFЩ jEpXG~T1ؖ(CR pV@SmG1;.Ŧ"RVRYy|ʢIלqR?-&q3\>kR^rjL}•RnT؏IGV}Vu_p'"s v>dm4耇B xx4Kqj}ÌKR %K #h$'PSmG1S c^nڭ4+M[W~x{BMK2YRsc8;EPHs\+ V*YyC[&) sq'AmĢ#wknEҲSNN!:Ybnk}iYioBH uvpa s\m+b Mi-%Ɍ [l)I\-UGY_)&'!zolqpƲܭe"RݛCȶ)p5`9'܌I."q (spJk8E2ۣs0;_*Qi| vVq!QŠ*fU tO"e8r@bqJؓ1tD<ԈnX#.ݻ]Mbt'abH:4-kL1.|S w{Y&r0 }a y ex򮆬ݰLgpMՅ}2`I'|C!*]J '٩w*;aLwVڙ1&C(IypE* UʴĂ|S?we41r %P/UDED18u0LI΄9R RB׊Q[?-gO,'VSî%&;jM.h ߓzWdw;_{Yguե)w:xL ַya9ljmCJ$*jTᗱ]X]ն sd?ٗkgUKEڥQ^znK'n,vw}i9J"Z%V^Iئ hQdaMq7tS#dT]Jr)FVuVԾg{CoǼ̆Wxale3TpmZ /=6N`XimYس0(MnS'@fғ e_9uf@D! FuB9ͯۛ*sE֯QcIYZ!fOIRH V[m5_טt[Yj,tA9ܒN*d#BR:7E1Z%uM??=yjZ-*ٻ;rMoYfь̡ yD:m,֜u:[p1X{yn223!).Yuz FOFGj$3kuRK{!|tmgɍڠX܌;p'8Ո!##DfM~)|Qq@fb,g|pa;s [f'ETF*ԪƉ>/cK U U0џ7"r$.IY=t;x7BmP}7|C+0 M!SEC[U"Z/x.O}L ~[ЮKm6$q%6DS~crc"80QrrZT=eH"x2P8nWn۹ݟvU>e'L2W$^uy)šw[um.:\Fq6YkwN'X `ܘ7]l"Ԭ6"\S}NRyr;i< (9XċD$J1Q52J?raZ ~=oV}r; qɌ:$!fP,{ PVܥVN9y?'k՛]z'ջܧݯъ86Uֿmn5s?i _`r5^O]:h5^O]:h5^O]:h5^O]:h5^O]:h5^O]:h5^O]:h5^O]:h5^O]:h5^O]:h5^O]:h5^O]:h5^?q+}pa7e6_ zk_autopsy-2.24/pict/but_force.jpg0000644000076500000240000000206711070040246016067 0ustar carrierstaffJFIFddDucky<Adobed       5!1a"d%Aq$2B!Ab#1qa"Qr$ ?#af|;9QEZ"/^~U@:nUq~패+,x9يTrw.S53bb+X".aA62*Ȋ#7^ƹ\u5)C{Ftƅ*K`BpDѭreVqb@".2\ r(++OSA0ķ$D{FqJ$,8HGZ嵭rѨԩPEHSDp_};7oe?j;s:q<cTJTD'EYRߘE u.+dF/#:&o+y$+^{pR#7;ʫ \]j{y#mgWd<Џ%T/ܪ~{{_WXV4g`fUG6?nEt|`,H<)k%i$g6-Bȏ_ePmϢl||..n͉LH%b26ʽ9/Yi(d̸N:м-6_1&"FQPnU`epepE۰6e;L n m'4']tHP.%JIL,#ع(UsE ޵̃.Ѥ|pOV40p\(@ẽN3NɌfmU$ڛvB`aň@"~}ҕVQGJyMttVw$':jezt؎11S41"TDJXWVHach-@kj'ٴ㑘1CbknLȻ6lL&o7~%i/I $sf(EMXa\ 8f]xζa(zGL%1.IUUb%p(S$;3rqL0ά{Oq p'.Ls~޷{n77gpUXts\=|[rkݦk_%V4s\/Goiz;UM&Kh5^nG5ɯvv9M|[rkݦk_%V4s\/^G8oaڜ;k*y-fڹ-z}8r }b-يaɔOxsq"N9~O1:*S,tKy%qYRBN>CQlU)]Uu9YiOUV_sI)63!b4ű_M %֚CeKo9eFd' Ac/2z1~K|hưLj㊓৤!j/9)Х: ˊ)IJ$u6[iȄuƍivnmS+TVJII*C rJ(8XCO0ۭZT1Vg adn?TyG7O)'E)"8I>I G.L|jW$x[1R W%sWEEj7Z+ZJ9}i'֑JJs뎣YlxH)ӊqG6+c:cI9ͷpZҡYZan[-J\VRsNp8x(6:Ej 0dL}NkTBKZ8FSE7ɰwn@uяl0}K!$'c,@"KBD8PU;1¯B.9>aG\ίޭ活DĴȳɵ@!j}"ҎxuQ B Smƚi&%> >KI,65ÔRRQa[# BGlPҶ[VEÐcCNVNPVǗ+DFYE^j7ZE))QeD Ul幜' }kJOJ>H/|nΩ/ODlo;UMRMGoiIhV6uI7MݦΩ&[$4vv:&ngTDlo;UMRMGoiIk_q0񫳡cT ~?j8-z|^/=\jautopsy-2.24/pict/but_new_name.jpg0000644000076500000240000000263311070040246016561 0ustar carrierstaffJFIFddDucky<Adobed       O!1"2d%Aa3#!1Qb#Aaq"B2 ?Ӯn;ǥ_n+j䃸TZVQ*aÓgkh4nh^//,¶ *s~"\)OiGWi2{!6F|d1dM[BJ$-*/mPTF[$ms1kϼN*㎂6BH$$! Z\3*9 ͊ƁGK5#/rAMHթ)\/\6gsa6[oVuhIM<* ݼoNzg)Ia$B0ZC %6!EƔ$.@ĚL#m煲Hm`U@IK 拆~FF.Ϸ65(껚m}NtҊ8r,2!S43"TDĶe`] .+4Wy\h"=*/@i#) -*&(\ha.)|%wY \srO.]$Y̫Ɍ!Iԙn@Rw Su0}X [EZuw`<ܸCH/7*B*W62%3O+ckCω'8T:1w'IuDdTD]oC9Bj=;+nF "#* V9.J*}gyH|D,YH_"2Ntq@pKrv@05&-YI )v̇=eBn&VAauˤup`qTPQRg>9gPSWiO\ ^MޘtCڛÌ|:]}Wϣ{Ղ9bo^:G>QÃVъ=xpp1GX#F(_eNX)ъz/9J%[{g-ӽsn5autopsy-2.24/pict/but_next.jpg0000644000076500000240000000247011070040246015745 0ustar carrierstaffJFIFddDucky<Adobed       Y!1d%AQaq"S2Rc!1b#AQa"q2BR ?ݡ )TepmFS~wpѹ@rn,M=/ sd6x̅[\})Ķd793nNqN-/"mJ !h-1*2vKo2UX_‰hwv.AY8 :H=b9NIT'nW܊/mSZ,&_K/da+s۽T?8Rn8őQLw)z8 [I$O݊7~3{pӘi{%+^=VSX)9 nQyCW%hW FI\84sI&p$k;UÃG4hW FI\84sI&p$k;UÃG4z;1W~|)m|_V~Gautopsy-2.24/pict/but_ok.jpg0000644000076500000240000000156111070040246015400 0ustar carrierstaffJFIFddDucky<Adobed       + !1Aa"d%QBq2C4!1"b#AaqB ?3jDs"Zz#WTX ի̎# =m){?Onr<{V]Nn-.5O^\NJu3SחŒ~ O[׿~r㋏%,K1mgOxzwcbautopsy-2.24/pict/but_prev.jpg0000644000076500000240000000304611070040246015743 0ustar carrierstaffJFIFddDucky<Adobed       Y!1A"d%Qaq2Bc!1b#Aaq"Q2BRc ?3n;e%qG6)ν֢kSWUr0ɬ_ʌvCqͭ@6LyW.9amډD_، J#R$`Wloόr[[eNpd6( jJN9auI+لg 3><]O?y7 V;sèx`\ iNۚUGwu]^5 ?l # )CI$n@cEE q7?V57Cl'Ez!+M7lۍϙbQ,Q,-9FOt %FH8Y&>U9H zԫT^;v yzZl:$e.o)p1VSp9ț^- %OFH dD2 -:e 9譪.G!<GDg $&DcZ7".*z-8Iʌ͖uZ@/;ؿy,s;ca1;=ʕ̥)kZ) _xs%\315c'+uyk?Hզ`:K(Ծ'piFeΎ)guv,s;ȴwHe,j8ŋ"%#&=D8SmY6T ČDkWoOuڗ:.4aM_mm[ E ҭ7q-C4VQ? @G8 |%<|i3~$\ŭэVtѪ} ݥ2=lM%t̋@ "gqؓu,*GU;G9+9T D6]T [q*~ii1@E,'DlpDr%]U&ĠefkT3 [Gr Cu2 0'iZ( oyZ|ytǧ0˖"mo+OwU ?l]\DB85n 4[_)B:)P9*ѹy]߻| %?*;WIho:6u`WFά{Ղ7bo^:FQãgVъ=xtl1GX#F(Uѳ;1[ֿӷ/B^ާڜ4>):Wautopsy-2.24/pict/but_replace.jpg0000644000076500000240000000237111070040246016402 0ustar carrierstaffJFIFddDucky<Adobed       B !1AQ"d%aB2Rc4!1b#AQaq"2B ?y{?㲯w1UzAn:GMQyZR(_.q)2a2IF`3c0f6!Ss !0ůb' s7[sh!,R&$jT, | Qv]wmHdeBZ u8jT^xLY}4w I P%ENL,E3lO+/v!KlD̪.3 y. ?9ra:5&HEM`,ДQVUpƥ@[,s${^;teն̋5Yӻ]m UӫmVҴf#ZO 1}߳sƞ]e*_)WN ؎Ґ)Q*Dư`e`h3*vw*K\ĥ"e ;\A[@̖EL@y]78]VYRo^dՂ߿{Ղ7bo^:FQÃgVъ=xpl1G X#F*q{[_09}u>tautopsy-2.24/pict/but_report.jpg0000644000076500000240000000247311070040246016305 0ustar carrierstaffJFIFddDucky<Adobed       X !A1"d%2CSQaqBRc!b#1AQ"aqB2R ?h`3HV! Y*]ȋ=:[iu5Le;EuM$/geQc>I\#r.>ITvRp}Q$11 b[shT-+s_ z[OtE8O+ntB$ZeD6bJ_zzK t"AP_D\޸0[ e>8Pf/ɗ(9C@r!3dM'7l%,?hGh[w#6NohL\٩Zn*;aznݨ71fkWQqI%R)[YQLSj|)dBk6& [f܊]i:hylk f.D;TnJKӳu.^$N4ynfqU߶۳bo6$V)W!}ՑϽ0lwS:H 3ܯft~^e->,K9:Tz,:f56rFI$F#e0 Qb-WbwTƗA3]-to:_m%" F1`@׳LG*m^*Jv K=hԶuTm㱎sHxq*=NpnѕVT&mf+O!]q\ "0 gmܩĘ-{/BѶv5m IcM`шf zt\s%9dtȈ:Yq7ۄfʘ܄1.dE:6&V4dJ˲Nn|׉,//՛.Ìz9] | #_%ÃG5zddS:r>ߔHa"hTQjW'SifiN;§lğ-v>},(Ɲ Kj>U%&f`a'c1 7\lmc BpPv-x,;^&~8۽Fqoz7R.b~K{m+vudr[Kg:!T,npzc:ƌ#Cj۷Z$Q߰C`QCl[7H@lx;1k$ETJ7R7 1ݎ3 cYRgۃhC7x[-q`hgsѲn~*DVYsR?FZR-{w|GϹ Y0o L.lUUXפya:iRRhVBHf^ΣRz0X匮 w;S3];!U{/ -]znܚ|xJw1S#@[ri(Tb'|xJ3:X4 &N \[riq*3:CG\Snri*ø }J-sOGcI_swyY_autopsy-2.24/pict/but_view.jpg0000644000076500000240000000164311070040246015742 0ustar carrierstaffJFIFddDucky<Adobed       -!QA#2ST1aq3!A1q"RQaBrS2# ?܅q01':}`O>lR_zWS(KãX=!J}77jT+8i#b7䏖jLc~Hk:ƣLjёlFYDnEJKjN܍D/E?%iȀ٢ (Va;(nYyx%?K4] =_h;^fxv$]#}.GΜN41S#Iși;'#!^-Eo9qjA lVNCIJ/5^)# 88ۑXIBK&HTQE%u5,Av!-et/+yg4o2XL ?qŒ|JMarv^F0>'w &e:Wd|7pRk>WX{OWyH4x*_ƫӦ^xJ%VX߰ ßtL> >~T6e?IF-4J5>.+VGoZ0is _#nwjtjpazQ w)s;"6o޿autopsy-2.24/pict/but_viewcont.jpg0000644000076500000240000000360411070040246016625 0ustar carrierstaffJFIFddDucky<Adobed       { !1"d%ABQa2qRb#1b#!QAaq"2BrR ?j8!;Uy"/ݯXq[)t lv\Ǔ%6"屽꟔Tn^ 5 Vʘ u/,'1%-LE@SuŠ) W q " [sO К9 "*UTxᗡ]a-Y= ];'Bzӳ Ny62d/F$_zʱȼ}eZSh]U턿t7g:ubnuҮCKD5#R2)c- Gڱ~b6F6PDRJ*KJ;FHL:KM.v[Ǯω "JEDSYj,[A7%ew`^<1䕶v8؆Q\JdeDT */ VpRSn'-ğaE=|'xiÝ9!(.%ohî7׮Q1+8y.sFm4#^H[R$iwv{hpOQnѿ)'˶ muu_e/WNhz/G4s\/G4s\/G4s\/G4s\/G4s\/G4s\/G4s\/G4s\/G4s\/G4s\/G4s\/G4s\/KCOJ^_۫Q-Nxk^2autopsy-2.24/pict/favicon.ico0000644000076500000240000000257611070040246015543 0ustar carrierstaffh( db`a{-> n5JL(&(zgE[Hxug;GUS..Qm"-{mRӯ-wVӨ_,b1|,Ҿ"_TZ\$Vü)F[gž~Vfm yVӣ-O?Zjښte|)M[SNυXVL7H(pIBIQ;ƺ$ܔ72\(NXp{  f%QMVP+4+SZ5>%8']3$mPUN[)Z qmh> FH۵o\,}K7J9`Z>Iq {r~_di6w5I pGeI@״WO-a.SvUn!-sxYe%Ju^'QF<)^us7 Y[yrS֓lrșHw0YnI7 e܅[)*&3Ninz+s*+Bq;l'SG?sA8O}qbG)HmȴF7eHw{??jaST0>ə_ΊG 6F' *(QoYW qٶHv++O6FD8 .l 6-UI>8Z6?8ώ_[>JZY4i?;{*.5%ي}c}vE|MKxvvme*O^07TkАOϞ2&q}GXBx8|pOa"|®smKmPViHjr˶KZ,PFH|771U ݳeYq6?E.uhiJ?,o\m梭>(1{/+j|/A0G9mHp(p\?y4EP"kʊsaƼ8JG٠`6}(pEKb'G,~#*ԟ,]aʱۏ[?X|"rn>~/?X|"PG,]aR}Au*[Krn>~/?X|"PG,]aR}Au*[Krn>~/?X|"PG,]aR}Abqj=I]?PL jFxYv autopsy-2.24/pict/file_b_allfiles.jpg0000644000076500000240000000317211070040246017210 0ustar carrierstaffJFIFddDucky<Adobed       pT!1AQS"aq2B#3s!1AQaRSq"2B# ?ݠ‚.bfKJ U_O[o oCte\ϳ!UI}i0T+.U1XL}buM22GᆱIYX(ZND3%V<%UiUE_qwtE+UrY5[LҨHMEU^cSLm{ MW*J""gWd+mجS猺ƮdlVz)X$V2ܢ|K϶ [^;)pvbu_rxa[wmo9;[>8{k[ɻwᶵޣ,a]=ص^_$s$5%cg#@7x`*"&ʀ:i{fJ\7Ul_dnS@ DE1A\gF,ֹ֟#U]LՅM J<d:@JƯ#Ȋv9{8EAڛ:*Z<.Fk^e ;ny._S}kԂUۮ8-+IjjY@(EMɑ v y"'v<"ךjw7imOY)?Z̎ /i6㈈ XFx#M*^˟EkZI?cl&QٺX-Kq9q!g&5N[JV1Cw5ڸ=CfT 7ʙxr\0=k(s IifO5ޱf䉌{ MJxA<%Es7.sE?ƊP Xƚmvi3= ^H\Oԕ2u[_T6ylQ$m=@QuG,dɏ [vnꏆXdׄN ÝQ Is>a^;X9w:1u*5vꏆXdׄI˹ ɏ MDAQ I˹ ɏ MDAQ I˹ ɏ MDA!G,G DA; "6ms~m_autopsy-2.24/pict/file_b_check.jpg0000644000076500000240000000073211070040246016471 0ustar carrierstaffJFIFddDucky<Adobed        t!1A23 !1AQaq2B# ?wlN:nmY/%+IB]1!q$ j }&YZ]sXYw+|.S2fClQng͵H:4(飄nfU`O~y"feQ/NOM\9SJ(autopsy-2.24/pict/file_b_expand.jpg0000644000076500000240000000436411070040246016700 0ustar carrierstaffJFIFddDucky<Adobed        !1A"d%aQ23$q#C!1b#AQaq"R2B ?K5*xRXW@E%ӚN%Î6L8J%Uھcwm]+83dF-julEDx*gQſ Dz-¶\@lcY@bZ$z+o0e8-!6qwZuE9UP}w7i)BpdvpJP%#+@CDT3Tj;0Gludߕ=ƅlGy*xP{ʩš 64 6 M[fC֕T%D٤z(l!R\P/3l|h+{šxwFL! -+.as 0U mpH8$d 6twY`Zd5F!K5bD#$* *5^ 0)a(f(n# }aN؎nٺi];0&1 Yq7GAqpYGAHz[܅MN CUXODa1zHjorI6 jAABxSCR-t<y6u}ȶ3Qϴn 9%_ޚ=%y\`{~kNc< +2nQ!RE3J%HXep] m"rKyrq|V8K7-V,#hDV>~$^ּ(@X+kZ&3 nǤ+0[W] ݔM7WvZW+o6G?-KgC+QC5`GZivҧ a`2 i *3J !3`8C/q/autopsy-2.24/pict/file_b_hide.jpg0000644000076500000240000000410011070040246016316 0ustar carrierstaffJFIFddDucky<Adobed       1!Aad%"Qq2#3$!1b#AQaq"2BR ?80bC^F"ծ>b`0.`ZAs!f6Krդ*xEl(D&r# 윉vty2,v$jcc$dч QEuskXgu!N yhh{V`RrF xӶfai gZuEyGN&U9gsX&ɞ:Jl$7Ųm(iji&kU{-3i&Od -#yAܪ]T~qVg?fH jYId4m_CTUAUQiY?dph,r }v: K ˭_7l$Y$.ikyY$yaR%iºy*;e&Hw|a粸8jJ9 DiJ]]<${ %/!8v9: 0M#Vf蟂Du K6,(ۭY@{Di\5Y'=i_GI9`$0H RDR2&H ^ۙULyEhNEq[RMs:R)) W)OU_e? 7|5kGdγ~9ϑK\4eEDDDb BBK:܅x#ڻ&F͓v7ZȸF~+w~:se1 -4-7Sx.:⍵~: TOLV߮ 9)u칕 w*Fٛ6ɰQk+=s#)tf!_5Gj#rKNAIݍ΄˴Zl>Cf✆W#%ue-J)%GY9#6"OڭNB,%ʹ99F[ kq fN:V U31認:&9Tlm=H'n SDLH{P h_b6Ӳ߸A Mԋ\CySCqEM$)H_w!Χe2cinK>}豂tdSʓ]B/\ȵij5IC{J߆v|{+ ѷ[=_!R.:#`JibqTyXQzte(9rٌwˊ q'UxY^ЫD4T%3ʉq nP1c(Z1fGѩ"ͅR]j/OKZyx[O8u`q1\U˦άF(U˦άF(U˦άF(U˦άF(U˦άF(U˦άF(U˦άF(U˦άF(U˦άF(U˦άF(U˦άF(U˦άF(U˦άF(U˦ά?DNu}܏nuqk^2autopsy-2.24/pict/file_b_md5list.jpg0000644000076500000240000000523411070040246016777 0ustar carrierstaffJFIFddDucky<Adobed       !1STAQq"2a#3BRCs!1RAQSq2a"B# ?<֑mxTXZ,iHQh +V񕕀@U?H*4J..k "Z`4=5w6ͺiS Snk=vۦE;pݵ6馳N7mMiS Snk=v۪,gͯ2'WJ*"}3ҸK@$XnQ0 ~2f Ozp⌒HWD#oWfE☰g2e4]ĺ6m!?_ %!Ŕ%ҊJ9%%t1Qo*[(m^6XsY#bB*J s\5+^lB6zDUVN: 츃ez nE;q^tY4z)M5wjm9/SF[a'qs@2U1& 2Z?>'-q.?*KvAp@E{T,hpKL5tz)㌻6馳N7mM[_I|wS}zw!6yP_QWN1W{x#qw>+D]gzɌR۵8#1ҠXu,Hفh1T7sEWKvC Y1үiGp5 &U6 6?~bG<zݳe7{*7ٍ4w ކ]D3BL]9\غX\ -+O+v\߳PT]-̚H@2!2(*0Jk[٣ L vkk۷6FYlVo4~NSdnL//Fk{x;gڱ91 [6 H\>bc4AJ0Xo䵝ǷKctVٌ>^0f`.jOʫ*^j9 oqUOa1x[)6jռvXFɝr>8JB?Y`_)ۭw鶕me,'=-jy@da7IE fΌ _5hYŌvzy{fKDwz-UiT:SlxrɌKsg]Daa23qw&dNRcI/Jҡ|Uv:J8Bݠ8 $|?'1P#tArK#Z[}&]%6Ò8鄥n*9ْL~59f `AW%QV6NJ/ j8#HQb4Vo'L^E9z)Y1{gtXS >QaN^ Vo'L^E9z)Y1{gtXS >QaN^ Vo'L^E9z)Y1{gtXS >QaN^ Vo'L^E9z)Y1{gtXS >QaN^ Vo'L^E9z)Y1{gtXS >QaN^ Vo/2f_iQ,|~$/tT3>ցUt]"壦ˏqpʼ:autopsy-2.24/pict/file_h_acc_cur.jpg0000644000076500000240000000260511070040246017022 0ustar carrierstaffJFIFddDucky<Adobed       Z!1Aa"2Qq#bC!1QAa"qR ?Yvg`ĭrEq"ᢪ%W}xZ+fwC:{ڢ"/6j"WPHA%3 7Z[kwI7hl[^,rC@(. /.2i ;w*a^ ġRhA vLXKRtJFaFLcUH9)TIDRD**-< {У!<-LABYpWdPB$RM >g+v&ר <+Bh2$(WLc:/$y 'Ǝo "ϫڤZp˗*SK=%gWёu8]4Z m̗֞r_Jt;hrA[{"bQUUY=%J-5,hB 9RB7ZjZHzhrOqiPKMhͿDћe^9p;awC<īSqUN2F s]ƍuY-7{HHFTc~# pcw6|F3Fn[/cL $831: &e_.b)+==|rɘʿ.²Kx5 d |xg4 eҪt~,dB7zu"]SKi ^Edρ`o/`I]:g̾=Kȏ{[Ʉ\ }ȳ¯~H/ǵ78.>4a".Et]wj\kIPr]@<mj#6Ѣټ# mR\D'g`LY5q"L,Cc4Ò CX0g1cEju]k~]v֑DEDQDEDQautopsy-2.24/pict/file_h_chg_cur.jpg0000644000076500000240000000260111070040246017031 0ustar carrierstaffJFIFddDucky<Adobed       Z!1"#AQBaq !1AQaq"B ?seܚIvu[0䗅w (T)*Wg ԚrE1Ǯuh<? !=(IQDdNJOkUe'`g{"/wF_VxwN\YڌħgGF+#n(*ДcbHb7]ZYu^b;%tmzQt0Ĥrl{nS$)-ДRҺ[M "G/ɇauԔʀKSE>K/Q,-7MͲ~%EmU})UE UMVL k$bZqD&[^CɖUq|t>Sk*m eU"mOcm@JkVXKH)ÞKU`"fK <c lpNE߹]F;JL ]ș.?cVCt9 KHb2&Ȝm\R-Dӏ1eŌ0u0hWVj嬥gIjNL͆nNpx ;T_Og+ =*qsF- ve;ɎPP]aOzR5oSDy&?bgWe^ՄR[xV9%]JIO1 kzf^$opIC_ir6}ǐ_cPZ3D`)#HTs y"&nma3lw+J%:8Mz ^2s%pi-t&̍*ەB֔?F:Vc- ZGM/b\[iiD4i!CH ">>_O.:n5.U߮e|<ܭWwiW}7]r'8autopsy-2.24/pict/file_h_chg_link.jpg0000644000076500000240000000217411070040246017202 0ustar carrierstaffJFIFddDucky<Adobed       >!1"#AQaqB !AQ1aq"B ?s䕊0,񏠆YpyP#`h1uw%ؖ@ js=Bpsf״%Y1I~FǜMG:V[oF7_'Hͮ}R9pX5UdZmVԈy4!m#0ؤh1ȒK[ĥK[j6͠$ρ&w΃ R8_7A1 I%0G#φ֗TGpy$1㚠HQ5i2L.K:ϑ| w#W"̈d=3ېJ@b" =33qd{my;M.G|jɲ9(]{?`[Cv3j$z.HKa\{sXyX241$uUUX<68!w&wc&L ţ(ՌLb`tvh7?sYh5N" Wlֵ|۸wj>f+CzIԝB ~)/5䕾 iEBN~1OW&&*@Ȅua^RPznyI+PWcW-G"g,4/h7:1IA*>u{rfmy-+fѓϋ֭^Z6Xo0{恌a^`\WL^h#DF"autopsy-2.24/pict/file_h_cre_cur.jpg0000644000076500000240000000255511070040246017051 0ustar carrierstaffJFIFddDucky<Adobed       T !1"AQa2BqbCcD&!1QAa"q2BR# ?Iuc0䗅w (T)*Wkm)Ԗ[n+;֫*,pW <mH%Sf }.ću(\bA܅6F(BuRSظI5TlZ"8hr`ڲ%N!ZN ,_FSXgt={5Dゎ6D@dN<#fr03)AR .YL%Ryo\eTw#]9ꍺ-9 e%%GJd$T{} ;+ՆúUl~2Z/m%>2XVbƛOοzQi·k1M($SvAqTVρr{&+sc3%e1݇plpNE~!#I<A"@wP6ks}@oQnH}Zr4f2&Yp˨[/ZSyR`ج{Ѱcܓo2r"a1GavY[m ־c{mL),y6eJ/n{V){&磺Eoq)"T0Z̪<5'6!K0?;Mr33/bΈMYI'PUĎn4$&܌@#:p粸3a$VXb##hq66ؽDZi&>'hak;#MBQ ""Cn'i2A?DoB $5f61*(aمIW^Wcv/%<1\sXp1-el]5f;=Q#qEA7רּmmk}'c;L0+ *UiU0nmx[8 -b}S^gw\>ws;*ngpB8!G%ǒ'[9(eO9wK-wJqUKuۯsyoUƯ7Bautopsy-2.24/pict/file_h_cre_link.jpg0000644000076500000240000000211711070040246017207 0ustar carrierstaffJFIFddDucky<Adobed       ; !"1AQaqBr4!Q1Aaq"2BRc ?-=UFg:ߝ+0䗅<"|m4*G2Y{mpsVTV i\V ' x $1BMIinAv$;+(K+#VېYFHPlMSqڒȱ Y:Ց.^鿯Plb2;O HpQhU t6g-fҬg x!UnwoG0[6tH[),*8@[!"A~SuMɨ,o#FfK-<c&&{wO׺HbO_Q ;2o3>r 7PQܐifeM /ᩗQ${TƯO)6 >z6"\r#ra#Aexw5œǎ~+#fYo೶fgPNUS.8K 9w"SU@D! Tw08gW6!K01; -p*ۊe5s2Sy0K"I"~T2TTu]Ծ:utɡ sTr1B_)n=zҶǩ$VXb#6FѸmmOz5Q4svN1LBQy1[~DDO2pOQЦ#E$8sښ+\><s'?{}ʺ3)Rט#DF"4Dhautopsy-2.24/pict/file_h_del_cur.jpg0000644000076500000240000000165511070040246017044 0ustar carrierstaffJFIFddDucky<Adobed       1!1Aa"q$2Cc%!1AQa"2 ?nحw.AzDETkaU)v,yAe H^潿^\7=T:H1CĒC+, G=FQ[Eۅ#au8;ƧgSo oǎVlxLV"8[׷nFB3q 0r@%S-s_>~zFftr#~8IB60<ˡRc1WPul-um%PḦ$దw<\j^SbpԎLln+_i}_忏WSO_*մsPautopsy-2.24/pict/file_h_gid_cur.jpg0000644000076500000240000000167111070040246017041 0ustar carrierstaffJFIFddDucky<Adobed       1!1a"AQ2#Cc$!1AQa"R ?/-5UF:}+%g*@L1TμmXҘYv%`POx­ ݬѬuagDU: |6]nF߄~|49f6 W44XA!-iX |_ÇQ}Yh0\-(r@w$PFÊI;}׃'WsZJrhr -]STUEEs,;%xuL.5[hB.yUW0v9bQ_t' 2Y!Tsuɺ/ס]ʸGA,򌄉 .* ~DgfL:\V7}A^k#c}tt#pk.$qr=5efF)'mg}F<"1-XйekSaD 713y>.K s$EpђA85mSYܗzorKU5 (TIRxҘ݀Yv%`PO8¶ˬn4mL*L/\g&a|Gt0scpjӄ3XBC|[&҇U0X t!1"AQa2B$#3!1AQa"q2BRr ?Ǿ6oq|PTmJ xsO/3[w&s0[-k*iuH@{*@IS-,ov $VٶWb^_?U~29i)#!m/r&؛%\x Kd&QrLgRDLr#(ZO)jᎨTĥd2##䀸rU8z.+@D՗'ޟ7&g|Hc@{$L讑(UJmZ}\!hD9r2$tJMb7' ^g+=u'ވDr;ϥL#禍l%(JGS*$O1[C$[c7%=B5k5cmmBTJ{t\d'WVI Tsw.k Ѡc@2NH(G )^I"R:qd!)LI*%fDa[ ]א,͈-&ۏG4&U>,E$xk]/<1L{"n124?_gkZzW'nu.vvll`KŲT ¥N6_/ wp+^kuxfb*rj\UDvD롻m% hB/RBϚ3;P[m:ʞQ])cOGc;Yj6)umxNcautopsy-2.24/pict/file_h_meta_link.jpg0000644000076500000240000000161711070040246017370 0ustar carrierstaffJFIFddDuckyPAdobed      ' "2#!B3RbD% "2BRb3!qr#CSs ?Fam"`g5mԁڕj:*5fFe*XrUu,7e~Ƀ'OQ_:5)D 7ty ' cFgSߚMeL!hBy/۪_s%,]bj4-ra3g(dTRzS"-^/֯zI0pd_A8emH5frvZf4 hTEp{3t{~V[\ ->YoXҏS;?]Ǧ yv;r,*&5)V6CcHF̔ 궛tϠժՈ‘IzNN9 jnj֢ >Uْ/؊zTT?|T nDp9z3Dp2Q8yxG ȈA.SZ&HQ #ˁH#meVm=f[>Š[wObѡЄhB4!autopsy-2.24/pict/file_h_mod_cur.jpg0000644000076500000240000000252411070040246017053 0ustar carrierstaffJFIFddDucky<Adobed       T !1AQ"2aB3SqRb#C$dE&!1QaA"BR# ?ǜc ogmA&'Uݻkz[V99uޭ*84җ/~MqI#PF *%D~l['TI2ZѴҒQۮhL KD{1cr#%7cFDY/E _c%8s0ZqZrJT S([)kS\܎!Icw0Z~y,!5Jv8)Bg2MqmSdS(&"J ^dB]z_E7#EȄ~^#BBU6ZSVqkͅqۊThX|QDЗʟgr 6^%%GEQ$mܺ bX]Yԗ'>d~"DCJmgEt@\ Mjp!kdWR2$|!~Yk2+sVro(D{PV{&7_wҎUe ^&CǚuKt6% lkHoݥM:l w;NO'2gʅGǕ-㫓]RZtɧf}ld9J"x ظnIeذ!̈́f/v먨`㪫Fa(IY|F20<ry#u)!גpj|`6 P)wS6xH9 crĴn;s ^9 =u$R=uV4ݥZdX}݄?h|:LF)ܑ3KZ :tS{?]5w'lEautopsy-2.24/pict/file_h_mod_link.jpg0000644000076500000240000000211411070040246017212 0ustar carrierstaffJFIFddDucky<Adobed       >!1A"Qa2qB3CS!1QaAB"Rb ?ӏ8ǃ1 @!8ϒ* M)j'+]>=Wcpj-7.[ղW@R_-~oIğk5$`FʱQ qULm4"8bJ#M s8d܈b ёK!vE2Buј,b\N8NfN+N^RBtJq~TnGYט-{|GވcuSTz)BG2MqmSdS(&"J ^BRqYx)Bg߇ùo$/ǍgN]e٧9%8mȑ$Ɓ~]"P K:WO˄)\C")"GeX?^-vEbNjPsq"05SM߁0jxU 2OʰL# xVvζ#nB5dB"R.[M:l |g'NRrX`N@B#ĖvɮP-3KR]uZRӃ3?7'NR5W-{m,7yEu p}>~p# 3VI+]8̟1$m-ݯ #Ȁ7r:NmOLt;ʒ"npWGcZ7.$KK;"QԐ K/ֲ݆7;[L=2ScW־0d8kݕ\_I/Gv[m3ȉ%6RLj""(""(autopsy-2.24/pict/file_h_nam_cur.jpg0000644000076500000240000000211111070040246017037 0ustar carrierstaffJFIFddDucky<Adobed       L!1AQ"2Ba#3$!1AQ"aB ?k›3f'NEAYER.DTVrx-īcaX)HY c(+$_b"u :ĵetԎO3Rp"+%H*hڧѪ6sR{& St>uX2=~1fW :3MfTUQD]TݪiVY,l,#1qJ0r#([w[nZvo8-P_K"129n$ƋĒ駂םGW NI*cE7dbȔeSjdfl%ڪy֓ \N5{&|ms[Yb<&9$;~AE[ZP)%KE|T2yv37|bK)]h9 lU2]RV|-o]`vS#~W0"zSLr)?pݼhn:$J ֪nڛ[QM7MYW\Nem_ZAq?m/v,u֟&autopsy-2.24/pict/file_h_nam_link.jpg0000644000076500000240000000150211070040246017206 0ustar carrierstaffJFIFddDucky<Adobed       2w!1"Q2A#1Q!Aa"B ?YܚNe8F202 =<P֓Sud1{ K6 vD)-7r=ͷlYJkd}1n"PȢfAG"<;kUy\Ԓn f҈G#BļeO3xeG`tSO5WcrPbZ$JBFPiJ L4*Ec2To"Տ4xQk${cGy0'F>﹎z԰BX&.)*$Jo^KE{,,ey,2e%\ (_)g/NT¡Za--A(:(װ}:[Lz<[f3&ԙ8Q9,k@y҉5﷽4U5*2U҉֔}oq*Ijaa>G+`[ME :.ȮATjefT% `BXoVH.HY2UϮAC~ngs{F_׮%7autopsy-2.24/pict/file_h_siz_link.jpg0000644000076500000240000000135511070040246017246 0ustar carrierstaffJFIFddDucky<Adobed       y!Qq"12!1aRAQ2 ?`RےYYG .=tRPX7&v>R"7,mUy-*%#u#Gx{˶ 1a$;0Ĝ'p#VIAV_TU*]ϓ\ : \dcɉeDhLo`Tjm:Yb,Au0tH٦7&fA*`#VZ%t+[<^P?_uY E:ڼY Asd/f,8FWȮA [rRyD/z>Q X\-)6ii9`dW1\5=[c]}- RTIҕ;'b>#iTzSƯ|n+HMUW*o,br =G58^"$WF#B autopsy-2.24/pict/file_h_uid_cur.jpg0000644000076500000240000000163311070040246017055 0ustar carrierstaffJFIFddDucky<Adobed       1}!1AQa"#$2!1AQaq" ?mfxjDv?k e&*nTL_&yD08$-WI+3O~L:XS~D^LyJ ǵr07Y%?GvUU%, ]?Z,4qHfWiWXQr߿J<hQTG:W%ZT|#oQeawik_)yW(Z|>(ONBW>$J2W,=ЋťȆ$[r5ƪ zqfUV VK%#mFO  D529ZdYyjǢ襖f35pn([q0('0j/Z-}1keXGsI2^xi҅kVA%fLگᙹV'Db٧tύy"vsz;(}F~}Kr-n4#_J/‰nP]F\~z7vӴvU4VR+cKRO/autopsy-2.24/pict/file_h_uid_link.jpg0000644000076500000240000000125511070040246017221 0ustar carrierstaffJFIFddDucky<Adobed        !1AQaRbrS$T!1AQaq ?mfԒt;%F V?kHkO`zE.jECj-wE1g3#ϗ zq0rd61ɵbipF™^tG+Z(m %;Wg~s_ўa`0Bautopsy-2.24/pict/file_h_wr_cur.jpg0000644000076500000240000000247011070040246016724 0ustar carrierstaffJFIFddDucky<Adobed       Y!1AQa2B"R#3$t!A1Qq"aBRbr# ?-.K+whyzGbEfYGjG׋ГD"lJ>ܮ+qq [+6T;ff@>ꆵOMHvs0.Y[^WZf,n& W0V'Rpbb} <ۆC\b](ԏ0'3gq#I=>/bH s%4(svJkDKY v/bH mot cmv+YєBH VPi41pP\6"a:mgRL'9V։+6{4cwSݟ81 ksHª£םhMFux.{=êW<$n+kmh0"yc޶dCt=n2XqXB)SF(!P+Ttf\݉YgÁr6U%_1I$o,qg¸aʢI dBN?GIp`a7Wq iOMhxsa|ӭ^W bb EfbnOj= XN'n==~U˱Mu3UAjI=>ڧ]nG00SH"7BIN"Z P~Sr9Թ+Virkn"82I#mv61pPvʷg`ۍêoDB;2vhqףlLȆz-dGQy򘊪bdmE2&7S%E uD/DBLfs\|Sֵ oŕDxwTwEnm9k73(3BO%=wc>OG$0˳2 eW 6z+B\]z/ U01?QlY]ݟo\ujM;&+~k3I|Ya22,G&͓k䱧NCF\ CLJwyI#a^m٬ހ;5ӑߤj5h#DF"4Eautopsy-2.24/pict/hashdb_h_alert.jpg0000644000076500000240000000456311070040246017051 0ustar carrierstaffJFIFddDucky<Adobed        !1A"Qa2#qBR3$bC4D%Ff'!A1"ab#QqB3 ?q-*d|e-lDe8^8r&Ɔsv3+[(TėjQ=b&#f#ё\^ "Q`]\0JwG`E?^>Fi[R1MJ]HRdGRT(rK p ġ\ $?z&sUtpLaPB 0pSIC&lE"S׀h %=!ݽw5=#*((u)Jq/upWSfyvSv@<<(㎛~k‘ew-y탈]Ġ.ƞtBx&*S ]qJ]@Y 7K@<1 jvw*K"dp uk)H$q6TE!J J@o`pmۙiH;w>2p].3U)\1 -Sn6fٌ;ksGh*wh&V8882vwp|#ݍM^T(E)+4ۍJo wd"^=8'GExdL,&Dh@Fw\V{ඞs%tV=^s^sU3 ߈*f@d#)n&&U'۔) b@c,|m-tnSDD jTiN4+r2ڐ-3yVV]eMu1hpT18h)"#7|Pm##)C )'W\\_Vq2t7v31Mo`dH)% [ L¨71N"6HStCn6&wkJ*&KiR!CE_ 0 vdae[7LN,Qۂ@FWll_vtCKHELۍ$dv8(uD(n>n6q%ZN^PCs0@(1q"uȯQ(@CC_ZHncb'IQAR4ʂTM"|LNZ9d-.w{I2YZ\˶> Di莊I:%GW¹|Y0к>M㧯9}d S' ˾p§/@^p}nm >.4b׹w# Χwa)oOtN妯+#?sb+to=9W:jW,%~Z'I(zt+Zaw0` W_0autopsy-2.24/pict/hashdb_h_ig.jpg0000644000076500000240000000512011070040246016327 0ustar carrierstaffJFIFddDucky<Adobed       !1"A2Qa#qB3$%RbrCcs4Vf'!1AQa"2Bb#3 ?]mМP9L$cRJPvȓ>*g#(J`/#w}ʬΐꠚƯT"RQƃg%U%۲QGD@eeKTmJut ig bǔ_צR9l4I(%?)HD$<>f5ZoΜ y(~<[RYUD)NfED `| 8UR6ݼ-PMZAs%4 '" M]Jj:ZӥkV_$E3/&[Sxmz@cN$O7(BP>7p9 RYk$(tAYQ@8aӪ{e΍XlJ'!q(s)" uh$-oS (fi(KQ]m[J ]Z|JU4&0Ҕ"c vp.ۻJc 6QxnWt-&WmIM ܐAbVNpy撔1µ3'l U8MʳAl M9$̢4י`*IO!}OR*zZw[y[Ɍa.d}GKosqjF0ſ?(Ah?e߫ԗYG03Wޖ;EFSO4|Q\6ϭܴL\CL QЖ2u:n]yaYN iX􆁶4z̜/N^gO+2:n;&RMfK(I$!ůgs;h'yuedt/?QV}޶is(K6gW*Ɠ z>*{o #M8Hh~E ky+}/2tHnNsirsY}~~sxQ!=Fմ4|͇Dܼo9@8}=qlY_i2Ób}U=G7bͣTϜ1/QhN%۴dO'6N;ϙɇMS3lCuehV]g itٰ?sK2#kw+NmYYi̞y20?ZZNշm>\L1NMX:0Hautopsy-2.24/pict/hashdb_h_nsrl.jpg0000644000076500000240000000217311070040246016713 0ustar carrierstaffJFIFddDucky<Adobed       ? 1A"2!QqBR#3arC4%&!1A"q2Bb# ?C)Xto`gv!ӧ7ٶgVβJyF$4Qv~,Hx),xq0E1=^ݻ5w5HY5ٙ\P8Iwj9 q)?рOB 5@(;X2٫qJbqibBHq&8Gtu'D|,y[ZRTڂN0!뇈ClYבVX2ڝVU5O " .RLCI]<mo4fQ2% Jio]uT!V=wevWIFᣐW] ]X}MsU.Ȼ!yڔ3zUI,& =λZ!x vzu6o^45"DƘ$ǑvjIkVaka>) *zz_OӼ3rd`|hB;+3`A/:_~4~_T. 压L{QW=RA+uZ Yr2u0G6Ole)Z권S|M,&7)o/(̜ )^D?]3GO)~_ͺ8ͳ2Sautopsy-2.24/pict/int_b_calc.jpg0000644000076500000240000000344011070040246016170 0ustar carrierstaffJFIFddDucky<Adobed       !Sd%1"AQ2aqbr#$b#!1AQaq"2R ?8v)uo~u:Z"WS-EL"'Jwx=H~R)Nn?}O18SjSNGڔu{~Z5]t1Ͷt$8"(8~7vL"ph0#g"d0ݭ%>bY5p_f6[z36*:@>$ DTɄa!-[pʶ GσC,yL15])2"֓Pmu!NY'!~0 `+Mk!SN+Q;MxD69Pߍ%tm@q5WIWGwoPB @YГR"kwWQF'{Y$:h ]}"2cB!V?߱Up# ' >ˆZ"J&5>JCz9e+p7>ԧ))' sQ#Jy°#`L~H)6y%"(ʬ$GtG.fX*"%r_qA]VY#22ΰa\QSS:E6qΑM9ASi^yng3e+a(6[oĖ$ateM*_ {cb ŷ3Ň9g86D`BAzU u|;hnhOz8V6Ip$OO_ -\x Vr>7֋|l q+7|T~đSj`qP-:)"Cq˴@`dqE\~tVо)C[-k[sn߁[|I-Ri0'Oڝ2Z!hba $}Z"m7؊'zӃw:'Pu(O9*g=7x򭶈hS#彃mDuPѡ<)v嫭vԣmt A3.-YlrN/zւ>(C=}xnn$,>lwsanB1iuQqmT:1¹EA1 N%KKom5eɷ8rK"a#_Gtu}2;]*YGz5>uEu)F"JsQHҜn )ݸDlUIQ"*.;<QLDZI'XH0x0^8uܱƪޞcӆμpԽvd laJs4V0$Dӷ[4T=Nl RLM;UL5I34V0$Dӷ[4T=Nl RLM;UL5I34V0$Dӷ[4T=Nl RLM;UL5I34V0$Dӷ[4T=Nl RLM;UL5I35h&:j*Ɇ~ʵkKwu~Xi^vlW]twautopsy-2.24/pict/int_b_valid.jpg0000644000076500000240000000317411070040246016371 0ustar carrierstaffJFIFddDucky<Adobed       !1Sd%AQ"a2b$q#4b#!1AQqa"R2Bc ?8yt@`_n~u;QH(CD)\Қ>Ԫy\~R`<1q#JydaW+]Jyd[gej}C'BJW]eQzoZW?qLm5t%Klw@vXFlݾwp9GtE.c?Fo#&×-Իur,!4zEBf@%!UKEQ.ʾJT7yDU`d$Ѩ+e_%fʬ`.!+[h4/!]}1_ *U۩kB O]hyX<.K!$-]m;kE7 |\~R l\~R`<1q#JydbGڔa7dS"'B!qK`+"(ʬ*Q8 heb"W&E:YQScXD҅+ZTbu֑F")QZDR>O14FdV -Kg;Y?R6EpZt^;)Oo]UG7pMj*va7+,GaiS˖ f:{ڏsԪcs!gZeZs5姹>FbsRlQD `ڕJZu/B[O]E+/JFFKeÈ&_ethWqCR9Īh?<Ǚ~VQ:fCMyRs0BU9dF*7P}iJTn"1DlUIQSMTLǟ#e̾E""5Xb"UO3͖|7^>c?o}8? Zqȇ'놣 '=?31aC=?31aC=?31aC=?31aC=?31aC=?31aC=?31aC=?31aC=.owڳ6:*&)Uwy-+6^hCkJYautopsy-2.24/pict/int_h_data.jpg0000644000076500000240000000401211070040246016201 0ustar carrierstaffJFIFddDucky<Adobed       !1A"Qa2qRB#!1AQqa"2Bb3 ?K9 \aEH̦\VKciE'_\ ݣUNq^B6O3 b0bSTLkL &QHhaTaɎUOnSQ"uKUq'ƥ|KA>ˈSV;1أI]SXti147n D}^.<5@{^aٽDNK(6&HIw"&u}]ʵZvrd0m9&mzUN«n9(IL줘QнnH./*Txd7L,jEkHȰXܝtXIZt{xͲ!ΐMDDKDꪪױ~ikV3gjLjqqnqtljcUA_qUmyPߵ,㟱D^֟q)ؒj/骝͌9f8W\UD@*t*ѽCF`¸Q/+dD(I-\v_)ZǓQ=Ъ*:'AUxkq%m 8-O|$}}"dWMbiV*91mlی3kiH:к/]k̤'p\HvC܍E;[L}uIV6hy8}m0r6Phʩ[&F@j&ܯ奜Ώ_w%) Hv7[".>ɮJ+);k;[qX~k/;)#>Q[oroxx۵#gWۻSWP#([AEN:6;'r~B+UQgE$yRt4Ts^ ξQmAX1G L">?R,A;Q:ƆςG@ڕ <"8[_R&3tיQ㏹wߙL TZH)8%G苫[zqm:G;D_gW$vάdM4zIy jډ9& =Yt=mdx`CmpH[ݱ$:gOt]ێƀ]h@4 +g=\hӹ|7a3ǖ]hautopsy-2.24/pict/int_h_img.jpg0000644000076500000240000000372511070040246016056 0ustar carrierstaffJFIFddDucky<Adobed       !1Qa"A2qRB#3$1!AQa"qB3b ?u3?2Ȭύ0L䞵X$܌X5֮1ݎl>B$8ܴ5/'ƱlMiIJKsR؈F*JFŪӆ9Q 削IJAЃI$2C٦ Bqf0X:1 ͈ mo2X.+ط3t*>B7fN|Ijں(łrMrx죆#-|TE9B}//?sZX/В;{nBH㷞MfBP#t>QaY@d1!&䠪%MܜB v /Qc9zrHxZ_joGm kWtK5jNp $₩ٿoثC(_oֹĖrW`@!Yr#sSVblwt:_nXZ$IFuJ:U]>@2^,&zŪ$ZT`yse ЮIj-_7ϱRyZV"i <[e*xhZ_@3/g~:JY,MGK\,NIaWc:;_1آjO|Q X٘2͸^d"G c=bigx_Z܎pf鶶nZŋvz.cjZTl!bx>GMM|s6I4 hnU'e;"6EݎuV^n?elvBgtbnQmIqzdNmIvȄJF 9!c;+Yl, qmdrun rlsm(<|5'je+F¥ҕWʎ%#\z=.k%vD=5]uK@P!'9,(+ #sUˮ_"UqB=L]鑵I"dQC-8,Q_=G#JgfUVʖH7W<(;x&Ǵ䝊[ʨh{ͥx#n:& *؟kc]:7vVV?Jdp `פdWȫS>:J5Hsy]dnBQ;ѧ'',( $ER4|H-;;y:ÖܶڿZ%䰠qqq2\5T!^3A h@4 h@ 1=tܾ٠3 autopsy-2.24/pict/int_h_tl.jpg0000644000076500000240000000214411070040246015713 0ustar carrierstaffJFIFddDucky<Adobed       \!1AQa"q#2BR1!aAQ2B3 ?GCJ~эdN~08+q #yjiD:hVJiV5v45%l1LuK&3}c"*d{$/d(h||Ds=vJcf4peY3c}0("//-vj`H= [oA7 P@"U]uUֿ#ڋC۔pV%ki؛?&7Mbk%)R*I5YX,#m^k{YK0&( Y$_crm~*IEF@{Vz qf0\aPLKUiR=M!U)ȈFCKEpH6 H[|FM6)vDNzE7ZdO;"Ksv:$Wm:ut좯,&qtׂO rSX.R\H)Ѵc qغm5:\v&eҝR~< ,lWmpE]w>׮{W)3_46D1V mk* g͍_CˬY W" DU6SN$z^j)?Mu\R7!8?sw uuY0rk0|4@r, ƫ?Me&^'uKj[:~~0qhBtEׁ.kDz>M!ƹ4 NJo xN8㍱t!8qtautopsy-2.24/pict/int_h_unalloc.jpg0000644000076500000240000000453611070040246016740 0ustar carrierstaffJFIFddDucky<Adobed       !1A"Qa2#qB3r%1A!Qaq"br# ?|#W_"t_a]c%I\g>3q6TKOrCU &\?o|*#NۮWZ 'Kڈę-$\+Ƙȇ}ɮjLdEQ"cm8 16tTmNʆ-c=) h`9BW:*OM&ոM4D>EVԠn -ĆnvCĀa5m?͸!qƩmcyMoAb5uBNyFU6о3`P5SUaREejKj5pUd# U1j{^[ƪaFgb8s1Y=ý0f!"< h7U'\cwUּ7$|my '^tlB""\'UUU~Ē\|`f"Pc^~ő(սf%2RQ-"\Q:uưDuk*Uք6UP t.qq5IoT7t_(] ' (#yކ+Tq5p,^AI+ar#_oi$6[0C*AL0ۨFfkDO FZɨ1,ؖ;ãJv55Bۻ&_z#& F'2mEÆc?}\x ؐ<F{Ĩ)u$3@,{kZȓ.x+0f+Ъ瑗¨!/oD+*=f^J\ ȡ4ˆ ۄو|*L0u7l{>^6~;ot}v8i! ʫpZ'J`G1ŏrrfy,I䇦8J$h*"u]tKW#(]-l`p ccH͛ؾur%hۋ (bkж;t3q&>TR2DN*g9'nFԐj 9U+dӨТԍ[$ەS-,̄spY85bb( BIݫm: Ua9ŏ9^8!`H]Q}p]rd*K?*?㚪I[Xl.Aj55t@OIx`Љ#rb+oyDjw)iLZQ$~[U㕓M 5tPДE1]s$J|.uM$M}=6"ŮԍG["^1a^V lL v^:' C+R2IoݼU$Qo]yUE'.T[fk -Dmsw*!!]d)I._:aUZBp'U't׺B{/muYO5epc0,*RT\0anA>AV9[ LU,w>7qaϮjZe(J u5NJQ]`bqj C(A]x˖H}86$cH3*Twƾa-h@4{w/mLqn =t@۵wcn:4@4 h@BgO.u2'@autopsy-2.24/pict/logo.jpg0000644000076500000240000011445011070040246015057 0ustar carrierstaffJFIFGExifMM*bj(1r2iAdobe Photoshop 7.02003:12:03 00:50:08Ƞ(&HHJFIFHH Adobe_CMAdobed            l"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?I%I$JRI$~u쎚}5u+QFKY%E KO?; bd3m1>܇Wb>l$c5S~́OSK#Sv<\_Qlf#F%w9'Rf7+ ]QK}} Ikk #Pi)$I I$SI%I$JR) f4A!W鹻~ibIh~ix~guWU]nwS~EGߧMtdcu}U8ɱF>mjuUY]z+ddt.N0/sM_RfJo?sӳ~e޿a~!0P3Ӧw)..F̊n8FF?4Bx,N?sR9.<P2HA(4|эpmm;om6zﲏrF~QysK`aģ_Fce㉇8fh//;d6_ԲVr/ƎsZb?}kZrum}T5۹;x},=jC`,cCĵxUg?*{^2ЍM񿱇.Q_I$%$I)I%I$JRI*؝?E },c]g*= 4cg10Yv7FcﺿS&U,.?6]i}.^NMu3eֺ2?W\LvY_f^Fnf`e5W[S[xxl+kό+@l6Sg4S,ƒS٭?R3zNūM N۫}O]~.i}bkiXlƧֲZ/ʩo|7u5.k`unwT"uzZeb]n~3RfU@ΑcI4xĠZM,nocf=fR×(r?7?ioHF[kO낗[6dze1fOӡ :V]t [q]xb]RNU!+g|_Z؝}cK^(V]zL\ֻs[s3e.fLbMd%7܏O`9Fh )$CsIrI$JI+/ۓ`M\6?]+v~jbʦwT.fC˯`jַGz*{lugs̻]z,p_dm[gj@E.lۋSs_p7>[;"05_G;kCkpY֬,e>/ϦoEjz}ոnCXƹMWU_Cr 0ю׿)j}l uR_ϰ{US}WYVi e[k+_C$kb/_`ߓ8feSCw]cj/y crΡsԫ}f_MueX?Ṏк?OSㅗOa\z,fWٷkDzd~7e`ug`;mX~7v~)fG^ O}T~[,űL{}i6[^/уޓӚ4;/fe+u/ەvlvEzo1EgSn-&6|=?IK(*R7 Y .4'ڷzN73<2k=ߊLǨ~uY~5dVzyG㵛g \I$x%/k?Krv9فOç-ߪX^K$ga5FڿA[eojr>O[ 鹵uAz-̣,ɦElN65k,[*ZLo} z&|5K˛5f7lHȪV@zC9 B$keUhUp{?zk.rtZΙMm_{-9SFn1OwFzvOYdeFE,m-"캪g^щN~wڽ߲c>t/b}\{v?OPn閶 cs6W~^=\*5*?58[Q;"{mוΥ(M\M T/F.=zGzuVѓ/YS# PKnpu-u8ؾޠܺ1Uv,ז۸ Z}'㲈}/Qz4dl06Nf}؝WH[EX1]fUՏG׳M_.l`oVnT3QwQ}b;ԋ,fC]so[Mu=[޴ze#(4?%ޮ+%>kFwޠn|uygSқ~U2B@TME]S*~-=9~S=?v7TrqMYĦ3e[7YWO롅GtLmuಬG ~a{l#ѵN+H8_-^]i:P}^ie6_V5YZZ?W3+'8+-nz;GKg;?J:_@f ̾B-hnN>>68m4RRUzXYx7O1ilE{}>*pS9=8?f!c^g먠tZk&Τ9 k/=&Wp:8H[m#Q鲯wmʱe}g< wںp۲ϸZ~Ī{s>gj뺇dSqIOKcC%^Z7;?WUr1@Hqd?R/' +S_ۨnE㵯G-ks7OP&78P\>[>zAu.ձȾp[[-X[ӻgpYWtQHmIiwX WL/ANXa{rP#+5#q_X#.cgOҡg`7ctkպ{ M\kƪ;ok7^X0XKI챍׾d:s(sm1-o*;1_]GOӰ /jrxbxxç|WD__Ey5ًvdtѶOwݽq936.`3(~ FqHI(~h?gț+xkxBXU;atzە\'xTz/ZĤ>dU3y.v+OsjQwQȻu쎨Qlu5:(n>g[euuS'LȯѲu 3mke+l9y갿Q__]%ʃqzt1}3ޘ}1K05:Qcf6wf{\׼}ʹg龖ӻ'UzS)ƺ . ί; ?VǷ7*۪%vO~Je u&-gPucduF;/о[~0[VNVO9gZ{ݑnC}q @2DcLяv:G/Y6dQ̇ѷ􍦷5{KGWG܏mN;طً}ug[u-eG˕ϻ ׏i8_YˮһK,*q鮚v>}]Xpg97:w?ߩ[dœkQp?,rF=B;?g]eU'ܛ3XMԆ6cחE4zGRՙ++ }8QN'Be5{OJb}__8> V(X9ֺP}0eE m7 :G\^Y~;\3\xYȎ.bzC?U "< Q#~c7ftיּVgOc]vjszmzzޅGiDZ1вmSӏoUcU^>~y_YY]Y +~btlKc_pZrEK1}z9 9Ʉp*RIcky2z=ᔢxezvaޤ%ӻ{=oO^Y+ߓkZz~S.n>_]l9jAyA\{Szl.{路`9=>U{i\C)"91䗤JqOLem>K?_\SaW޼?S;{ca9; *-m3UW_:qgn.=V`mōۑԲ{k>e~y=SY}_LSgl~O}H&M>>?CTl HE}PYZc6u&U]k:XnSrkZֱc15kFWSc;՟R}4 d/ zuh~S%vU}Y5dVֿm}j,PS[1:7̫֞-_rh!3.*WKIU&4?pw͏ѿ9[lób]Vܻ7sqiƱKoY}_gNtgZ}WesZK*c_V3+Ӳ~;nzG8e17L1| }V;FssdV/.#K~̿?M/MYmW)j[ouޕxϳ"˿gd7?}`Di†䣐w5?iy9G}V5*dGOapZ=ߚZ?acd[cMǧx_,J?b{\U}.kXǧWt?hPhotoshop 3.08BIM8BIM%F &Vڰw8BIM com.apple.print.PageFormat.PMHorizontalRes com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMHorizontalRes 72 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2003-06-03T23:14:48Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMOrientation com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMOrientation 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2003-06-03T23:14:48Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMScaling com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMScaling 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2003-06-03T23:14:48Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalRes com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalRes 72 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2003-06-03T23:14:48Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalScaling com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalScaling 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2003-06-03T23:14:48Z com.apple.print.ticket.stateFlag 0 com.apple.print.subTicket.paper_info_ticket com.apple.print.PageFormat.PMAdjustedPageRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPageRect 0.0 0.0 734 576 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2003-12-03T02:11:23Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMAdjustedPaperRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPaperRect -18 -18 774 594 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2003-12-03T02:11:23Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMPaperName com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMPaperName na-letter com.apple.print.ticket.client com.apple.print.pm.PostScript com.apple.print.ticket.modDate 2000-07-28T22:57:04Z com.apple.print.ticket.stateFlag 1 com.apple.print.PaperInfo.PMUnadjustedPageRect com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPageRect 0.0 0.0 734 576 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2003-06-03T23:14:48Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMUnadjustedPaperRect com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPaperRect -18 -18 774 594 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2003-06-03T23:14:48Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.ppd.PMPaperName com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.ppd.PMPaperName Letter com.apple.print.ticket.client com.apple.print.pm.PostScript com.apple.print.ticket.modDate 2000-07-28T22:57:04Z com.apple.print.ticket.stateFlag 1 com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.privateLock com.apple.print.ticket.type com.apple.print.PaperInfoTicket com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.privateLock com.apple.print.ticket.type com.apple.print.PageFormatTicket 8BIMxHH@Rg(HH(dh 8BIM8BIM&?8BIM x8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM 8BIM8BIM@@8BIM8BIMM hash-autopsynullboundsObjcRct1Top longLeftlongBtomlongRghtlongslicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongRghtlongurlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM8BIM"8BIM 5lJFIFHH Adobe_CMAdobed            l"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?I%I$JRI$~u쎚}5u+QFKY%E KO?; bd3m1>܇Wb>l$c5S~́OSK#Sv<\_Qlf#F%w9'Rf7+ ]QK}} Ikk #Pi)$I I$SI%I$JR) f4A!W鹻~ibIh~ix~guWU]nwS~EGߧMtdcu}U8ɱF>mjuUY]z+ddt.N0/sM_RfJo?sӳ~e޿a~!0P3Ӧw)..F̊n8FF?4Bx,N?sR9.<P2HA(4|эpmm;om6zﲏrF~QysK`aģ_Fce㉇8fh//;d6_ԲVr/ƎsZb?}kZrum}T5۹;x},=jC`,cCĵxUg?*{^2ЍM񿱇.Q_I$%$I)I%I$JRI*؝?E },c]g*= 4cg10Yv7FcﺿS&U,.?6]i}.^NMu3eֺ2?W\LvY_f^Fnf`e5W[S[xxl+kό+@l6Sg4S,ƒS٭?R3zNūM N۫}O]~.i}bkiXlƧֲZ/ʩo|7u5.k`unwT"uzZeb]n~3RfU@ΑcI4xĠZM,nocf=fR×(r?7?ioHF[kO낗[6dze1fOӡ :V]t [q]xb]RNU!+g|_Z؝}cK^(V]zL\ֻs[s3e.fLbMd%7܏O`9Fh )$CsIrI$JI+/ۓ`M\6?]+v~jbʦwT.fC˯`jַGz*{lugs̻]z,p_dm[gj@E.lۋSs_p7>[;"05_G;kCkpY֬,e>/ϦoEjz}ոnCXƹMWU_Cr 0ю׿)j}l uR_ϰ{US}WYVi e[k+_C$kb/_`ߓ8feSCw]cj/y crΡsԫ}f_MueX?Ṏк?OSㅗOa\z,fWٷkDzd~7e`ug`;mX~7v~)fG^ O}T~[,űL{}i6[^/уޓӚ4;/fe+u/ەvlvEzo1EgSn-&6|=?IK(*R7 Y .4'ڷzN73<2k=ߊLǨ~uY~5dVzyG㵛g \I$x%/k?Krv9فOç-ߪX^K$ga5FڿA[eojr>O[ 鹵uAz-̣,ɦElN65k,[*ZLo} z&|5K˛5f7lHȪV@zC9 B$keUhUp{?zk.rtZΙMm_{-9SFn1OwFzvOYdeFE,m-"캪g^щN~wڽ߲c>t/b}\{v?OPn閶 cs6W~^=\*5*?58[Q;"{mוΥ(M\M T/F.=zGzuVѓ/YS# PKnpu-u8ؾޠܺ1Uv,ז۸ Z}'㲈}/Qz4dl06Nf}؝WH[EX1]fUՏG׳M_.l`oVnT3QwQ}b;ԋ,fC]so[Mu=[޴ze#(4?%ޮ+%>kFwޠn|uygSқ~U2B@TME]S*~-=9~S=?v7TrqMYĦ3e[7YWO롅GtLmuಬG ~a{l#ѵN+H8_-^]i:P}^ie6_V5YZZ?W3+'8+-nz;GKg;?J:_@f ̾B-hnN>>68m4RRUzXYx7O1ilE{}>*pS9=8?f!c^g먠tZk&Τ9 k/=&Wp:8H[m#Q鲯wmʱe}g< wںp۲ϸZ~Ī{s>gj뺇dSqIOKcC%^Z7;?WUr1@Hqd?R/' +S_ۨnE㵯G-ks7OP&78P\>[>zAu.ձȾp[[-X[ӻgpYWtQHmIiwX WL/ANXa{rP#+5#q_X#.cgOҡg`7ctkպ{ M\kƪ;ok7^X0XKI챍׾d:s(sm1-o*;1_]GOӰ /jrxbxxç|WD__Ey5ًvdtѶOwݽq936.`3(~ FqHI(~h?gț+xkxBXU;atzە\'xTz/ZĤ>dU3y.v+OsjQwQȻu쎨Qlu5:(n>g[euuS'LȯѲu 3mke+l9y갿Q__]%ʃqzt1}3ޘ}1K05:Qcf6wf{\׼}ʹg龖ӻ'UzS)ƺ . ί; ?VǷ7*۪%vO~Je u&-gPucduF;/о[~0[VNVO9gZ{ݑnC}q @2DcLяv:G/Y6dQ̇ѷ􍦷5{KGWG܏mN;طً}ug[u-eG˕ϻ ׏i8_YˮһK,*q鮚v>}]Xpg97:w?ߩ[dœkQp?,rF=B;?g]eU'ܛ3XMԆ6cחE4zGRՙ++ }8QN'Be5{OJb}__8> V(X9ֺP}0eE m7 :G\^Y~;\3\xYȎ.bzC?U "< Q#~c7ftיּVgOc]vjszmzzޅGiDZ1вmSӏoUcU^>~y_YY]Y +~btlKc_pZrEK1}z9 9Ʉp*RIcky2z=ᔢxezvaޤ%ӻ{=oO^Y+ߓkZz~S.n>_]l9jAyA\{Szl.{路`9=>U{i\C)"91䗤JqOLem>K?_\SaW޼?S;{ca9; *-m3UW_:qgn.=V`mōۑԲ{k>e~y=SY}_LSgl~O}H&M>>?CTl HE}PYZc6u&U]k:XnSrkZֱc15kFWSc;՟R}4 d/ zuh~S%vU}Y5dVֿm}j,PS[1:7̫֞-_rh!3.*WKIU&4?pw͏ѿ9[lób]Vܻ7sqiƱKoY}_gNtgZ}WesZK*c_V3+Ӳ~;nzG8e17L1| }V;FssdV/.#K~̿?M/MYmW)j[ouޕxϳ"˿gd7?}`Di†䣐w5?iy9G}V5*dGOapZ=ߚZ?acd[cMǧx_,J?b{\U}.kXǧWt8BIM!UAdobe PhotoshopAdobe Photoshop 7.08BIMHhttp://ns.adobe.com/xap/1.0/ adobe:docid:photoshop:2470773a-978f-11d7-9105-d3cb4fd3ef16 Adobed         ""     s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?fWb]v*UثWbWWVv]]H¥74pV+ lѮGi/D˼ކ]oR v0'֐?*07IPӼNojI9c5Fo9a!"ӌ]v*UثWb]МfWb]v*UثWbk_yxJ .hX$gLj}_ۋ@P"DmHgAMlXTԭ>_9dE[7t stʴdtJZ9 7cM3z?ט.}"H/kI#n]Nɖ:4YnT]v*UثWbќfWb]v*UثTUm W۳}%')?rB$WyQ̋4FS,9*Ö",;}< }~6=mۃOQ1igb}EE`;TNUPt,Ե-AlfB ʀTӓFьbg1h.I2pL1 /:,$"Rm[0Z[hJ%crU\<}R+{.ngk5kPr=.N3x^fq(xZ#M e:Xqa*W cLQ-kj)%{_BqFRf4~Cj' _ oLIG1'38VyWy"rՊW1Œ!ETl7q!YRY*YUn? ƙ\1bQ; e,GJG^X"y^[yLd˂}Nf0pr|9Չq&Ua wli|_Y=Ďs@Hz w-lHm܃;"300/Y'>ua mnWU4:]01͌\La.Tu[i#9 嚌|\@rUMgMgw[Dچ=/ :HN"cAiRv*UثWb]՜fWb]v*UثV;bO-eYڍA,J o EMGK2ޅWZ[Դw8\bicWb]v*Uث֜fWb]v*Uت$(YX$q 劰.|:wYd<ʮHeyWmdE2 unPUnS20)ei2][paja?W9v*g!"ikfp W7aI[HU%A/6,>/ Gy*\0VR#mAz5N+-շs;OKcU?7p'_Zq^%CFLQثWb]לfWb]v*Uث l [ ܳAR=ySY.maM-@,./>o+,0+sZ8JZEއr #6Huw\zAG,VuGg͸?s-fg?湺o's GML@" սjSS$qӱ}a\|{V/ RtQ̄$K\Fuᕏz\UثWb_ќfWbZ$(,vHu/5@d#oJJB=?tṕIcqGBǨCӀ L++/mb)EG=o418_.M1ncb+PٮYU$fsx|ͧ0~Ob}8dh$=OVtפּvgJ2UѼg,OfdAR#oOZ30е=fNͻ:j}b=J=Y)`,@y9iV?{r/L@Nfxido[UՎEh4Eje\j#ÒCrrAyI}WE+ܲV?NKh3YA?DaQL<5HDAJzn>V~Tb]ҜfWbF];OG[njUَrZYaomG%k[7Qn;8YkV:>m8oV(BA9\N[8d1k\!yn5.=B7$i?iSן/އ_2ŸY_,@-&47}9!&mN> ) ԆFV=ʕUثWӜfR pǛWӅ)Ody a:'(T.d1̨bȔC5E.څ'+R?oݗ䥐eV:^ =""}^8z =Y$13&`Ro$*B6+,2ͬe DԜƃp.f9zl:mrQ9;IPqcٌM>8&Z?VOM ֒25ɷ5_ynBCu- sgjܡ,7&8DMo.5c@`if!qEOClA2D;7jEP ɒ,Z*k]fEg\obH]m o]P0|G_@Sb9V3$;O!,ٱHII *B7ag9(?j^ҵLQgOAVW}?k̺,_/ #_m5xO8f m?YiOB^M;viPR_v_菙087Q1;pw"bԔkvs{m4AJ׈ʅێcV3]f}ud##PF~6V2aVeVjH)k]H ̬Ū;fjOo-O6Jx;[QN1(azh?a?5HcL4#</(ڕq|Id>_&[=^-˺4L"NT~QzIL=(͆;b? <ipUY7 O`jϦ_W*A?bDO~, A''^H?#jMq6?w1_nQݧ'?w?TK8[}cDq oh2II'9e刳'L35WSVu=6]11 pWYjYXnR܏RΫ0.ʒՙ[լf5,9[K/{;,flqvC_X5MỶeb͓z~4}qN~k֌ȶQ|R H%nXe|J]~K`#kGG9&}DT[ezP:6}j| Kj8o,dj4C6iI?.50h)" IZIu(O.q@ȱ֜f >}Kp[3COa_NyVgyni+ı]xcPӷ["#2,>&i#Feed9qVNMn"Ye Qd?<< =6jzi ~?YvmQ]ywI9(Jˉ>P2A 1k/Hl#o _H38f,Ʉ8C\i51 y1+K]BOKmBqq~M$^jk"v"W͗z5{oHk1P x71@a2Y״$k-4[9K!ȟ7HQw:EP"(e 3Cc>cI}c4Z4`Ku#/!Sx+}e%Lji3\Ko6$IJ"}?01sO?fG+!D҂:z?nF13͓,#m'eנlʗf(Kw >u0F2=.)ֵy5{qa\4jEZ2Uu$iqIq^g;9]F bvx$,#rnR?8M}LZY WlaL ]b kEL&^*FkМfP7Ѳj~ؿFBy9c"/7vWI3fAyo[}E B>8UhwKc یijj 4i!g2r/#8H I^H+fEVVfP7kb?&+|H{[69"O<.rnĭ oik- QF'UkvKnÝߪ+M??4Rd ?3>;kxȒHz-qqOe"z<'4\f%Ha2k  ^@-8 .6&-@i%ѓV7Fc-|ã֨*#gvߍsn8pHoZq{Elq05R2DcTzxXis9;joe80m?edD{DS:sO zk5+ :2 Of7ߑt[mQj~E-5+>%R#kݿ33wqSzA/1E]'Y&nH  iќfVHll)[g'73}.fbD&}gjͤ>,,2|hܟ#"k`icSV@D=?npCoioD/N[Jb/Ԣڲ/%)ƞ3#qKVORU3X)Mq_@PkО@ATiSP)o1;8pn~Msoռ1`JKnOPri^nhNy,uKIm$@2(Qy"b/!Qg#"h M2Jׂ7|<"om=x93Hq^3'U)4*).4Iޯ:&l"a0dO2*9tM+(㆗A^(]HzOҕyP7>¹p8q%H9z4xPݖd *!Dݺ_tU9N&AfYg([[{|2ǭ Ɛ~9Vx@ÇR[l8wu1eߵZgnQbQ<4⊪+*-Qtm%O,)*8_ HVԾ6InMمۘY9h0oY  "N+ē͒%'XrL3%MmZ|(&=.Z@T0{xG2,ifE}iAU+dyi.Z8[^_7켘تJ?9i)$E?i0$ R(uWGDp {QJOU9jl~*z[vg[yt8er_-UgH+FXIOƎJwL w#Hr} B N _P\W=`^|stf;+&5%$F/iC5Tnꕴoh` O`jnc6B)aBM2;i PoYʮSH.5|4L>k Ѣc@2NH(G Zع8$^ꕻm+2I&]?߾j%Ǚ?5{n?3FFFRpa!q 9_UsmUv}IU9VuZ&7n<'x62$6\gX(ɕ}G \$j1{Pk,n, 7QaGnødƺƥm."ETo>ur3|t=!i=dxn=OJ֕ӨD  du~VUi l()d_E{pbWՔK0UXdIOˈH> ȎN {um$_bחd_48e>!kJٖA>{? 4,}7~iOfYnY4Ҟ̲ >!i=d< mL%HPyV<:yvM6Z ߺ/mQ*(DJ"[O?TfOM^#D^ִLQ m)Cft'0K/N D.Eq{#vL\{mء̏qOPo{_|EAĬq]6X^K\E@V${+筢u]ֱD%(DXuUwq*LۅcʎE&\}tڱⴄiWggḪ !k&oAƴ[ʃn5D7fywC=nF4>{ӛajNny9nF5n:W~r<Cz/'[2k-U)Λ\۪Y,'!S`![i\K)%xHQP"<C6XLRȧHywdHA#=gN,ojg4PM6j Y +A63v郄PnY ,dw1K[lѳ&;M))oj][#NiME\4hLUp8!W>5\DQbeilT2yN: n"n80 Scz߅׀ ZYS̘J TrMN̡LoM/m?s-kv3=u"޽I("鹾ϼ$.e (S@9 p ғaG>< }ilW8kRBjEv4*&W5e r&"sH&i>/,nu9!㽚q'=CitQXY3TwuLiܶ8XTd2o{֪O3u% mKiZ1DL-o$g|C/?tR|jݮ9Yzڸq"Z("IP6yNJCߚm_D;4I2jcmw?/,^JF_Sh^XS~\&`9FF|/mlwtWv=e6mYn"hmYn"hmYn"hmYn"hmYn"hmYn"hmYn"hmYn"hmYn"hmYn"hmYn"hm='nSp1EeNmJ!-q# rpːaQ0@ @ ?W?]q1wøF-Fmǡ]Qqs|;bfz1wøF-Fmǡ]Qqs|;bfz1wøF-Fmǡ]Qqs|;bfz1wøF-LfX~q1Sautopsy-2.24/pict/main_t_fil_cur.jpg0000644000076500000240000000441011070040246017063 0ustar carrierstaffJFIFddDucky<Adobed       &t!1SAQaq"B#2r3$%!1Q"AaqBb2R ?Cf:^}!*x?;].2v2?c)BűkI/y;Ub#w]ja֕hjI)>k"C3AT6-mٶ)5*)y婦kPV̞ct*b\7n׶΅ $,5!ZYI$eY0Ӑq5fBݥP 2 w̠M$T,|\G/]uS?"m÷ijBHd s^}G%2Z?d+z6FvBs4+󌦵Of*% AxcYe5[gBCpK 9|h$sm5ʈN yJ5ɯ wiۏ3|lYM˚o+Bxl} ":vUBBBժ9Cׂ+7,s??dPjrz.%)Ȯ4Aʆ9;}WEq92AI?b.cVL~뒇wFu5٭ %I~tܐY`uqK6Ϳ'-nuTؓu1m\isi2IcɄXf 5[oQ1mbh.-&;EqEiAJY>TɸDdsG0]nú^ݱyEGbmJ+T}9JO*/mRruNR}>xC_vTk "lʺ8@P[aeIʎq+r;,*3d&l jZ-0#I 2OI;iTdx'Ua6{qX4Ǣ۝yL d̩2DzDc?q!XnJ)+ 6\F#ZŖlwvSDT$g)MϪ#MHLĞ|ͺ8m5L;r*%M8<U6Y#|3{J^a?M;J`T ZM?8rLznY?n#Oٖ{OۆeG=h}gmOfZ;^ xTŕӸA:х29~KN8v(f=~3+uK0UVdIOˈ|Ȏu-Xq^LrZLS=7ԟ6=h}gmOfZznY?nSٖ{OۆeG=hۖ,)eiVc!pVcC*tiN._e1wvLvp?ՊjN #Miʌސm*ZH+ r E%87h ΄[k@yJ1D/"nbMv|2۱QwfSe8W9R֕7ψ#r|JȈ5ø#R_5.#(|yc筢u[U)D`#F̹}jWljKVܝQ:=Ò5ZWrt{$j^w-x39#UMLY9Ors?f5V|F9p{q0biO\R9SЮ`>Fdؤ9kPY)΄&oD9f5jfW%֫TjNz|pVܝQ:=Ò5ZWrt{$jFHjautopsy-2.24/pict/main_t_fil_link.jpg0000644000076500000240000000372211070040246017234 0ustar carrierstaffJFIFddDucky<Adobed       &t!S1Aђa"#QqB2r3%!1Q"AaqB2Rb ?Xq!/> 𯟝bv[Sa"_t+-$WYv-SZVU;M$k,W#%ݛnBCRZmF Kk&8@#2zEseոpݻ^b:7ԐԇYie$d8R%U@f!7JjeAAB(HĨ,|`:q.i=J;s&;|6JV.LB >|2ַg8Oc\1B!\Vѵ'$3 TN8% vƳ(!0q-$~NuK%Gism5ʈN yJ pY8NvF6d,nei 7҅fPCFǔeCWTmnʵYhHZY,:N< [n]/Zeĸ2OlTNɯ*^T$Gqi#"Q\3|OQJT֐ӊʤ?r^[GMnF'jima9msҦĘCj[N;.;N)H?0"/ˌFҴbK:Vuk[X" @I\itPRp8:xVCk8EdLji֝Yu7vQnߌP="6إ*T>'~5k[5rN*u;XmfUF8ʄ(E_[.ETTu\.[9=\e* 8Kǫ[ܶ~m?tYٹѣJc)Wi0ɘ\msQZ[6TwrQeD ÀuBl3tϦ7 1Džkqݿ[Vg0'V,Zo&ER9_t.sRLguTUE$X4Ho#42%DAnj?f=X񤔸ʣm<&dD.w+'ҌJ4H6niIs=cI$>\k4O_le*E*ཽܱ--* ۶vBY. J[iZjc1K#Ž-۳"9!6f:hBi#PY^۸'.|ٳ8s&[66'u$x }K Xl݊8T˧nNQt¥ ^w*V+oQ"+ 5gܕz]\ܓq4_t'3NuܥJ d_Z\OVO\{`.3m2ӻIgf*2cRm5&A8ۺH OdOsnVT,%ԫ5?:*lFΕYF%WW +؛ ~C | _ 0*K]E Mēp$9jnn 7h|5^&Y >sݡHeM= 4&Y >sݡHe$gkpx"{UHrNYnΧB24DS#}U1=)/Kf9k(Q Ȓ|AOm$/kpQjrUT.zn9k&&Y >sݡHeM= 4&Y >sݡHeM= 4&Y#f p&YJ8>4­@ry22|72m6 "ƭ=2L䑦ܿBjaN 0FgByP r^^$R)X7kĵɗ݊)X!b8c^o>*֣[j)GxzRa|pËKY;1ɌppnRdvs8!a=>m)Ip{puYQGxzRf8Wgautopsy-2.24/pict/main_t_ftype_link.jpg0000644000076500000240000000334411070040246017611 0ustar carrierstaffJFIFddDucky<Adobed       &tS!ђ1AQa"qB#3RrQ"!1qAaBb ?6nU((`Qhq;1.{(rXvD!t^t+f5Jfh|j @ ͳdk,KLyUY=uʢE>R37 &!ƒ*K*V`l cn#gR {0r4X4{l֧OpAš).a0iUTB_"U>ʱiNi>UI9P2"nb Dٶ6GRqUéF)[ky+3p S]. DVnE@g2CH@vF/,ӥ"a;U['S"%]9>LD`dJe 2[3fZ<̠"V&bŋzd]2A7E^xB2 }#o^>e(AE!CD3e/__^E^v)ergmU1JQM%scC$3vv9%dQ)Fe+I9ySz[LKGGdtTU佽--*@\EN*:+֩%I a4dF'+Œ1GɈqoo6CelW׍8U4ȷ'R*iE.ͪs"tĸ[{+fZ1(BQE9HÖ+R699EӕM iY4EDnAMRU$\֩3JW%(Cqoh%^?rNH~ Rq-Yzvts;A)8JUS:[JSgF6~iϧ&Qvͷ[pnQW榕c@W{|숛Jӵ@"`XL͂"n拂&sBfl Jh>jCpMu"u*钤d~F.Ay.ZS IW9w6iTI vBߴ7M/TLRAH?xn⠑Tl Y˯LRr+S"wO $ ͤ>b#F1e{z^1ƣ!Z! #ɞM3Ӌ3OuM8{l"y9-6TTb(lFtŚUbL\Z-­ Jhn0JviPZESD9h4Hq3 )L$/~Fuʕ7R4\3^LS*Ngp(Z*$-HPPMM#P^x!}( %/TJ`Zq&T֟[W@RXouM8NY eH*%L#f8ҫao+:Zq'1[4-&JxWU6:wm=if!tym'm=Z6jGxah٪HvsIᅣf!tym'm=Z6jGxah٪HvsIᅣf!tym'm=Z6jGxah٪HپXRˎV~ET?{.9 J:c<L`@ @sbs%",(wd-S %"TUVىԕe13 8ऋar"C %o4- R?&KAb(*Vo uqy3hqe$(C$|(BAI?VG G1m|]%OPn ӈ%##v9VIx$G-1+0/'JX|./%TKpWd+$֗9g_i[0[ MuCrݚf%M'Y[{2#~i=h?Y|ڞ̴ny>ZmOfZ#;^ Y*Oݭ+qeYr+;Fo-8g-H=U,̮9ՔK0JȒ",* N%_ [q  חd%_48es~kjٖM'M@weGpgj{2#~i=hMzWHPyMu~#Jy:t4jrX7^=5D^T"("ސmЕ-$z֙*$s= F)%89h ΄[k@zRzRJn^"ni{'^ \{mب)2+ԝV HMkWψz6W ^iffT޾z*0BHl"-bWy&m p#׾ݱvʣ$ u76n9JFAcY!$b ?Slh?ZݬLS~,3+'",JlPr@Lemʁm/+ 4|QW{:"V@mK+ tf* &K '#jWWvYj835m/i)ѩ7jN]TYpY1cշ;&G2;w& onmdL%1SnTTOdO1j3n=bPZۏC#6.uŨ͸9B1j3n=bPZۏC#6.uŨ͸9B1j3n=bPZۏC#6.uŨ͸9B1j3n=bPZ͸}Ecautopsy-2.24/pict/main_t_img_org.jpg0000644000076500000240000000271711070040246017073 0ustar carrierstaffJFIFddDucky<Adobed       &t !ѢS1"AQaq2BR#3Q!"1Aab ?O).NI\)? b{6dNVDh.Q+w5#o\2H@TBC`EE|xd7fKG piC 9J$"Ɖ(SGH> mB&-Zcoqu$˶`4K樐͸crc0"E\t)+PRN)9s& a:ʯu[&6N+:TFQ E|R ҋ_(M&RD7GQ~r7omﵢ}8<$ޟ6 ɿvyS59M(KQp4yM aeqF=$IѠgɮeJQ2`@G|mpAc{+.ls{/ye\3I\K "6< 1A"2[Ĭ\gI17s`P+.B˧I"»jm+pJ,#,Չ*J&Z4abQs{/<>?exrݤ֒݉sOg\'ߥHLeIFfI!*2{*C+i2C3^\$i.E >j\i̩f _13v(/mXcse&@MZ6efl[77gbZ_Eism zR u6ay4%(D=7M_-2Cy>4%(D=7M_-2Cy>4%(D=7M_-2Cy>4%(D=7M_-2Cy>4%(D=7M_-2E^̒hD|/a]; 6ZP @(P @(N)Kzcj{| MB67G]t#j{| MB67G]t#j{| MB67G]t#j{| MB67G]t#j{| MB67G]t#j{| MB67G]t#j{| MB6F~MEautopsy-2.24/pict/main_t_met_cur.jpg0000644000076500000240000000414711070040246017105 0ustar carrierstaffJFIFddDucky<Adobed       &t !1Sa"AQqBr#3R2$1Q"!Aaq2Rb ?3EV\ GތWSe5,M`9B#Yϳm.@1TOLRl >ٱلi*.li7ߊGaSD⚂R%Qw#'-PS$okyw?d&NfnK}u[삫TȢf2tf(KhG[u_ۚ[X5|jbY ͪPQ(@)(ٲ,rWjY ?;zt:oXnW%``;".ܔ(k##,mF"Pdx*>(#G8N9NO4Q;EV:JFʺ&M18șswf49^61@HQ ^ׄo/d! R4P4 (CVY[+QjT]Aaȡ@}46)q jY4ۈ_*4QT\VzY!P< (ad6r0#ڹH?ŗ|y%h03z:SM9Js(C9%s-ӣB=y銦R-GtEfuQEB8b@tg%FRT%̚[{kVk&R\$*dPX"~\ss7X$lɲoRCYRX`lz=^ӹьGE9%.c( 2axӶ8JTNϳ- M,u*MQW.6ХU*T(T%L&XTY)DBc/1`ޤGۥ]Z2ە6UL])AɈ$Qam"lq# -`ni_\/,rIH$ت\k,bd]tJ)sjF0d!.erSm9|y_S\Sa6T!$*KQ(ǟʕ6>E54ln!~1YCD0#,":ؚNc7D?d4~K&8L=bf7 [g[_ WٖH<όhi̲A|eEHe--/G,b65X"bݝN24E,7ٮ%!P咒B@>,ŘD*S:]EWLpSSPbd=_+ʏUk|eEM%̲A|eEHe--/G,ymn|0=dlvᆑ$I;rC*+/QD>DކR˧ /T#@i,M>:I; c@T3$Ȓ!nW8 ỜK霁!vv}єSGȱ-] .⿋HV-˻mV`z%b.iryWvQIlAԧd_/KO۲>zt6by{HU;4aq; – [.nj|wpVw-f<.n (exRaq; – [.nś/]M-fautopsy-2.24/pict/main_t_met_link.jpg0000644000076500000240000000345011070040246017245 0ustar carrierstaffJFIFddDucky<Adobed       &tS!1ђ"aAQqBR3r#Q"!1Aaq2Rb ?Vmܫ.PQC?<ъvcS m"P~aаyB#ϳm.@1TO,Rm6##S_ˑT]~ sli7ߊGaS$⚂R%IQy#'N!F-V0) -6Tnr[$\UWdZE1L'331B[(UkW\,* ڨEM-ۣL9%6EYG_o_|bM=mj<Ģt! ` #.IB\Dagmr0%@#UD AA">8zuDJ%y*YU 5m.U2iD`4wO|K4kGTIc T% e藔!ɉe(AEB!C3eъ_yJ˻"B,8 幦tLm_cSKXj Y4U%VHT*Of &~eř@ \<&=`E[.L⏋.1xKZ`f* u|g rQr 3m%y[NlU9WClH 6 ~C;4AE:xlbi>Q%FRTϙ&ޤMjҾ uҐdjKSEL @Q ۔scۦ?' nM+,9..\o]^+Ԛw~Z1At$sa4S O)Rt}HNAԩ7F\۳BTSСS2(aQg(\%8 Ip1w$|?DQte fܩdb(LLA"01 Snm#ʄgԹ?ǂi4)o .ܴdŒ 6*]hnه*0/#EcY%6WFg}RmOpM%P+).DDbJ`m?ʖ76>?F54tmBcD0#- 6 '}XOdikڋO:{3d`r͎ng1}̴C-_l-̴C-_l-̴C-_l-̴C-_l-̴C-_l-̴C-_l-̴C-_l-̴C-_l-̴C-_l-̴C-_l-̴C-_l-̴E۔ qQY~ӛgQD?"D/a.N9r 2# u|P@ @S|I *s4Ũ͸:1j3n=LZۏCaS6/nŨ͸:1j3n=LZۏCaS6/nŨ͸:1j3n=LZۏCaS6/nŨ͸:1jS6;e-Oautopsy-2.24/pict/main_t_met_org.jpg0000644000076500000240000000256711070040246017107 0ustar carrierstaffJFIFddDucky<Adobed       &t S!1ђaq"QBR3Ar#Q"!1Aaqb ?%4yXI>mُ oєDrXOQw^KL$;4)yEWܙ{V\P '`%3(VAg!t7ƉE %V&,Exu<ކMlNPݢl!Oͨ*Jh)T'a@A}ɋf3 h6LO5}朸KE) 23jgB^. :'W8|s)AI }DC^ײԼbN#"N 阆kZszU#d6MŮKFPT$\m,6`SR|'Q{P_& zȶ͓0"(aJ+HH@5DIJHOb4HQsaARSLVL[QSb'-%4 eH*%Lk1iU]V%)O$im 5Vq5 Iݫ͎gbNgۓu9@@ @WޣNq/zi:aF*ޣNn6b< /zi:aF*ޣNn6b< /zi:aF*ޣNn6b< /zi:aF*+_,cOautopsy-2.24/pict/main_t_srch_cur.jpg0000644000076500000240000000470111070040246017253 0ustar carrierstaffJFIFddDucky<Adobed       &t !1ђSAa"2B#Qq3rR$!1Q"Aaq2Bb ?z奛{`uU7 9z"JU<˓r2qLsu"̩"F?]WT.3y|͢qpqHa1Z.l;'jqHa㚩~~u/yYo5"cEH UGl~/Te?a&Nķcթx8( %FԅMPlrνϑS;QlkLd^j^,e n OuT WsƜqBqUx enD63 y8ˎJqE#F]_\GEFe߮+hZN̳7 _#Z;ފB87htKh᣾C<uŲ1Y3>f3[s#(nreid:'DIrm؍t)~K軶c,7N]mͽĎ_N,ժy,},n TʥY8gdHz~U[ېJaf(+ {}TU䊉:,qU_El[,(V IQۇ=JSɖmå)@wҔe]7[Ѝ\vɗDԈ%k6Gnޝm?Jk^`zyꈓP#DMiʌސɴۋHQ]kft r E%80n @6yN K7(ȱ*X>FZ-renvd~Z)CkJכψRxȈ5A^Kc\E *~lNiڭu#DF"OkJWr:G=rkZ֨~=nF:njG{ۦkZ+?=nF&J+ yo')gd*Wyy 9p{!X겣1:|QINݴ27_֐y,2fVB~[7dꃍl:* 9Я! 76^x{unF:njG{ۦkZ֨~=nFNExۦ-kUautopsy-2.24/pict/main_t_srch_link.jpg0000644000076500000240000000421011070040246017412 0ustar carrierstaffJFIFddDucky<Adobed       &t!1SђA"B#Qaq23RQ!"1Aaq2Bb ?@rSYʭHDAL7U5 \9<4]huF2sa%1͙U[&H,2WMf˟c&|YJsf- TQd'.L2-dj퓔@ 0GZWz=Cϖ#6{UN5@7]M̈́MJ#(kE˖it8 Qk:TiTňm WJn8W,Yb!{5]y橗 l]=ۮrVeԬiEx&).9)D8f_Ge5wɴ1Jf9qcnۮu Z%]"38h│s6|tG|[_pϔY}f5ZGjQˎɦ ui E)'D w8#}Q8K0$k{[p,ޮ7NUiͽҞĎ_N,IW>|"}udM:r$bW8gdHZ~UNSېJaf(+ [{/}V]mw3~|iӟYz*N$(v)UWy\IZU NKCĉ|5Y&EGO_)"2RGn8VT&*X2] ej %D^+2wsDVWrYx>Cm~-_Ygg]Sd M̓I9]5pwˌ6eD{>\-Lpw˅ɕznYpy2M=.&TA}gʈ=7x|ZheD{>\-Lpw˅ɕznYpy2)hF;e"bR(B-u|#NI/,k^ Ϙ^x1000000>/JUv{pFnbݸ!plUC=n vx Tn}6*ۏ7Qq{pLnZ_7تautopsy-2.24/pict/menu_b_add.jpg0000644000076500000240000000424011070040246016167 0ustar carrierstaffJFIFddDuckyPAdobed       US!1AQ"aBq34EQT!1Aaq"2B#R ?"HL&NE3[,8mh>r0by[iX? CCɺ;LڳI4W}REL)N,LgMO|7IS_ Rm"tW|H0i5?U%&,Uzέ hJ~#M'qE$AeHbnNaPXTǐ9\TW1.)uiu/*!S((@H>"Tjbi1 ˗RJc7p|fE${Lcx~kj2jUE'(TL`<ݭҚD@ F1'#}i&1'ELi)6b`Sb~MXƘoi-2O-6bp[@2j$kLxLTa6&"}BE0>x"MPBL&O^!bb'/S xy6uu$򩚬(aBu% -T9\ )QƴNQrUjTm)sb8{; }H9Dj'2DG?m [$E:xtC6@6ZSۚC2\=.}\Xi)`b}~ 亲ZH}%U9rO-2ѝLO:pu%}kBr@,S~䲱\Zp ~* F@.R`cς75YX?pR:'g#O%'Β|1,")*Tʪ/8fNdC4@;`"A0 =s&gO.q?wݍuJKvoV,IvXIrUdPfa G1kZԒI3#}Gӝ[Ϙ[m8/ib'/Z+mؘ !lLDa6&"}BE0>x"MPBL&wN i $.J|al[>H89 N^SaNߚ)^(t?Q.npGQ Dq~\EVo0W6/L}jIWV\KRf{n7*8_ 3uUU&AƾRxTۯMʯ&:25=¤znUy1eɐqT&grɎ.Lyj> grɎ.Zdk{U/Gܪc˓ ^sک|<!"GJG?Ô?P?J֟w߱j3 /񮁙8;1yyGMomh$!?ۗ\Eyfx?w 0"?+autopsy-2.24/pict/menu_b_analyze.jpg0000644000076500000240000000530611070040246017106 0ustar carrierstaffJFIFddDuckyPAdobed       !U1A"SQaBq#34E!1QTa"Aq2B# ?:Q>0T ]X7un\ 0 ֑J閭N?!kqd`>&40 fr;kVW%-H[پJS =}GվRm#湇V7*gيNg܆ym~Zu[-IO̶6k*Na,lbl'UG)p[CS0)ʒH%>.݋5/Vj&Vim 2&Xc–1L DI`B ,n@$ m Wj S_0qf }x ex{k0iXmEL0QSy8ڧ)R@&WO5}m,@L)t BDqNjjvxm.|/}m,XVJ+OT\֒ KlƦ"Xs..)*2ql&zé*v~usy4w}imږܔ!I$d:"Mx};cVhe,8c7o}H پMpPo[e8+W9nBniGWMT>0V.[iiG1H2N?$oXե4 *5S9γ[>,ERROnwV"k-]J_%hteb-/D7-1QN#q>bȦS8"OԧShIjB%^$gZeK})<6x UG`q;d5xkݕ`L J^fT=^eӜC?iş'dp).2\}.Hcp6oJ))#gceHa2X24f[LxJ:sK=t.SPk_AeoMme3ZU)s|(B+K!$)(; Sh46eK=Zotn0EL:Xb]e޳  _tS'Y4F'֧ҳ|F-V3M& Cv + %ˎN:{Z?٠K"#l mY>Y>looM0FzB~CMuR]Ss-GR%55Z J1$ئ4ibHgad kUwc[]&u֧#H5n<@nrZKJg^ 8F,@RQ@ bxLZ}[&2qllU׽;]V Ԍ51%%ANft֨"35%ėXr0\ޢF8J&lgetDsF *iӛ,ka}cm dEҝ5`R9 T"T]%` ^ҔMU˧:\9ZqhN$ ro.Lo+z^̴NWE&ԽE~z_JڪDc!\LF"m6ezCO}@2Lh-"$1Tƛ0S[eE/.zI]U\`jL&iUvإHC*qݣBPZ nm꺜<2b`?<\-@Y|҉]m:ϪO<O)N#q>bȦS8"OnV ' Ap 6I{\ժskډ |}ֵ8.+:/⧒5^ m)Q[b?Q "9@l.GA~M+s7 2[1Z#HG*;>`&ܳI=Xׁi>1NBGҹvTOMج* sYr;vTOMئWk0NBGҹʓܪ1f HzW7Ry=7b_99 OJ;*O'Sr5'!#\geI݊nU~$w=+=v)Uc9 OJ;?'Sr5'!#I\gcG݊nU~$w=+hMʯ`'s}v)Ucߤozn7* sYr;v4~OMئWk0NBG~ҹƏܪ1f HzW7=7b_99 OJ;?'Sr5'!#I\gcG݊nU~j*zM*̧Q= lGJG?Ô?P?J֟W߱jء/ejO%XLJ U} utxG?.aeD!omautopsy-2.24/pict/menu_b_back.jpg0000644000076500000240000000455211070040246016345 0ustar carrierstaffJFIFddDuckyPAdobed       U!1SAa"Q2B34EQT!1Aaq2B"#Rb ?:EJ`LVf 2YpF(}#˘mRg M ?8}Y7Yi[Vi1ƚ%+H0i5?%*"tW|H0i5?%&,LgMO|7I3i ?v4DV ʚeDF5ophOC"BOu }Qn J!bvĿoodnF?ްDb#\NջWWSLfc*ү2*F! $8⁹C0pƮvd2=!e3Nlo8Hr,߶ AeqICZi`A mҚ ڟXyazy,?&.%+"ג/"-Ƙ)Ki&1'ELi)6b`Sb~+MXj|M|7i*ҚmlI77ɨkxLh֘yi-CRo0A8Eu ^~h}c"V8<Zҟ)<~+zrb %#իgtZW' JD[Ev"~axV*M^!bb'B)ؘa6&"~ax"MIS$nd̀kZ)QQE9H@1R ~c8= c6w6gڳo7 =HVIE @#r@)8 a5-f˛*>Ns{8v|XǏ'?u'7̣ە$dTiɈW5 NIeśDl/_a)o*t G͟S$:URB &csqUkmTUnM#Ə `9@ePJk䏡E{O(I\ڡKg:aYD&V`g4"r9?,j-Vg2!2-` r}B&̒x_lc5g]7]GM*fSHSi˝7UI<7l/hsBs& P@c˴f^i>/L}J 3u{^LuYrdkzU/Iܪc˓ _sҩ|<*LmצWV\KRf{n7*8_ 3uUU&AƾRxTۯMʯ&:25=*|&Fn:U<'_i{kdsAVK:sYS'*/D@@Dn9!CXmtQ3aOTlUH1%T8;j ђrf*܎H:2`Q%?U=ªF Ć]ݠZ9v,D2!aF\br,!T t9 + hlpVwFoo^Ќ{Fm {B3mKo^Їpp|;f!&;5FDlzɶ+QL`(QUB<*L搀G%.E:-ECl!@DbbLF؅3M Tfb"66/XDmSnue 3T%ih ,U:TZ-?.7XۗnLmr$H Z۵i)R|lQGH(h,DID*g13ǢC_@T] t6Ol>˳lz7ATSG0 ;l]@T '1۴Kt)]41aIjmࣺ=7ĨƐF4WU)U2iMMȀ2,(-Pjv|">*~K]JnYͨajd*¢cLPA / c+7ǢrG}9TGJ*%sjSS۪d&ԍq{|rDwJj߱ Y'. ?)qǔz-ٳO\\>O1:)SM;f5j\gݝo~-#*Kg7!8QVOsy[hzZXu LdƔٌwO/x@{uk5ֱL9hCkKoC+JLbK8 /I):G-W eȎr1W!Z ejphBFіsHXCRpRa -wqlvnSVG7 1/!n Ch)Nіjp4ïlw@D9Pn-#zS9 o9TU!]ۯst- QYOvc/v#A[jmuV{ TCνF\nc6DBT{PVˑ|n@ɉ85q.lXcﹿ#- oOT<ފqqE<OSNɌ{OSN%KAPHl~=ڏ qk\ai[ʖ{ªI Wv.7(s|.d,"}iͥ8"}iS'֑M8"}iW6%ïnznM ,fd&;%986ڛq+`=w6 s ~mq F*.Noȓk-v3pc)^Do ܜYhswh[Q{. %N^nnȋv1CT `a*A5`u n-\˟m% qI]͸na=!1 3ӂ >XiLH}A@#xMVb;bdpb͹sԴa? $z{.Vnlc/9`q! n]i@?V 7GWӌ=ڋ^ͶT>lM@2eq!2m8* (XE] pWIh4Ĩx:R&P>)YT[Z{vz~ܕMl" uTˋYǒ^Gl6?VO}Z; C@!쾛4l1'[WIRTr3b6uv>V6 |qWm)FHҜTo>m(eH«weHmY *vLV0#{$Iv"yぺaH>}zT곜3gc5G^&~kfTM:5L5I340$Dӧ[4T=Nl RLM:5L5I340$Dӧ[4T=Nl RLM:5L5I340$Dӧ[4T=Nl RLM:5L5I340$Dӧ[4T=Nl RLM:wZaI7c8]ϑ+:ܼautopsy-2.24/pict/menu_b_close.jpg0000644000076500000240000000467711070040246016562 0ustar carrierstaffJFIFddDuckyPAdobed       U!1SAa"BQ3$4ET!1QAaq"2B#႒ ?BHT*NE3O)2K0)f|ܹ`ZE+mRۭ6~qG2nsNb7*r-5?V1\#d:j~aJYGɶtX\H6ΚkI&Sc rRi#w}ؗ VpFUr]eD@;6 XC:TgT%784{ͥ)\Dxm',{ A;r㤺{I(Hrj ^Pd%E9'j*&@>DutrfF?CvK9 dճƫNP8Cb@|BQ`A[T"XWwF0'A}U3-WznϙNT y̽񁇾a]I@Eф;#RbĤ(@<#s_- _U kQ;Q)E: "Z)CŷLFk!Fuͷ.Fҟ:PHٻ*1Hp~kpE y-a0YcLOՌie/zHƘkI"c vRi#d[b~aM$p\tO-4ZII f5 >23yvR 暓z Ab+R&$S4 (5S9{\@Σ[l=CDWsj&YٵXrR-{Dv*ʩD.c1?pB3f'B)tLE. ^!3 !x/ {u;wo5+j1zcc9f,QUY&$qRc R4R%oM`n?ɦM>c/1l[OƙڕKoŮV+p9rl3 lUϯSL@9*I6c\D탋!m!o.l<|p%{PݫG{lyMQkԋXѐAIT͘2LuT-.t@?6ZiS.@al޵=u-~)|8n%NVXrEDojpd `r>siSP{ >->ւ_uUH2"6ěEe,Wd/+-[ވ̯[.n2:dhC>BNiOSM s>i_$10w M2CEgܰ_WEմ]A"~x2gMokѪ9jj j1N)P{$tMt>I.tIOt~` #l>{cl'U Tvm^;򮝀9H-V1W 0 ڵ7ft-enlװs "պx&b~x"OO/R]<1?pBK]F.{dR&E4E 0%eN.| Se'7N)^(t?Q.npPE7m ATr,$Ҷ|Aߩ} T{D' CYt$68خkOƋSqT0JxoG"3/FrC lKH8+8`.e߻A2$&C♛t ᲴlXSI'i |=UAk[M/# ^Hl+Agw^0O:N13bM{kQ_y^?څ(Rpi#AАs\Tw.HJ)H`,+2ct.\";])[sq)]p7h))' sq)y¾1)yinT#❟vUGZ8D,Z`VDr 0CbݰM+:򋢽.2|n"}iJsQSiNj7>m)F'֑M9D)݆rZqTbVڙZiSP]߳xn#'GuPؑaus"bmy6!qa\db |2::;HH(ӧMO&߯ GEu]]mC`P6&ƸGsb缾:@U}'s/P<.m8d[!'R`VVUw5>ub˛J g4o #íJeB:/D 16튅tq>9c9[Q3%_`IYY#`g}qf`bw@}7,q4UzK ]Dk;kfMEO)y!nUmjͦ4mGG_P}u>mI{n]YM'% 5&܈n%l%#88<0ۘ.ED?n"}kƊٴ5ZE6qHҜn"}iPˌH«weHmY u&+0YĐ|"٤[#p7L4R^U/ ?K6y0U[FgiaIoi&z&ݦvvjgiaIoi&z&ݦvvjgiaIoi&z&ݦvvjgiaIoi&z&ݦvvjgi۾<yi&z&A8}O|ZpǦ!?g[autopsy-2.24/pict/menu_b_copen.jpg0000644000076500000240000000357111070040246016551 0ustar carrierstaffJFIFddDucky<Adobed       1d%!A"SQa23b#!1AaQ2q"R ?,(lڼ(ث^?ZC$G_¨ܵ-,&E?*+z GJ瘝#<7)'E@j{MŃ>$"("DDJsŢ%qDJi{Mc\N3 *Fm"c'^8{44l"M#-M"ܠHVu}QLH).juv ƟP.fݭT,뀦\ bWyW| ;"VI§3ƒIޙWGʫMAR޿tV&umyV)Z/nLq__msyh& h6lܶLې~PAyP$/n U0U Ƒ"窴եL\LWQvʋ/ߋIMZ_:?88*!$()R.BtJ"fi沘}DT`FB+o7+btSɌY)AG#$mS|?JGV"Zm!dGԍvaUܒ]ܢ^QtW!gF֑\S"JsQASNj7>q+IɿcJl;/Cq|pCLS6֮Xbiz.z Uk D2XXJʎ6 gD"Fy%hvՖ;t=[{Ȉv(z&4ܽb-BM#r}L8mZ^@Kk=Dj"`+>ma[t!^u\9Vz,<4?eX5ɬtӑsVԧ31JXʞ c6aYvmg0?ucl<8}>#j-5kKPw׃%d0 pT $bMxR6aUu-ֹܶKc—Mq F*kmeng 9!^h%H !LSQE>;Q,Y+-\x WYʷYSچӏ xN+33x"jw6t8XwVlb?eFNIɗ[YE6mnjxPo3}ʸ.&vpב },-ne b ~/u0 o5ZT|Ho}iQeDASU;`dkdcH\UQ~ꪕv"yぺa}zT곮yzcɇ_ݪ0%=Nn RLM;UL5I34V0$Dӷ[T=Nn RLM;UL5I34V0$Dӷ[T=Nn RLM;UL5I34V0$Dӷ[T=Nn RLM;UL5I34V0$Dӷ[T=NL5I352Ӈ\Mv:1u!__autopsy-2.24/pict/menu_b_fs.jpg0000644000076500000240000000360411070040246016052 0ustar carrierstaffJFIFddDucky<Adobed        !d%1AQ"Sq2b#aB3C$b#!1AQqa"2BRr ?8v)uo|kvFDb_:DO•p]#qqR))'E8O1:*)7(!QA'E\1\R&pg tj;mWWJTTQW mv ]Oi-X.qJ!ׁ]hq#%1AUU$U;7e(fgL IƛrKxoy[11LD4-Y^Gƍ,\QeٓnHe  Khf"/QSU­|N7CV`تDDB݋o k+ǵ)ochFM#?dxă&m`ա$WpPMbORxT R ̐ɓnh 91SE*?J+;JoB{a_aCWSW[ltaQz)œ3VZ8.d2j=-iYTE&^х&>l#[ D 1AQ!T;Qk3ÂD+O1:)GJyN*??*SN2)"'𧖠 ^qK`+"DQ_ ;Ch܎]̰TDJQuadZU48uV^*7>u1JJqQRTop|kmD댸  &*5lnja>̽i;v7"Sz'04 {=RxoXZc[rSsʓ%eS.3JHq Dj5џ6¨E?1dl DQ4=Alu44|]@[qʯ`m[b4 :-."*ox cX`xbIN*7>tRS"8*"c%i㿹#e̿b"IE9 7c|vY\ m奧}L*]zhΔ% ETjrI`WVVq. K@pU2uPFԠbѭ2DEAg SنTA;@(Z*ߓR{~i="liȺ!E\,-!^m۱*$5׺jL ndlq܋!ûVċ ZdpQpr|@u|C*X UEie/On,ZZI؏LjȑC%q&l&HˆVظL 33:Y=SV>i^B6E7%Jr4dr7߈/䧷{B몴͠6n!ƌNr=)L!^SbO@E%H:2;{*q!aH;*Pi*/e Ⱥ[zZFܐT*6 XP;U' #fFRB H 8vWz%?apQL}Phq%$P'ًCIr01#T`.db68?<`Lw]2Zne҂qTI $ U /{%M2'Iӥk7Gz'z|j{~u>#7-{'ƗmujguM#p(ԦԩEF)P2s~WحRII埨4}>k~#W%2-܈sy*P4UE1.U!%'o! UeBdO:tަKs7*y6Bay+p`G4m>m18\ S.<7rwW<rEs-{,J@ q[q 3xqZԧ<찮Vq_5xlZ+{+|a%T*xלNT ,J*wcxU6{CJ$4٭3>)g\RKLK[Jml19nnMn]9J3"NǧP$Yswˆ:R,(03j7^R*]*w>|FI6==}T&b"UBu&n2s˕LCnrI}2‘~4ȣ36f7JYQ@qwD}:3}.x]Lۄ|8\qR]J>+y[Hn6Iьܒ]OPbuZ|KD%Q[."| v◚KkfftD]f+ER]B *4F]>]@`# 䏺3٥=7u+\7uR4:]KQ#gV wbpᳫъ<uÆάF(:M\8l7bpᳫъ<uÆάF(:M\8l7bpᳫъ<uÆάF(:M\8l7bpᳫъ<uÆάF(:M\8l7b';M;qhv_e6v:1ɒr'3>uautopsy-2.24/pict/menu_b_hcls.jpg0000644000076500000240000000360111070040246016370 0ustar carrierstaffJFIFddDucky<Adobed       !d%1AaS"Q3b#b#!1aAQq"2BR ?,(R*WxQ[5[^?ҖaYw$-aAI7(s}k.d)QD*6|SiNj7ȟzE6|Si\ؗKU77ȱOĘ̔jmįmom-'1Xok1Uuu;xFD]k71L#Ty:CBFU`v*5;ڽznnE["- S3{9_0 1(6߻qj\o-mJmut; ) YxgA+w1"]? 5Skf$km[^V%0F #ݭCPs*GGjsijxݿ"PRñ>iplkݲ~[75 4%eĹdmq-Z-hUsQD4VJsQD)5O"Jq"}VxT՝gdFpDo0YĐ}I"٤[#p7L8+·\j+96>?6B?z쮻ǚ|~_%autopsy-2.24/pict/menu_b_help.jpg0000644000076500000240000000271411070040246016373 0ustar carrierstaffJFIFddDucky<Adobed       Sd%!1AQ"aqb2B#$b#!1AQ"q2BR ?:sB U -*v+S M7 Ј?(G4\:Ro_w mK 6$!mK 6$!mK *(twtƏSWp \N 0c[w4UO+F7֕᡺²5HP*%jE#(eF–ÈXnİ̉Y!`DV'RSN Wa[ܹbIuEAE.IAE0mAȊ/Ym"y61* n"%1%hDEXU i6$!&!"mI|B&!"mI|B&!&;5"PCBB=dd(&0~Qh9MUBx U)J`G%eE:QPtP; 4OffKD&f%Q40*مTM6/x4Jia{U(߹q#{O,Ƥ* q,Hf%)ȥMc~i|:^JOR\^-J;J}IEwʓTL.U; loo ̅R.>E"UOrtmJJ|#. (Ι%ȁo#*E>"3؎UI~:3%hEMU<,]H  %KlsXՙ"xT5q%fqjWj4^ۊt…E 2B@$BH XrVtb|y5ea,3M 0i&f%Q40*مTM6/x4Jia{U5PhDLti)mT R"sUU_d_ʪ}N~6YzOuȣ{阳g:-^5ߪUjpCߪ 58goa3 NxXa U?#WƞT/&gN+MxeE/Aa-e#I 93?]vɻ~U+.H,L5>O'[ӯuu$`PcUJ^u M%/MBSIAv MWT u&*,@h0$q{flcatg ߊ2oו?6y0ˇ\1Fgi\0T=L?a 0$Da&z&u 5I34aIp RLM0jgi\0T=L?a 0$Da&z&u 5I34aIp RLM0jgizefjgkkF1b_gautopsy-2.24/pict/menu_b_ifnew.jpg0000644000076500000240000000675411070040246016563 0ustar carrierstaffJFIFddDuckyPAdobed       !U1AQ"aB34% !1TAQaq"2B#Rbr ?j`r-Y$N ܹPU`iAXCΡFdͻJ fe[ж1']Q7\X;|@#fF"#@ _ :Ai%}j?f7 Rgqɳ΃ŗYUL&⁈`zSZM5fH\QTm4ְ ڲ4dUݑ.ppDʙLe\an5ᮧ|73)~I(ԐWge2с8 <3Ux5Hp=yy?E| ÖvJ0դ1j7;yRHL "cP[~2f8b҈yAOGOMB/3(?b+6LdBj^ږ⑒j37*$îܐciiPHRT:c " ~  `A(Y\Kp8bbÂkP9ո!Er)Xpγ~\]۳4L (ͮi@Y"- 6;NnkipՓͳngz 1~cƙbnxf> =hb d MĞ;hFI董}>ک\{+N'v1u>کG}7o1u>کG}7o1u>کG}7o1u>کG}7o1u>کG}7o1u<کKlM+ yTy>Nz=}%w5y>Nz=}%w5y>Nz=}%w5y>Nz=}%w5y>Nz=}%w5y>Nz=}%w5y>Nz=}%w5y>Nz=}%w5y>Nz=}%w5y>Nz=}%w5UFQLTP(@@#ӁKGC?ԏ5GkOKm13_񮁙t]j^]̊Ո:d2O۵autopsy-2.24/pict/menu_b_inew.jpg0000644000076500000240000000344711070040246016411 0ustar carrierstaffJFIFddDucky<Adobed       !Sd%1AQa"bq#$!b#1AQaq"2 ?8va/9[ׁ+rib$C~\%,'Wh{{))'e:E=Wh5mNYdn3 JXFc0HN*-_7$#Uivh$FmnƓ!MS2Mf1bHNY*a #<\ )_ Rܥr1vnK$Y,Cc4mƚUm~cU("<eI^b"+4$hHˎ²8вeirSb8*1*Q+dEC& T[AC\H8meIb[67-rm˷`U%mr.ړI~ }url{l܆ XQH1lͷSiۧ풢Nt4L͐ r1Dn'-?%>TSOSNuq){N?%>Oq;*.2ڞڃ`(-'@ZS'6#9ta)KkV+b !U3#X:!UsR锧UZ:e)F'֎JuQRmb{՚Y n2'8!m#cIRqR;1»[ x.ڜ me`jo_b\-NXi/CwRZeV)_A]^թO;2eؘYثo'Qܹ]"X[%ZS`fC=/! )1?Z.Z&f\&]!7"F&'$.̓ai;ջRFb!¹ cO#mq-0vFݓ"Lg1|.D w_fZؓmYX!.6S6~u\؉?mf܇%Q'[)F'֎JuQRTnb}h锬n"6TPET8Ad_hIx?ճ3ӆ/? _漟j)mz?NZԽx J?ݨE;*?ݦΪ&iloxv:*?ݦΪ&iloxv:*?ݦΪ&iloxv:*?ݦΪ&iloxv:*ogwmZy%Y-_ZUp090ۏ^rd^Dgοautopsy-2.24/pict/menu_b_int.jpg0000644000076500000240000000407411070040246016236 0ustar carrierstaffJFIFddDucky<Adobed       !1d%SAQ"#aq2bBR҃$4!1b#AQ"aq2BR ?8v)s&"8""uFD)EL"'J;x8.Ƞ7+by)O1;+yLI0*fJq]wDn0+kORָH8dS.lWgL~ 8(pj?Jy\HpSMxap75}V]&:^'.b9 pv}ИH y\CP[M(ȎGLWؘTo.lo)o]< &#\fsh188ڤ0 =Uln9~1;0`&ړMEn#C;]n??JU<<)GJyœD~)GGJy´#`L~)6y%HWVguBhj:#FE,wW"B̌"Vyޠ6zHҜoP|S"J񛯶˖W*m5 WmcYT *g mDmv[kӬơx<Ekv^QoWMmZIۑ&&,cU|j델"K@d]g *;ڂ-&3ͣc7Z@t3qT 6I/W0T/.F-͸N߬<47qؒ@I̟zcZy֍Ȼi@Ort+VZL1Er8.uڶ}{V9*[w=jtkq.ARDpJ#׈T:ulN t .7e[6-p@?Dtm)FΑMsvU'eDTdtH"E3/j$`?EԑRfr|?paOmjy?.~;o vOZv RSoi&z&ݦvvjgiaIoi&z&ݦvvjgiaIoi&z&ݦvvjgiaIoi&z&ݦvvjgiaI8VgUL4U\*\< >_q|+ݛ4]twautopsy-2.24/pict/menu_b_next.jpg0000644000076500000240000000442711070040246016424 0ustar carrierstaffJFIFddDuckyPAdobed       US1!AQa"B34EQT!1Aaq"2BR#b ?"HL&NE3[,8mh>r0q<-WLڲ63ΡFϐɹ;Lڳ)ܩȦ4>)z"ɦt\I&M3EL)4bd:j~kJM$Xm]5ܩ F[6pfAqMUAPSLpΡ}i-7<)R3 ";{I&$z> QUF0 ?KC{CuD&[ xC.[8WpF`DJi䨩 f2j."@+gW{I6m}8jBG2ݕZ:t -8Spis)tfED/|{Τ|"P ])5 /Un |F kJ@NNdjͺ` L?pͅ$ L\\RI4ʀ)hi;\jJlq;c ${L^*;gOK<ɕKoNXfr2 h)XQfy2TK .c(۵Z/21ϖ\Kv /sf'/R+olLp1>ax"&O^! 3B)lLpuߴlA:@/%0kTɽff1QEPYS9p<XW`tW#K0GQ Dx@vz.G!~bM+x 8R6{ync} ?-A͎7.љx=#Izt5=;*LOM׫Ux1e8_ʓuU5'@_sک|;*LOMצW\}j1=7^^ sYrt5=òzjUx1e8_ʓuU5'@^sک|OcGԪc˗yjh=7^^ sYrt5=ñzjUx1e8ל_ƏuU5'@^sک|; `Ityp?PHc3GkOjș@\XBk/ lGWH(;W$~8(F0ۿ+gK3Cp"w;}Wautopsy-2.24/pict/menu_b_note.jpg0000644000076500000240000000351711070040246016412 0ustar carrierstaffJFIFddDucky<Adobed        !Sd%1A"2QabqB#C$b!#1QAq"aR23 ?8v)uo~;#Z"V1EL"'Jwx=~)TS)'E9RbtT~[k7tŰB5E%ҫxUT@ER.Vk.۳ l7vֻ@OYW<0s!x]ngt;CZp] U2})Qq[e2H "%E8tTZ~Cy392̈)f"uv4UNwIE=0e[iw+)s *8k& ɑcCʭkI z,[S,24+\dn.(.ꏚxQxqm$T i]3N@2.vIG`T4ē_%줱ŒHD;UQ dM/4\jk]*)o0s: ˕'"B}xR\Qth_a즆V~)Xnsq#<7?JSNsQ#<Ḙ"?<U7d "fwQ$*?9t`D[2Q+S;Dh!dfFTzj7}jbq֑JJsQH%9AR/d{#7=͈^C~e i6ql (d_:(5= xN|flvQ[Vh.%KjIEmDPT־.팪&j<`0Y{a'/Ig؆lDmG}1AUULGN+y7#@osIU315]pBl6ؤy$XiqO:{|Z~LךݩRٓ.Fؙ9 o1Kqjn]lK? n]5 E۹,O@dVբ X;i U4/TqtQ]կp.7xbi5"1A0q tÈ4:;C:iY;4п.kr ΘٔUYHTpH򷎟R0s |n +vn )INj7}i5>RTn"6*hN](e"-_$ɕ$~WLOwyxapOmՎڪ?ucˆܺ!^ll%;M;UMM;UMM;UMM;UMM;UMM;UMM;UMM;UMM;UMM;UMM;UMM;UMM;UMM;UMM;UMM;UMMlgMYZeW0ҟVr\nw.ن|+(W!ZQautopsy-2.24/pict/menu_b_ok.jpg0000644000076500000240000000251311070040246016051 0ustar carrierstaffJFIFddDucky<Adobed        Sd%!1AQ"baq2#$b#!1AQaq"2 ?:sB U;lڍjEML҉Wd]@fwmKaݑ6`mK 6`mK 6`mK _۴jtp}pF@,0QIzUU[87َRU9:)dV!L -iF~vy攢S)8vTl*5a8HG:#96s 쉶%sțo^P0l%sțo^P0l%sȚo^P0l Czɶ+QQ3ʊ)T@*g55ܵ*)Ej*+ DK(S3M ;J؅TM6.DRi!w"M m]DlBE*P4{ܔqk̫["kɦd) m빺oF9ԫU}.THħT~W+N}T@_YW%,0@Pu@H'P>O67bA+=zwRTU}B)'!Ad<\I}{|pyZԃ5r-77:z؅"]J؅TM6.DRi!w"M m]DlBE*sV2@U!£ש"s*Yk}OK>lͱk<v8ȣ1geyٸȇZ'5WcnLit{&4aC=~j0!ɍ?5vndƟ 7HgcO]31 Wa Lit{&4aC=~j0!ɍ?5vndƟ 7HgcO]31 Wa L?q'[<.3c֯0O%R7O`Y?[E?S~iTk?autopsy-2.24/pict/menu_b_ref.jpg0000644000076500000240000000321011070040246016207 0ustar carrierstaffJFIFddDucky<Adobed        S!1"d%AQa#$qb23b#!1QA"aqB2R ?6t@F0L@>;qHͨvED#z)1mKO0ŷ/Cor^:#!0tF-xB`A~cRQ5E鎔n*Y4@K{Lv+{bH~d{ jr`dY0QtS0@5-!0k}h^zh(U&FFL)Gӂnn/wIйtV9dnE2y 9"qVACyDNUZSȁW@ d&Aw7#K7K=d]jjg):@]& @%p]  49i O@v+;]N?"zHmܗ"a=or^:#!0tF-xB`S{<,1٨2%?<alW)c G,*Q5NJ)S9 ɾQNEThP64J^lLE*1M 6.DRaJSkE*x>5Z$MhyULiGQ"^3^1*:7Tk@UJ@%N#:iSJrdʺPcp鋷J^:@.ê:iș˙V͵d /]7n`܉| ' kwF5XSFvUT9~fre\8Z]NSp ȸAd^ ]O:@#{`Ӣg?ɹFG,BrI˃LOQ2׫+1͂>rw,z.쇜Y} LIEzcDVkTCҖwu4wyp8/p*ӂ~D|IA*JjIYM H<ۡ#ÎSF9b^ly:Qmx]F)v"ׅTb^l")SDj8Tz X=@Ns|/ik~M>^%=M=uc?鶷q9]D5ob0"s1XaC=?31XaC=?31XaC=?31XaC=?31XaC=?31XaC=?31XaC=?31XaC=?32H:˦,·_Ba?J›g!gZg=Fy֕Fautopsy-2.24/pict/menu_b_rem.jpg0000644000076500000240000000322111070040246016220 0ustar carrierstaffJFIFddDucky<Adobed       Sd%!1AQ"aqb$#b#!1QAaq"2 ?"'J0}a8SSœ\}Rpr>ԧ)܏)' qq#J{¹۸ LdNٽ<(n2E2n紸B憘,c>v\䑾8!5.>Mf詶QUGy!c_)h<9,{ZZNb%Px𭱽”]Â/E' 0m"_hc{WtSHٲcLsћ1iېWA$%D%*a 67^{ lΛ +͊6B$T%EDUmD4mH[{dĜ[ji+h)Z[^ԋ`܏*Gڔ8=N.>}Oq8SjSN7ȧ䈟ڃ`*2[_E~UfyQ$*?Ɔ9`D[2"VK;+UES]6*6}jbJqQHҜTm)x>m)F"J;ǵf>2 \\(rڕ:8NˡeVk-8h\HЈ,X.:LTȄ,g#Ks6R'@ 7lG44H|oem!aИv\tVWyf a8=)0E՗Q £"ˤ Vv;v莐?Ǫa(YfNG-7c?.㨆bwvOʶ{-: ;8l@]D?QxuoiiߩU>;uȮi82bNƜ r46&qu̸C|Y5]x>+ҜTm)x>m)F"JqQHҼDlUI𨊑lNI](e"-^$u$~T65_^Ojx~[לbZkV RSOi&z&?զtkVjgiZaIOi&z&?զtkVjgiZaIOi&z&?զtkVjgiZaIOi&z&?զtkVjgiZaI#Koyjՙ~ʯa߷Vp\)lv]=oE6iW]twautopsy-2.24/pict/menu_b_seq.jpg0000644000076500000240000000462311070040246016234 0ustar carrierstaffJFIFddDucky<Adobed       !1$dA"Qa2Bb#Sqc!1Qb#c$Aaq"2 ?RshʤbtIOfOʘz>u :Ҙ/=~ %di'8d,h[*!(G{s%vczU0HfHtHk[  xĸ|)Qz22=}701KFH:H`!e+(rQͪU7 >4T]HOUeX)1Hphڏa/`HUF"ZWb`bmT(H˅E Hp\-neVg10XĿ(e5 d>N(}L wG3#tJfGIfpܭg1Á%r2D5/K!K%"D4f(F!oj޻16O>Pk*gƺۏk (r1qkU}*^`D(u[skJTcLDWdu+7l'( ]QXncq-4l\|wE*]LLF7K Jb>򯬵{(>j"# CkW"+}+C6 !g< BY} cQQ1řD+/K f̌T"|񃅩- =Tops_~s,eJ%#J\ɻS1ӔI/P :n\b÷ߩ4I$ɃC91 c> ie𘵃jNTfc`\/_Ooi@&"ɗq2#s@+ڲPIk؞E7,7=-Y+6zC\/k dD5xR EtURlz#reZ҈Fnb"YZr"%QIЗwxQ%jINF< .9H Zb1V&$6֙Zl@cwYl4j#@k?8hVi;(,"4n/-[첁 l ҁ<2 d)e -@ʤ\J=yQI =-csK/PV6EK.b[1FEV E1 2gTیf$Yj7+UD_/7XGiۏrC(pCD̉W.Ůؚƽ(F#/nyPhT' ]OԺgV!jkڝS[1#l+b9myb*vRRb|8b-jBή&ѷ ͂mI3HxBGj(ɖݛQp&d$ k i{r /҉?,%I 3Ykmѭ5S:,fȯ˕Ԫ\Ts@|O #iVyԺN&|dAw  rz8ʅhSg[eu(Q?B3Jr=3.% ֲ rbM֔]ix!_mRr!4/AL,B{Q<#tEM9&hBJ{߆o1 "67.@#~xp8rЖ[1UMnU2> .I"b/ 5{".2$\ ޽1 b'JQop3RgdOWSҟDُRK^6+[<H[<H[<H[<H[<H[<H[<H[<H[<H[<H[<H[<H[<H[<H[<H[<H[fS9w.Yu>|p~?h>w//"/›k^, `^N7b~#autopsy-2.24/pict/menu_b_tl.jpg0000644000076500000240000000476111070040246016066 0ustar carrierstaffJFIFddDucky<Adobed       !1Q"d%Aa2#Bb3$4!1b#AQaq"2BR ?8v)w%E^5%u2Vvf+ibl,j8j*\\ل{La\bT\r5m gPc KD%J.uG`ߒc{$ϑ$w6UJ -Q+۸s$@^dVfDY\8ۨ*h T]s}-|]2;;˥g5;aRZv/n{cZƒGkmr7+ub*nZ WFS260Po=-T"ɎHv %?yVZʱX~CS!*!Ix]iA$+AqJ꦳SاaVs<[]]&:/Er]TJavq9E-N&0Kq]A{Oƞ!P|٭]ay;nsXاPq1Jӂj\y9(i-%o qWcbf8;\o b4ä®LUNMBnTORfXg^6Kknx)E~) Id*tSSX+Ľ m\pK"[dfq]mm+ZUP7bi_GI}V_wv*m4RloނAĵ'Q:$֌ްi2xETg#.ۛvtGzJQt[d-8iKx~3^۸Yܞ|E Ǒkm8f -FsUE$6 촺c+ՠL >Aڑ^,vG$[$A['&S\jj8HCp`1[e .ai:a#9ER*] xCIh^vęyM1:VmS~iY!uRG7{>.թ,>"d,gWY]ę0dƋmˀtx^^_Nb74Ml rr>KMD6nKkt9l>He!E'b W):XJo"0rt g%{lΪuBD/vR0Dщa6}74Efa εL\u8r4@M:n)lESG)>681ි[wn8`ziI7\)mp *HȻUHς}5m7:!}YA@|sfl?=5J>(.%ohîmb1ZР[H"E3/"Τ $仪55fgɥ>RNJ1O?^s9؅c(hNLQM&LQM&LQM&LQM&LQM&LQM&LQM&LQM&LQM&LQM&LQM&LQM&LQM&LQM&LQM&LQM<wu3oW,MZ^T{z]{ƿ^z-K=Vq4g_autopsy-2.24/pict/menu_h_cdet.jpg0000644000076500000240000000300111070040246016356 0ustar carrierstaffJFIFddDucky<Adobed       !1A"QaqR#2!1AQqa"r ?u+\|XG/̳[ UBK"L&zeW]qvTy.,(T3g'1O&v)uT\tնRd&-jn`ňKU@}qsjQ!SCwi&Zm'M js8\j,^0$`V7("nǦi-?;SR MiTC-ܕ3Y)hIwGj3!!ԯas/s] ̤֫'^?;o>ek˦~џ{ʸ(bBע,5AU^Ia"p\tQ'E訽SOE %\u7'#rJGT~/ݔ1u]bTWˇlؓ`j&pNc"UMɨڔ$Un[ 8LKWZ*w$ U{ -)ifi֌\h UU}sz42nr8ϖ*Ieyaj9$ߌ%,pĮ,Ezq# + #jW\ %LaɤyIk䃼z[f%q8G,}H3תko\νr,+Y HMˡwMJQũ׸+63b hf,"iM>̅2mvs s.s.jZ&!yH4k7s^rʓXC㖓 0>"*z!Q5>*I\q8W,6ylPI }tVM.2>ҪPߒW$:N8.e6vN뮩7͓Ī+eVH(a;/nSHh@4 )g=?#! v|;ūJ7A[B*.SdCnC(ܐb@I<ia[)95;I#b(L`)<v[d;O۽kJ ]b:)t̚1MĦ7ۉw1d8Q*A F6f {FvwUi IPAX몭xb.n}Ʊ-;~ ʧts b%1!DkW.w\@T%  8 |ap nD;kP߰#.)3?H~H+gK!&ۇ^XTIţJDb.Wtq&厧eOQwqĨEG)@ b(RR lwxs[4vB0̏Թku]A5Վ1ƉMY15*S\P(s($€L3~qQ!qbXdj]"Ơ(%6PF&Khc!~^noL|9gGv饇Tr!xV9^''I|3 [鎉vɡM,LfeǦ<ߋQ}:U!Lfz\|#IJq|sS)FAmu}7.9tr,S9^؇+EHhɕˈK OyAe?}ŀj[$ZYa򥟢q8}D+C\r$2Ô8b\z6 ;A71fW~xHK%^VN^K!Ff-ͦ"]'>3tfuKゼ1-lQgOxW9zݡ[rƦ\^~}UP3xsd8ͷi3ior30,cxuo2;!Y~d#WFfBog[~d$WTw5KKoSZ=T ~dc~z,?N7qsu\J͙#^q'C?oȚH'<~~sautopsy-2.24/pict/menu_h_hdet.jpg0000644000076500000240000000274211070040246016376 0ustar carrierstaffJFIFddDucky<Adobed       !1AQ"2aq#BRb36!1QAqa ?#A8St>]]ŜefÒx=QTM ֋uvH5vR}_( 0DUW So$vC ]gw,ޛq9GcJRbJ8IH_pU3r8Nkl5 _BHw#{¢J9EI^$qم 4@ڼlhd.=7&;UKBN5WYu;{K ۲?װ ux GZWuIIh-ɦVȝѯyw*ʢR,$EE"U"&UW_!+?c ֞lI"NJ.eoy=6G=[u Ql9Ӏۀr#6]7N|EdDU^URL[Ѳ ~myL <(BT_\Wp$NWhrkӛRRpT^*jH>LkTeYsţe7V%"'HK_]uo'H^Q-dAvN52>ayp;[zzTMrdHo0j}-?kZIGW"qzEMWf#~O:ip6#YBddF*&=Msjͧ6%)71 M8ЄSt_B4^ ]uֆ.0%W,[ 0DPz+nO@ZlB`ARP4""+Wy$j?.\m֜홳iĆʋ 6>(EvxI399Т6 IkKhh&DV*$S**Fͱi- VarN"$|7r,[; +JފqmZc&|5CK* Yٗyo8+^ۯ婕TPȼGsvc-vn^?T[OGXt{maꛀd()7=߮|I>)fqdxǓM㓱 H=Wc}"!!uKF$5Zr+D0W,ɽcXp mi t$ Klq]ywɪ!3-iZpX*8suUm~SEU"+1r+Nh &S`So]u[nDK♅ @_dJԇ}QdGت*ru{f }սRnZ^cnە2%u 8HđUߩ_MM>jI"AcL#*˝yc+NHK}_kǐϧ;kWX~T1IkQms&Ī;"⿊.D h@4 h@4 h@autopsy-2.24/pict/menu_h_idet.jpg0000644000076500000240000000302111070040246016366 0ustar carrierstaffJFIFddDucky<Adobed       1!AQ"a2qBR#$61!AQBq"b ?xG@Wu8wmU0[`$nN9khqHߒPFbMGH<[̓r gQ:kh eo)ieYjC&BpU3pV+:nM8&\}?%DUmnpjq#66n"FQ5jT^IaI-kUxr Ϳ"iʈ*ᴘ׭+b ]䫯@zA3|b,7nkIwVH!xqV $B.6xEw_AAEuUp j $jyfcv^=ѲkdM+Z~DfPryΣN:LN]fH-/?b=,͂v]0$q=$1kD񠩪u@ԥ'#{'sH"Eud4>bݴ%jG7_G(_bGkӘ ޏD5RcˏSTCJn|,8-rΚYg_ϡZO~=$Rp F6:T *VWXW-(LIs*5O+izccZZX>&%c='F9(G]"HT|j~Df'MJmWTk{prwƦv! R!EP#3kQ-ȸW6֍4FJ {]mD6lcC{sgt4áNneP6}u|Քۖvݢ:#LKUNH"*)uz\h)/CW(!;x"hΛJ-Em'RLҋvx EWl%em|1v?(rEvJ[.a<^ -m,̣ÍK,$;a $^%Z]rnsuYuWȜ^ӭ$G[XKU41e'߁7tIE FmD7/EMc$ VP4 h@;vmdž:c@N4{w/ML@N4#۹zngZt autopsy-2.24/pict/menu_h_inew.jpg0000644000076500000240000000342011070040246016406 0ustar carrierstaffJFIFddDucky<Adobed       !1AQa"2R#qr34A!1QBaq"2# ?3\Շؗy#4)խ@}OZGFEGpl+vMWm+u 5-FP0̒h tmQ#h$V *9KXsZr;,5Ԯ+5) %[e&[e52#-. 7$]bk32 ,+[dp^29iUQ s>cpɚT4SqKi*!5)%.]fgS:?HBGQJڮ2&#j#6Kncr[ks $n'.5lN9o>Lp%jW5H8OMQ9YJڕmRrPucPw->wk7nMcP9r&ދ/pl>5v񯦣Xx¿zbM[&Y=6 Ҙ<–IwqGYmt%hZM TAaH3>b7n]Oj,y]0Aöʒ7 ۪_=9*k"BzEpYl9])nGH}#ptuԄr/X QSbtkautopsy-2.24/pict/menu_t_cg_cur.jpg0000644000076500000240000000710011070040246016721 0ustar carrierstaffJFIFddDucky<Adobed       A!1RaѢSA"2qQB#4r$ !1AQaq"2B# ? @(P @(P @(P BO ^5LOW21&yLqɴ^ex*#rm>^4ʈOW21&yLqɴ^ex*#rm>^4ʈOW21&yLqɴ^ex*#rm>^4ʈOW21&yLqɴ^ex*#rm>^4ʈOW21&yLs0(GB!ZSk~F%;n/RʹBRw~f"byo#+]oCҷ j(Rsu֫\ yk&v[>!dwMZw[#ޔ 'Φ7Zn:r e K: 1Ĝwo#mpn_sܼ'*Hii˂MP!$QX΢+;]Ikh+-'ZOiHrZPGmO>Bwj:itn\Q܍[2w6\nSMZs}ѹ =Loő0LVĨ$%mA6V?Uً~2"[&B%Lvk4_[VBTN|0˗k)R[GreqEzR[ՊUa*|HjV͗rJ+vL梪̻]-[}:;p5IN/h >i y1`] %.#IR ˋw&>ι{æ-֫M\[-Uq*g;6:iԗ}$[s.L {I ym)̩+?H۲_Ok{؋tځ }VWRBP\QVmuV] jVDiClۺ[#aJ@q$!̊ڒ1p;k8IƵeUS2X1 GVM\NߡZO(~R9~mR-:EyugeP@poo3*yJ_ˏGyS)$p5RWMQj~c#~{iL qzTTraCpN#f6Ό7|FoMNCrX\Ͳ2e"R r֔% lپXݷa^NW N'{Ֆ=_4&fN-і m+SH(;ہؕTex~WZSRn#TjzvG'XisnYpUUQJP?>i~TqP%DM|/io5nhz${&bHr*QmHkܷ9IeU)fI-dKuc/PƏ!i[gPsnݣvn[ůmN:y8אtVoM7kq[,]aP)q1$1^뻗=t_,.q ~fh-_xx_%/WmڥÙtl͔Pr2aQٱF1J1Лwmոӧ?q$iFe+CJJJcr2eȔ}vWToZSN46{7KߵzyقӲ߸6W JVIfJ*^Qr7m6Y.geSLDXؑ^fmRg5uZwZ==vM\Rʐ* eIU2kiڍ5vMoIIƞK='f˺ "nl) d% W'n>8R]R!EI}Sl-?tn8KJqi$,&u:/Wu2e k^D^?rmlOgJd:LZ5I.0{Ʋff'QT751߂KӐccpru,nNCic1Ա 9 f:7!R41A"#Ӑez7!R41X3KӐepfrI x!,nNC(c2KӐccpru4~NC+N8l(6Ε,?əZ>Jp`7$~V뼴[ D6ZKsIcȎBj2#wPTdGȎAQ#"8GuFDp |ˁoY6 W75kS}BT?]sVʤJ.u#(҇T$(S28ʢ;ܩͣ"8GurȎAQ#"8GuFDp ;*2#wPTdGZ(Iܔ_kYnsک"P @(37ѣ.-'3bu;vI3ݟr4[i~ ]mOj[1fRFϕzҽ2Y8N aHzf T3 G^7g=Qia s HJWԓ纼;yzjP @(mjn0s ;j]P-]8C ǐ]ש^uMOW65&zMqɴ^yj#\rm>ש^tڈOW65&zMqɴ^yj#\rm>ש^tڈOW65&zMqɴ^yj#\rm>ש^tڈOW65&zMqɴ^yj#\rm>ש^tڈOW65&zMsa,Q(=q֛#iM)m Kx_%r)$*桺"byo#W5kԏu2rYnHD HR>,nrQ^YYIEUqd_6jHXku\*XJsvfHz0ue)9z҇;ZF&$&&9J}#g[vdXUbJ֋Fum6? 8;1P' q֍?9dttB zץ뒥ۯ-bB!)JR}Wv5OI1T-Iw0,5[mB-Ps(CU`)K{x`"L,%Y"o׬qש'&v wzY3(!rfeY^dܑ,M .mPk&o _ 6rJAMwWcp\5X f:7Yipccp\5X fPHPH;.̯R4k1Ա .u,nKKR4k2Ir~k0u$S(;7R,nK(5$P — fWcp\5X f:?YWx/pQ'fl6ޕ,?Z>Jp`7$}Z*9/W񷚉p.I5fIcȎBj2#xPTdGȎAQ#‚"8GFDp <(*2#xPTdGȎAQ#‚"8GFDp <(*2#xPTdGZ(IJ/5趪HP @(P @(P @F֪L桃IR*בoP悔!0zC !0zC !0zC !0zC !0zC !0zC !0zC !0zC !0zC !0zC !0zC #Fx!&)TZ@(P @(P @(P autopsy-2.24/pict/menu_t_cg_org.jpg0000644000076500000240000004614711070040246016735 0ustar carrierstaffJFIFHHExifMM*bj(1r2iHHAdobe Photoshop 7.02004:03:14 23:42:14ȠA(&HHJFIFHH Adobe_CMAdobed            *"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?O`/{w2?mR 7zcsZx;袺w9ĕK#{?K__䔙p~ջH3u =ƛ}2c{XX;sv}cW{ ˕I/Pu0 ui{7VkFw4zkɮmcmݏhK1+qgL;i*n[_$)1$UV']غ4R:9hIwy%EVǴOx? !-{b?g no.ĿKUT{Bz 7?b_%==[ 1/UОsx}-jsOA>KĵUG?'xKsx}s%bZno 9f}br>ddžƧ~+Photoshop 3.08BIM%8BIM com.apple.print.PageFormat.PMHorizontalRes com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMHorizontalRes 72 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2004-03-15T04:23:44Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMOrientation com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMOrientation 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2004-03-15T04:23:44Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMScaling com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMScaling 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2004-03-15T04:23:44Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalRes com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalRes 72 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2004-03-15T04:23:44Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalScaling com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalScaling 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2004-03-15T04:23:44Z com.apple.print.ticket.stateFlag 0 com.apple.print.subTicket.paper_info_ticket com.apple.print.PageFormat.PMAdjustedPageRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPageRect 0.0 0.0 734 576 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2004-03-15T04:23:45Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMAdjustedPaperRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPaperRect -18 -18 774 594 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2004-03-15T04:23:45Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMPaperName com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMPaperName na-letter com.apple.print.ticket.client com.apple.print.pm.PostScript com.apple.print.ticket.modDate 2003-07-01T17:49:36Z com.apple.print.ticket.stateFlag 1 com.apple.print.PaperInfo.PMUnadjustedPageRect com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPageRect 0.0 0.0 734 576 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2004-03-15T04:23:44Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMUnadjustedPaperRect com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPaperRect -18 -18 774 594 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2004-03-15T04:23:44Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.ppd.PMPaperName com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.ppd.PMPaperName US Letter com.apple.print.ticket.client com.apple.print.pm.PostScript com.apple.print.ticket.modDate 2003-07-01T17:49:36Z com.apple.print.ticket.stateFlag 1 com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.privateLock com.apple.print.ticket.type com.apple.print.PaperInfoTicket com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.privateLock com.apple.print.ticket.type com.apple.print.PageFormatTicket 8BIMxHH@Rg(HH(dh 8BIMHH8BIM&?8BIM 8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM 8BIM@@8BIM8BIMQAmenu_t_cg_linkAnullboundsObjcRct1Top longLeftlongBtomlongARghtlongslicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongARghtlongurlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM8BIM8BIM *?JFIFHH Adobe_CMAdobed            *"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?O`/{w2?mR 7zcsZx;袺w9ĕK#{?K__䔙p~ջH3u =ƛ}2c{XX;sv}cW{ ˕I/Pu0 ui{7VkFw4zkɮmcmݏhK1+qgL;i*n[_$)1$UV']غ4R:9hIwy%EVǴOx? !-{b?g no.ĿKUT{Bz 7?b_%==[ 1/UОsx}-jsOA>KĵUG?'xKsx}s%bZno 9f}br>ddžƧ~8BIM!UAdobe PhotoshopAdobe Photoshop 7.08BIMHhttp://ns.adobe.com/xap/1.0/ adobe:docid:photoshop:f744cff2-77a0-11d8-9ce5-9be283243e66 Adobed##""     A" yQ!1A2aBq"bQ!1AqBr ?qr\') izW~.񺳇wRQ\GX9q[I2}T^U,q^fKh + GCgI8dLɧE!:I TZJs#KjȒ2UoY%[κ:Pf,r][OіIE%(-?i&ttU>qqMѥ%%(%D4"M%Tb}'+!b7 $Og+e9<`f:`9`f:`9`f:`9autopsy-2.24/pict/menu_t_hg_cur.jpg0000644000076500000240000000676511070040246016746 0ustar carrierstaffJFIFddDucky<Adobed       A!1aR"SAQ2qB#4Tr3!1AQa"q2B#br34 ? @ @ @evcIN=%"R*-Qu~2+XD8jSivY86K̮mDk +QiF}/286K̮mDk +QiF}/286K̮mDk +QiF}/286K̮mDk +QiF}/2cvc'lE&~cʧϓrȰ@IçucQ3dӂ5-RyMܑ>ݳ57[kaTa+ p%Qx944G!%_W~ bc$6hMi i [|CRѨG}GO4mlVQyeܨkRˏGYFNP\_ I!)E십brȾUD kI[TuIԔ| kui6Lj++3:ӯ*Zu`/gH>!2K;5mƃd}]T˻K-aR(9P^JXfGKi81}3O̢92KRM9o5YٵU:rU,"iHthd9\.)?ܨYI|Ur[KpީP\u%)aJ,+IƉO&\I~+|uffV|]wKSjs*կ)mA J$=cf|zIEJIPdcN)H^K3VT=yV{}3Ljm"SU}eJH1op3A@zףY;ej|6|bu;3-Jt$Mįyjɡ߁RpiL~ZDRRK*ITqSB¥ٔZ} Mapci .s-6Ye0k1̴ۆ f9p2n\5Zm Mapci .̧2Rx k0s%)ւ~k2MapedG fWi .s->YT~#*RϸN:XRj ѧGQT*͕KJbWUe#/Wk1~ԓ_bw3 `F5; *0#tv@T`F쀨Q7-~&A#LGo6ծVwgT*/8uՔid)IӅI*)#ČJת<4*PW6TR6pS9S)FnwQ7GdFn ; *0#tv@T`F쀩P4 }8~s˹$ @FN e]Bq>N^-8l+Rf^R4]Ѵ> ]궫ګ|)V%)Dh֖hy;9WK ʡ [u*A#2G?xܞ:=Qa q(*쓧n<񾨺  @6q2Ù'LKȪEE"N0mks ^0mks ^0mks ^0mks ^3iS)9ƌ<T=<] 4dmle,8X"E*ε-\9#Z{$GqEeV$-Sj^i%SFkL%` GT\ש^!86kԯڈOWmDk +65zQiJ q^xF}RCj#\pm>ש^!86kԯڈOWmDk +65zQiJ sSa,fRa|r֔ȤI)$b&*%%Ceocԩͷi6|xJ" DJa8IVIX-:o挕lmdBֶ% R~N^#⛔Sg=ިH7ߊ,9rZ㜄cBxm8K-:9\5 *܌fk yfm݈aB2sJyi⾕6b]澩L"$G":sE",;s*=N|ONL/^1!1֌"^v;b]9LĭH5MFMdRν FB׼%יՂB6sOT~ّyF}u?[2F^UcJ%P2%(#ШFft1<ҵt4ˑAT~߆Y,-6%פ#CsxS2RJ݆q\K$,3*RM馺SPr7mU+27Pv*]Nn/qHV#N"UGJv9U,4-:Jps]%ffVɾ ρ'Ij.+m'_:ȴ `IEwdj*nZ|گFi÷H3m[ٯ1̶6ϕm5DJ[VH!)UIճ=GD=rcG%":DۢS8ڶnle%I:ҍ*$ȔU*G^{ҥK˭˰e/̕)֣%dFjptA+J1ͩ7D̺ܳ|Nrtb&Sԧ" oO(+? D9JkI*3xbuGJUHyugPGy VIvd-gB__/G˺Uќ|rj_ϐ۟ )JKM0%DIВ3WJ|6Sg#2Ӿ썸smqcoêV5U(ѯ͙G.9KљB I]FGr| ldz$ 7#/&ңɡFdom[Z֦ RSެv̬Yo*vf"JBkA-KSeMyHʟA<%3ݛ%Uu}i$xEδ-G3/ajkǓm^ΏyQP%H=x_R/̑ל{حwK,s;/DZMUY$QKGiTWsqE$O& ׃̝^4yr.|,*Ks fmh2Otaq2^a--O%sd!!sMWCqu6A z?sT8*!V(F+2nl[̍ Im !+mNq;Vbr[]e"5%^;;嬩ޢ}Vc5<NPma'Xϑƞ\XU| cU4g|J$\ۗ-%|ih< E q#pk2/ee K-sQY,CyQvTeǚ2fAG'YU Lw"Z$ÕCc>C*NO$8ǒ1&CE۫]B9&TÈm m$TJWӪ`|nD(9QйmufE_M鹪&KCx%)#mU2WOc3mз&{#պ,4[Mrnu͸)Q)nLXu&5WXx"L,%X#R҉1/K96kSd[?zY3(!rfXI2MHSca&zE3xZ2'1f221ky6Yeapccn\5Xۆ f96Yeapccn\5Xۆ f96Yeapccn\5Xۆ f`$RzuYdZ:BHFF2=d fgcn\5Xۆ f96Yfapf'Kn 3=R c2}ָV)Ne%!hwE_VMu,]ty$*0#t.]*0#tT`FwQ7KFnp .]*0#tT`FwQ7KFnp .]*d “7ܴ_cYw9T+o LpafzDqy[D^א[B59н ya/C^Cam א[B59н ya/C^Cam א[B59н ya/C^Cam א[B59н ya/C^Cam א[B59н ya/C^Cam א[B59н yn$6Ff+)TX4autopsy-2.24/pict/menu_t_hg_org.jpg0000644000076500000240000000456211070040246016735 0ustar carrierstaffJFIFddDucky<Adobed       A!aR1AQѢS2q4"#s51!AQ2aq"#B ?@@@@@@&(g1SYxѵYR%_~sΎ{j%{ꖢ+{ꖢ+{ꖢ+{ꖢ+{ꖢ+{ꖢ+{ꖢ+{ꖢ+{ꖢ+{ꖢ+{ꖢ+{ꖢ+{ꖢ+{ꖢ+{ꖢ+{ꖢ+{ꖢ+{ꖢ+x="X{ia9,NOЭIzyq~ұ*&+,׻Ć;.pUyMNWrYhѱH<"YiۗYE;C{0$w=#8Xjn]:|幅FX9~{ ~OQA1a ?TP#֩kl1٤3K|pS)V7Xte80gi QOnh浓8Fp<|}_ر_enfx.$ck{,"</$ǤK9/A$d :֟\1Iu {9C E1Q'%3M4,xTaSZ)e(4CVRjrPm7J+X<鲙iȄ\UͻH=7S*b/{&k$<WGgqmdˢ%nRT%]ۇ qN菭bұ@g]2>W G]1SA>M5Fp\5)L|U:IaÓ##ÝPygA" ? ?ɗhSi+]p9G`+8sM%&VY4J$J27HSJQo>i.Hyt}1mծ<;X3))l|g+Qm֞k[B:v4VM<Z3Z2rk%Y[:wfBO~mg)% hԸˇ;zA7<t@G $~{^ᬥб1&Ši/dn:LVfmۋ*i= evNݿ0}3QFح#{X @U[SGKKk]OQ3H!urֿh>*c$Yk&cr e0ԯzIe2aͨ{+;6(_%epHי]TM1ǣiTF8m>י]ʈ+QѴ^ew*#z6k̮eDcFyLq}2=OW}21ǣiTF8m>י]ʈ+QѴ^ew*#z6k̮eDcFyLq}2=OW}21nÀx0$FJZ-)8mn=n;VbP NֿN;rq:lF wڿG٢2ñ$#q䬭*6#XuF''ZW:.\qqKδ"oeuzO)'gұ8׮8ƨ^9t6u|FέhJ 9AWƦ)rQ/vC~'KKS\\7f\Uʣ>[*HV!Xuj/[Uz^:]|\L;4}o1qz[ipb q ,tU\k]Ib+̓<ȲꙊopc?rE\vOJυg+Jh]Rz6J18H U̜Ry_<%]8vg_ۣr:Z8ΞNi9l4ˬOХ$ wv?CI/ M7^՗TpA JB  Q)uۏ Bu&dhkd6oCV.!Y>NwƫԸr) Fs7J]pL$BbR%Cz6c;I9l۽h3le%<IT)Ԅ)!J́ATו&KwKuӖ:L H7=3AG7VԜ ^c+%zޓt33nҤH)͑=Sc;Eюr;1~rr"e&ʤO&:}ҒHWŁ3TN 'OgR#z2ϝ#6:$÷^ds3ou+RpRq0\Z7Īənrk\|9n+s4f"n9s*II N::nLM3t4t;gdú׮!Oέp+@_݇mRNvѯh^O7!wkژum#))Z1*ْrW&?ֽ=l~$}EAsm%ep*QđEvsITVktfgs/oa/Ka$ BPΌ+ΰKjC~DtA\eg+r;朇pl,$Vo-ԿsQR 5Hjҧh\?bI Gt%n1pW0Oџ/ +ۖ#D%ˍN\R(LX+SKsdSA=`zwe^n2C_AU 6$IPDNamTF7򋬡'Gr;4끭mɊ8"LbJ 8xJJvtoBjڶr_2w &z)|A%K.a-I'UNvb%Bmݢf;g[r9Fl[bމ$~srS[OgVvrm6%n{w:ɨeo mOF62Y#%=̻5\nL&!FZ`!RlgPR1#i?AG>kNUFmZy*5)Kny$$IZfmbOX/_tvNR-UWo̒J#bAY?/OݤZٗ1seV!y p,K%5ZKoUGM Tg^mjlķHqIfǂ)'D8W/MRܷe}oGZ L,%Y~Uӆ5uv$@νnhYmn;ej|::]ɗg;MynrG5ZhY\oSGҡZ-")w$T#aNeKfyı 9 f86!41Xۆ3KpӐccnrq,mNC%ic1ı 9 f86!41Xۆ3KpӐccnrq,mNC%ic3c~t1m)g1K+ jٛg;J )͹GʭC+T[5j ի&6oajI59MT@(2#tvP;(*2#tvPTdF젨ȍAS_ޣ~8ɰ H$mta_G8Z=4,%ASyۮ;O%k!JNܪIQN^ΤePޒCj}%*fR9TGQ>_ӕ<aL2#tvW!z;(*2#tvPTdF젨ȍAQ"7GeO@`(@mRf7%[親HP @(h`̗p[Ng4zsuIkݟR4[i|CڞԷb;*̥(zҽ2Y8Nr o)ԩf$?LExݞFP1@e^NǢ;yzj\@(P 6ک3{5 NڗqT.x]G4N<418]9!0 y!Nhcq .sCCauӚC ǐ]t<SiFSn'kk2Q~塆 3aK6@\SUӒ5K(iVd-Lp)ƒU-nu;ndFHxcщW9^=y|C ǐ]t<418]9!0 y!Nhcq .sCCauӚC ǑtFC`UkjLP @(.P^D2چJ+P @(autopsy-2.24/pict/menu_t_hm_link.jpg0000644000076500000240000000644111070040246017107 0ustar carrierstaffJFIFddDucky<Adobed       A!R1AaѢSQ"q2#4%!1AQ2aq"BR#3r ?+JAFP.,"Ñ/R$:,l#ѥINWy q)ֱ2/3~M>w]_-Rb[XTT#a%+dnę] Vy+WE!iyАQ4-“e)%fU+-nnCqSV6tB[ZuWuh5"ǑHzFud@hAp}Ƣ2?26ceK{ǕSUIJU] J,rg6RU<˦]sdĜn44{%=DjA֢|j|<)Qz녃01[K4L tm6QYD!J6J_ &G=1)dw sJ7x-]Cl zDEBcR5lQ$iiAygr#8ܻmv!͌ g&$8MI*z6mQ%dN7xy1w[u$kASGXlyQׯmiQ:*f2!-KYTtc쒍#_6g.DSrdޭp3Y\xedu#I+R<'wr^xwXnymo5iS&kZ%$jb7XFh{.3ɑmI҇QI٨RbۦućȍiFv\?6{)iabSM<˩hq _G6~<:HQz0.WK}_C}ʯ*,O2'#QjV~|r=ߨI*3xbuF.,&A#BOVd?_]al5q FBSfTybǽ~ƥF0' +oO7q))F՚o/<29y~gFq?ɭ1r٢$D=s^<ԆVjRQp3y>F86Jթ^$O]G-7 ꭕǣ󞚙INJ!??S|VY|bxVOuw(zM*ZU.%ϙG$c/LFyb#-Y84ۚM̆|+/umJ}i*;#e9MGRg (ݳl:PvK.[eMmm p"ғ EQǷ$ڔ%rKT }yOqOZ]SD6mgO Ğxe_BMAF|zm%čN/VUI0ɣZ\]TE3"g\FU>G]IKv 啴zdܸś(LXZܢE>;69]*#O|.vŢӘ ފ'NC%P %J";v ¥a:>D /+ҰN;j%JئisQ}gHY"$)ڴ&kv/=wKW+KCL3~ HxBKqf+[8CïZ"ro_3lnJIFbr'J۴=rgdSFM[y.MoZyxCfԪf̵$etɎ1IJF~7'wՍX]%R2S-UЉ[Tڞpפ)}#n5-:J$ʾUJ$Ƽg_4?MK&xd8Lܵ+Q1Ilu$o[T_xɛё94H\iy6Yeapccn\5Xۆ f96Yeapccn\5Xۆ f96Yeapccn\5Xۆ f96Yeapccn\5Xۆ fpy$S##AiY,m p+Nl(j¥ZyZ8TQbKBT1͖_1d]K5KΌEID}_ƄnQB7KFn / ^@*4#tThFyЍQB7KFn / ^@*4#tThFyЍQB7KN@L)3|E˹ΌEI0wd0u hT.oRH|VN(r=->7=BD".j0d.84GD EYb25Z|wtՆfiܖo>k-;9%7UZ$uak\ keq[eނBY '(bq;(Q6]H4?fӁRHTm ubhqw˿bdԒڶ>I/K)~V$:4w ZK1-۰L^^mjr&~K"Oboi ˈij=``^Lnii)%:^JFap>?,T^eӕ#AS[&gz:S:#;1]䏒oO(?Ipra *P/"Y$APPZ`ف, inhkF;7^5,ЯSW %ؒz:eԴf-2ݶgZC$se$8#5x$Zc-I9`cXKH2'm8&ӻ%Ǘ1x(rYCAoU;CUjs5Rҳ,C 5a?]b>.zL>UE4YAD[˴vHqjm -s^젽FùZsR{9fsO ~kLYvdd=]5jbbPs0>ZR} .KOc$LN1 c"zS3P lPcx 1J>H^ΕPs,rw|>7ݖ,lK2ffmԚ$N(zY+Y#$?ee~;5"j&ٞZNR@j:Fqu?A9G`koNΛx8 prs֨)3vc2ܑl]$ 2Ǽmp}VLޘq2 5߃[CYS!r)ckrk1ܵ d5Z܅2w-nB f;!L[CYS!r)ckrk1ܵ d5Z܅2w-nB f;!L[CYS!sW)gNvf`\5F֤8Z yr u+Kw9RA(dg(Bddg(A##9G ~yшٗAt۹HFS-!3m%G)o/!&_ȚR.Zmf(@ v̓! =s`&GiT$s\[Hѯlz3[Auf # NY% (SAIn(tf(%"L`O(3fI&G..[ # $iJ1 T?xttM89/UjE[@:@LN&@fP۶+IbNQio-4ێ4"X"5Q Rtדݺ_4~ }!m)o/!&e(AE&YbʯxS7ۓ:k4o3AZ2`.3M.)m/.6JshT-7s?I9Jʡ &HY fY}iOd-hn;B G6bapXS1CsވjR Hu2j7+ #n4v7D\II!1$M `ʟ^tT*M~3+42wvonWWB,$4Y¡#l 1se*"!¯ р&rZB4 yZ}2#268ҙBP;4I2J2+\f)O:]:Otqw~ᓠ1Wu}?X67:Y}?݌;8^ S[bo:5 V& S[bo:5 V& S[bo:5 V& S[bo:5 V& S[bo:5 V& S[bovK1ؼ4TZ~kg iOzautopsy-2.24/pict/sanit_b_san.jpg0000644000076500000240000000302611070040246016373 0ustar carrierstaffJFIFddDucky<Adobed       t!d%A"S1aqB#Q2r$!1Ab#"Qaq2BR ?Xq!/>}fZS"hS16U. <ˎʞf ()-#2@'ʝQꑅnT{oIݹLgn Tnm%I*JJRRRqI"G2Z`*z6DV%TDŔ RmxQ8{stH+m&VqqRu<ۮ4 ,N}-hiPibdkhT8 1'5ZzD $d1i=O%?\w R.]HHrC Pb1@ wRXPNKȢSsP% 8dɛ6l|0|#)60V|E?h^b9~O16SO9ZH&UF8ffW#ʞ!B*b dBmVJ Y9ޢ~u+oQ?:E%+!Bͻ~jqŬ7,B).;ڭ}P+Zdæ+֞c!V̆-|3ډ#"NrBpb4Өx>\>tZvUS'޾MLbuݩ-'ME/'Eȓg{ 5-iӘ5Azf_e[mOv'^11+`aKz*e)w(2\ ULxSa?:)ڏ.2O Ɏoo_{=wʯ[VKњ;UNY'>p9fnӇVIϣ4vv:N}[ՒsݧFhV8ud3Goië$њ;UNY'>p9fnӇVIϣ4q0WfmSɅ>p>_v\˥xsc6kautopsy-2.24/pict/sanitized.jpg0000644000076500000240000004366511070040246016122 0ustar carrierstaffJFIFddDucky<Adobed        !12AQaq"#345BRrCsbƒUѲSTt!1AQ2qa"BRrb#3SC$ ?Z}:4Dh#DF"4Dh#DF"4Dh#DQ\ѫfU5`p FsAmgɌ?yҜªe`;Ul(d s}ZXN~v*k-!mxؒ碿kASwo۹N^HIU})Dd=# v?JM%eS+&gªDcD_^ȁW7sqs7'7|?.D3'_6),bIx1^]/j?Rfl_5/o{4CGO$QFQJ<ĻIi7:A%H֞"useD|ޤÿєQԨ s(zbK_W621ݫ?D;֒'Zz\zl }!W@Ryy٘,8}]tGsW<6V{j'j.yx%]̮Gv7+X6+X)چSuԧ7h0#GiD#`!VQ5NeJPRNjR\cΚ@:W"%u-i&2?~.SⷜsHӊ ˏĂ"p{NV^.}fBjj`]6 *"8E r^r  mVkRo~m^"u>[7m Z#tj>U|Y>dؙsp2s-ze}u?)I?_rI77 s>.:yKO-{D\eM^u:a-} QoW 6uxRҟk's{۹ZFmN'hRpqS#JrQQ5Dd8/k\ssJh 2=,-TAOYNjR"C4F-2ЩUHx""h&I7$UfuÊs*r@%U[ۋ2̇!"e%h(7BJ#Bb@BAI<o9t$IA?F-:%E*yٗ&oIJ4UN}.jעy +WK\!ܠGBq-z3Ȋm@ITE"5=-9X*_}jPRf*"%R*篖cp$Vr= Gnٌn g qmQ{LZp맻^:,8dUl*Wr-i!CTjD<xt #F-e Jڍ\2 gxnq*pI qOF\5N־iڋ}sn;G7FɉPZHҋb#S+ UIq Kvb3|pW# wsZeТUQN폧ѪY -뢞9"ffl " rGPU=鮗sˣzGѭvT+TV[j,VTZdJk̒Bɪ n31^E1UuOr߂=ʂF}).* ^_+!ȵ%i!X5h.*2fDWQjp}޾ip,G86u't3 ;GwXEx_~^CqзbBn. m58}upީqiʋON$IkǴÁ˱C[KmיwX(l# @| ޚot{s]\gk-r,;wHi^˛(&UUUAtzyu%(t΋6MO4Ѻ. $h5^z++yRCMw{UY6Gl#`$BÜ?(JP}1'KhTl`Nc?bf*?J 6dD, QQ kf#;}|/JJ}vlFjX9iDI)Ҋdšo69$8Rv[ ssú[ۦcd̆͵&:HzQ4-8.XW!Ub'E~&;-qAL"*I/5#@h)V\OYl>;L5Tb*tjI'Oq|Xm^*R*WY4TI["l^y UT *VNIjaU\8*O%w!w{u~?W#1"-OZ3)H]wD3D_$7OUCUu?m­W9gai"N{>SSr8*|B޼?1H`A=MJ[>{<0D^^5^Of][;.qarhR2RB׆\GB!d.W:/ _LQ(152yǽTʯ`2+ W'zG:]kw6Fx{;wN,ma94v↟ǹ4z>]xoɆ'/,]gH=߶ &gVQeۡlm9{3nĹFCN )^tB_S]pPRւ,ț2K\岈 v:OJ.u'@\'\eZ \^~ot{m 2l΂'[n<Ѣ-RB\S^`.a*yx/Gzk*l)/EжY NI܍TZYTs 9뫶sJjTHeV? ?еy]Xޫ# Bd(bqU}HʧۭG$?{TxLݿ?ǻNOBǷHZ:5OH^J - QHj~D>Z]ؐі=-|?2kԥOoS gUJ|%wCwڣAE**B[Ve}i oqdLyԯ:'Foy ^]!nc; "צCCTY7%a[!wq`?}Qy{T8OxzeN*|I+c\yHDμUBG91upecS䙼.㿝jt^i&|yץaCBr~>3KD;!oZܬ-#ܬNڰ bھۜ7ӟݪ?+(f/bJSO.@vaF‡)N_v<YWJ4Dh#DFj5/"4Dh{8ά8Uo7p +M+TUOUM~gEunb\"o#AAME@*^)Ѽ4;wv[5m|˛spENu- uлV\$t:7H &'feɊ\'ŋ2j4BONܽ i&bMÉHbLҎn@쥠6d^ 5HyT@f]B Cך*rgt,OgWU}־^JjoQP5]t1*]mq'%0OZ9TB[Aq.q9N!;E} O]{׏zYbʲ+=<,=]cm*s6FadJdxqg\<1ƞ.q-ߑZ S&>`ߘX?2OEĖngHr]fLe?}ۻzx-\}LŴN~z^) T<K!uoLqh3Em{ c%)!}}ͮZfWBB**EN(uh#DF"q,6U\D!ڧu"{A=Jxof@%r$U^Hq5[;ׇzQ(oi,XCy=buC>Xi|mr޳`%<\?mxd,7O0+exiT7Zx107]1eY-Oo{_vnۓ^噹 ٬ouy6#xzCO~yc&DfdUf]|iJFxJ{K^Ks8*SuDF"˶9nc(M!'6Otr7J|\W^,di0#NI xU sylYiu.=*!usMɭcU?4m>Ag]Yx/m'Y]?'=$T%ѹ {G6gѻڨF{̢ǗV"H'J[4N~RE~%TjϘ[5:ZY^3zrcw3殉ydbuva>؊Ğ/zkѷK^!DZT=+]f36!a&\M S'τSӯ'XOI@`- Qmh F 3O1v~_ryX[65qwRq܌O: e.l\.j"7Kz$aa֦iU8Ź6땳wp*rn#7__‹mTWP56wtAp 1 E$4SREJS x7fZW-7'őrUbw$u)zQ^-;nq3&̕m޷7-p[m*KDdQWFcsdN]*+524 G4g43E=+Zk-1֨s̶} ǗUM7(N>غxWދP "vlYŴ̼Nfq}}돘\3'TnY|mdgJz6G O]COiKG聴i -Ǻ4UOQ5ߤ S'~z|ݮ}vbF.d`}߷Nr- -?sHvSJw|S$Id9i wԯ癸e\Flv02.wKh{_UuNX*367ݵ-o\TSE=b~qHHBz{U7rV!;p3kl0?٬O2o U=ʆiĞ/x7̋!ԻK@h[}:21 Ndkkm+GI8_r]Wuټaܪ# ]lǬA"@O=Df fH )R"Z"'WYIN,DTAUE*iZ: (VZJ4Eg>Z-AȆed>} yN+ugbd6O5%cQV ֘ʶ̸@I9Z Q/eSdnA>R;bSd.ꨪq㭛u+kG;ϥFHw,1qaȲ>ۢ}*HHEN23i*ol$9*[)v&o}6=F\ +B^<o ƠJSn_sGyBiJ€]&"HJ4ZpO7v5v4NSdf3ؠs -7'ΆN*7BfUT%5}ߋ¾ӚnEnY&3 h̩8-7 pQM=4E^}5Ek;X͛GlY.+ϳ )(ZO2(^*nTEBW:=)ߊRxfnNubr&;k[Lt\G7PPּ-~CC]':6"l<"5 zqxDzh\կ.Ӗu:0!h 9n_q=mp#}RB!ȥ ̗ ǣrSҡ\|űW_m1QiFBT7 WOLC%3 ݲ%87cM;!!m\q.AV)cj +Ymq;fe[Ɛj.f$Q6A\oiz XU7\G~f?,̼Fpà/E1By+h~v\ u_ /.6 $MIQ]\qFК7~s)jl)W"RnzQC! mRC߅3u /{?sk*$r䘾@qdfy?w{.&ʝi̚Tu5`od+W˔1ǢppIzFoYw줨] |{7 y2e;nU']*"S.\繬w`锗w-[v-xDh/M{(#DF~4y R^` ]H$dkԲEq_y_nY{3r{VNaJU+$>\ĭ tSǙHx_в6QN6w"=ƾ' ;&$fl9</0OƓu1_wmUT0Y;F6 *4˱_^f*R"]T.v>Է'rWbX_m~lY )K":8(Ōo>VO~,ġl-[۴N` dHF\Rrfucܬ7tveÀ`|nn+UHJ%UUk+fEgf\N*LDNIi@$u_7lUsAQ~_6u[ r"[?4B HQiT..9ĭ{v `/̔_L JWm \ (d Nh+޶^aL0-[ noi:.d({NpU+d|S8wTO°ўdY ]c5 On6d@hzƊ,D}&1MO $[|2V(2HlzɎڪ£ݢ ׂ߰d6{Y94غ]`VPOD))T!:놼{?rWƝҴwJdͲxfETl;^xKg%z^j܎ŵؑNP ?^w, nUY,yؼ]($w*㏹Mtkڧ51I*傫Z EW,b udmUW`QAjlUj%k֚UkvMjTn^OYw;q(e$WMEU(ԔNI:nf{ڍSYĂ+DlJr(*>:EYix+b,V^+~!.26muqWպG\@_7 Ҋ ,C%]bu"TU UݏtđVhUkK5׳{MTUѢ&e…1fdv䲼x~EMK\Zj d7JZ^#ek&;e>ep̞ ʋpOc.tWOcsGYur&nOR][$4Oq"4D̩4}'71%DԵk5r}WHC?gu TX|-/;ֶ]7 :⧡_ft# <‹:u4Dh#D\x$o򸭦ȅnwOjD׼]f~ӽnor' t_[-1҈RU=o nwu; O=/9ȧBVͪoNUY8BqG߲Od%9]fsrp<0vC!V@RAUu%{YV (9&ԣDF)1`xJHiTMg1o&tѼ)CbTRe_nSgG[%"JDNy|Jx9,f˭V*59%w xj=b#TӊksG )ܪ4o(]v`l3i[1'u F[-MfO)sڅm?ãe?T2VRI61Or@E9xyL~Hƕ*+Uӷ8&QWvܚr0$BXѠ8>$]t٢iePml;62{>)9PiN>.WݬnuOӿ6gnw]صR/= \ղCNJ* =)&l fTa\0{mYFrN/#<*pivxz2):Tko;󚱘c2J:H%j 8/P^%գ|ϳÑ↚Vc+( ly/2na-\@G 8'#[^ %&\C`ط_|< l>:pןOXQ_ZM˖MNAO=n8G=IGWo1쏩eC_]YM?=#/{i;9jRzѱ$.F7Gx_ޱm}{Hf?~}j=t<^yke_\rۆfvWHx޵q&Ø=2h~UMqQY!Cx^BQUJ*S ȢvOiK/u(|*5uikt|=x NyIrV9ej@+EZqA]RO8Q܁dVF"4Dh;npnreտķ@D5U$ukҴ354Q YL)i6]D̹ n<"TsX8o(mŭY=(v:bU.Oi: vr>3 s?U˅h_r[q㸰rB)n#J SW^fMªkdea v'dD[!4tĕhƂ>]`"1nmk۰h\NحIKIj T+l-dvågY0W߄ܡ*X%uu: UU:l i TI9.!mm-蹋JxEiLTTZRZdܹ2T k{Lfx<9u2դ\N;$z_Q͡qS_7  pE\%{&il ‘ `󂈊t^5TЖ)EIJGr,B[z.;W[ɹvG?- D!6$}ƜTEDy-QuȞ ~5Lg> '_j)6ga _ *e?Qhp Yp+B4q{Q\XCڻuonnvC]ÊټNt"r=Zc C+ǒ[}aNd4ͮp)vQHhDj׫skZ}涅Dm"N֋s&_b*C[pI )UZ  '=`[4UUg͏_.VǤp [AW δMeszֺ@+k/\pZM:cIo8VvF$}œZ⤀ܳL*jBZ%_O$U]Y=E Y9a# f$/?rkc@U{X_ "UwZNG\SG{?W/}*aBOv,-[!woh Z` 9ƋMr}6WW nL{]Nqh4[oOp+7nORB\WQ7&uAd67;tn#(n ^/E~[s CGlok6ٸVB}5kݫO/L3udDmL ='П֣Jz@+3g؀CoG؍)]Aq0 w,͐JxwrE] ZMuB7f73f<vp7aOOj7$Tݪ Wp[T0J6U>^3"SIQ+Gy9<F0C5 }83Y~) ]k'{TڲRU ZFq5ä`AVJ4Dh*JD ƈqH(knӑp%<,ұ[$fI&/z:Z/}ئpSf nM]!m'D}_ӌ"."_H꼏NJp 2TBO7ϏdQ]'Xc *V-y\BZ+²{4jQi55Q vrؚ˙d<1j*oQw'h7EQs!#lm0lp#F= n8j^PZ\LˈG0}ϢmK%MWdv #fɩ6ЀɔPxWY 2X~p&l{f8;m!,eɛ) CR. *(-xq.] TnخWLe*cU80 ``dmEDIQ8Bga/ۃ15!miUZ]f6Lg JQSr9na\ Sk1sp݁jAhCMFPEJ+ШOի}hr CDJ %D.Fruޅީ>( %~[PVkqenc:]R 9z'7n_l;x>Q]\r(i>qL-+ˠeK}? &=Ak!G7oBj<#K]\MnY%h,&Od1Y|Ir/{j֮93\Y3mJ۩QO>;yZ1-4;}}Ql~D3]4 UJ4Dh#DF"4Dh4]{}.$]Ysr4U-5lk81Rc/A[S9翽dheb_(quESWpV$"6+qn> x9be?bۛԊR6-M\r9X:*pǜSGo; WI~Y{>YkK6绠޴ҝ0v=~XZIN=%I}j٨w2ThHŨ8ݲڡ§x5S\q=kfѐ YDF"4Dh#DF"4Dh#DF"4Dh${X1X_Ut֣$m^094KpDP˝_T# {qaj) NSio9-_l,ۓS\Y@MeS{+ ہ}- pMZ !!ےqCv.Kuɤ4zZ 8ʭ o[m?o`ӓ?騩}}ܮZ W#Bkh"4Dh#DF"4Dh#DF"4Dh#DF"4Dh#DF"4Dh#DF"4Dh#DF"4Dh#DF"4Dh#DFautopsy-2.24/pict/srch_b_lorig.jpg0000644000076500000240000000365311070040246016555 0ustar carrierstaffJFIFddDucky<Adobed        !1AQ"d%a2BRCq#3S$D!1b#AQa"q2C ?i)&(dEUcj'S,b'\@r9d( GUD6{-jʤKeŪbCû‚|@ 0\QpW3yk3VbҶH=?*[ckfU ,Svm)o6Lvp@ns ; ƢoÒsAN>aIJQ{](NVM&q 4 TQ%e۔n R*'aܕ^4̈>ĭm{};+ &:򅿥)e)5!P{luYs{kv8?ٖ-u֍Q8 k F qmbL-s(m!9RcQ1s'/MZ'VP,ѳRUc@ vdʂUE2 ι3cq\+J~ 9r^տ׳oF]02_";Kccj.yW*&(\F2䷸YJͭy ;N$)1:p scFtʪȰA%xBjnGB[e^tGJsPϦ穗fFFw.@L 6A\Kx˾9&fQz(ɇxT#"Z#"<ԑBn̆BޯtH0!Y5en)P{4`<^kfו- m4T )AcM15Ύ %%^\7Pc+Xfqnq} (iUdJiT}z_bX gs|0][A!l0!)WBC2GR5mM^I? o˻֭.̱oU0L fTTDN?vsWF 89) Y&.krtVӗ!!E%Ztorh fM8T|UL+![K4gM}Q${Ata<ŀ&+xޝwؒs͢DX i[B q;4P,E[2Uc/3AW@I+o4@zj ù2epHљqz2Ez7"Ͱ&"WQ ѭ'қĀ[dk&0ߦvNKE}5D%]jӧ >Q+XUR99kKkϬ:qϺм2B*E%ByQj@ {}!oO{5"K[e{lY61G{h8p̸aU7ttߙFS ěztQ1kSoiP"T |B *m^Pنo?⬜jIe32QãVъ=xtp1GX#F(Uës:8u`}WGϣ/ӺׇGъoV[~_Z}5 |.bautopsy-2.24/pict/srch_b_str.jpg0000644000076500000240000000407711070040246016252 0ustar carrierstaffJFIFddDucky<Adobed       !1AQd%aq"2B#R3C$D!b#1QAaq"2BRC ?mzJs HѯUcj Nb'`=whLZG=bZ3GyضOL9AQT֣&#a=le|dAF$nuU~R]D^<5VMΜy3Anl2^(&:QjX z1|rQeӢtU]FUg$N' SWCҞɰVDp 'ޕ0:+Ȱ9RCfDC)QC B) WS͟ opsN|\EQep*$IUC<B' GIŸseCGs2kGZJ(3 pj®ϰ1lnt'7/ HUEJ:^Xc&Epox;|i ֝$sz.DN5-Y2H6i֌UB AURDQTUNrU;S r3N4C&m9%Ǚl :ǧAVdǘXr~ojmniE.)mU뢬l%Y).DBfLc2[ ˢ)SRjpݲ~0*w÷Z^o50L fTTDN>yqWFB%_]Y3cf=6\OeMeoM |NbEQkد^@($p8<5KE"3oY m+/jZj.yYbq_%M?SkbE bhEU׉Ws,I\|! ecEY@wh#!sq,QҦꄡ}_zF@_sYB1ܜW.PJCaG'I T׭e86[N)kG&L]6DžRM Hse;1$xҢA6v?#Ư9p+4"KĽ %LQ㣣R!_Q׏klScTʌh[L\Mn`~Y l$s k!(Oeu[H.z,m{U$0\m%gP8uTSm]W[*svvz*g/+,K8"jk4G{{%My!BS{݊Bc |R;i|XfqԽ\ s,܎UM**-5 mڂAiN%˲۝A[qQFL|+dBvuHHᕄ|Eӡ2|Bok}F/>h(Ȫ6nYWUUם Tx?\֊4#hV{SEש5#ĥrdo]^J_kC_6w#һ՛{;^?_Wnr_%O]4s\/G9M|wM&Kkk_%5G5ɯz飚z=?wtrk滺h5^O]4s\/G9M|wM&Kkk_%5G5ɯ/ӺWwM.L+zrZz}=[autopsy-2.24/pict/srch_b_un.jpg0000644000076500000240000000461511070040246016062 0ustar carrierstaffJFIFddDucky<Adobed       !1AQ"d%2aqb#3B$!b#1AQaq"2B ?8v)w%E^F!ꅧ[CD4t g&+#-wY#[TGY]F xCY zqvIЃ8H)tIvx83N>Nzs\<$@ZI#+M7n^&L(PB 9WpR@xvT)eR^cø]kuAٵ$5Fq 0dfM2S' v UIW5&7QeI'8[­:NT>Ū׆K *nj'y yd _@i`Kj'8qDcCbTHe5ITJWYD[B0{{^"(ֆݷOȖ88h-y тFM0WB*uUZ)}[kMGv;AU帽CQSB-MEKVBbOCn# 3v;E," b h^=ڨ v&TdW܏&naE֜v *..\!ePa |8$RPIXWGf^ӹq7QN>eI#\`?,Dc&vt7fAa0#P56^qK`+"DQ_ ZS'6#0"-QQ5~F !dfFT`J K1䝚|*k-zmd8u*/ofWD`i'jqxWE/?k/ K)<ͽf'R-^3cFJCȶ-vŎ==:ٙMLk<'G`O%Lg 쎻n07U<m|D?S?|y\+7N`YVr \yZ67qGt<h ҳr_h[gߣ?ſz9"#OA"SLM)٬HD4ř.E~rE 1[b7jKS 24IJq!! ky/fUzeqd*h4lcPdGNWbBHI dBR?~J%nbu.VM]"Oܥ@#)"*~ꗟU%͸":};u'ҺAtl]r @}TY*"l6uO蠌[%)82lcF* HmJWDh,$EqIg }h[y[ӕ#?_7LL?p7.IgI/B 0  w]Z>(2K-a TQJ 2h`PŒNy6? ,jظ!e22ȦsMS iZSiVYL$ecx%2Rvf镁;ZF v_s6̤zɌf,!)B|y<)LH&!&@e 7 /BC͟|dT!2JQ^tVwuI 1Y28tkA+Y>n2ZJKA#K{}DC{Mrw u6Qeq1彪iEˬZb7ZN&Zb7$>dKh[Dy]u,6%XFW *\'$SJ+@lGas6mb"}IIڳy2,Vڄ\]x~jO婴)@hv^|tSdtvtWJ$pd`<E?"_XO6=ҰyVG*56Q_P|~Ͼ=`v5}BQMq[ q4əWFjˑ15їRju&@GOvi70qS_TR?}wT.CS."C'SFTF^ƒZ:[autopsy-2.24/pict/tab_help.jpg0000644000076500000240000000234511070040246015674 0ustar carrierstaffJFIFddDucky<Adobed       &4 !1ASq"2#Qa3CE!"1AQaq2B ?,$XB8IR%DU돜ɸ x])h]{g/BUr8kU)Ll?]j^ \%`孾C͔͘[#$ Bkyûۤ+ΤvU 8dhIPrdb}D"yuzm3x@4e!E*\ 3NN8$"^C2:I@d0pEb8wj*eL9`.-,m&=n{gZqG#xWcY؝W?wC,Sr(rcj<ضQjGUah%3pbo$Ή'm:?]w[p\q;$JiQ΂>,ωE&L駁E6ݻt-2IQdGElUbBTq9n R9m߱K-Zϐ:f2,^(q9eqTbmM=ҿ ZՖ]m1彪fY΋拗Rb??jo.Q:GeIpY *':"rƱ3JRJě#Ʉa N?+DOw??9jɗ@mT!q y2ҟ&^|iG浲:bΊ D2n+;p+WMILii*"0o~8Qy.27S 9ߕϗ0qpəc6B?NR6M]{Գbꇊ3ݫ fνƑ7]NԎBr(]{ԁu^+=j]l]ROpU[autopsy-2.24/pict/tl_t_data_cur.jpg0000644000076500000240000000553211070040246016723 0ustar carrierstaffJFIFddDucky<Adobed       &!S1ђAa"QBRq2r#b3$&!Q1A"aqRr ?DV,]SPdU+uA 'j*Yse-v[-MCs D3mN+ռ =DY9<ŸaBEdG"A%ET31:~Jq;3ٮlrN9(TT$4*ɞ<4j,c\\UT@lЋTT*Kn; $θ$4َ5$TZm> ":,W{hڲcMSj-NvK ǧA6$܅҄(J3FU2PWMVJHfIDJ:tILWUMS(M*-Pgz6elCfs B(eqEU vULĸ)|o2ĜR8hѾ/2%Inؗ&&IYq,6@O7vIQMǩI"_sq2sZˍD(mhIb~Q+4t!I,f7]7'׶ Ǩ!\TEoHIp6oFD6jW6Xɾ#VfGBdnԬZTH(fYauEu.d-4A?|id,:iT`W {(ܔٽUEuEO ]XC21&uՁ^{ng&į A%}6$&;4 / oP EAWW|] s,_bnK}\IcYߏoζ28&f[-|d--kO& ZU3r'N-@wF%[J\6y͸[UPQ^_KY|y]8e#P-1͸] QܚjeXʪI&fGnߕyd32c+eh8"kPc:EV1xW4X5A/7vp?0^@4>ټ>_@LMʊłsEB"൭De.N$eQ1N\lHC}ι&Q+b- tWOfr5tRgKݸDlUIh]nI7;lWq*']\(7*c@wuoO0׫0(k*&{>!) r9)W dz@:o=x +O8%VVȆ* $Z Dw89,~{?-1SeOLS`M=ɖ>{?-1O-}7~Zb&["cV'#l;׎'ZuXΔ{[d""[Mi':N[ x $bņ"32XqBMESׇ*,W`}gqSeOLS`M=ɖ>{?-1O-}7~Zb&[nY0>L v-Hq?Ii܉LBLm"Gi[FsHd\}[u\,E* Nh@ΫffD%(DJ"Qm[f"6 "??+j?{#6+^Q#Vx%$H02OIJvD^mʃf!HO*o D$J@ਝ{|YXrެ/D"4Ft5[7$<9'G|iVhhrԿ Gƭ EY [R&Bq--rX }t[WeL؞TOB}8(w[V $Jn%u 5VN [s'qad@1usrNxt5[7$<9'G|iV:=O$jNnIy#UsrNxӛt{ƞHnGrZ~U|hPautopsy-2.24/pict/tl_t_data_link.jpg0000644000076500000240000000502411070040246017063 0ustar carrierstaffJFIFddDucky<Adobed       &!S1"AaqR2B#r3$Q"!1AaqRr ?xFжAe'_肜5Z$CK~;QWr˼]<~5oH5]t1Ͷ 7U[TWTw~UE>UtY(Ne~NC1n0bPGY&ȐI@gQxx&կMjpe׮v*q`EEڤ &UY&F_l2|qbǖ},F5uUD]EMʭZ !PdYd}[1ܚDVYUECW6='vSTE'ȶ:K ǧA6$܅҄(J3FU2PWN,țTN .w_WT%0q_aU5NOp]4˒PW>TQF\.Pٜ-,J'FQUB@5]ViK]W?\iZ,I)*8_ HZn_*^Y֖ #&Ye,o70" >`"@EڜW'F$c͉QUfT/ۍe"`AE_]4MW֭.D+oľ٦ Mad5 7 85i|Lft= cl6dKj w"Uq=P7b8#J-#*OD^{kLZ\4A?<^E6n:HN[F+*?n,`"5G Ns96%J /幱%1yxdzj* »xRtoLs4J~a3+1Y\oYI-⊪-ME@[S+F5e˛, ۱̓B2l>8lL%CH%qCT!%£'uSuW{.pM'/o﷫- 9ruAG=`W)oScRpH-c Žd}Ų zӗ+sIvJ؋SKt4ۻq䋤%LJ-> b81_vU'^5NՍ:ܒnw'J0)4خUDN+ƺ(:cn$ py׫iXٮU(M@#x$3Rտ|3/iZ}I*&EZꌓ`j&'XڎK}C|hKG->ޡiheۇ{?--LCpz奣ɖ{nyPy2m=&Z!}CD=~ZZޡiheۇ{?--LCpz奣ɖ{nyPy27oBԉ&H֍V6)r#JVKo=J؂{T]R斤؊?bmfP @(P @(P @rH<_iGuՒrNϘV\cΛ1j:'gyp-GW$:nŨ䝟1M˜\cΛ1j:'gyp-GW$:nŨ䝟1M˜\;P1H6NSP$VPU5; } I+LyCyR%O {%Nuhɾ>tϸHɴUrK\PQUT͝0DE:ӥqtӍiTi 2zi ̺.Lb21Ѳ^H^Oxqm D1#\ pXbDFJ횺gdU֟ݷV{-|Q+\_EyG:&죉2?T:_,ivVKG0&N!18| F&uUE?;{mmXKb'8ju`|ԶQj[P}Ŝ :Wi'!$E e2S"Ur4?3۩<=N9Bv:rmܹgnI:xAm&3#`dXcoM'Ƞ8V@-J93M?Pw9V]&TlK6U5;sB>1&]rTg)M[JYQ&qTb.t,>[sCƞއWrYs Y>"HYmDdd?.GIp5tKW[qQSɊ[ YTMJ" M<\SĤy&\+R$_ZUJM;w.q > L+·!!onw_!h1_f6 )rNMD).?Q% 2mN.b15OԿA\=}ve՚(U+}m9cf"l4$(df~͌tl椦;KDG~0\Ժfq6<: TvE0V{qǻ9ڴi4>j[P}ŏ5->TbJ6*lb*J[N*. M6+bm]&R;SZ^-?'T0f MC@QLؙُ(OrzRIebO+!=g G+!=g G+!=g G+!=g G+!=g G+!=g G+!=g G+!=g G+!=g G+!=g G+!=g G+!=g G+!=g G+#ѶX:|I P}̋YdfqFO;TG)9N#pyL -6mM 0q#ܶՙk4q gBcЛ %W}Tw 6i> IHT#p6^e˴>H3*!N'>_xZW:>^;k8"9,9dz"7t=O5ʝHL"cFUM^ٍ0{fr_qsz10_t k]!b$>;}lmS(L8=cN O$qcO$qg=z~ICKh2ӕ1 9L jI]B~JU$J |"QKEfVՐjcMW+U"\[n:- Y**P9}e}~N9eiS@0Tfagk|?LTg_%2ah~`[7 Ҕ )I%Z/[?༶r,AeIpv[H[Um%EƁx$|]2˖ZP l`)JhqT؉I8lDGAaHIS'"IX3yw̹ASMQ2M${F4E5=S[VR-+0<w+M'&[m{k[+|Ot6j(_NЩSJ@Rc(^=Gwaĝm=q7Qۣ{Y;6nGwalD;ndÈٺv3݇u8bIu4:{r.b:ܛoA.F#2J`(Po$X൑[n׸M[B ]!TE%@UTLWyk8ݻ\ BLWYFH8W1:_Jϫr"bQ1_%ȶ;9.!lߝqLG(dJU8,֭~$ةUKg.1Gf;*l/Fìy@[lxe%uoFtq.ߒG#86DM&(F8u4X5\;-m.M) "(qL©WY2GtmCܻ~s)1%:M2N\肫=b+}(`[l*SaT צ+k;ٶ".t(]dqO2U$ETǦ7/녮hr=j.U:8!L s"~͊SRII)Ҏ{eՊn\BaugVTI$(8ȄLˁt"qTr7ŵ.-i k˿v\)M6uGZ5|3 pZÛmGөWǕPC Y>.(qθeEk1~S݅yܩNW|jtbCM}]- R}smi]kEiTU"n9WH'2gl:V#t]}-5upi((Y]Qm5bPIR~kSǛm)eO{%*MLvqڞ)M==;Sx"gjVDiqo*UEx'J)cUMJ>??p_ {nS:4c09*'tGeVNs7ǜԂw䆯-M$>{NemhN\EK 0aVӷZkt֪Ѿݳ"lri[ͥ%>7^LEANpk2T9%Fu."6*pM6rIܝ(bU8Eد66K֥nmzE-1^҄͟6#bmO{ +O8%VYdh]QR{v "n.h\{n9&[!|Cd=7~ZZs!ihe$Mly N6@CxଯSG^! m3N~G8½ %źcշFlbKG|\L 1N9bѝF~{?-V|lKG->s!ihe{?--LCpx奣ɖzn9y2Gmб"u$IR%-Ad[F+HqFO)r#JVKUo{(C-ɱEP @( ̷͵T t3p'E"lD*~{\k:nN;שiqVx%$ au\x;*JU \y.Y'7U% \STN>5\,;cGGK wLͺ! ' 8-y-4˙@(PWR ]˸-Ʈm;1n5w''{i)q9=cNL[]w bjNOXӸSWrrzǶ˜=Ÿܜp-ɣ;gb=h_] a 5ĶĶˎ(6B]2|kZܤn?c|WO(ۥu1,[?oeؑ*Ea$`\[W;p\~>ۙ<΋$R"[mpL[]w bjNOXӸSWrrzǶ˜=Ÿܜp-Ʈm;1n5w''{i)s4wp+ڸm+")sautopsy-2.24/pict/tl_t_tl_link.jpg0000644000076500000240000000472611070040246016601 0ustar carrierstaffJFIFddDucky<Adobed       &!S1"AaRQ2Bb#q%Q!1"Aaq2BR ?xFAeয়?I$p9%M/AGF Mr˼^Tty ^p1.l)kQ 'Eq >m>̆^Ɍ޻]#* (̠1 ZMq]KۉUo=mn:uZaAbebpod86[n׸Lu +[qe%TB b|j'qAk^耋BLC*XƟtL]+TG\ !%3 O1Udc܍`E@.R[X7INT(<Yb/߇N \J[?ݡu}ٍ2;1uSfAz4Vdu mʣ<+iz?d,]%ǚ&+GHq6JShP)`\|8E.W7m ܄uMc\q>5?t\]?}q1+vmy2BJKڜHJF>4QFv\ҵ[dŜ*2t$XcQ=MȒb80S)"N^֚; 7hd;c̞8;c̞`̸-䌙)8?Q^xYjL\5:g),ftݽ)ǍA4Ys#)qFnR;Pn6\Vl6[~jELqܐ *[IoI%|8V^sμlVpXei`]W"٤6-$IJR2PbqN?oObgޖݽp-G\LvR[TepDC ʔfq#,n)JUIIҏ;eՊn\Bau.Y)SLIR e(ucүJw&8?EM5}'enJnVwMr0|:e̕pars*ybP;b́Yp+udžTj5_pHWMJuRѪK@m[cOܮrZژZ%AyS]^D>r'2g9V+瑺.H>:R&MI Z)l55($V5|d},[mmZvrlc)2PS8[y.rOOJÇůt)DWl[ondF.7-+).$&ܵK^Z UG ⟻[nRCran fBмs@1=FZ9;r|Ww䆯-MP>{NemXSKhCr%\p"敍:zeÏ%U^(7۶d[BmUmDކsjM i>ן2To\T:nI*pp뎦[euIܝTd4NexxWe_bqԗK;c̞y0l@1>z҄?6#G>mOw#\|Eq ɪ2X{v VJs py$2ۇ{̟M1L'LG+!}{ny2}4y2ۇ{̟M1L'LG+!}{ny2}4y2ۇ{̟M1L'LG+!}{ny2}4y2ۇ{̟M1Lm±Rp~(a bd[F+A 6?#hqTG4No;%AT=ҹ8#MdXP @(P @(P @( ¤:=k.5w'gzӨSUƮOZu jܝiNMW=i)Wrvy:5\jN4P]枴q;<֝B5w'gzӨSUƮOZu jܝiNMW=i)Wrvy:5\jN4P]枴q;<֝B5w'gzӨSUƮOZu jܝiNMW=i) i=iYMw?autopsy-2.24/pict/tl_t_view_cur.jpg0000644000076500000240000000517111070040246016763 0ustar carrierstaffJFIFddDucky<Adobed       &!S1AQ"a2BRbqr#&Q!1A"aq2BRr# ?!lO>1Z$CMzpm;-uGOW>T{$]wYl1ɸę-DE.YΩEKe,#itU+,j<7-mmsb"l ) dL2JQ.Nxzni\ /EK,edQݛ_HдwӶ9IhWǶ+_x-,LHAoH"Aˢن51&ҥ+4Aپm;#LJ9̕&GqCOm>/R*,nM2BƉ&,ؼfzDQU\/gy%VFzvcmu N)#nIC Ȋ'Ȳ:f&ۓMˉ%dqP#\&**©,\Е/-{um]6 [pYqu!uUqB$N ڵ+4(8[j.d80Ok*eB^i|T{K ؎&T</dm Z\us {[M<Φ1-æaKE彔nJdΪ;mdbLQ놧UΕ7r{>1F'2M^ c8"~)ZaIt)ZYn@ۋO,89E0JE7ŊIq\H[=oo2"pJKܨXA6G%Nu9owJZ&YjVULOLEJۍ*-*Q+Z?ε\8/F/m+}=M䍸`#ך8؆5nNGVWםUⱺ{QXgz! Gژ.m%"=\Ҟ)AZ= &vwٗqtxwkݪcSC,5O 1L8+L{xeWr|۪+,⹴i>oCs7R2Zn P$,5G2}[chkUB%ǯ#qe1&Ptz&#\[̑~9.gu*DlUIT:ܒnw'J0)4خbUDN+öQnuIu/-æa^c f"dLWt63gտSѱVzAzm{D,jU=7A?Zt-ľۇ{?M-'ٖ{nY04{2m=fZ!}gD=~Z=hO?!IFhsue|Lr{ lS$Ki 8 q 2ȔkaVEXm#3%.pI0 4U>^ZFv-nY05[Ieۇ{?M-̴Cpy饣ٖ{nY04{2m=fZ!}gDTvݽ '\ODx"RDl"Gi[G+9uf_Vy[Y/bT<ԛ,(P @FemN[?")`#S|qc398]IKŷ)%@T I`8)WO,R<|x%qgT4HstBdTVHqN#Q;0k{YdwCcGGK wLͺ! ' 8-y-4˗@(P^@N󬻎bjNp-F:w bjNp-F:w bjNp-F:w bjNp-F:w b֎&8VVK 82kmmKeQu6B]2{q TpjBo7bz 9ʺӍS,Z?oeؑ*Ea$`\[W>l8. umgE)K"Z:&<)Q:>#͘<)Q:>#͘<)Q:>#͘<)Rwp+7\G+")Sautopsy-2.24/pict/tl_t_view_link.jpg0000644000076500000240000000445711070040246017135 0ustar carrierstaffJFIFddDucky<Adobed       &S!1A"RQa2Bqb#Q!1"Aqa2BRr# ?!lO>pANC\!86`^UVe/C: {#J["aMŵ$j :-v7ީ"ùx%ks^eG徶Ͳ͢q^rDYm$7\\LSJ9%´!)їvc]m<+4rE*Xl/'Y} )}nfO'B>Xt[7vY#D!%FߺDےqiRAٿ.m;#LJ9̕&GqC Qxg^g:(o̐I"B6/+-8ٞQ"(*ڨIqyoUihcTmti$m (a܈X.?_F6bn}4n\| AqM%1AU1QUO s_bVTZ,m=2nfBB눪 *HjVQ>87n\qa]hSBTB_ i|=q\+mvd{s=ݏowbO|ErVT7}S',7b8#=O,|/v6߶faF+%]G07iz[?iz*9oe+*~^xYb1GX26ők Y"19h) ik5%Rz.-.[t;|W[:ڊE-`⚈cxz~V튋5wSeۅzیILh 7:=¿৅JuQtiZAM_n=|H2}@(qAiI11%M=#"}vŪEm }! "ɐjJ)+ϧJV%q!l m *.crMbX +i^QٔRJs1 M2k9 EJۍ* y}K)?XGfy֫m#°EbﷵILqG_ƴ]\T}%Z_t\9VWo=k;ַa m8TA{|J=RVv4PiB./ێs~i׻T{,XkO 1L8J_u\R.OuEer|W6;nx]\k\[M]ajY`7(Jj=m>Kב82ĘmBT4!./d#qT~lԫfuz?qTX#bN'QRVrIܝ(bĪWuvQnucjK pO0W\Q;(N o>ypCݿc^iG_$l-"On"MO%Ú-c:q/o=M1'ɕ=g#ɕ=g#ɕ=g#ɕ=g#ɕ=g#ɕ=g#ɕ=g#ɕ=g#ɕ=g#ɕ=g#ɕ=g#ɕ=g#ɕ=g#ɕQv,Hq?iaѰ5QE?DsId̾Vr ^T=ҹ8# dXP @(P @(P @( Ҥ9Gjܚ<ǭ:5\fMc֝B3w&1NMWGPɣzӨSUn=i)7rhq4yZu jܚ<ǭ:5\fMc֝B3w&1NMWGPɣzӨSUn=i)7rhq4yZu jܚ<ǭ:5\fMc֝B3w&1NMWGP-QXqautopsy-2.24/README-LIVE.txt0000644000076500000240000001176211070040246014713 0ustar carrierstaff Autopsy Forensic Browser http://www.sleuthkit.org/autopsy Live Analysis Mode Last Updated: January 2005 What is Live Analysis? -------------------------------------------------------------------- Live analysis is, in my mind, an investigation that occurs using the software resources of the suspect system. An example scenario of this is when a suspect system is found running, a CD is placed into it, and commands are run. If the suspect system is powered down and booted from a bootable Linux CD (or similar), then the investigation is a dead analysis. This is most commonly done when investigating a server or other computer that is suspected of being compromised, but verification is needed before it can be powered down. Using The Sleuth Kit and Autopsy will prevent the access times on individual files from being updated (although the raw device's A-time will be) and can bypass most rootkits that hide files and directories. What are the Issues with Live Analysis? -------------------------------------------------------------------- Live analysis is not ideal because you are relying on the suspect system, which can lie, cheat, and steal. In addition to the potential of getting false information from the operating system you will also overwrite memory and maybe swap space during the investigation. If you are interested in examining the memory of the system, you should probably acquire that before you begin a live analysis. An issue with doing live analysis with Autopsy is that it requires Perl, which is a large program and will likely need to depend on libraries and other files on the suspect system. How do I make a CD with Autopsy on it? -------------------------------------------------------------------- You will want to have a trusted CD for a live analysis, and autopsy makes that fairly easy. Compile autopsy as you would for a normal dead analysis installation. Then execute 'make live' in Autopsy. This script will make a 'live-cd' sub-directory in the autopsy directory, which contains a copy of autopsy and copies of TSK executables, grep, strings, perl etc: # make live Making base directory (./live-cd/) Copying executables Copying autopsy files Creating configuration file using existing settings Try the 'make static' with TSK to see if you can make static executables for your platform. The 'live-cd' directory has a 'bin' directory where additional executables can be copied to and then the whole directory can be burned to a CD. How Do I Use the CD? -------------------------------------------------------------------- After the CD has been created and there is a system suspected of being compromised, then it is time to take advantage of the new features. There are two scenarios for live analysis. The first scenario uses a network share from a trusted system that you can write to. In this case, autopsy is run as normal and you specify the evidence locker directory as the mounted disk. The evidence locker is specified with '-d': # ./autopsy -d /mnt/ev_lock 10.1.32.123 The above would start autopsy, use '/mnt/ev_lock/' as the evidence locker and would allow connections from 10.1.32.123 (where the investigator would connect from using an HTML browser). Remember that we do not want to write to the suspect system, so we should only use a network share and not a local directory in this scenario. The second scenario does not use an evidence locker and does not intentionally write any data to disk. This scenario does not need the network share and each of the devices (or partitions) that will be analyzed are specified on the command line using the '-i' flags. The '-i' flag requires three arguments: the device, the file system type, and the mounting point. For example, to examine the '/dev/hda5' and '/dev/hda8' partitions on a Linux system, the following could be used: # ./autopsy -i /dev/hda5 linux-ext3 / -i /dev/hda8 linux-ext3 /usr/ \ 10.1.32.123 The file system type must be one of the types that are supported by TSK. The remote IP address must also be given, otherwise you will have to use a browser on the suspect system and that will write data to the disk. When you use the '-i' flag, then autopsy will start in the 'Host Manager' view where you can select the image that you want to analyze. You will skip the case and host configuration. The default case name will be 'live', the default host name is 'local', and the default investigator name is 'unknown'. Additional Information -------------------------------------------------------------------- I wrote a more detailed explanation of the live analysis mode of Autopsy version 2.00 in the 13th issue of The Sleuth Kit Informer. Some of this document is taken from the Informer issue. http://www.sleuthkit.org/informer/sleuthkit-informer-13.html -------------------------------------------------------------------- Copyright (c) 2004 by Brian Carrier. All Rights Reserved Brian Carrier [carrier sleuthkit org] autopsy-2.24/README.txt0000644000076500000240000004115511355002261014156 0ustar carrierstaff Autopsy Forensic Browser http://www.sleuthkit.org/autopsy Last Updated: March 2010 Quick Overview ----------------------------------------------------------------------------- The Autopsy Forensic Browser is a graphical interface to utilities found in The Sleuth Kit (TSK). TSK is a collection of command line tools that allow you to investigate a Windows or Unix system by examining the hard disk contents. TSK and Autopsy will show you the files, data units, and metadata of NTFS, FAT, EXTxFS, and UFS file system images in a read-only environment. Autopsy allows you to search for specific types of evidence based on keywords, MAC times, hash values, and file types. Autopsy is HTML-based and uses a client-server model. The Autopsy server runs on many UNIX systems and the client can be any platform with an HTML browser. This enables one to create a flexible environment with a central Autopsy server and several remote clients. For incident response scenarios, a CD with The Sleuth Kit and Autopsy can be created to allow the responder read-only remote access to a live suspect system from an HTML-browser on a trusted system. Refer to the README-live.txt file for more details. Autopsy will not modify the original images and the integrity of the images can be verified in Autopsy using MD5 values. There are help pages for the main analysis modes and The Sleuth Kit Informer is a newsletter that adds additional documentation. This document provides an overview of how to use Autopsy and what it can do. http://www.sleuthkit.org/informer/ Case Management ----------------------------------------------------------------------------- Starting with Autopsy 1.70, you can have multiple cases. When Autopsy is started, there is an Evidence Locker directory (specified on the command line or at installation time). This directory is the base where all cases will be stored. A CASE is any investigation and can have one or more hosts in it. A list of investigators is assigned to each case. Each case gets a subdirectory of the evidence locker and there is a configuration file for the case and the list of investigators. A HOST is a subset of a CASE. A host contains one or more file system images that are analyzed. Each host gets a subdirectory in the case directory. Each host has its own configuration file that describes the files that it uses. Each host also has five directories in it: - images: for all the disk and partition images - this should have strict permissions to prevent modification - output: for all output files from tools. This includes unallocated disk space and data unit contents. - logs: Audit logs and investigator notes are stored here - reports: All ASCII and HTML reports can be stored here - mnt: Can be used to mount the images in loopback mode An IMAGE corresponds to a disk or partition image. Image files are imported into an Autopsy host. The image file must be a raw copy of a partition or disk. These can be created by the 'dd' tool. Issue 11 of The Sleuth Kit informer discussed how to make images using 'dd'. When importing an image, you have the option of moving the image to the evidence locker, copying the image to the evidence locker, or making a symbolic link from its current location to the evidence locker. You also have the option to calculate or add the MD5 hash value of the image. Main Functions ------------------------------------------------------------------------- After you have setup your case and imported the file system images, you can begin the investigation. The Host Gallery view provides a list of the imported file system images and you can select one of them to analyze. After you have selected it, you will enter the anlaysis view. The top of the window will have a series of tabs that represent different analysis modes. Each mode performs a different type of analysis. Choose the mode that will help you find the type of evidence you are looking for. If you are looking for a specifiic file, choose the File mode. If you have a specific keyword in mind, choose that mode. If you are looking for a specific file type, then choose that mode. You will now need to use your sleuthing skills to search for evidence. You may want to refer to some books dedicated to this topic if you have not done this before. I will now give an overview of each of the modes: FILE BROWSING: Allows browsing the image as a file system. This gives a list of directories on the left, and files and file content on the right hand side. The output of each file can be seen as ASCII or can be run through strings. Since this analyzes directory entries, deleted file names can still be seen and depending on the OS, the deleted file contents can also be easily recovered. If a file name has a check before it, it has been deleted. The directory contents listings can be resorted based on name, size, times etc. by selecting the proper column header. KEYWORD SEARCHING: Search an image using grep(1) for a given string. The result will be a list of data units that have this string. Selecting each unit brings the user into Data Unit mode to view the contents. Case insensitive searches and 'grep' regular expression searches can also be performed. To decrease the searching time, a file can be generated with just the ASCII strings of the image. Also, the unallocated data can be extracted and searched to make deleted data recovery more efficient. The search.pl file contains predefined search values. Autopsy currently comes with a regular expression to identify date strings and IP addresses. Additional values can be added by the user. The format is given in the file. TIMELINE ANALYSIS: A timeline of file activity can be created and viewed. The timeline allows one to identify file and directory locations to examine. The times associated with files can be easily modified, so the time line should be used as reference only. IMAGE DETAILS: Details about the file system are displayed. Examples of this mode include the Volume name, last mount time, and the physical layout of the data structures. For FAT file systems, the FAT contents are given and UNIX-based systems show the group layouts. FILE TYPE ANALYSIS: Data reduction is an important aspect of digital forensics. One way of doing data reduction is to exclude known files and identify unknown files or categories. The File Type Analysis mode will examine all of the files in an image and sort them based on their file type. For example, all JPEG and GIF files would be identified as 'images'. This mode can also identify files that have an extension that is different than its file type. This uses the 'sorter' tool from The Sleuth Kit. The hash databases are used in this mode to exclude files that are known to be good and identify 'known bad' files. Refer to issues 3, 4, and 5 of The Sleuth Kit Informer for more details. METADATA BROWSING: Metadata is descriptive data about a file. This includes information such as times, owner id, and a list of data unit pointers. This mode allows one to view the contents of the file system structures that hold these values. In UNIX-based file system these are typically called inodes, for FAT they are directory entries, and for NTFS they are MFT entries. In this mode, one enters the address of the structure and the details are shown. The file(s) that are using the file will also be displayed (even if they have been deleted for some OSes). Metadata browsing can also be entered from within File browsing. When the file's metadata address is selected, the browser switches to metadata mode and displays the associated details. The data units that the file has allocated can be viewed using the data unit browsing. DATA UNIT BROWSING: All file systems need to store file data some where. Typically, the file system space is organized into large chunks of consecutive bytes. These chunks have different names depending on the file system type, so we will just refer to them as data units. For UNIX-based file system the chunks are fragments, FAT are sectors or clusters, and NTFS are sectors. This mode allows one to examine any data unit they want. Just enter the address and it is displayed in a variety of formats. This is most useful when used with searching or metadata browsing. The contents of the data unit can be displayed in ASCII, hexdump, or by running the raw output through strings(1). The metadata structure that has allocated the unit will be displayed (if any) along with the file name (if any). There are two types of data unit addresses in Autopsy, regular and unallocated. The regular address is the unit number in a regular image created from dd. The unallocated address is the unit number in an image created from the unallocated units in a regular image (by using blkls). When unallocated addresses are entered, they are converted to the regular address and the corresponding regular unit is shown. This is useful when using Autopsy along with foremost (http://foremost.sourceforge.net) or Lazarus (TCT). INVESTIGATOR NOTES: An investigator can add notes about any file, data unit, or metadata structure. The notes can be viewed through Autopsy at the Main Menu or by any text editor. The notes file is saved in the 'logs' directory. When viewing through Autopsy, the location that the note refers to can be easily viewed. REPORT GENERATION: Each of the above browsing techniques allows a report to be generated. This report lists the date, md5 value, investigator, and other context information in a text format. This can be used for record keeping when deleted data units of data have been found. THE CELL: In an ideal world, forensics should only be performed on an air-gapped network. In some cases, such as incident response of critical systems, this is not possible. For this reason and because of a history of HTML-browser security issues, files in Autopsy are not "interpreted" by your browser. For example, an HTML document by default will be shown as the raw HTML text. If an investigator wants to view the actual HTML output or an image, they can do so in a sterilized environment that parses out embedded scripts and off-site references. Refer to issue #1 of The Sleuth Kit Informer for more details. Requirements ----------------------------------------------------------------------------- Supported Platforms: Autopsy will run on any Unix-like system that is supported by The Sleuth Kit. To run in Windows, you must install and run both The Sleuth Kit and Autopsy in Cygwin. Autopsy needs the following software: The Sleuth Kit (version 3.0.0 or above) http://www.sleuthkit.org/sleuthkit PERL (5.8.0 or above) If large files will be used (larger than 2GB), Perl must be compiled to support Large Files. Most systems now ship with 5.8 with large file support. HTML Browser: Any that supports frames and forms will do. Some issues exist with some versions of Internet Explorer. Netscape and Mozilla always work fine though. Explorer will sometimes error when referencing 'localhost', but '127.0.0.1' will work. Recommended UNIX Utilities (most platforms already have these). The default version that comes with some systems are not supported by Autopsy. For example, the grep in Solaris. grep: http://www.gnu.org/software/grep/grep.html You will need a local md5 or md5sum executable as well. Most systems now come with this utility. Regular Usage ------------------------------------------------------------------------------ To use Autopsy: 1. Ensure that the evidence locker directory has been created and start Autopsy. # ./autopsy Copy and Paste the URL into an HTML browser on the local system. It will look something like: http://localhost:9999/290263284571318993/autopsy 2. Select the 'Create Case' button and enter a name and list of valid investigator names. Note that both the case and investigator names must be valid directory names. 3. Select the case from the Case Gallery and then select 'Add Host' in the Host Gallery menu. Enter the host name, and time information such as the timezone and clock skew (if known). The timeskew is how many seconds fast or slow the original system was and the output times will be adjusted using it. For example, if the host was 3 seconds slow, this field would get a '-3'. 4. Select the host from the Host Gallery and then select 'Add Image' in the Host Manager menu. Copy the images to the directory shown on the screen. It is a subdirectory of the Evidence Locker for the new host and case that have been created. After the images are in the directory, press 'Refresh'. The images must be partition images in a raw format (i.e. dd). 5. Select the file system type and mounting information. By default, the MD5 value will be calculated for the image and saved for future integrity checks. If you already know it, select 'Add Known Value' and paste it in. 6. Continue to add images and hosts to the case. When done, select one of the images and using the different browsing modes. Common Configurations ------------------------------------------------------------------------- The basic usage is for a single user with the client and server on the same system. Autopsy 1.70+ can now handle more than one case at a time. The syntax is as follows for the server to run on port 9999 and only allow access from localhost: # ./autopsy To specify a different port number, use this: # ./autopsy -p 8888 To specify a different remote host, use this: # ./autopsy 10.0.0.1 To specify both a port and remote address use: # ./autopsy -p 8888 10.0.0.1 If more than one investigator is going to be using the same server, then just choose different ports: # ./autopsy -p 9000 10.0.0.1 and # ./autopsy -p 9050 10.0.50 You can also specify a new evidence locker location by providing the '-d' argument: # ./autopsy -d /usr/local/forensics2 Security Considerations ------------------------------------------------------------------------- The Autopsy server is a Perl program that only processes Autopsy urls. It offers easy access control restrictions by limiting access to the server to one host and uses a random numeric "cookie" to further authenticate a remote user. The random cookie is generated when the server starts and allows an investigator to use a multi-user machine. The recommended usage is to have the browser and autopsy running on the same single-user system, which is the default behavior. If a non-localhost system is specified, a cookie is automatically generated. If localhost is used, then a cookie is not used by default. The default behavior can be changed using the command line arguments. SSH forwarding can be used if encryption is needed over a network. File names must be very simple (letters, digits, -, _, and .). This allows fast and easy checking of file names passed in the URL and does not allow people to move out of the morgue directory. Symbolic links can be created between the simple names and more complex ones. Troubleshooting ------------------------------------------------------------------------------ Autopsy is complaining that it can't find X: Verify the variable settings in conf.pl (see the INSTALL file) Autopsy takes a very long time to display large directories: This occurs because directory contents are displayed as an HTML table, and many browsers are not very efficient at displaying large tables. So, it is not Autopsy that is slow, it is the browser. Autopsy hangs when opening directories: Same answer as previous question. Browsers don't like big tables. Autopsy is getting slower and slower: If you start an intensive operation, such as searching or making a strings file, and you hit the back button you will not stop the search or operation. There is no current way to stop these types of processes besides issuing a 'kill' command from a shell. Errors are generated by the 'strings' and 'grep' utilities: This occurs because you most likely do not have the GNU version and the flags are not working. Install the GNU grep and bin-utils and verify that Autopsy is pointing to them in conf.pl. Internet Explorer gives protocol and host errors: If you are accessing the localhost, then use the 127.0.0.1 IP address instead of the localhost name. A file system image doesn't show up on the menu: Make sure your version of Perl supports large files. Feedback ------------------------------------------------------------------------------ Please e-mail me with suggestions on what you would like to see done differently and new features. ------------------------------------------------------------------------------ Brian Carrier carrier [at] sleuthkit [dot] org autopsy-2.24/TODO.txt0000644000076500000240000000345211107446406013774 0ustar carrierstaffRemove HFS check in autopsy.base when HFS support is standard. Look into adding the unallocated partiion space when an image is added. Look into integrating clamshell or other AV There is an error when viewing the event sequencer notes about initialized in "ne". test date search Add SHA-1 to more places (images, lookups etc.) Get "Can't ignore signal CHLD, forcing to default." message with file type sorting (BUG: 919829). Figure out details around having Perl on the live analysis CD. (BUG: 919831) -------------------- FILE MODE ---------------------------- - Make a file system depend seperator for / or \ - check for tar during install - List contents like HTML does now --------------------- SEARCH ----------------------------- - new mode where searching is done on output of 'icat' of allocated inodes - Bug: if the string that matches a keyword starts with spaces, then the 'index' function returns the idx to the start of the spaces and not the substring. (BUG 842858) --------------------- TIMELINE ----------------------------- --------------------- LOGGING ----------------------------- - New Report Creation: - Add pulldown in notes for common things: - New MD5 / SHA-1 - Part of rootkit - Suspected child porn - known child porn --------------------- SORTER ----------------------------- - Should sorter be at the host level instead of image, with output files appended to each other? - Allow one to browse output files --------------------- GENERAL ----------------------------- - Add foremost - link in meta data to list just unallocated / used - Make data bases updatable in the host details view - Option to mount images in loopback when it is a Linux system - read config files in autopsy itself and not everytime ... - Make a way to kill intensive processes (searching, fls) autopsy-2.24/xcode/0000755000076500000240000000000011355002265013560 5ustar carrierstaffautopsy-2.24/xcode/autopsy.xcodeproj/0000755000076500000240000000000011355002265017260 5ustar carrierstaffautopsy-2.24/xcode/autopsy.xcodeproj/project.pbxproj0000644000076500000240000001656311323342333022345 0ustar carrierstaff// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 42; objects = { /* Begin PBXFileReference section */ 02B041C40E9070E400E46A87 /* .perltidyrc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = .perltidyrc; sourceTree = ""; }; 02B041C50E9070E400E46A87 /* Appsort.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Appsort.pm; sourceTree = ""; }; 02B041C60E9070E400E46A87 /* Appview.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Appview.pm; sourceTree = ""; }; 02B041C70E9070E400E46A87 /* Args.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Args.pm; sourceTree = ""; }; 02B041C80E9070E400E46A87 /* Caseman.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Caseman.pm; sourceTree = ""; }; 02B041C90E9070E400E46A87 /* Data.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Data.pm; sourceTree = ""; }; 02B041CA0E9070E400E46A87 /* define.pl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = define.pl; sourceTree = ""; }; 02B041CB0E9070E400E46A87 /* Exec.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Exec.pm; sourceTree = ""; }; 02B041CC0E9070E400E46A87 /* File.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = File.pm; sourceTree = ""; }; 02B041CD0E9070E400E46A87 /* Filesystem.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Filesystem.pm; sourceTree = ""; }; 02B041CE0E9070E400E46A87 /* Frame.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Frame.pm; sourceTree = ""; }; 02B041CF0E9070E400E46A87 /* Fs.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Fs.pm; sourceTree = ""; }; 02B041D00E9070E400E46A87 /* Hash.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Hash.pm; sourceTree = ""; }; 02B041D10E9070E400E46A87 /* Kwsrch.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Kwsrch.pm; sourceTree = ""; }; 02B041D20E9070E400E46A87 /* Main.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Main.pm; sourceTree = ""; }; 02B041D30E9070E400E46A87 /* Meta.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Meta.pm; sourceTree = ""; }; 02B041D40E9070E400E46A87 /* Notes.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Notes.pm; sourceTree = ""; }; 02B041D50E9070E400E46A87 /* Print.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Print.pm; sourceTree = ""; }; 02B041D60E9070E400E46A87 /* search.pl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = search.pl; sourceTree = ""; }; 02B041D70E9070E400E46A87 /* Timeline.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Timeline.pm; sourceTree = ""; }; 02B041D80E9070E400E46A87 /* Vs.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Vs.pm; sourceTree = ""; }; 02B041DA0E90710300E46A87 /* .perltidyrc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = .perltidyrc; sourceTree = ""; }; 02B041DB0E90710300E46A87 /* autopsy.base */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = autopsy.base; sourceTree = ""; }; 02B041DD0E90710400E46A87 /* make-live-cd.base */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "make-live-cd.base"; sourceTree = ""; }; 02EF3BBF0860F668001CA8B0 /* global.css */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = global.css; path = ../global.css; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXGroup section */ 02670C57079A2F7E00BA95F3 = { isa = PBXGroup; children = ( 02B041D90E90710300E46A87 /* base */, 02B041C30E9070E400E46A87 /* lib */, 02EF3BBF0860F668001CA8B0 /* global.css */, ); sourceTree = ""; }; 02B041C30E9070E400E46A87 /* lib */ = { isa = PBXGroup; children = ( 02B041C40E9070E400E46A87 /* .perltidyrc */, 02B041C50E9070E400E46A87 /* Appsort.pm */, 02B041C60E9070E400E46A87 /* Appview.pm */, 02B041C70E9070E400E46A87 /* Args.pm */, 02B041C80E9070E400E46A87 /* Caseman.pm */, 02B041C90E9070E400E46A87 /* Data.pm */, 02B041CA0E9070E400E46A87 /* define.pl */, 02B041CB0E9070E400E46A87 /* Exec.pm */, 02B041CC0E9070E400E46A87 /* File.pm */, 02B041CD0E9070E400E46A87 /* Filesystem.pm */, 02B041CE0E9070E400E46A87 /* Frame.pm */, 02B041CF0E9070E400E46A87 /* Fs.pm */, 02B041D00E9070E400E46A87 /* Hash.pm */, 02B041D10E9070E400E46A87 /* Kwsrch.pm */, 02B041D20E9070E400E46A87 /* Main.pm */, 02B041D30E9070E400E46A87 /* Meta.pm */, 02B041D40E9070E400E46A87 /* Notes.pm */, 02B041D50E9070E400E46A87 /* Print.pm */, 02B041D60E9070E400E46A87 /* search.pl */, 02B041D70E9070E400E46A87 /* Timeline.pm */, 02B041D80E9070E400E46A87 /* Vs.pm */, ); name = lib; path = ../lib; sourceTree = SOURCE_ROOT; }; 02B041D90E90710300E46A87 /* base */ = { isa = PBXGroup; children = ( 02B041DA0E90710300E46A87 /* .perltidyrc */, 02B041DB0E90710300E46A87 /* autopsy.base */, 02B041DD0E90710400E46A87 /* make-live-cd.base */, ); name = base; path = ../base; sourceTree = SOURCE_ROOT; }; /* End PBXGroup section */ /* Begin PBXProject section */ 02670C5B079A2F7E00BA95F3 /* Project object */ = { isa = PBXProject; buildConfigurationList = 027355510E7C4D6D002BD6DB /* Build configuration list for PBXProject "autopsy" */; compatibilityVersion = "Xcode 2.4"; hasScannedForEncodings = 1; mainGroup = 02670C57079A2F7E00BA95F3; projectDirPath = ""; projectRoot = ""; targets = ( ); }; /* End PBXProject section */ /* Begin XCBuildConfiguration section */ 027355520E7C4D6D002BD6DB /* Development */ = { isa = XCBuildConfiguration; buildSettings = { }; name = Development; }; 027355530E7C4D6D002BD6DB /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { }; name = Deployment; }; 027355540E7C4D6D002BD6DB /* Default */ = { isa = XCBuildConfiguration; buildSettings = { }; name = Default; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 027355510E7C4D6D002BD6DB /* Build configuration list for PBXProject "autopsy" */ = { isa = XCConfigurationList; buildConfigurations = ( 027355520E7C4D6D002BD6DB /* Development */, 027355530E7C4D6D002BD6DB /* Deployment */, 027355540E7C4D6D002BD6DB /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; /* End XCConfigurationList section */ }; rootObject = 02670C5B079A2F7E00BA95F3 /* Project object */; }