mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-16 09:47:42 +00:00

Added additional RegRipper modules to support STIX data. Stopped RecentActivity IE parser from generating empty user accounts.
350 lines
9.5 KiB
Perl
Executable File
350 lines
9.5 KiB
Perl
Executable File
#! c:\perl\bin\perl.exe
|
|
#-------------------------------------------------------------------------
|
|
# Rip - RegRipper, CLI version
|
|
# Use this utility to run a plugins file or a single plugin against a Reg
|
|
# hive file.
|
|
#
|
|
# Output goes to STDOUT
|
|
# Usage: see "_syntax()" function
|
|
#
|
|
# Change History
|
|
# 20130801 - added File::Spec support, for cross-platform compat.
|
|
# 20130716 - added 'push(@INC,$str);' line based on suggestion from
|
|
# Hal Pomeranz to support Linux compatibility
|
|
# 20130425 - added alertMsg() functionality, updated to v2.8
|
|
# 20120506 - updated to v2.5 release
|
|
# 20110516 - added -s & -u options for TLN support
|
|
# 20090102 - updated code for relative path to plugins dir
|
|
# 20080419 - added '-g' switch (experimental)
|
|
# 20080412 - added '-c' switch
|
|
#
|
|
# copyright 2013 Quantum Analytics Research, LLC
|
|
# Author: H. Carvey, keydet89@yahoo.com
|
|
#
|
|
# This software is released via the GPL v3.0 license:
|
|
# http://www.gnu.org/licenses/gpl.html
|
|
#-------------------------------------------------------------------------
|
|
use strict;
|
|
use Parse::Win32Registry qw(:REG_);
|
|
use Getopt::Long;
|
|
use File::Spec;
|
|
|
|
# Included to permit compiling via Perl2Exe
|
|
#perl2exe_include "Parse/Win32Registry.pm";
|
|
#perl2exe_include "Parse/Win32Registry/Key.pm";
|
|
#perl2exe_include "Parse/Win32Registry/Entry.pm";
|
|
#perl2exe_include "Parse/Win32Registry/Value.pm";
|
|
#perl2exe_include "Parse/Win32Registry/File.pm";
|
|
#perl2exe_include "Parse/Win32Registry/Win95/File.pm";
|
|
#perl2exe_include "Parse/Win32Registry/Win95/Key.pm";
|
|
#perl2exe_include "Encode.pm";
|
|
#perl2exe_include "Encode/Byte.pm";
|
|
#perl2exe_include "Encode/Unicode.pm";
|
|
#perl2exe_include "utf8.pm";
|
|
#perl2exe_include "unicore/Heavy.pl";
|
|
#perl2exe_include "unicore/To/Upper.pl";
|
|
|
|
my %config;
|
|
Getopt::Long::Configure("prefix_pattern=(-|\/)");
|
|
GetOptions(\%config,qw(reg|r=s file|f=s csv|c guess|g user|u=s sys|s=s plugin|p=s list|l help|?|h));
|
|
|
|
# Code updated 20090102
|
|
my @path;
|
|
my $str = $0;
|
|
($^O eq "MSWin32") ? (@path = split(/\\/,$0))
|
|
: (@path = split(/\//,$0));
|
|
$str =~ s/($path[scalar(@path) - 1])//;
|
|
|
|
# Suggested addition by Hal Pomeranz for compatibility with
|
|
# Linux
|
|
#push(@INC,$str);
|
|
|
|
#my $plugindir = $str."plugins/";
|
|
my $plugindir = File::Spec->catfile("plugins");
|
|
#print "Plugins Dir = ".$plugindir."\n";
|
|
# End code update
|
|
my $VERSION = "2\.8_20130801";
|
|
my @alerts = ();
|
|
|
|
if ($config{help} || !%config) {
|
|
_syntax();
|
|
exit;
|
|
}
|
|
|
|
#-------------------------------------------------------------
|
|
#
|
|
#-------------------------------------------------------------
|
|
if ($config{list}) {
|
|
my @plugins;
|
|
opendir(DIR,$plugindir) || die "Could not open $plugindir: $!\n";
|
|
@plugins = readdir(DIR);
|
|
closedir(DIR);
|
|
|
|
my $count = 1;
|
|
print "Plugin,Version,Hive,Description\n" if ($config{csv});
|
|
foreach my $p (@plugins) {
|
|
next unless ($p =~ m/\.pl$/);
|
|
my $pkg = (split(/\./,$p,2))[0];
|
|
# $p = $plugindir.$p;
|
|
$p = File::Spec->catfile($plugindir,$p);
|
|
eval {
|
|
require $p;
|
|
my $hive = $pkg->getHive();
|
|
my $version = $pkg->getVersion();
|
|
my $descr = $pkg->getShortDescr();
|
|
if ($config{csv}) {
|
|
print $pkg.",".$version.",".$hive.",".$descr."\n";
|
|
}
|
|
else {
|
|
print $count.". ".$pkg." v.".$version." [".$hive."]\n";
|
|
# printf "%-20s %-10s %-10s\n",$pkg,$version,$hive;
|
|
print " - ".$descr."\n\n";
|
|
$count++;
|
|
}
|
|
};
|
|
print "Error: $@\n" if ($@);
|
|
}
|
|
exit;
|
|
}
|
|
|
|
#-------------------------------------------------------------
|
|
#
|
|
#-------------------------------------------------------------
|
|
if ($config{file}) {
|
|
# First, check that a hive file was identified, and that the path is
|
|
# correct
|
|
my $hive = $config{reg};
|
|
die "You must enter a hive file path/name.\n" if ($hive eq "");
|
|
# die $hive." not found.\n" unless (-e $hive);
|
|
|
|
my %plugins = parsePluginsFile($config{file});
|
|
if (%plugins) {
|
|
logMsg("Parsed Plugins file.");
|
|
}
|
|
else {
|
|
logMsg("Plugins file not parsed.");
|
|
exit;
|
|
}
|
|
foreach my $i (sort {$a <=> $b} keys %plugins) {
|
|
eval {
|
|
# require "plugins/".$plugins{$i}."\.pl";
|
|
my $plugin_file = File::Spec->catfile($plugindir,$plugins{$i}.".pl");
|
|
require $plugin_file;
|
|
$plugins{$i}->pluginmain($hive);
|
|
};
|
|
if ($@) {
|
|
logMsg("Error in ".$plugins{$i}.": ".$@);
|
|
}
|
|
logMsg($plugins{$i}." complete.");
|
|
rptMsg("-" x 40);
|
|
}
|
|
printAlerts();
|
|
}
|
|
|
|
#-------------------------------------------------------------
|
|
#
|
|
#-------------------------------------------------------------
|
|
if ($config{reg} && $config{guess}) {
|
|
# Attempt to guess which kind of hive we have
|
|
my $hive = $config{reg};
|
|
die "You must enter a hive file path/name.\n" if ($hive eq "");
|
|
# die $hive." not found.\n" unless (-e $hive);
|
|
|
|
my $reg;
|
|
my $root_key;
|
|
my %guess = guessHive($hive);
|
|
|
|
foreach my $g (keys %guess) {
|
|
::rptMsg(sprintf "%-8s = %-2s",$g,$guess{$g});
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------------
|
|
#
|
|
#-------------------------------------------------------------
|
|
if ($config{plugin}) {
|
|
# First, check that a hive file was identified, and that the path is
|
|
# correct
|
|
my $hive = $config{reg};
|
|
die "You must enter a hive file path/name.\n" if ($hive eq "");
|
|
# die $hive." not found.\n" unless (-e $hive);
|
|
|
|
# check to see if the plugin exists
|
|
my $plugin = $config{plugin};
|
|
# my $pluginfile = $plugindir.$config{plugin}."\.pl";
|
|
my $pluginfile = File::Spec->catfile($plugindir,$config{plugin}."\.pl");
|
|
die $pluginfile." not found.\n" unless (-e $pluginfile);
|
|
|
|
eval {
|
|
require $pluginfile;
|
|
$plugin->pluginmain($hive);
|
|
};
|
|
if ($@) {
|
|
logMsg("Error in ".$pluginfile.": ".$@);
|
|
}
|
|
printAlerts();
|
|
}
|
|
|
|
sub _syntax {
|
|
print<< "EOT";
|
|
Rip v.$VERSION - CLI RegRipper tool
|
|
Rip [-r Reg hive file] [-f plugin file] [-p plugin module] [-l] [-h]
|
|
Parse Windows Registry files, using either a single module, or a plugins file.
|
|
|
|
-r Reg hive file...Registry hive file to parse
|
|
-g ................Guess the hive file (experimental)
|
|
-f [profile].......use the plugin file (default: plugins\\plugins)
|
|
-p plugin module...use only this module
|
|
-l ................list all plugins
|
|
-c ................Output list in CSV format (use with -l)
|
|
-s system name.....Server name (TLN support)
|
|
-u username........User name (TLN support)
|
|
-h.................Help (print this information)
|
|
|
|
Ex: C:\\>rip -r c:\\case\\system -f system
|
|
C:\\>rip -r c:\\case\\ntuser.dat -p userassist
|
|
C:\\>rip -l -c
|
|
|
|
All output goes to STDOUT; use redirection (ie, > or >>) to output to a file\.
|
|
|
|
copyright 2013 Quantum Analytics Research, LLC
|
|
EOT
|
|
}
|
|
|
|
#-------------------------------------------------------------
|
|
#
|
|
#-------------------------------------------------------------
|
|
sub logMsg {
|
|
print STDERR $_[0]."\n";
|
|
}
|
|
|
|
#-------------------------------------------------------------
|
|
#
|
|
#-------------------------------------------------------------
|
|
sub rptMsg {
|
|
binmode STDOUT,":utf8";
|
|
if ($config{sys} || $config{user}) {
|
|
my @vals = split(/\|/,$_[0],5);
|
|
my $str = $vals[0]."|".$vals[1]."|".$config{sys}."|".$config{user}."|".$vals[4];
|
|
print $str."\n";
|
|
}
|
|
else {
|
|
print $_[0]."\n";
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------------
|
|
#
|
|
#-------------------------------------------------------------
|
|
sub alertMsg {
|
|
push(@alerts,$_[0]);
|
|
}
|
|
|
|
sub printAlerts {
|
|
if (scalar(@alerts) > 0) {
|
|
# print "\n";
|
|
# print "Alerts\n";
|
|
# print "-" x 40,"\n";
|
|
foreach (@alerts) {
|
|
print $_."\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------------
|
|
# parsePluginsFile()
|
|
# Parse the plugins file and get a list of plugins
|
|
#-------------------------------------------------------------
|
|
sub parsePluginsFile {
|
|
my $file = $_[0];
|
|
my %plugins;
|
|
# Parse a file containing a list of plugins
|
|
# Future versions of this tool may allow for the analyst to
|
|
# choose different plugins files
|
|
# my $pluginfile = $plugindir.$file;
|
|
my $pluginfile = File::Spec->catfile($plugindir,$file);
|
|
if (-e $pluginfile) {
|
|
open(FH,"<",$pluginfile);
|
|
my $count = 1;
|
|
while(<FH>) {
|
|
chomp;
|
|
next if ($_ =~ m/^#/ || $_ =~ m/^\s+$/);
|
|
# next unless ($_ =~ m/\.pl$/);
|
|
next if ($_ eq "");
|
|
$_ =~ s/^\s+//;
|
|
$_ =~ s/\s+$//;
|
|
$plugins{$count++} = $_;
|
|
}
|
|
close(FH);
|
|
return %plugins;
|
|
}
|
|
else {
|
|
return undef;
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------------
|
|
# guessHive()
|
|
#
|
|
#-------------------------------------------------------------
|
|
sub guessHive {
|
|
my $hive = shift;
|
|
my $reg;
|
|
my $root_key;
|
|
my %guess;
|
|
eval {
|
|
$reg = Parse::Win32Registry->new($hive);
|
|
$root_key = $reg->get_root_key;
|
|
};
|
|
$guess{unknown} = 1 if ($@);
|
|
|
|
# Check for SAM
|
|
eval {
|
|
$guess{sam} = 1 if (my $key = $root_key->get_subkey("SAM\\Domains\\Account\\Users"));
|
|
};
|
|
# Check for Software
|
|
eval {
|
|
$guess{software} = 1 if ($root_key->get_subkey("Microsoft\\Windows\\CurrentVersion") &&
|
|
$root_key->get_subkey("Microsoft\\Windows NT\\CurrentVersion"));
|
|
};
|
|
|
|
# Check for System
|
|
eval {
|
|
$guess{system} = 1 if ($root_key->get_subkey("MountedDevices") &&
|
|
$root_key->get_subkey("Select"));
|
|
};
|
|
|
|
# Check for Security
|
|
eval {
|
|
$guess{security} = 1 if ($root_key->get_subkey("Policy\\Accounts") &&
|
|
$root_key->get_subkey("Policy\\PolAdtEv"));
|
|
};
|
|
# Check for NTUSER.DAT
|
|
eval {
|
|
$guess{ntuser} = 1 if ($root_key->get_subkey("Software\\Microsoft\\Windows\\CurrentVersion"));
|
|
|
|
};
|
|
|
|
return %guess;
|
|
}
|
|
|
|
#-------------------------------------------------------------
|
|
# getTime()
|
|
# Translate FILETIME object (2 DWORDS) to Unix time, to be passed
|
|
# to gmtime() or localtime()
|
|
#-------------------------------------------------------------
|
|
sub getTime($$) {
|
|
my $lo = shift;
|
|
my $hi = shift;
|
|
my $t;
|
|
|
|
if ($lo == 0 && $hi == 0) {
|
|
$t = 0;
|
|
} else {
|
|
$lo -= 0xd53e8000;
|
|
$hi -= 0x019db1de;
|
|
$t = int($hi*429.4967296 + $lo/1e7);
|
|
};
|
|
$t = 0 if ($t < 0);
|
|
return $t;
|
|
} |