mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
Update Changed plugins
Update Plugins that have changed from Autopsy's last version of Regripper.
This commit is contained in:
parent
ac34265b9e
commit
78042da4c7
1119
thirdparty/rr-full/Base.pm
vendored
Normal file
1119
thirdparty/rr-full/Base.pm
vendored
Normal file
File diff suppressed because it is too large
Load Diff
355
thirdparty/rr-full/File.pm
vendored
Normal file
355
thirdparty/rr-full/File.pm
vendored
Normal file
@ -0,0 +1,355 @@
|
||||
package Parse::Win32Registry::WinNT::File;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base qw(Parse::Win32Registry::File);
|
||||
|
||||
use Carp;
|
||||
use Encode;
|
||||
use File::Basename;
|
||||
use Parse::Win32Registry::Base qw(:all);
|
||||
use Parse::Win32Registry::WinNT::Key;
|
||||
|
||||
use constant REGF_HEADER_LENGTH => 0x200;
|
||||
use constant OFFSET_TO_FIRST_HBIN => 0x1000;
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $filename = shift or croak "No filename specified";
|
||||
|
||||
open my $fh, '<', $filename or croak "Unable to open '$filename': $!";
|
||||
|
||||
# 0x00 dword = 'regf' signature
|
||||
# 0x04 dword = seq1
|
||||
# 0x08 dword = seq2
|
||||
# 0x0c qword = timestamp
|
||||
# 0x14 dword = major version
|
||||
# 0x18 dword = minor version
|
||||
# 0x1c dword = type (0 = registry file, 1 = log file)
|
||||
# 0x20 dword = (1)
|
||||
# 0x24 dword = offset to root key
|
||||
# 0x28 dword = total length of all hbins (excludes header)
|
||||
# 0x2c dword = (1)
|
||||
# 0x30 = embedded filename
|
||||
|
||||
# Extracted offsets are always relative to first hbin
|
||||
|
||||
my $bytes_read = sysread($fh, my $regf_header, REGF_HEADER_LENGTH);
|
||||
if ($bytes_read != REGF_HEADER_LENGTH) {
|
||||
warnf('Could not read registry file header');
|
||||
return;
|
||||
}
|
||||
|
||||
my ($regf_sig,
|
||||
$seq1,
|
||||
$seq2,
|
||||
$timestamp,
|
||||
$major_version,
|
||||
$minor_version,
|
||||
$type,
|
||||
$offset_to_root_key,
|
||||
$total_hbin_length,
|
||||
$embedded_filename,
|
||||
$reorg_timestamp,
|
||||
) = unpack('a4VVa8VVVx4VVx4a64x56a8', $regf_header);
|
||||
|
||||
# Updated 20200219
|
||||
#----------------------------------------------------------------------------
|
||||
$bytes_read = sysread($fh, my $re_org, 8, 168);
|
||||
if ($bytes_read != 8) {
|
||||
warnf('Could not read re_org timestamp');
|
||||
return;
|
||||
}
|
||||
#----------------------------------------------------------------------------
|
||||
$offset_to_root_key += OFFSET_TO_FIRST_HBIN;
|
||||
|
||||
if ($regf_sig ne 'regf') {
|
||||
warnf('Invalid registry file signature');
|
||||
return;
|
||||
}
|
||||
|
||||
$embedded_filename = unpack('Z*', decode('UCS-2LE', $embedded_filename));
|
||||
|
||||
# The header checksum is the xor of the first 127 dwords.
|
||||
# The checksum is stored in the 128th dword, at offset 0x1fc (508).
|
||||
my $checksum = 0;
|
||||
foreach my $x (unpack('V127', $regf_header)) {
|
||||
$checksum ^= $x;
|
||||
}
|
||||
my $embedded_checksum = unpack('x508V', $regf_header);
|
||||
if ($checksum != $embedded_checksum) {
|
||||
warnf('Invalid checksum for registry file header');
|
||||
}
|
||||
|
||||
my $self = {};
|
||||
$self->{_filehandle} = $fh;
|
||||
$self->{_filename} = $filename;
|
||||
$self->{_length} = (stat $fh)[7];
|
||||
$self->{_offset_to_root_key} = $offset_to_root_key;
|
||||
$self->{_timestamp} = unpack_windows_time($timestamp);
|
||||
#----------------------------------------------------------------------------
|
||||
$self->{_reorg_timestamp} = unpack_windows_time($reorg_timestamp);
|
||||
#----------------------------------------------------------------------------
|
||||
$self->{_embedded_filename} = $embedded_filename;
|
||||
$self->{_seq1} = $seq1;
|
||||
$self->{_seq2} = $seq2;
|
||||
$self->{_version} = "$major_version.$minor_version";
|
||||
$self->{_type} = $type;
|
||||
$self->{_total_hbin_length} = $total_hbin_length;
|
||||
$self->{_embedded_checksum} = $embedded_checksum;
|
||||
$self->{_security_cache} = {}; # comment out to disable cache
|
||||
bless $self, $class;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub get_root_key {
|
||||
my $self = shift;
|
||||
|
||||
my $offset_to_root_key = $self->{_offset_to_root_key};
|
||||
|
||||
my $root_key = Parse::Win32Registry::WinNT::Key->new($self,
|
||||
$offset_to_root_key);
|
||||
return $root_key;
|
||||
}
|
||||
|
||||
sub get_virtual_root_key {
|
||||
my $self = shift;
|
||||
my $fake_root = shift;
|
||||
|
||||
my $root_key = $self->get_root_key;
|
||||
return if !defined $root_key;
|
||||
|
||||
if (!defined $fake_root) {
|
||||
# guess virtual root from filename
|
||||
my $filename = basename $self->{_filename};
|
||||
|
||||
if ($filename =~ /NTUSER/i) {
|
||||
$fake_root = 'HKEY_CURRENT_USER';
|
||||
}
|
||||
elsif ($filename =~ /USRCLASS/i) {
|
||||
$fake_root = 'HKEY_CLASSES_ROOT';
|
||||
}
|
||||
elsif ($filename =~ /SOFTWARE/i) {
|
||||
$fake_root = 'HKEY_LOCAL_MACHINE\SOFTWARE';
|
||||
}
|
||||
elsif ($filename =~ /SYSTEM/i) {
|
||||
$fake_root = 'HKEY_LOCAL_MACHINE\SYSTEM';
|
||||
}
|
||||
elsif ($filename =~ /SAM/i) {
|
||||
$fake_root = 'HKEY_LOCAL_MACHINE\SAM';
|
||||
}
|
||||
elsif ($filename =~ /SECURITY/i) {
|
||||
$fake_root = 'HKEY_LOCAL_MACHINE\SECURITY';
|
||||
}
|
||||
else {
|
||||
$fake_root = 'HKEY_UNKNOWN';
|
||||
}
|
||||
}
|
||||
|
||||
$root_key->{_name} = $fake_root;
|
||||
$root_key->{_key_path} = $fake_root;
|
||||
|
||||
return $root_key;
|
||||
}
|
||||
|
||||
sub get_timestamp {
|
||||
my $self = shift;
|
||||
|
||||
return $self->{_timestamp};
|
||||
}
|
||||
|
||||
sub get_timestamp_as_string {
|
||||
my $self = shift;
|
||||
|
||||
return iso8601($self->{_timestamp});
|
||||
}
|
||||
|
||||
# Added 20200219
|
||||
#---------------------------------------------------------
|
||||
sub get_version {
|
||||
my $self = shift;
|
||||
return $self->{_version};
|
||||
}
|
||||
|
||||
sub get_reorg_timestamp {
|
||||
my $self = shift;
|
||||
return $self->{_reorg_timestamp};
|
||||
}
|
||||
|
||||
sub get_seq1 {
|
||||
my $self = shift;
|
||||
return $self->{_seq1};
|
||||
}
|
||||
|
||||
sub get_seq2 {
|
||||
my $self = shift;
|
||||
return $self->{_seq2};
|
||||
}
|
||||
|
||||
sub is_dirty {
|
||||
my $self = shift;
|
||||
if ($self->{_seq1} == $self->{_seq2}) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
sub get_type {
|
||||
my $self = shift;
|
||||
if ($self->{_type} == 0) {
|
||||
return "Registry file";
|
||||
}
|
||||
elsif ($self->{_type} == 1) {
|
||||
return "Log file";
|
||||
}
|
||||
else {
|
||||
return "Unknown (".$self->{_type}.")";
|
||||
}
|
||||
}
|
||||
#---------------------------------------------------------
|
||||
|
||||
sub get_embedded_filename {
|
||||
my $self = shift;
|
||||
|
||||
return $self->{_embedded_filename};
|
||||
}
|
||||
|
||||
sub get_block_iterator {
|
||||
my $self = shift;
|
||||
|
||||
my $offset_to_next_hbin = OFFSET_TO_FIRST_HBIN;
|
||||
my $end_of_file = $self->{_length};
|
||||
|
||||
return Parse::Win32Registry::Iterator->new(sub {
|
||||
if ($offset_to_next_hbin > $end_of_file) {
|
||||
return; # no more hbins
|
||||
}
|
||||
if (my $hbin = Parse::Win32Registry::WinNT::Hbin->new($self,
|
||||
$offset_to_next_hbin))
|
||||
{
|
||||
return unless $hbin->get_length > 0;
|
||||
$offset_to_next_hbin += $hbin->get_length;
|
||||
return $hbin;
|
||||
}
|
||||
else {
|
||||
return; # no more hbins
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
*get_hbin_iterator = \&get_block_iterator;
|
||||
|
||||
sub _dump_security_cache {
|
||||
my $self = shift;
|
||||
|
||||
if (defined(my $cache = $self->{_security_cache})) {
|
||||
foreach my $offset (sort { $a <=> $b } keys %$cache) {
|
||||
my $security = $cache->{$offset};
|
||||
printf '0x%x %s\n', $offset, $security->as_string;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
package Parse::Win32Registry::WinNT::Hbin;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base qw(Parse::Win32Registry::Entry);
|
||||
|
||||
use Carp;
|
||||
use Parse::Win32Registry::Base qw(:all);
|
||||
use Parse::Win32Registry::WinNT::Entry;
|
||||
|
||||
use constant HBIN_HEADER_LENGTH => 0x20;
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $regfile = shift;
|
||||
my $offset = shift;
|
||||
|
||||
croak 'Missing registry file' if !defined $regfile;
|
||||
croak 'Missing offset' if !defined $offset;
|
||||
|
||||
my $fh = $regfile->get_filehandle;
|
||||
|
||||
# 0x00 dword = 'hbin' signature
|
||||
# 0x04 dword = offset from first hbin to this hbin
|
||||
# 0x08 dword = length of this hbin / relative offset to next hbin
|
||||
# 0x14 qword = timestamp (first hbin only)
|
||||
|
||||
# Extracted offsets are always relative to first hbin
|
||||
|
||||
sysseek($fh, $offset, 0);
|
||||
my $bytes_read = sysread($fh, my $hbin_header, HBIN_HEADER_LENGTH);
|
||||
if ($bytes_read != HBIN_HEADER_LENGTH) {
|
||||
return;
|
||||
}
|
||||
|
||||
my ($sig,
|
||||
$offset_to_hbin,
|
||||
$length,
|
||||
$timestamp) = unpack('a4VVx8a8x4', $hbin_header);
|
||||
|
||||
if ($sig ne 'hbin') {
|
||||
return;
|
||||
}
|
||||
|
||||
my $self = {};
|
||||
$self->{_regfile} = $regfile;
|
||||
$self->{_offset} = $offset;
|
||||
$self->{_length} = $length;
|
||||
$self->{_header_length} = HBIN_HEADER_LENGTH;
|
||||
$self->{_allocated} = 1;
|
||||
$self->{_tag} = $sig;
|
||||
$self->{_timestamp} = unpack_windows_time($timestamp);
|
||||
bless $self, $class;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub get_timestamp {
|
||||
my $self = shift;
|
||||
|
||||
return $self->{_timestamp};
|
||||
}
|
||||
|
||||
sub get_timestamp_as_string {
|
||||
my $self = shift;
|
||||
|
||||
return iso8601($self->{_timestamp});
|
||||
}
|
||||
|
||||
sub get_entry_iterator {
|
||||
my $self = shift;
|
||||
|
||||
my $regfile = $self->{_regfile};
|
||||
my $offset = $self->{_offset};
|
||||
my $length = $self->{_length};
|
||||
|
||||
my $offset_to_next_entry = $offset + HBIN_HEADER_LENGTH;
|
||||
my $end_of_hbin = $offset + $length;
|
||||
|
||||
return Parse::Win32Registry::Iterator->new(sub {
|
||||
if ($offset_to_next_entry >= $end_of_hbin) {
|
||||
return; # no more entries
|
||||
}
|
||||
if (my $entry = Parse::Win32Registry::WinNT::Entry->new($regfile,
|
||||
$offset_to_next_entry))
|
||||
{
|
||||
return unless $entry->get_length > 0;
|
||||
$offset_to_next_entry += $entry->get_length;
|
||||
return $entry;
|
||||
}
|
||||
else {
|
||||
return; # no more entries
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
1;
|
464
thirdparty/rr-full/Key.pm
vendored
Normal file
464
thirdparty/rr-full/Key.pm
vendored
Normal file
@ -0,0 +1,464 @@
|
||||
package Parse::Win32Registry::WinNT::Key;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base qw(Parse::Win32Registry::Key);
|
||||
|
||||
use Carp;
|
||||
use Encode;
|
||||
use Parse::Win32Registry::Base qw(:all);
|
||||
use Parse::Win32Registry::WinNT::Value;
|
||||
use Parse::Win32Registry::WinNT::Security;
|
||||
|
||||
use constant NK_HEADER_LENGTH => 0x50;
|
||||
use constant OFFSET_TO_FIRST_HBIN => 0x1000;
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $regfile = shift;
|
||||
my $offset = shift; # offset to nk record relative to start of file
|
||||
my $parent_key_path = shift; # parent key path (optional)
|
||||
|
||||
croak 'Missing registry file' if !defined $regfile;
|
||||
croak 'Missing offset' if !defined $offset;
|
||||
|
||||
my $fh = $regfile->get_filehandle;
|
||||
|
||||
# 0x00 dword = key length (negative = allocated)
|
||||
# 0x04 word = 'nk' signature
|
||||
# 0x06 word = flags
|
||||
# 0x08 qword = timestamp
|
||||
# 0x10
|
||||
# 0x14 dword = offset to parent
|
||||
# 0x18 dword = number of subkeys
|
||||
# 0x1c
|
||||
# 0x20 dword = offset to subkey list (lf, lh, ri, li)
|
||||
# 0x24
|
||||
# 0x28 dword = number of values
|
||||
# 0x2c dword = offset to value list
|
||||
# 0x30 dword = offset to security
|
||||
# 0x34 dword = offset to class name
|
||||
# 0x38 dword = max subkey name length
|
||||
# 0x3c dword = max class name length
|
||||
# 0x40 dword = max value name length
|
||||
# 0x44 dword = max value data length
|
||||
# 0x48
|
||||
# 0x4c word = key name length
|
||||
# 0x4e word = class name length
|
||||
# 0x50 = key name [for key name length bytes]
|
||||
|
||||
# Extracted offsets are always relative to first hbin
|
||||
|
||||
sysseek($fh, $offset, 0);
|
||||
my $bytes_read = sysread($fh, my $nk_header, NK_HEADER_LENGTH);
|
||||
if ($bytes_read != NK_HEADER_LENGTH) {
|
||||
warnf('Could not read key at 0x%x', $offset);
|
||||
return;
|
||||
}
|
||||
|
||||
my ($length,
|
||||
$sig,
|
||||
$flags,
|
||||
$timestamp,
|
||||
# added 20190127
|
||||
$access_bits,
|
||||
$offset_to_parent,
|
||||
$num_subkeys,
|
||||
$offset_to_subkey_list,
|
||||
$num_values,
|
||||
$offset_to_value_list,
|
||||
$offset_to_security,
|
||||
$offset_to_class_name,
|
||||
$largest_subkey_name_length,
|
||||
$name_length,
|
||||
$class_name_length,
|
||||
# added 20190127
|
||||
) = unpack('Va2va8VVVx4Vx4VVVVVx16vv', $nk_header);
|
||||
# ) = unpack('Va2va8x4VVx4Vx4VVVVx20vv', $nk_header);
|
||||
|
||||
$offset_to_parent += OFFSET_TO_FIRST_HBIN
|
||||
if $offset_to_parent != 0xffffffff;
|
||||
$offset_to_subkey_list += OFFSET_TO_FIRST_HBIN
|
||||
if $offset_to_subkey_list != 0xffffffff;
|
||||
$offset_to_value_list += OFFSET_TO_FIRST_HBIN
|
||||
if $offset_to_value_list != 0xffffffff;
|
||||
$offset_to_security += OFFSET_TO_FIRST_HBIN
|
||||
if $offset_to_security != 0xffffffff;
|
||||
$offset_to_class_name += OFFSET_TO_FIRST_HBIN
|
||||
if $offset_to_class_name != 0xffffffff;
|
||||
|
||||
my $allocated = 0;
|
||||
if ($length > 0x7fffffff) {
|
||||
$allocated = 1;
|
||||
$length = (0xffffffff - $length) + 1;
|
||||
}
|
||||
# allocated should be true
|
||||
|
||||
if ($length < NK_HEADER_LENGTH) {
|
||||
warnf('Invalid value entry length at 0x%x', $offset);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($sig ne 'nk') {
|
||||
warnf('Invalid signature for key at 0x%x', $offset);
|
||||
return;
|
||||
}
|
||||
|
||||
$bytes_read = sysread($fh, my $name, $name_length);
|
||||
if ($bytes_read != $name_length) {
|
||||
warnf('Could not read name for key at 0x%x', $offset);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($flags & 0x20) {
|
||||
$name = decode($Parse::Win32Registry::Base::CODEPAGE, $name);
|
||||
}
|
||||
else {
|
||||
$name = decode('UCS-2LE', $name);
|
||||
}
|
||||
|
||||
my $key_path = (defined $parent_key_path)
|
||||
? "$parent_key_path\\$name"
|
||||
: "$name";
|
||||
|
||||
my $class_name;
|
||||
if ($offset_to_class_name != 0xffffffff) {
|
||||
sysseek($fh, $offset_to_class_name + 4, 0);
|
||||
$bytes_read = sysread($fh, $class_name, $class_name_length);
|
||||
if ($bytes_read != $class_name_length) {
|
||||
warnf('Could not read class name at 0x%x', $offset_to_class_name);
|
||||
$class_name = undef;
|
||||
}
|
||||
else {
|
||||
$class_name = decode('UCS-2LE', $class_name);
|
||||
}
|
||||
}
|
||||
|
||||
my $self = {};
|
||||
$self->{_regfile} = $regfile;
|
||||
$self->{_offset} = $offset;
|
||||
$self->{_length} = $length;
|
||||
$self->{_allocated} = $allocated;
|
||||
$self->{_tag} = $sig;
|
||||
$self->{_name} = $name;
|
||||
$self->{_name_length} = $name_length;
|
||||
$self->{_key_path} = $key_path;
|
||||
$self->{_flags} = $flags;
|
||||
$self->{_offset_to_parent} = $offset_to_parent;
|
||||
$self->{_num_subkeys} = $num_subkeys;
|
||||
$self->{_offset_to_subkey_list} = $offset_to_subkey_list;
|
||||
$self->{_num_values} = $num_values;
|
||||
$self->{_offset_to_value_list} = $offset_to_value_list;
|
||||
$self->{_timestamp} = unpack_windows_time($timestamp);
|
||||
# added 20190127
|
||||
$self->{_access_bits} = $access_bits;
|
||||
$self->{_largest_subkey_name_length} = $largest_subkey_name_length;
|
||||
$self->{_offset_to_security} = $offset_to_security;
|
||||
$self->{_offset_to_class_name} = $offset_to_class_name;
|
||||
$self->{_class_name_length} = $class_name_length;
|
||||
$self->{_class_name} = $class_name;
|
||||
bless $self, $class;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub get_timestamp {
|
||||
my $self = shift;
|
||||
|
||||
return $self->{_timestamp};
|
||||
}
|
||||
|
||||
sub get_timestamp_as_string {
|
||||
my $self = shift;
|
||||
|
||||
return iso8601($self->get_timestamp);
|
||||
}
|
||||
|
||||
# added 20190127
|
||||
sub get_access_bits {
|
||||
my $self = shift;
|
||||
return $self->{_access_bits};
|
||||
}
|
||||
|
||||
sub get_largest_subkey_name_length {
|
||||
my $self = shift;
|
||||
return $self->{_largest_subkey_name_length};
|
||||
}
|
||||
|
||||
|
||||
sub get_class_name {
|
||||
my $self = shift;
|
||||
|
||||
return $self->{_class_name};
|
||||
}
|
||||
|
||||
sub is_root {
|
||||
my $self = shift;
|
||||
|
||||
my $flags = $self->{_flags};
|
||||
return $flags & 4 || $flags & 8;
|
||||
}
|
||||
|
||||
sub get_parent {
|
||||
my $self = shift;
|
||||
|
||||
my $regfile = $self->{_regfile};
|
||||
my $offset_to_parent = $self->{_offset_to_parent};
|
||||
my $key_path = $self->{_key_path};
|
||||
|
||||
return if $self->is_root;
|
||||
|
||||
my $grandparent_key_path;
|
||||
my @keys = split /\\/, $key_path, -1;
|
||||
if (@keys > 2) {
|
||||
$grandparent_key_path = join('\\', @keys[0..$#keys-2]);
|
||||
}
|
||||
|
||||
return Parse::Win32Registry::WinNT::Key->new($regfile,
|
||||
$offset_to_parent,
|
||||
$grandparent_key_path);
|
||||
}
|
||||
|
||||
sub get_security {
|
||||
my $self = shift;
|
||||
|
||||
my $regfile = $self->{_regfile};
|
||||
my $offset_to_security = $self->{_offset_to_security};
|
||||
my $key_path = $self->{_key_path};
|
||||
|
||||
if ($offset_to_security == 0xffffffff) {
|
||||
return;
|
||||
}
|
||||
|
||||
return Parse::Win32Registry::WinNT::Security->new($regfile,
|
||||
$offset_to_security,
|
||||
$key_path);
|
||||
}
|
||||
|
||||
sub as_string {
|
||||
my $self = shift;
|
||||
|
||||
my $string = $self->get_path . ' [' . $self->get_timestamp_as_string . ']';
|
||||
return $string;
|
||||
}
|
||||
|
||||
sub parse_info {
|
||||
my $self = shift;
|
||||
|
||||
my $info = sprintf '0x%x nk len=0x%x alloc=%d "%s" par=0x%x keys=%d,0x%x vals=%d,0x%x sec=0x%x class=0x%x',
|
||||
$self->{_offset},
|
||||
$self->{_length},
|
||||
$self->{_allocated},
|
||||
$self->{_name},
|
||||
$self->{_offset_to_parent},
|
||||
$self->{_num_subkeys}, $self->{_offset_to_subkey_list},
|
||||
$self->{_num_values}, $self->{_offset_to_value_list},
|
||||
$self->{_offset_to_security},
|
||||
$self->{_offset_to_class_name};
|
||||
if (defined $self->{_class_name}) {
|
||||
$info .= sprintf ',len=0x%x', $self->{_class_name_length};
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
sub _get_offsets_to_subkeys {
|
||||
my $self = shift;
|
||||
|
||||
# Offset is passed as a parameter for recursive lists such as 'ri'
|
||||
my $offset_to_subkey_list = shift || $self->{_offset_to_subkey_list};
|
||||
|
||||
my $regfile = $self->{_regfile};
|
||||
my $fh = $regfile->get_filehandle;
|
||||
|
||||
return if $offset_to_subkey_list == 0xffffffff
|
||||
|| $self->{_num_subkeys} == 0;
|
||||
|
||||
sysseek($fh, $offset_to_subkey_list, 0);
|
||||
my $bytes_read = sysread($fh, my $subkey_list_header, 8);
|
||||
if ($bytes_read != 8) {
|
||||
warnf('Could not read subkey list header at 0x%x',
|
||||
$offset_to_subkey_list);
|
||||
return;
|
||||
}
|
||||
|
||||
# 0x00 dword = subkey list length (negative = allocated)
|
||||
# 0x04 word = 'lf' signature
|
||||
# 0x06 word = number of entries
|
||||
# 0x08 dword = offset to 1st subkey
|
||||
# 0x0c dword = first four characters of the key name
|
||||
# 0x10 dword = offset to 2nd subkey
|
||||
# 0x14 dword = first four characters of the key name
|
||||
# ...
|
||||
|
||||
# 0x00 dword = subkey list length (negative = allocated)
|
||||
# 0x04 word = 'lh' signature
|
||||
# 0x06 word = number of entries
|
||||
# 0x08 dword = offset to 1st subkey
|
||||
# 0x0c dword = hash of the key name
|
||||
# 0x10 dword = offset to 2nd subkey
|
||||
# 0x14 dword = hash of the key name
|
||||
# ...
|
||||
|
||||
# 0x00 dword = subkey list length (negative = allocated)
|
||||
# 0x04 word = 'ri' signature
|
||||
# 0x06 word = number of entries in ri list
|
||||
# 0x08 dword = offset to 1st lf/lh/li list
|
||||
# 0x0c dword = offset to 2nd lf/lh/li list
|
||||
# 0x10 dword = offset to 3rd lf/lh/li list
|
||||
# ...
|
||||
|
||||
# 0x00 dword = subkey list length (negative = allocated)
|
||||
# 0x04 word = 'li' signature
|
||||
# 0x06 word = number of entries in li list
|
||||
# 0x08 dword = offset to 1st subkey
|
||||
# 0x0c dword = offset to 2nd subkey
|
||||
# ...
|
||||
|
||||
# Extracted offsets are always relative to first hbin
|
||||
|
||||
my @offsets_to_subkeys = ();
|
||||
|
||||
my ($length,
|
||||
$sig,
|
||||
$num_entries,
|
||||
) = unpack('Va2v', $subkey_list_header);
|
||||
|
||||
my $subkey_list_length;
|
||||
if ($sig eq 'lf' || $sig eq 'lh') {
|
||||
$subkey_list_length = 2 * 4 * $num_entries;
|
||||
}
|
||||
elsif ($sig eq 'ri' || $sig eq 'li') {
|
||||
$subkey_list_length = 4 * $num_entries;
|
||||
}
|
||||
else {
|
||||
warnf('Invalid signature for subkey list at 0x%x',
|
||||
$offset_to_subkey_list);
|
||||
return;
|
||||
}
|
||||
|
||||
$bytes_read = sysread($fh, my $subkey_list, $subkey_list_length);
|
||||
if ($bytes_read != $subkey_list_length) {
|
||||
warnf('Could not read subkey list at 0x%x',
|
||||
$offset_to_subkey_list);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($sig eq 'lf') {
|
||||
foreach my $offset (unpack("(Vx4)$num_entries", $subkey_list)) {
|
||||
push @offsets_to_subkeys, OFFSET_TO_FIRST_HBIN + $offset;
|
||||
}
|
||||
}
|
||||
elsif ($sig eq 'lh') {
|
||||
foreach my $offset (unpack("(Vx4)$num_entries", $subkey_list)) {
|
||||
push @offsets_to_subkeys, OFFSET_TO_FIRST_HBIN + $offset;
|
||||
}
|
||||
}
|
||||
elsif ($sig eq 'ri') {
|
||||
foreach my $offset (unpack("V$num_entries", $subkey_list)) {
|
||||
my $offsets_ref =
|
||||
$self->_get_offsets_to_subkeys(OFFSET_TO_FIRST_HBIN + $offset);
|
||||
if (defined $offsets_ref && ref $offsets_ref eq 'ARRAY') {
|
||||
push @offsets_to_subkeys, @{ $offsets_ref };
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif ($sig eq 'li') {
|
||||
foreach my $offset (unpack("V$num_entries", $subkey_list)) {
|
||||
push @offsets_to_subkeys, OFFSET_TO_FIRST_HBIN + $offset;
|
||||
}
|
||||
}
|
||||
|
||||
return \@offsets_to_subkeys;
|
||||
}
|
||||
|
||||
sub get_subkey_iterator {
|
||||
my $self = shift;
|
||||
|
||||
my $regfile = $self->{_regfile};
|
||||
my $key_path = $self->{_key_path};
|
||||
|
||||
my @offsets_to_subkeys = ();
|
||||
if ($self->{_num_subkeys} > 0) {
|
||||
my $offsets_to_subkeys_ref = $self->_get_offsets_to_subkeys;
|
||||
if (defined $offsets_to_subkeys_ref) {
|
||||
@offsets_to_subkeys = @{$self->_get_offsets_to_subkeys};
|
||||
}
|
||||
}
|
||||
|
||||
return Parse::Win32Registry::Iterator->new(sub {
|
||||
while (defined(my $offset_to_subkey = shift @offsets_to_subkeys)) {
|
||||
my $subkey = Parse::Win32Registry::WinNT::Key->new($regfile,
|
||||
$offset_to_subkey, $key_path);
|
||||
if (defined $subkey) {
|
||||
return $subkey;
|
||||
}
|
||||
}
|
||||
return; # no more offsets to subkeys
|
||||
});
|
||||
}
|
||||
|
||||
sub _get_offsets_to_values {
|
||||
my $self = shift;
|
||||
|
||||
my $regfile = $self->{_regfile};
|
||||
my $fh = $regfile->get_filehandle;
|
||||
my $offset_to_value_list = $self->{_offset_to_value_list};
|
||||
|
||||
my $num_values = $self->{_num_values};
|
||||
return if $num_values == 0;
|
||||
# Actually, this could probably just fall through
|
||||
# as unpack("x4V0", ...) would return an empty array.
|
||||
|
||||
my @offsets_to_values = ();
|
||||
|
||||
# 0x00 dword = value list length (negative = allocated)
|
||||
# 0x04 dword = 1st offset
|
||||
# 0x08 dword = 2nd offset
|
||||
# ...
|
||||
|
||||
# Extracted offsets are always relative to first hbin
|
||||
|
||||
sysseek($fh, $offset_to_value_list, 0);
|
||||
my $value_list_length = 0x4 + $num_values * 4;
|
||||
my $bytes_read = sysread($fh, my $value_list, $value_list_length);
|
||||
if ($bytes_read != $value_list_length) {
|
||||
warnf("Could not read value list at 0x%x",
|
||||
$offset_to_value_list);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach my $offset (unpack("x4V$num_values", $value_list)) {
|
||||
push @offsets_to_values, OFFSET_TO_FIRST_HBIN + $offset;
|
||||
}
|
||||
|
||||
return \@offsets_to_values;
|
||||
}
|
||||
|
||||
sub get_value_iterator {
|
||||
my $self = shift;
|
||||
|
||||
my $regfile = $self->{_regfile};
|
||||
my $key_path = $self->{_key_path};
|
||||
|
||||
my @offsets_to_values = ();
|
||||
if ($self->{_num_values} > 0) {
|
||||
my $offsets_to_values_ref = $self->_get_offsets_to_values;
|
||||
if (defined $offsets_to_values_ref) {
|
||||
@offsets_to_values = @{$self->_get_offsets_to_values};
|
||||
}
|
||||
}
|
||||
|
||||
return Parse::Win32Registry::Iterator->new(sub {
|
||||
while (defined(my $offset_to_value = shift @offsets_to_values)) {
|
||||
my $value = Parse::Win32Registry::WinNT::Value->new($regfile,
|
||||
$offset_to_value);
|
||||
if (defined $value) {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
return; # no more offsets to values
|
||||
});
|
||||
}
|
||||
|
||||
1;
|
51
thirdparty/rr-full/README.md
vendored
Normal file
51
thirdparty/rr-full/README.md
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
RegRipper2.8
|
||||
============
|
||||
|
||||
RegRipper version 2.8
|
||||
|
||||
This is the GitHub repository for RegRipper version 2.8
|
||||
|
||||
Note: This tool does NOT automatically process hive transaction logs. If you need
|
||||
to incorporate data from hive transaction logs into your analysis, consider merging
|
||||
the data via Maxim Suhanov's yarp + registryFlush.py, or via Eric Zimmerman's rla.exe.
|
||||
|
||||
Updates 20200220
|
||||
- Added warning that tool does not automatically process Registry hive transaction logs
|
||||
- Added check for dirty hives
|
||||
- Modified C:\Perl\site\lib\Parse\Win32Registry\WinNT\File.pm
|
||||
- if you're using the Perl version of this tool (Linux, Mac) be sure to copy File.pm
|
||||
from the repository and replace the appropriate file
|
||||
|
||||
Updates 20200104
|
||||
- Fixed issue with processing of key LastWrite times
|
||||
- Modified C:\Perl\site\lib\Parse\Win32Registry\WinNT\Base.pm
|
||||
- if you're using the Perl version of this tool (Linux, Mac) be sure to copy Base.pm
|
||||
from the repository and replace the appropriate file
|
||||
|
||||
Updates 20190128
|
||||
- added Time::Local module
|
||||
- this allows plugins to be written that parse string-based date/time stamps, converting
|
||||
them to epochs (for timelining, etc.)
|
||||
- modified C:\Perl\site\lib\Parse\Win32Registry\WinNT\Key.pm
|
||||
- extract access_bits and largest_subkey_name_length values from Key node structure
|
||||
- call 'get_access_bits()', 'get_largest_subkey_name_length()' to retrieve the values for parsing/display
|
||||
- IAW https://github.com/msuhanov/regf/blob/master/Windows%20registry%20file%20format%20specification.md
|
||||
|
||||
Note: The modifications to Key.pm are 'compiled' into the EXE versions of RegRipper. In order to fully take
|
||||
advantage of them with the .pl versions:
|
||||
- got to \Perl\site\lib\Parse\Win32Registry\WinNT\
|
||||
- rename Key.pm to Key_old.pm
|
||||
- copy Key.pm from this distro to the folder
|
||||
|
||||
Updates 20200104
|
||||
Based on how key LastWrite times were being converted from FILETIME objects to Unix epoch format, the function
|
||||
appears to have 'broke' as of 1 Jan 2020. As such, I modified/fixed the code, and have updated the compiled
|
||||
EXEs for the tools. I've also provided an updated Base.pm file, with instructions below as to how to update
|
||||
your local copy of the file.
|
||||
|
||||
- Navigate to the \site\lib\Parse\Win32Registry\ folder in your Perl installation, and remove any restrictions
|
||||
or attributes from Base.pm (i.e., 'attrib -r Base.pm')
|
||||
- Rename Base.pm to Base_old.pm
|
||||
- Copy the Base.pm from this repository
|
||||
=======
|
||||
|
22
thirdparty/rr-full/license.md
vendored
Normal file
22
thirdparty/rr-full/license.md
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
This project is licensed under terms of the MIT License -
|
||||
https://opensource.org/licenses/MIT
|
||||
|
||||
See also:
|
||||
https://en.wikipedia.org/wiki/MIT_License
|
||||
|
||||
Questions, comments, etc., can be sent to keydet89 at yahoo dot com.
|
26
thirdparty/rr-full/license.txt
vendored
26
thirdparty/rr-full/license.txt
vendored
@ -1,12 +1,22 @@
|
||||
This software is released AS-IS, with no statements or guarantees as to
|
||||
its effectiveness or stability. While it shouldn't cause any problems
|
||||
whatsoever with your system, there's always the chance that someone may find
|
||||
a way to blame a system crash or loss of data on software like this...you've
|
||||
been warned!
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
This software is released under the GNU Public License -
|
||||
http://www.gnu.org/copyleft/gpl.html
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
Specifically, GPL v2.0: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
This project is licensed under terms of the MIT License -
|
||||
https://opensource.org/licenses/MIT
|
||||
|
||||
See also:
|
||||
https://en.wikipedia.org/wiki/MIT_License
|
||||
|
||||
Questions, comments, etc., can be sent to keydet89 at yahoo dot com.
|
27
thirdparty/rr-full/plugins/all
vendored
27
thirdparty/rr-full/plugins/all
vendored
@ -1,17 +1,10 @@
|
||||
# 20161213 *ALL* Plugins that apply on any HIVES, alphabetical order
|
||||
baseline
|
||||
del
|
||||
del_tln
|
||||
fileless
|
||||
findexes
|
||||
installedcomp
|
||||
installer
|
||||
malware
|
||||
null
|
||||
regtime
|
||||
regtime_tln
|
||||
rlo
|
||||
sizes
|
||||
uninstall
|
||||
uninstall_tln
|
||||
wallpaper
|
||||
baseline
|
||||
del
|
||||
fileless
|
||||
findexes
|
||||
malware
|
||||
null
|
||||
regtime
|
||||
rlo
|
||||
sizes
|
||||
slack
|
||||
|
3
thirdparty/rr-full/plugins/amcache
vendored
3
thirdparty/rr-full/plugins/amcache
vendored
@ -1,2 +1 @@
|
||||
#20161213 *ALL* Plugins that apply on any amcache, alphabetical order
|
||||
amcache
|
||||
amcache
|
||||
|
285
thirdparty/rr-full/plugins/amcache.pl
vendored
285
thirdparty/rr-full/plugins/amcache.pl
vendored
@ -2,6 +2,7 @@
|
||||
# amcache.pl
|
||||
#
|
||||
# Change history
|
||||
# 20180311 - updated to support newer version files, albeit without parsing devices
|
||||
# 20170315 - added output for Product Name and File Description values
|
||||
# 20160818 - added check for value 17
|
||||
# 20131218 - fixed bug computing compile time
|
||||
@ -9,9 +10,10 @@
|
||||
# 20131204 - created
|
||||
#
|
||||
# References
|
||||
# https://binaryforay.blogspot.com/2017/10/amcache-still-rules-everything-around.html
|
||||
# http://www.swiftforensics.com/2013/12/amcachehve-in-windows-8-goldmine-for.html
|
||||
#
|
||||
# Copyright (c) 2017 QAR, LLC
|
||||
# Copyright (c) 2018 QAR, LLC
|
||||
# Author: H. Carvey, keydet89@yahoo.com
|
||||
#-----------------------------------------------------------
|
||||
package amcache;
|
||||
@ -23,7 +25,7 @@ my %config = (hive => "amcache",
|
||||
hasRefs => 1,
|
||||
osmask => 22,
|
||||
category => "program execution",
|
||||
version => 20170315);
|
||||
version => 20180311);
|
||||
my $VERSION = getVersion();
|
||||
|
||||
# Functions #
|
||||
@ -40,121 +42,208 @@ sub pluginmain {
|
||||
my $class = shift;
|
||||
my $hive = shift;
|
||||
|
||||
# Initialize #
|
||||
::logMsg("Launching amcache v.".$VERSION);
|
||||
::rptMsg("amcache v.".$VERSION);
|
||||
::rptMsg("(".$config{hive}.") ".getShortDescr()."\n");
|
||||
my $reg = Parse::Win32Registry->new($hive);
|
||||
my $root_key = $reg->get_root_key;
|
||||
my $key;
|
||||
my @sk1;
|
||||
my @sk;
|
||||
my (@t,$gt);
|
||||
|
||||
my $key_path = 'Root\\File';
|
||||
::rptMsg("***Files***");
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
|
||||
# Newer version Amcache.hve files
|
||||
# Devices not parsed at this time
|
||||
my $key_path = 'Root\\InventoryApplicationFile';
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
parseInventoryApplicationFile($key);
|
||||
|
||||
@sk1 = $key->get_list_of_subkeys();
|
||||
foreach my $s1 (@sk1) {
|
||||
# Volume GUIDs
|
||||
::rptMsg($s1->get_name());
|
||||
|
||||
@sk = $s1->get_list_of_subkeys();
|
||||
if (scalar(@sk) > 0) {
|
||||
foreach my $s (@sk) {
|
||||
::rptMsg("File Reference: ".$s->get_name());
|
||||
::rptMsg("LastWrite : ".gmtime($s->get_timestamp())." Z");
|
||||
# update 20131213: based on trial and error, it appears that not all file
|
||||
# references will have all of the values, such as Path, or SHA-1
|
||||
eval {
|
||||
::rptMsg("Path : ".$s->get_value("15")->get_data());
|
||||
};
|
||||
|
||||
eval {
|
||||
::rptMsg("Company Name : ".$s->get_value("1")->get_data());
|
||||
};
|
||||
|
||||
eval {
|
||||
::rptMsg("Product Name : ".$s->get_value("0")->get_data());
|
||||
};
|
||||
|
||||
eval {
|
||||
::rptMsg("File Descr : ".$s->get_value("c")->get_data());
|
||||
};
|
||||
|
||||
eval {
|
||||
::rptMsg("Lang Code : ".$s->get_value("3")->get_data());
|
||||
};
|
||||
|
||||
eval {
|
||||
::rptMsg("SHA-1 : ".$s->get_value("101")->get_data());
|
||||
};
|
||||
|
||||
eval {
|
||||
@t = unpack("VV",$s->get_value("11")->get_data());
|
||||
$gt = gmtime(::getTime($t[0],$t[1]));
|
||||
::rptMsg("Last Mod Time : ".$gt." Z");
|
||||
};
|
||||
|
||||
eval {
|
||||
@t = unpack("VV",$s->get_value("17")->get_data());
|
||||
$gt = gmtime(::getTime($t[0],$t[1]));
|
||||
::rptMsg("Last Mod Time2: ".$gt." Z");
|
||||
};
|
||||
|
||||
eval {
|
||||
@t = unpack("VV",$s->get_value("12")->get_data());
|
||||
$gt = gmtime(::getTime($t[0],$t[1]));
|
||||
::rptMsg("Create Time : ".$gt." Z");
|
||||
};
|
||||
|
||||
eval {
|
||||
$gt = gmtime($s->get_value("f")->get_data());
|
||||
# $gt = gmtime(unpack("V",$s->get_value("f")->get_data()));
|
||||
::rptMsg("Compile Time : ".$gt." Z");
|
||||
};
|
||||
::rptMsg("");
|
||||
}
|
||||
}
|
||||
else {
|
||||
# ::rptMsg("Key ".$s1->get_name()." has no subkeys.");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
::rptMsg($key_path." not found.");
|
||||
}
|
||||
::rptMsg("");
|
||||
|
||||
my $key_path = 'Root\\InventoryApplication';
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
parseInventoryApplication($key);
|
||||
|
||||
}
|
||||
else {
|
||||
::rptMsg($key_path." not found.");
|
||||
}
|
||||
::rptMsg("");
|
||||
|
||||
# Older version AmCache.hve files
|
||||
# Root\Files subkey
|
||||
my $key_path = 'Root\\File';
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
parseFile($key);
|
||||
|
||||
}
|
||||
else {
|
||||
::rptMsg($key_path." not found.");
|
||||
}
|
||||
::rptMsg("");
|
||||
|
||||
# Root\Programs subkey
|
||||
$key_path = 'Root\\Programs';
|
||||
::rptMsg("***Programs***");
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
@sk1 = $key->get_list_of_subkeys();
|
||||
if (scalar(@sk1) > 0) {
|
||||
foreach my $s1 (@sk1) {
|
||||
my $str;
|
||||
$str = "Name : ".$s1->get_value("0")->get_data();
|
||||
|
||||
eval {
|
||||
$str .= " v\.".$s1->get_value("1")->get_data();
|
||||
};
|
||||
::rptMsg($str);
|
||||
eval {
|
||||
::rptMsg("Category : ".$s1->get_value("6")->get_data());
|
||||
};
|
||||
|
||||
eval {
|
||||
::rptMsg("UnInstall : ".$s1->get_value("7")->get_data());
|
||||
};
|
||||
|
||||
::rptMsg("");
|
||||
}
|
||||
}
|
||||
parsePrograms($key);
|
||||
}
|
||||
else {
|
||||
::rptMsg($key_path." not found.");
|
||||
}
|
||||
}
|
||||
|
||||
sub parseInventoryApplicationFile {
|
||||
my $key = shift;
|
||||
::rptMsg("***InventoryApplicationFile***");
|
||||
my @sk = $key->get_list_of_subkeys();
|
||||
if (scalar(@sk) > 0) {
|
||||
foreach my $s (@sk) {
|
||||
my $lw = $s->get_timestamp();
|
||||
|
||||
my $path;
|
||||
eval {
|
||||
$path = $s->get_value("LowerCaseLongPath")->get_data();
|
||||
};
|
||||
|
||||
my $hash;
|
||||
eval {
|
||||
$hash = $s->get_value("FileID")->get_data();
|
||||
$hash =~ s/^0000//;
|
||||
};
|
||||
::rptMsg($path." LastWrite: ".gmtime($lw));
|
||||
::rptMsg("Hash: ".$hash);
|
||||
::rptMsg("");
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sub parseInventoryApplication {
|
||||
my $key = shift;
|
||||
my @sk = $key->get_list_of_subkeys();
|
||||
if (scalar(@sk) > 0) {
|
||||
foreach my $s (@sk) {
|
||||
my $lw = $s->get_timestamp();
|
||||
my $name;
|
||||
eval {
|
||||
$name = $s->get_value("Name")->get_data();
|
||||
};
|
||||
|
||||
my $version;
|
||||
eval {
|
||||
$version = "v.".$s->get_value("Version")->get_data();
|
||||
};
|
||||
::rptMsg(gmtime($lw)." - ".$name." ".$version);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub parseFile {
|
||||
my $key = shift;
|
||||
::rptMsg("***Files***");
|
||||
my (@t,$gt);
|
||||
my @sk1 = $key->get_list_of_subkeys();
|
||||
foreach my $s1 (@sk1) {
|
||||
# Volume GUIDs
|
||||
::rptMsg($s1->get_name());
|
||||
|
||||
my @sk = $s1->get_list_of_subkeys();
|
||||
if (scalar(@sk) > 0) {
|
||||
foreach my $s (@sk) {
|
||||
::rptMsg("File Reference: ".$s->get_name());
|
||||
::rptMsg("LastWrite : ".gmtime($s->get_timestamp())." Z");
|
||||
# update 20131213: based on trial and error, it appears that not all file
|
||||
# references will have all of the values, such as Path, or SHA-1
|
||||
eval {
|
||||
::rptMsg("Path : ".$s->get_value("15")->get_data());
|
||||
};
|
||||
|
||||
eval {
|
||||
::rptMsg("Company Name : ".$s->get_value("1")->get_data());
|
||||
};
|
||||
|
||||
eval {
|
||||
::rptMsg("Product Name : ".$s->get_value("0")->get_data());
|
||||
};
|
||||
|
||||
eval {
|
||||
::rptMsg("File Descr : ".$s->get_value("c")->get_data());
|
||||
};
|
||||
|
||||
eval {
|
||||
::rptMsg("Lang Code : ".$s->get_value("3")->get_data());
|
||||
};
|
||||
|
||||
eval {
|
||||
::rptMsg("SHA-1 : ".$s->get_value("101")->get_data());
|
||||
};
|
||||
|
||||
eval {
|
||||
@t = unpack("VV",$s->get_value("11")->get_data());
|
||||
$gt = gmtime(::getTime($t[0],$t[1]));
|
||||
::rptMsg("Last Mod Time : ".$gt." Z");
|
||||
};
|
||||
|
||||
eval {
|
||||
@t = unpack("VV",$s->get_value("17")->get_data());
|
||||
$gt = gmtime(::getTime($t[0],$t[1]));
|
||||
::rptMsg("Last Mod Time2: ".$gt." Z");
|
||||
};
|
||||
|
||||
eval {
|
||||
@t = unpack("VV",$s->get_value("12")->get_data());
|
||||
$gt = gmtime(::getTime($t[0],$t[1]));
|
||||
::rptMsg("Create Time : ".$gt." Z");
|
||||
};
|
||||
|
||||
eval {
|
||||
$gt = gmtime($s->get_value("f")->get_data());
|
||||
# $gt = gmtime(unpack("V",$s->get_value("f")->get_data()));
|
||||
::rptMsg("Compile Time : ".$gt." Z");
|
||||
};
|
||||
::rptMsg("");
|
||||
}
|
||||
}
|
||||
else {
|
||||
# ::rptMsg("Key ".$s1->get_name()." has no subkeys.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Root\Programs subkey
|
||||
sub parsePrograms {
|
||||
my $key = shift;
|
||||
::rptMsg("***Programs***");
|
||||
my @sk1 = $key->get_list_of_subkeys();
|
||||
if (scalar(@sk1) > 0) {
|
||||
foreach my $s1 (@sk1) {
|
||||
my $str;
|
||||
$str = "Name : ".$s1->get_value("0")->get_data();
|
||||
|
||||
eval {
|
||||
$str .= " v\.".$s1->get_value("1")->get_data();
|
||||
};
|
||||
::rptMsg($str);
|
||||
eval {
|
||||
::rptMsg("Category : ".$s1->get_value("6")->get_data());
|
||||
};
|
||||
|
||||
eval {
|
||||
::rptMsg("UnInstall : ".$s1->get_value("7")->get_data());
|
||||
};
|
||||
|
||||
::rptMsg("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
233
thirdparty/rr-full/plugins/amcache_tln.pl
vendored
233
thirdparty/rr-full/plugins/amcache_tln.pl
vendored
@ -2,12 +2,18 @@
|
||||
# amcache_tln.pl
|
||||
#
|
||||
# Change history
|
||||
# 20170315 - created
|
||||
# 20180311 - updated to support newer version files, albeit without parsing devices
|
||||
# 20170315 - added output for Product Name and File Description values
|
||||
# 20160818 - added check for value 17
|
||||
# 20131218 - fixed bug computing compile time
|
||||
# 20131213 - updated
|
||||
# 20131204 - created
|
||||
#
|
||||
# References
|
||||
# https://binaryforay.blogspot.com/2017/10/amcache-still-rules-everything-around.html
|
||||
# http://www.swiftforensics.com/2013/12/amcachehve-in-windows-8-goldmine-for.html
|
||||
#
|
||||
# Copyright (c) 2017 QAR, LLC
|
||||
# Copyright (c) 2018 QAR, LLC
|
||||
# Author: H. Carvey, keydet89@yahoo.com
|
||||
#-----------------------------------------------------------
|
||||
package amcache_tln;
|
||||
@ -19,7 +25,7 @@ my %config = (hive => "amcache",
|
||||
hasRefs => 1,
|
||||
osmask => 22,
|
||||
category => "program execution",
|
||||
version => 20170315);
|
||||
version => 20180311);
|
||||
my $VERSION = getVersion();
|
||||
|
||||
# Functions #
|
||||
@ -28,88 +34,199 @@ sub getHive {return $config{hive};}
|
||||
sub getVersion {return $config{version};}
|
||||
sub getDescr {}
|
||||
sub getShortDescr {
|
||||
return "Parse AmCache\.hve file, TLN format";
|
||||
return "Parse AmCache\.hve file";
|
||||
}
|
||||
sub getRefs {}
|
||||
|
||||
sub pluginmain {
|
||||
my $class = shift;
|
||||
my $hive = shift;
|
||||
|
||||
# Initialize #
|
||||
|
||||
::logMsg("Launching amcache_tln v.".$VERSION);
|
||||
# ::rptMsg("amcache v.".$VERSION);
|
||||
# ::rptMsg("(".$config{hive}.") ".getShortDescr()."\n");
|
||||
my $reg = Parse::Win32Registry->new($hive);
|
||||
my $root_key = $reg->get_root_key;
|
||||
my $key;
|
||||
my @sk1;
|
||||
my @sk;
|
||||
my (@t,$gt);
|
||||
|
||||
my $key_path = 'Root\\File';
|
||||
# ::rptMsg("***Files***");
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
|
||||
# Newer version Amcache.hve files
|
||||
# Devices not parsed at this time
|
||||
my $key_path = 'Root\\InventoryApplicationFile';
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
parseInventoryApplicationFile($key);
|
||||
|
||||
@sk1 = $key->get_list_of_subkeys();
|
||||
foreach my $s1 (@sk1) {
|
||||
# Volume GUIDs
|
||||
::rptMsg($s1->get_name());
|
||||
}
|
||||
else {
|
||||
# ::rptMsg($key_path." not found.");
|
||||
}
|
||||
# ::rptMsg("");
|
||||
|
||||
# my $key_path = 'Root\\InventoryApplication';
|
||||
# if ($key = $root_key->get_subkey($key_path)) {
|
||||
# parseInventoryApplication($key);
|
||||
#
|
||||
# }
|
||||
# else {
|
||||
# ::rptMsg($key_path." not found.");
|
||||
# }
|
||||
# ::rptMsg("");
|
||||
|
||||
# Older version AmCache.hve files
|
||||
# Root\Files subkey
|
||||
my $key_path = 'Root\\File';
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
parseFile($key);
|
||||
|
||||
}
|
||||
else {
|
||||
# ::rptMsg($key_path." not found.");
|
||||
}
|
||||
# ::rptMsg("");
|
||||
}
|
||||
|
||||
sub parseInventoryApplicationFile {
|
||||
my $key = shift;
|
||||
# ::rptMsg("***InventoryApplicationFile***");
|
||||
my @sk = $key->get_list_of_subkeys();
|
||||
if (scalar(@sk) > 0) {
|
||||
foreach my $s (@sk) {
|
||||
my $lw = $s->get_timestamp();
|
||||
|
||||
my $path;
|
||||
eval {
|
||||
$path = $s->get_value("LowerCaseLongPath")->get_data();
|
||||
};
|
||||
|
||||
@sk = $s1->get_list_of_subkeys();
|
||||
if (scalar(@sk) > 0) {
|
||||
foreach my $s (@sk) {
|
||||
my $fileref = $s->get_name();
|
||||
my $lw = $s->get_timestamp();
|
||||
my $hash;
|
||||
eval {
|
||||
$hash = $s->get_value("FileID")->get_data();
|
||||
$hash =~ s/^0000//;
|
||||
};
|
||||
|
||||
::rptMsg($lw."|AmCache|||Key LastWrite - ".$path." (".$hash.")");
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sub parseInventoryApplication {
|
||||
my $key = shift;
|
||||
my @sk = $key->get_list_of_subkeys();
|
||||
if (scalar(@sk) > 0) {
|
||||
foreach my $s (@sk) {
|
||||
my $lw = $s->get_timestamp();
|
||||
my $name;
|
||||
eval {
|
||||
$name = $s->get_value("Name")->get_data();
|
||||
};
|
||||
|
||||
my $version;
|
||||
eval {
|
||||
$version = "v.".$s->get_value("Version")->get_data();
|
||||
};
|
||||
::rptMsg(gmtime($lw)." - ".$name." ".$version);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub parseFile {
|
||||
my $key = shift;
|
||||
# ::rptMsg("***Files***");
|
||||
my (@t,$gt);
|
||||
my @sk1 = $key->get_list_of_subkeys();
|
||||
foreach my $s1 (@sk1) {
|
||||
# Volume GUIDs
|
||||
::rptMsg($s1->get_name());
|
||||
my @sk = $s1->get_list_of_subkeys();
|
||||
if (scalar(@sk) > 0) {
|
||||
foreach my $s (@sk) {
|
||||
my $fileref = $s->get_name();
|
||||
my $lw = $s->get_timestamp();
|
||||
|
||||
# First, report key lastwrite time (== execution time??)
|
||||
eval {
|
||||
$fileref = $fileref.":".$s->get_value("15")->get_data();
|
||||
};
|
||||
|
||||
::rptMsg($lw."|AmCache|||Key LastWrite - ".$fileref);
|
||||
|
||||
eval {
|
||||
$fileref = $fileref.":".$s->get_value("15")->get_data();
|
||||
};
|
||||
::rptMsg($lw."|AmCache|||Key LastWrite - ".$fileref);
|
||||
|
||||
# get last mod./creation times
|
||||
my @dots = qw/. . . ./;
|
||||
my %t_hash = ();
|
||||
my @vals = ();
|
||||
my @dots = qw/. . . ./;
|
||||
my %t_hash = ();
|
||||
my @vals = ();
|
||||
|
||||
# last mod time
|
||||
eval {
|
||||
my @t = unpack("VV",$s->get_value("11")->get_data());
|
||||
$vals[1] = ::getTime($t[0],$t[1]);
|
||||
};
|
||||
eval {
|
||||
my @t = unpack("VV",$s->get_value("11")->get_data());
|
||||
$vals[1] = ::getTime($t[0],$t[1]);
|
||||
};
|
||||
# creation time
|
||||
eval {
|
||||
my @t = unpack("VV",$s->get_value("12")->get_data());
|
||||
$vals[3] = ::getTime($t[0],$t[1]);
|
||||
};
|
||||
eval {
|
||||
my @t = unpack("VV",$s->get_value("12")->get_data());
|
||||
$vals[3] = ::getTime($t[0],$t[1]);
|
||||
};
|
||||
|
||||
foreach my $v (@vals) {
|
||||
@{$t_hash{$v}} = @dots unless ($v == 0);
|
||||
}
|
||||
foreach my $v (@vals) {
|
||||
@{$t_hash{$v}} = @dots unless ($v == 0);
|
||||
}
|
||||
|
||||
${$t_hash{$vals[0]}}[1] = "A" unless ($vals[0] == 0);
|
||||
${$t_hash{$vals[1]}}[0] = "M" unless ($vals[1] == 0);
|
||||
${$t_hash{$vals[2]}}[2] = "C" unless ($vals[2] == 0);
|
||||
${$t_hash{$vals[3]}}[3] = "B" unless ($vals[3] == 0);
|
||||
${$t_hash{$vals[0]}}[1] = "A" unless ($vals[0] == 0);
|
||||
${$t_hash{$vals[1]}}[0] = "M" unless ($vals[1] == 0);
|
||||
${$t_hash{$vals[2]}}[2] = "C" unless ($vals[2] == 0);
|
||||
${$t_hash{$vals[3]}}[3] = "B" unless ($vals[3] == 0);
|
||||
|
||||
foreach my $t (reverse sort {$a <=> $b} keys %t_hash) {
|
||||
my $str = join('',@{$t_hash{$t}});
|
||||
::rptMsg($t."|AmCache|||".$str." ".$fileref);
|
||||
}
|
||||
foreach my $t (reverse sort {$a <=> $b} keys %t_hash) {
|
||||
my $str = join('',@{$t_hash{$t}});
|
||||
::rptMsg($t."|AmCache|||".$str." ".$fileref);
|
||||
}
|
||||
|
||||
# check for PE Compile times
|
||||
eval {
|
||||
my $pe = $s->get_value("f")->get_data();
|
||||
::rptMsg($pe."|AmCache|||PE Compile time - ".$fileref);
|
||||
::rptMsg("Compile Time : ".$gt." Z");
|
||||
};
|
||||
|
||||
}
|
||||
eval {
|
||||
my $pe = $s->get_value("f")->get_data();
|
||||
::rptMsg($pe."|AmCache|||PE Compile time - ".$fileref);
|
||||
::rptMsg("Compile Time : ".$gt." Z");
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
# ::rptMsg("Key ".$s1->get_name()." has no subkeys.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Root\Programs subkey
|
||||
sub parsePrograms {
|
||||
my $key = shift;
|
||||
# ::rptMsg("***Programs***");
|
||||
my @sk1 = $key->get_list_of_subkeys();
|
||||
if (scalar(@sk1) > 0) {
|
||||
foreach my $s1 (@sk1) {
|
||||
my $str;
|
||||
$str = "Name : ".$s1->get_value("0")->get_data();
|
||||
|
||||
eval {
|
||||
$str .= " v\.".$s1->get_value("1")->get_data();
|
||||
};
|
||||
::rptMsg($str);
|
||||
eval {
|
||||
::rptMsg("Category : ".$s1->get_value("6")->get_data());
|
||||
};
|
||||
|
||||
eval {
|
||||
::rptMsg("UnInstall : ".$s1->get_value("7")->get_data());
|
||||
};
|
||||
|
||||
# ::rptMsg("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
1;
|
||||
|
48
thirdparty/rr-full/plugins/appcompatcache.pl
vendored
48
thirdparty/rr-full/plugins/appcompatcache.pl
vendored
@ -2,6 +2,8 @@
|
||||
# appcompatcache.pl
|
||||
#
|
||||
# History:
|
||||
# 20190112 - updated parsing for Win8.1
|
||||
# 20180311 - updated for more recent version of Win10/Win2016
|
||||
# 20160528 - updated code to not de-dup entries based on filename
|
||||
# 20160217 - updated to correctly support Win10
|
||||
# 20150611 - mod'd for Kevin Pagano
|
||||
@ -42,7 +44,7 @@ my %config = (hive => "System",
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
osmask => 31, #XP - Win7
|
||||
version => 20160528);
|
||||
version => 20190112);
|
||||
|
||||
sub getConfig{return %config}
|
||||
sub getShortDescr {
|
||||
@ -120,12 +122,18 @@ sub pluginmain {
|
||||
# probe($app_data);
|
||||
|
||||
}
|
||||
elsif ($sig == 0x30) {
|
||||
elsif ($sig == 0x0) {
|
||||
# possible win 8.1 system
|
||||
appWin81($app_data);
|
||||
# print $app_data;
|
||||
}
|
||||
elsif ($sig == 0x30 || $sig == 0x34) {
|
||||
# Windows 10 system
|
||||
appWin10($app_data);
|
||||
}
|
||||
else {
|
||||
::rptMsg(sprintf "Unknown signature: 0x%x",$sig);
|
||||
# probe($app_data);
|
||||
}
|
||||
# this is where we print out the files
|
||||
foreach my $f (keys %files) {
|
||||
@ -296,7 +304,6 @@ sub appWin8 {
|
||||
|
||||
while($ofs < $len) {
|
||||
my $tag = unpack("V",substr($data,$ofs,4));
|
||||
last unless (defined $tag);
|
||||
# 32-bit
|
||||
if ($tag == 0x73746f72) {
|
||||
$jmp = unpack("V",substr($data,$ofs + 8,4));
|
||||
@ -328,6 +335,37 @@ sub appWin8 {
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# appWin81()
|
||||
#
|
||||
#-----------------------------------------------------------
|
||||
sub appWin81 {
|
||||
my $data = shift;
|
||||
my $len = length($data);
|
||||
my ($tag, $sz, $t0, $t1, $name, $name_len);
|
||||
my $ct = 0;
|
||||
# my $ofs = unpack("V",substr($data,0,4));
|
||||
my $ofs = 0x80;
|
||||
|
||||
while ($ofs < $len) {
|
||||
$tag = substr($data,$ofs,4);
|
||||
if ($tag eq "10ts") {
|
||||
|
||||
$sz = unpack("V",substr($data,$ofs + 0x08,4));
|
||||
$name_len = unpack("v",substr($data,$ofs + 0x0c,2));
|
||||
my $name = substr($data,$ofs + 0x0e,$name_len);
|
||||
$name =~ s/\00//g;
|
||||
# ($t0,$t1) = unpack("VV",substr($data,$ofs + 0x03 + $name_len,8));
|
||||
($t0,$t1) = unpack("VV",substr($data,$ofs + 0x0e + $name_len + 0x0a,8));
|
||||
$files{$ct}{filename} = $name;
|
||||
$files{$ct}{modtime} = ::getTime($t0,$t1);
|
||||
|
||||
$ct++;
|
||||
$ofs += ($sz + 0x0c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# appWin10()
|
||||
# Ref: http://binaryforay.blogspot.com/2015/04/appcompatcache-changes-in-windows-10.html
|
||||
@ -337,11 +375,11 @@ sub appWin10 {
|
||||
my $len = length($data);
|
||||
my ($tag, $sz, $t0, $t1, $name, $name_len);
|
||||
my $ct = 0;
|
||||
my $ofs = 0x30;
|
||||
my $ofs = unpack("V",substr($data,0,4));
|
||||
# my $ofs = 0x30;
|
||||
|
||||
while ($ofs < $len) {
|
||||
$tag = substr($data,$ofs,4);
|
||||
last unless (defined $tag);
|
||||
if ($tag eq "10ts") {
|
||||
|
||||
$sz = unpack("V",substr($data,$ofs + 0x08,4));
|
||||
|
46
thirdparty/rr-full/plugins/appcompatcache_tln.pl
vendored
46
thirdparty/rr-full/plugins/appcompatcache_tln.pl
vendored
@ -2,6 +2,8 @@
|
||||
# appcompatcache_tln.pl
|
||||
#
|
||||
# History:
|
||||
# 20190112 - updated parsing for Win8.1
|
||||
# 20180311 - updated for more recent version of Win10/Win2016
|
||||
# 20160528 - updated code to not de-dup entries based on filename
|
||||
# 20160217 - updated to correctly support Win10
|
||||
# 20150611 - mod'd for Kevin Pagano
|
||||
@ -42,7 +44,7 @@ my %config = (hive => "System",
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
osmask => 31, #XP - Win7
|
||||
version => 20160528);
|
||||
version => 20190112);
|
||||
|
||||
sub getConfig{return %config}
|
||||
sub getShortDescr {
|
||||
@ -120,7 +122,10 @@ sub pluginmain {
|
||||
# probe($app_data);
|
||||
|
||||
}
|
||||
elsif ($sig == 0x30) {
|
||||
elsif ($sig == 0x0) {
|
||||
appWin81($app_data);
|
||||
}
|
||||
elsif ($sig == 0x30 || $sig == 0x34) {
|
||||
# Windows 10 system
|
||||
appWin10($app_data);
|
||||
}
|
||||
@ -291,7 +296,6 @@ sub appWin8 {
|
||||
|
||||
while($ofs < $len) {
|
||||
my $tag = unpack("V",substr($data,$ofs,4));
|
||||
last unless (defined $tag);
|
||||
# 32-bit
|
||||
if ($tag == 0x73746f72) {
|
||||
$jmp = unpack("V",substr($data,$ofs + 8,4));
|
||||
@ -323,6 +327,38 @@ sub appWin8 {
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# appWin81()
|
||||
#
|
||||
#-----------------------------------------------------------
|
||||
sub appWin81 {
|
||||
my $data = shift;
|
||||
my $len = length($data);
|
||||
my ($tag, $sz, $t0, $t1, $name, $name_len);
|
||||
my $ct = 0;
|
||||
# my $ofs = unpack("V",substr($data,0,4));
|
||||
my $ofs = 0x80;
|
||||
|
||||
while ($ofs < $len) {
|
||||
$tag = substr($data,$ofs,4);
|
||||
if ($tag eq "10ts") {
|
||||
|
||||
$sz = unpack("V",substr($data,$ofs + 0x08,4));
|
||||
$name_len = unpack("v",substr($data,$ofs + 0x0c,2));
|
||||
my $name = substr($data,$ofs + 0x0e,$name_len);
|
||||
$name =~ s/\00//g;
|
||||
# ($t0,$t1) = unpack("VV",substr($data,$ofs + 0x03 + $name_len,8));
|
||||
($t0,$t1) = unpack("VV",substr($data,$ofs + 0x0e + $name_len + 0x0a,8));
|
||||
$files{$ct}{filename} = $name;
|
||||
$files{$ct}{modtime} = ::getTime($t0,$t1);
|
||||
|
||||
$ct++;
|
||||
$ofs += ($sz + 0x0c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# appWin10()
|
||||
# Ref: http://binaryforay.blogspot.com/2015/04/appcompatcache-changes-in-windows-10.html
|
||||
@ -332,11 +368,11 @@ sub appWin10 {
|
||||
my $len = length($data);
|
||||
my ($tag, $sz, $t0, $t1, $name, $name_len);
|
||||
my $ct = 0;
|
||||
my $ofs = 0x30;
|
||||
my $ofs = unpack("V",substr($data,0,4));
|
||||
# my $ofs = 0x30;
|
||||
|
||||
while ($ofs < $len) {
|
||||
$tag = substr($data,$ofs,4);
|
||||
last unless (defined $tag);
|
||||
if ($tag eq "10ts") {
|
||||
|
||||
$sz = unpack("V",substr($data,$ofs + 0x08,4));
|
||||
|
1
thirdparty/rr-full/plugins/arpcache.pl
vendored
1
thirdparty/rr-full/plugins/arpcache.pl
vendored
@ -122,7 +122,6 @@ sub parsePath {
|
||||
while($tag) {
|
||||
$ofs += 2;
|
||||
my $i = substr($data,$ofs,2);
|
||||
last unless (defined $i);
|
||||
if (unpack("v",$i) == 0) {
|
||||
$tag = 0;
|
||||
}
|
||||
|
82
thirdparty/rr-full/plugins/assoc.pl
vendored
82
thirdparty/rr-full/plugins/assoc.pl
vendored
@ -3,17 +3,22 @@
|
||||
# Plugin to extract file association data from the Software hive file
|
||||
# Can take considerable time to run; recommend running it via rip.exe
|
||||
#
|
||||
# History
|
||||
# 20180117 - updated, based on input from Jean, jean.crush@hotmail.fr
|
||||
# 20080815 - created
|
||||
#
|
||||
#
|
||||
# copyright 2008 H. Carvey, keydet89@yahoo.com
|
||||
#-----------------------------------------------------------
|
||||
package assoc;
|
||||
use strict;
|
||||
|
||||
my %config = (hive => "Software",
|
||||
my %config = (hive => "Software,USRCLASS",
|
||||
osmask => 22,
|
||||
hasShortDescr => 1,
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
version => 20080815);
|
||||
version => 20180117);
|
||||
|
||||
sub getConfig{return %config}
|
||||
|
||||
@ -32,58 +37,55 @@ sub pluginmain {
|
||||
my $hive = shift;
|
||||
::logMsg("Launching assoc v.".$VERSION);
|
||||
::rptMsg("assoc v.".$VERSION); # banner
|
||||
::rptMsg("(".$config{hive}.") ".getShortDescr()."\n"); # banner
|
||||
::rptMsg("(".$config{hive}.") ".getShortDescr()."\n"); # banner
|
||||
my $reg = Parse::Win32Registry->new($hive);
|
||||
my $root_key = $reg->get_root_key;
|
||||
|
||||
my $key_path = "Classes";
|
||||
my @paths = ("Classes","Classes\\Wow6432Node","Wow6432Node");
|
||||
my $key;
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
::rptMsg("assoc");
|
||||
::rptMsg($key_path);
|
||||
foreach my $key_path (@paths) {
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
::rptMsg("assoc");
|
||||
::rptMsg($key_path);
|
||||
# ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
|
||||
::rptMsg("");
|
||||
::rptMsg("");
|
||||
# First step will be to get a list of all of the file extensions
|
||||
my %ext;
|
||||
my @sk = $key->get_list_of_subkeys();
|
||||
if (scalar(@sk) > 0) {
|
||||
foreach my $s (@sk) {
|
||||
my $name = $s->get_name();
|
||||
next unless ($name =~ m/^\.\w+$/);
|
||||
my $data;
|
||||
eval {
|
||||
$data = $s->get_value("")->get_data();
|
||||
};
|
||||
if ($@) {
|
||||
my %ext;
|
||||
my @sk = $key->get_list_of_subkeys();
|
||||
if (scalar(@sk) > 0) {
|
||||
foreach my $s (@sk) {
|
||||
my $name = $s->get_name();
|
||||
next unless ($name =~ m/^\.\w+$/);
|
||||
my $data;
|
||||
eval {
|
||||
$data = $s->get_value("")->get_data();
|
||||
};
|
||||
if ($@) {
|
||||
# Error generated, as "(Default)" value was not found
|
||||
}
|
||||
else {
|
||||
$ext{$name} = $data if ($data ne "");
|
||||
}
|
||||
}
|
||||
else {
|
||||
$ext{$name} = $data if ($data ne "");
|
||||
}
|
||||
}
|
||||
# Once a list of all file ext subkeys has been compiled, access the file type
|
||||
# to determine the command line used to launch files with that extension
|
||||
foreach my $e (keys %ext) {
|
||||
my $cmd;
|
||||
eval {
|
||||
$cmd = $key->get_subkey($ext{$e}."\\shell\\open\\command")->get_value("")->get_data();
|
||||
};
|
||||
if ($@) {
|
||||
foreach my $e (keys %ext) {
|
||||
my $cmd;
|
||||
eval {
|
||||
$cmd = $key->get_subkey($ext{$e}."\\shell\\open\\command")->get_value("")->get_data();
|
||||
};
|
||||
if ($@) {
|
||||
# error generated attempting to locate <file type>.\shell\open\command\(Default) value
|
||||
}
|
||||
else {
|
||||
::rptMsg($e." : ".$cmd);
|
||||
}
|
||||
else {
|
||||
::rptMsg($e." : ".$cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
::rptMsg($key_path." has no subkeys.");
|
||||
else {
|
||||
::rptMsg($key_path." has no subkeys.");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
::rptMsg($key_path." not found.");
|
||||
::logMsg($key_path." not found.");
|
||||
}
|
||||
|
||||
}
|
||||
1;
|
74
thirdparty/rr-full/plugins/auditpol.pl
vendored
74
thirdparty/rr-full/plugins/auditpol.pl
vendored
@ -4,6 +4,7 @@
|
||||
# *Works for Win7 and Win10 at the moment
|
||||
#
|
||||
# History
|
||||
# 20190510 - updated; Win2016
|
||||
# 20151202 - created
|
||||
#
|
||||
# Ref:
|
||||
@ -24,7 +25,7 @@ my %config = (hive => "Security",
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
osmask => 22,
|
||||
version => 20151202);
|
||||
version => 20190510);
|
||||
|
||||
sub getConfig{return %config}
|
||||
sub getShortDescr {
|
||||
@ -71,9 +72,15 @@ sub pluginmain {
|
||||
@policy = processWin10($data)
|
||||
}
|
||||
elsif (length($data) == 138 && $id == 0x78) {
|
||||
::rptMsg("Possible Win7/Win2008");
|
||||
@policy = processWin7($data);
|
||||
}
|
||||
elsif (length($data) == 0x96 && $id == 0x84) {
|
||||
::rptMsg("Possible Win10(1607+)/Win2016");
|
||||
@policy = processWin2016($data);
|
||||
}
|
||||
else {
|
||||
::rptMsg(sprintf "Data Length: 0x%x",length($data));
|
||||
my @d = printData($data);
|
||||
foreach (0..(scalar(@d) - 1)) {
|
||||
::rptMsg($d[$_]);
|
||||
@ -213,6 +220,71 @@ sub processWin7 {
|
||||
return @win;
|
||||
}
|
||||
|
||||
sub processWin2016 {
|
||||
my $data = shift;
|
||||
my @win = ("System:Security State Change;".unpack("v",substr($data,0x0c,2)),
|
||||
"System:Security System Extension;".unpack("v",substr($data,0x0e,2)),
|
||||
"System:System Integrity;".unpack("v",substr($data,0x10,2)),
|
||||
"System:IPsec Driver;".unpack("v",substr($data,0x12,2)),
|
||||
"System:Other System Events;".unpack("v",substr($data,0x14,2)),
|
||||
"Logon/Logoff:Logon;".unpack("v",substr($data,0x16,2)),
|
||||
"Logon/Logoff:Logoff;".unpack("v",substr($data,0x18,2)),
|
||||
"Logon/Logoff:Account Lockout;".unpack("v",substr($data,0x1a,2)),
|
||||
"Logon/Logoff:IPsec Main Mode;".unpack("v",substr($data,0x1c,2)),
|
||||
"Logon/Logoff:Special Logon;".unpack("v",substr($data,0x1e,2)),
|
||||
"Logon/Logoff:IPsec Quick Mode;".unpack("v",substr($data,0x20,2)),
|
||||
"Logon/Logoff:IPsec Extended Mode;".unpack("v",substr($data,0x22,2)),
|
||||
"Logon/Logoff:Other Logon/Logoff Events;".unpack("v",substr($data,0x24,2)),
|
||||
"Logon/Logoff:Network Policy Server;".unpack("v",substr($data,0x26,2)),
|
||||
"Logon/Logoff:User/Device Claims;".unpack("v",substr($data,0x28,2)),
|
||||
"Logon/Logoff:Group Membership;".unpack("v",substr($data,0x2a,2)),
|
||||
"Object Access:File System;".unpack("v",substr($data,0x2c,2)),
|
||||
"Object Access:Registry;".unpack("v",substr($data,0x2e,2)),
|
||||
"Object Access:Kernel Object;".unpack("v",substr($data,0x30,2)),
|
||||
"Object Access:SAM;".unpack("v",substr($data,0x32,2)),
|
||||
"Object Access:Other Object Access Events;".unpack("v",substr($data,0x34,2)),
|
||||
"Object Access:Certification Services;".unpack("v",substr($data,0x36,2)),
|
||||
"Object Access:Application Generated;".unpack("v",substr($data,0x38,2)),
|
||||
"Object Access:Handle Manipulation;".unpack("v",substr($data,0x3a,2)),
|
||||
"Object Access:File Share;".unpack("v",substr($data,0x3c,2)),
|
||||
"Object Access:Filtering Platform Packet Drop;".unpack("v",substr($data,0x3e,2)),
|
||||
"Object Access:Filtering Platform Connection;".unpack("v",substr($data,0x40,2)),
|
||||
"Object Access:Detailed File Share;".unpack("v",substr($data,0x42,2)),
|
||||
"Object Access:Removable Storage;".unpack("v",substr($data,0x44,2)),
|
||||
"Object Access:Central Policy Staging;".unpack("v",substr($data,0x46,2)),
|
||||
"Privilege Use:Sensitive Privilege Use;".unpack("v",substr($data,0x48,2)),
|
||||
"Privilege Use:Non Sensitive Privilege Use;".unpack("v",substr($data,0x4a,2)),
|
||||
"Privilege Use:Other Privilege Use Events;".unpack("v",substr($data,0x4c,2)),
|
||||
"Detailed Tracking:Process Creation;".unpack("v",substr($data,0x4e,2)),
|
||||
"Detailed Tracking:Process Termination;".unpack("v",substr($data,0x50,2)),
|
||||
"Detailed Tracking:DPAPI Activity;".unpack("v",substr($data,0x52,2)),
|
||||
"Detailed Tracking:RPC Events;".unpack("v",substr($data,0x54,2)),
|
||||
"Detailed Tracking:Plug and Play Events;".unpack("v",substr($data,0x56,2)),
|
||||
"Detailed Tracking:Token Right Adjusted Events;".unpack("v",substr($data,0x58,2)),
|
||||
"Policy Change:Audit Policy Change;".unpack("v",substr($data,0x5a,2)),
|
||||
"Policy Change:Authentication Policy Change;".unpack("v",substr($data,0x5c,2)),
|
||||
"Policy Change:Authorization Policy Change;".unpack("v",substr($data,0x5e,2)),
|
||||
"Policy Change:MPSSVC Rule-Level Policy Change;".unpack("v",substr($data,0x60,2)),
|
||||
"Policy Change:Filtering Platform Policy Change;".unpack("v",substr($data,0x62,2)),
|
||||
"Policy Change:Other Policy Change Events;".unpack("v",substr($data,0x64,2)),
|
||||
"Account Management:User Account Management;".unpack("v",substr($data,0x66,2)),
|
||||
"Account Management:Computer Account Management;".unpack("v",substr($data,0x68,2)),
|
||||
"Account Management:Security Group Management;".unpack("v",substr($data,0x6a,2)),
|
||||
"Account Management:Distribution Group Management;".unpack("v",substr($data,0x6c,2)),
|
||||
"Account Management:Application Group Management;".unpack("v",substr($data,0x6e,2)),
|
||||
"Account Management:Other Account Management Events;".unpack("v",substr($data,0x70,2)),
|
||||
"DS Access:Directory Service Access;".unpack("v",substr($data,0x72,2)),
|
||||
"DS Access:Directory Service Changes;".unpack("v",substr($data,0x74,2)),
|
||||
"DS Access:Directory Service Replication;".unpack("v",substr($data,0x76,2)),
|
||||
"DS Access:Detailed Directory Service Replication;".unpack("v",substr($data,0x78,2)),
|
||||
"Account Logon:Credential Validation;".unpack("v",substr($data,0x7a,2)),
|
||||
"Account Logon:Kerberos Service Ticket Operations;".unpack("v",substr($data,0x7c,2)),
|
||||
"Account Logon:Other Account Logon Events;".unpack("v",substr($data,0x73,2)),
|
||||
"Account Logon:Kerberos Authentication Service;".unpack("v",substr($data,0x80,2)));
|
||||
# The rest of the data is apparently footer
|
||||
return @win;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# printData()
|
||||
# subroutine used primarily for debugging; takes an arbitrary
|
||||
|
36
thirdparty/rr-full/plugins/bthport.pl
vendored
36
thirdparty/rr-full/plugins/bthport.pl
vendored
@ -5,12 +5,13 @@
|
||||
# other locations)
|
||||
#
|
||||
# Change history
|
||||
# 20130115 - created
|
||||
# 20180705 - updated to support Win10, per data provided by Micah Jones
|
||||
# 20170129 - added support for http://www.hexacorn.com/blog/2017/01/29/beyond-good-ol-run-key-part-59/
|
||||
# 20130115 - created
|
||||
#
|
||||
# Category:
|
||||
#
|
||||
# copyright 2017 Quantum Analytics Research, LLC
|
||||
# copyright 2018 Quantum Analytics Research, LLC
|
||||
# Author: H. Carvey, keydet89@yahoo.com
|
||||
#-----------------------------------------------------------
|
||||
package bthport;
|
||||
@ -21,7 +22,7 @@ my %config = (hive => "System",
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
osmask => 22,
|
||||
version => 20170129);
|
||||
version => 20180705);
|
||||
|
||||
sub getConfig{return %config}
|
||||
sub getShortDescr {
|
||||
@ -67,22 +68,21 @@ sub pluginmain {
|
||||
# Note: Need to get VID and PID values for translation and mapping
|
||||
my $devname;
|
||||
eval {
|
||||
# May need to work on parsing the binary "Name" value data into an actual name...
|
||||
my @str1 = split(//,unpack("H*",$s->get_value("Name")->get_data()));
|
||||
my @s3;
|
||||
my $str;
|
||||
foreach my $i (0..((scalar(@str1)/2) - 1)) {
|
||||
$s3[$i] = $str1[$i * 2].$str1[($i * 2) + 1];
|
||||
if (hex($s3[$i]) > 0x1f && hex($s3[$i]) < 0x7f) {
|
||||
$str .= chr(hex($s3[$i]));
|
||||
}
|
||||
else {
|
||||
$str .= " ";
|
||||
}
|
||||
}
|
||||
::rptMsg("Device Name: ".$str);
|
||||
my $n = $s->get_value("Name")->get_data();
|
||||
::rptMsg("Name : ".$n);
|
||||
};
|
||||
|
||||
eval {
|
||||
my ($t0,$t1) = unpack("VV",$s->get_value("LastSeen")->get_data());
|
||||
::rptMsg("LastSeen : ".gmtime(::getTime($t0,$t1))." Z");
|
||||
};
|
||||
|
||||
eval {
|
||||
my ($t0,$t1) = unpack("VV",$s->get_value("LastConnected")->get_data());
|
||||
::rptMsg("LastConnected : ".gmtime(::getTime($t0,$t1))." Z");
|
||||
};
|
||||
|
||||
::rptMsg("");
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -92,7 +92,7 @@ sub pluginmain {
|
||||
else {
|
||||
::rptMsg($cn_path." not found.");
|
||||
}
|
||||
|
||||
::rptMsg("");
|
||||
my $rs_path = $ccs."\\services\\BTHPORT\\Parameters\\Radio Support";
|
||||
my $rs;
|
||||
if ($rs = $root_key->get_subkey($rs_path)) {
|
||||
|
104
thirdparty/rr-full/plugins/clsid.pl
vendored
104
thirdparty/rr-full/plugins/clsid.pl
vendored
@ -4,13 +4,19 @@
|
||||
# Can take considerable time to run; recommend running it via rip.exe
|
||||
#
|
||||
# History
|
||||
# 20180823 - minor code fix
|
||||
# 20180819 - updated to incorporate check for "TreatAs" value; code rewrite
|
||||
# 20180319 - fixed minor code issue
|
||||
# 20180117 - updated based on input from Jean, jean.crush@hotmail.fr
|
||||
# 20130603 - added alert functionality
|
||||
# 20100227 - created
|
||||
#
|
||||
# References
|
||||
# http://msdn.microsoft.com/en-us/library/ms724475%28VS.85%29.aspx
|
||||
# https://docs.microsoft.com/en-us/windows/desktop/com/treatas
|
||||
#
|
||||
# copyright 2010, Quantum Analytics Research, LLC
|
||||
# #copyright 2010, Quantum Analytics Research, LLC
|
||||
# copyright 2018, Quantum Analytics Research, LLC
|
||||
#-----------------------------------------------------------
|
||||
package clsid;
|
||||
use strict;
|
||||
@ -20,7 +26,7 @@ my %config = (hive => "Software",
|
||||
hasShortDescr => 1,
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
version => 20130603);
|
||||
version => 20180823);
|
||||
|
||||
sub getConfig{return %config}
|
||||
|
||||
@ -40,77 +46,55 @@ sub pluginmain {
|
||||
my %clsid;
|
||||
::logMsg("Launching clsid v.".$VERSION);
|
||||
::rptMsg("clsid v.".$VERSION); # banner
|
||||
::rptMsg("(".$config{hive}.") ".getShortDescr()."\n"); # banner
|
||||
::rptMsg("(".$config{hive}.") ".getShortDescr()."\n"); # banner
|
||||
my $reg = Parse::Win32Registry->new($hive);
|
||||
my $root_key = $reg->get_root_key;
|
||||
|
||||
my $key_path = "Classes\\CLSID";
|
||||
my $key;
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
::rptMsg($key_path);
|
||||
# my $key_path = "Classes\\CLSID";
|
||||
my @paths = ("Classes\\CLSID","Classes\\Wow6432Node\\CLSID");
|
||||
foreach my $key_path (@paths) {
|
||||
my $key;
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
::rptMsg($key_path);
|
||||
# ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
|
||||
::rptMsg("");
|
||||
::rptMsg("");
|
||||
# First step will be to get a list of all of the file extensions
|
||||
my %ext;
|
||||
my @sk = $key->get_list_of_subkeys();
|
||||
if (scalar(@sk) > 0) {
|
||||
foreach my $s (@sk) {
|
||||
my %ext;
|
||||
my @sk = $key->get_list_of_subkeys();
|
||||
if (scalar(@sk) > 0) {
|
||||
foreach my $s (@sk) {
|
||||
|
||||
my $name = $s->get_name();
|
||||
eval {
|
||||
my $n = $s->get_value("")->get_data();
|
||||
$name .= " ".$n unless ($n eq "");
|
||||
};
|
||||
my $name = $s->get_name();
|
||||
my $n;
|
||||
eval {
|
||||
$n = $s->get_value("")->get_data();
|
||||
$name .= " ".$n unless ($n eq "");
|
||||
};
|
||||
|
||||
::rptMsg($name);
|
||||
::rptMsg(" LastWrite: ".gmtime($s->get_timestamp())." Z");
|
||||
|
||||
eval {
|
||||
my $proc = $s->get_subkey("InprocServer32")->get_value("")->get_data();
|
||||
::rptMsg(" InprocServer32: ".$proc);
|
||||
};
|
||||
|
||||
eval {
|
||||
my $path = $s->get_subkey("InprocServer32")->get_value("")->get_data();
|
||||
alertCheckPath($path);
|
||||
alertCheckADS($path);
|
||||
|
||||
};
|
||||
|
||||
push(@{$clsid{$s->get_timestamp()}},$name);
|
||||
}
|
||||
|
||||
foreach my $t (reverse sort {$a <=> $b} keys %clsid) {
|
||||
::rptMsg(gmtime($t)." Z");
|
||||
foreach my $item (@{$clsid{$t}}) {
|
||||
::rptMsg(" ".$item);
|
||||
eval {
|
||||
my $treat = $s->get_subkey("TreatAs")->get_value("")->get_data();
|
||||
::rptMsg(" TreatAs: ".$treat);
|
||||
};
|
||||
::rptMsg("");
|
||||
}
|
||||
}
|
||||
else {
|
||||
::rptMsg($key_path." has no subkeys.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
::rptMsg($key_path." has no subkeys.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
::rptMsg($key_path." not found.");
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# alertCheckPath()
|
||||
#-----------------------------------------------------------
|
||||
sub alertCheckPath {
|
||||
my $path = shift;
|
||||
$path = lc($path);
|
||||
my @alerts = ("recycle","globalroot","temp","system volume information","appdata",
|
||||
"application data");
|
||||
|
||||
foreach my $a (@alerts) {
|
||||
if (grep(/$a/,$path)) {
|
||||
::alertMsg("ALERT: clsid: ".$a." found in path: ".$path);
|
||||
::rptMsg($key_path." not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# alertCheckADS()
|
||||
#-----------------------------------------------------------
|
||||
sub alertCheckADS {
|
||||
my $path = shift;
|
||||
my @list = split(/\\/,$path);
|
||||
my $last = $list[scalar(@list) - 1];
|
||||
::alertMsg("ALERT: clsid: Poss. ADS found in path: ".$path) if grep(/:/,$last);
|
||||
}
|
||||
|
||||
1;
|
10
thirdparty/rr-full/plugins/cmdproc.pl
vendored
10
thirdparty/rr-full/plugins/cmdproc.pl
vendored
@ -3,11 +3,13 @@
|
||||
# Checks key for files to autostart from cmd.exe
|
||||
#
|
||||
# Change History
|
||||
# 20190223 - added reference
|
||||
# 20130425 - added alertMsg() functionality
|
||||
# 20130115 - created
|
||||
#
|
||||
# References:
|
||||
#
|
||||
# https://unit42.paloaltonetworks.com/new-babyshark-malware-targets-u-s-national-security-think-tanks/
|
||||
#
|
||||
# Category: autostart,malware,programexecution
|
||||
#
|
||||
# copyright 2013 Quantum Analytics Research,
|
||||
@ -21,12 +23,12 @@ my %config = (hive => "NTUSER\.DAT",
|
||||
hasShortDescr => 1,
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
version => 20130425);
|
||||
version => 20190223);
|
||||
|
||||
sub getConfig{return %config}
|
||||
|
||||
sub getShortDescr {
|
||||
return "Autostart - get Command Processor\\AutoRun value from NTUSER.DAT hive";
|
||||
return "Autostart - get Command Processor\\AutoRun value from NTUSER\.DAT hive";
|
||||
}
|
||||
sub getDescr{}
|
||||
sub getRefs {}
|
||||
@ -64,4 +66,4 @@ sub pluginmain {
|
||||
::rptMsg($key_path." not found.");
|
||||
}
|
||||
}
|
||||
1;
|
||||
1;
|
180
thirdparty/rr-full/plugins/comdlg32.pl
vendored
180
thirdparty/rr-full/plugins/comdlg32.pl
vendored
@ -3,6 +3,8 @@
|
||||
# Plugin for Registry Ripper
|
||||
#
|
||||
# Change history
|
||||
# 20180702 - update to parseGUID function
|
||||
# 20180627 - updated to address Win10, per input from Geoff Rempel
|
||||
# 20121005 - updated to address shell item type 0x3A
|
||||
# 20121005 - updated to parse shell item ID lists
|
||||
# 20100409 - updated to include Vista and above
|
||||
@ -14,7 +16,7 @@
|
||||
# Win2000 - http://support.microsoft.com/kb/319958
|
||||
# XP - http://support.microsoft.com/kb/322948/EN-US/
|
||||
#
|
||||
# copyright 2012 Quantum Analytics Research, LLC
|
||||
# copyright 2018 Quantum Analytics Research, LLC
|
||||
# Author: H. Carvey, keydet89@yahoo.com
|
||||
#-----------------------------------------------------------
|
||||
package comdlg32;
|
||||
@ -26,7 +28,7 @@ my %config = (hive => "NTUSER\.DAT",
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
osmask => 22,
|
||||
version => 20121008);
|
||||
version => 20180702);
|
||||
|
||||
sub getConfig{return %config}
|
||||
sub getShortDescr {
|
||||
@ -39,6 +41,50 @@ sub getVersion {return $config{version};}
|
||||
|
||||
my $VERSION = getVersion();
|
||||
|
||||
my %folder_types = ("{724ef170-a42d-4fef-9f26-b60e846fba4f}" => "Administrative Tools",
|
||||
"{d0384e7d-bac3-4797-8f14-cba229b392b5}" => "Common Administrative Tools",
|
||||
"{de974d24-d9c6-4d3e-bf91-f4455120b917}" => "Common Files",
|
||||
"{c1bae2d0-10df-4334-bedd-7aa20b227a9d}" => "Common OEM Links",
|
||||
"{5399e694-6ce5-4d6c-8fce-1d8870fdcba0}" => "Control Panel",
|
||||
"{1ac14e77-02e7-4e5d-b744-2eb1ae5198b7}" => "CSIDL_SYSTEM",
|
||||
"{b4bfcc3a-db2c-424c-b029-7fe99a87c641}" => "Desktop",
|
||||
"{7b0db17d-9cd2-4a93-9733-46cc89022e7c}" => "Documents Library",
|
||||
"{a8cdff1c-4878-43be-b5fd-f8091c1c60d0}" => "Documents",
|
||||
"{fdd39ad0-238f-46af-adb4-6c85480369c7}" => "Documents",
|
||||
"{374de290-123f-4565-9164-39c4925e467b}" => "Downloads",
|
||||
"{de61d971-5ebc-4f02-a3a9-6c82895e5c04}" => "Get Programs",
|
||||
"{a305ce99-f527-492b-8b1a-7e76fa98d6e4}" => "Installed Updates",
|
||||
"{871c5380-42a0-1069-a2ea-08002b30309d}" => "Internet Explorer (Homepage)",
|
||||
"{031e4825-7b94-4dc3-b131-e946b44c8dd5}" => "Libraries",
|
||||
"{2112ab0a-c86a-4ffe-a368-0de96e47012e}" => "Music",
|
||||
"{1cf1260c-4dd0-4ebb-811f-33c572699fde}" => "Music",
|
||||
"{4bd8d571-6d19-48d3-be97-422220080e43}" => "Music",
|
||||
"{20d04fe0-3aea-1069-a2d8-08002b30309d}" => "My Computer",
|
||||
"{450d8fba-ad25-11d0-98a8-0800361b1103}" => "My Documents",
|
||||
"{ed228fdf-9ea8-4870-83b1-96b02cfe0d52}" => "My Games",
|
||||
"{208d2c60-3aea-1069-a2d7-08002b30309d}" => "My Network Places",
|
||||
"{f02c1a0d-be21-4350-88b0-7367fc96ef3c}" => "Network",
|
||||
"{3add1653-eb32-4cb0-bbd7-dfa0abb5acca}" => "Pictures",
|
||||
"{33e28130-4e1e-4676-835a-98395c3bc3bb}" => "Pictures",
|
||||
"{a990ae9f-a03b-4e80-94bc-9912d7504104}" => "Pictures",
|
||||
"{7c5a40ef-a0fb-4bfc-874a-c0f2e0b9fa8e}" => "Program Files (x86)",
|
||||
"{905e63b6-c1bf-494e-b29c-65b732d3d21a}" => "Program Files",
|
||||
"{df7266ac-9274-4867-8d55-3bd661de872d}" => "Programs and Features",
|
||||
"{3214fab5-9757-4298-bb61-92a9deaa44ff}" => "Public Music",
|
||||
"{b6ebfb86-6907-413c-9af7-4fc2abf07cc5}" => "Public Pictures",
|
||||
"{2400183a-6185-49fb-a2d8-4a392a602ba3}" => "Public Videos",
|
||||
"{4336a54d-38b-4685-ab02-99bb52d3fb8b}" => "Public",
|
||||
"{491e922f-5643-4af4-a7eb-4e7a138d8174}" => "Public",
|
||||
"{dfdf76a2-c82a-4d63-906a-5644ac457385}" => "Public",
|
||||
"{645ff040-5081-101b-9f08-00aa002f954e}" => "Recycle Bin",
|
||||
"{d65231b0-b2f1-4857-a4ce-a8e7c6ea7d27}" => "System32 (x86)",
|
||||
"{9e52ab10-f80d-49df-acb8-4330f5687855}" => "Temporary Burn Folder",
|
||||
"{f3ce0f7c-4901-4acc-8648-d5d44b04ef8f}" => "Users Files",
|
||||
"{59031a47-3f72-44a7-89c5-5595fe6b30ee}" => "Users",
|
||||
"{a0953c92-50dc-43bf-be83-3742fed03c9c}" => "Videos",
|
||||
"{b5947d7f-b489-4fde-9e77-23780cc610d1}" => "Virtual Machines",
|
||||
"{f38bf404-1d43-42f2-9305-67de0b28fc23}" => "Windows");
|
||||
|
||||
sub pluginmain {
|
||||
my $class = shift;
|
||||
my $ntuser = shift;
|
||||
@ -128,9 +174,9 @@ sub parseLastVisitedMRU {
|
||||
@mrulist = split(//,$lvmru{MRUList});
|
||||
delete($lvmru{MRUList});
|
||||
foreach my $m (@mrulist) {
|
||||
my ($file,$dir) = split(/\x00\x00/,$lvmru{$m},2);
|
||||
$file =~ s/\x00//g;
|
||||
$dir =~ s/\x00//g;
|
||||
my ($file,$dir) = split(/\00\00/,$lvmru{$m},2);
|
||||
$file =~ s/\00//g;
|
||||
$dir =~ s/\00//g;
|
||||
::rptMsg(" ".$m." -> EXE: ".$file);
|
||||
::rptMsg(" -> Last Dir: ".$dir);
|
||||
}
|
||||
@ -213,8 +259,8 @@ sub parseCIDSizeMRU {
|
||||
delete $mru{0xffffffff};
|
||||
foreach my $m (sort {$a <=> $b} keys %mru) {
|
||||
# my $file = parseStr($mru{$m});
|
||||
my $file = (split(/\x00\x00/,$mru{$m},2))[0];
|
||||
$file =~ s/\x00//g;
|
||||
my $file = (split(/\00\00/,$mru{$m},2))[0];
|
||||
$file =~ s/\00//g;
|
||||
::rptMsg(" ".$file);
|
||||
}
|
||||
}
|
||||
@ -251,18 +297,18 @@ sub parseFirstFolder {
|
||||
delete $mru{0xffffffff};
|
||||
foreach my $m (sort {$a <=> $b} keys %mru) {
|
||||
# my $file = parseStr($mru{$m});
|
||||
my @files = split(/\x00\x00/,$mru{$m});
|
||||
my @files = split(/\00\00/,$mru{$m});
|
||||
if (scalar(@files) == 0) {
|
||||
::rptMsg(" No files listed.");
|
||||
}
|
||||
elsif (scalar(@files) == 1) {
|
||||
$files[0] =~ s/\x00//g;
|
||||
$files[0] =~ s/\00//g;
|
||||
::rptMsg(" ".$files[0]);
|
||||
}
|
||||
elsif (scalar(@files) > 1) {
|
||||
my @files2;
|
||||
foreach my $file (@files) {
|
||||
$file =~ s/\x00//g;
|
||||
$file =~ s/\00//g;
|
||||
push(@files2,$file);
|
||||
}
|
||||
::rptMsg(" ".join(' ',@files2));
|
||||
@ -305,9 +351,9 @@ sub parseLastVisitedPidlMRU {
|
||||
delete $mru{0xffffffff};
|
||||
|
||||
foreach my $m (sort {$a <=> $b} keys %mru) {
|
||||
my ($file,$shell) = split(/\x00\x00/,$mru{$m},2);
|
||||
$file =~ s/\x00//g;
|
||||
$shell =~ s/^\x00//;
|
||||
my ($file,$shell) = split(/\00\00/,$mru{$m},2);
|
||||
$file =~ s/\00//g;
|
||||
$shell =~ s/^\00//;
|
||||
my $str = parseShellItem($shell);
|
||||
::rptMsg(" ".$file." - ".$str);
|
||||
}
|
||||
@ -386,7 +432,6 @@ sub parseShellItem {
|
||||
while ($tag) {
|
||||
my %item = ();
|
||||
my $sz = unpack("v",substr($data,$cnt,2));
|
||||
return %str unless (defined $sz);
|
||||
$tag = 0 if (($sz == 0) || ($cnt + $sz > $len));
|
||||
|
||||
my $dat = substr($data,$cnt,$sz);
|
||||
@ -398,6 +443,11 @@ sub parseShellItem {
|
||||
%item = parseSystemFolderEntry($dat);
|
||||
$str .= "\\".$item{name};
|
||||
}
|
||||
elsif ($type == 0x2E) {
|
||||
# probe($dat);
|
||||
%item = parseDeviceEntry($dat);
|
||||
$str .= "\\".$item{name};
|
||||
}
|
||||
elsif ($type == 0x2F) {
|
||||
# Volume (Drive Letter)
|
||||
%item = parseDriveEntry($dat);
|
||||
@ -476,7 +526,17 @@ sub parseGUID {
|
||||
my $d3 = unpack("v",substr($data,6,2));
|
||||
my $d4 = unpack("H*",substr($data,8,2));
|
||||
my $d5 = unpack("H*",substr($data,10,6));
|
||||
return sprintf "{%08x-%x-%x-$d4-$d5}",$d1,$d2,$d3;
|
||||
# ---- Added 20180627, updated 20180702
|
||||
my $guid = sprintf "{%08x-%04x-%04x-$d4-$d5}",$d1,$d2,$d3;
|
||||
|
||||
if (exists $folder_types{$guid}) {
|
||||
return "CLSID_".$folder_types{$guid};
|
||||
}
|
||||
else {
|
||||
return $guid;
|
||||
}
|
||||
|
||||
# return sprintf "{%08x-%x-%x-$d4-$d5}",$d1,$d2,$d3;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
@ -498,7 +558,7 @@ sub parseNetworkEntry {
|
||||
my %item = ();
|
||||
$item{type} = unpack("C",substr($data,2,1));
|
||||
|
||||
my @n = split(/\x00/,substr($data,4,length($data) - 4));
|
||||
my @n = split(/\00/,substr($data,4,length($data) - 4));
|
||||
$item{name} = $n[0];
|
||||
$item{name} =~ s/^\W//;
|
||||
return %item;
|
||||
@ -538,15 +598,14 @@ sub parseFolderEntry {
|
||||
($item{mtime_str},$item{mtime}) = convertDOSDate($m[0],$m[1]);
|
||||
|
||||
# Need to read in short name; nul-term ASCII
|
||||
# $item{shortname} = (split(/\x00/,substr($data,12,length($data) - 12),2))[0];
|
||||
# $item{shortname} = (split(/\00/,substr($data,12,length($data) - 12),2))[0];
|
||||
$ofs_shortname = $ofs_mdate + 6;
|
||||
my $tag = 1;
|
||||
my $cnt = 0;
|
||||
my $str = "";
|
||||
while($tag) {
|
||||
my $s = substr($data,$ofs_shortname + $cnt,1);
|
||||
return %item unless (defined $s);
|
||||
if ($s =~ m/\x00/ && ((($cnt + 1) % 2) == 0)) {
|
||||
if ($s =~ m/\00/ && ((($cnt + 1) % 2) == 0)) {
|
||||
$tag = 0;
|
||||
}
|
||||
else {
|
||||
@ -554,19 +613,17 @@ sub parseFolderEntry {
|
||||
$cnt++;
|
||||
}
|
||||
}
|
||||
# $str =~ s/\x00//g;
|
||||
# $str =~ s/\00//g;
|
||||
my $shortname = $str;
|
||||
my $ofs = $ofs_shortname + $cnt + 1;
|
||||
# Read progressively, 1 byte at a time, looking for 0xbeef
|
||||
$tag = 1;
|
||||
$cnt = 0;
|
||||
my $tag = 1;
|
||||
my $cnt = 0;
|
||||
while ($tag) {
|
||||
my $s = substr($data,$ofs + $cnt,2);
|
||||
return %item unless (defined $s);
|
||||
if (unpack("v",$s) == 0xbeef) {
|
||||
if (unpack("v",substr($data,$ofs + $cnt,2)) == 0xbeef) {
|
||||
$tag = 0;
|
||||
}
|
||||
else {
|
||||
else {
|
||||
$cnt++;
|
||||
}
|
||||
}
|
||||
@ -577,10 +634,10 @@ sub parseFolderEntry {
|
||||
|
||||
$ofs = $ofs + $cnt + 2;
|
||||
|
||||
@m = unpack("vv",substr($data,$ofs,4));
|
||||
my @m = unpack("vv",substr($data,$ofs,4));
|
||||
($item{ctime_str},$item{ctime}) = convertDOSDate($m[0],$m[1]);
|
||||
$ofs += 4;
|
||||
@m = unpack("vv",substr($data,$ofs,4));
|
||||
my @m = unpack("vv",substr($data,$ofs,4));
|
||||
($item{atime_str},$item{atime}) = convertDOSDate($m[0],$m[1]);
|
||||
$ofs += 4;
|
||||
|
||||
@ -594,15 +651,19 @@ sub parseFolderEntry {
|
||||
elsif ($item{extver} == 0x08) {
|
||||
$jmp = 26;
|
||||
}
|
||||
# Updated for Windows 10
|
||||
elsif ($item{extver} == 0x09) {
|
||||
$jmp = 30;
|
||||
}
|
||||
else {}
|
||||
|
||||
$ofs += $jmp;
|
||||
# ::rptMsg(sprintf " Offset: 0x%x",$ofs);
|
||||
|
||||
$str = substr($data,$ofs,length($data) - $ofs);
|
||||
my $str = substr($data,$ofs,length($data) - $ofs);
|
||||
|
||||
my $longname = (split(/\x00\x00/,$str,2))[0];
|
||||
$longname =~ s/\x00//g;
|
||||
my $longname = (split(/\00\00/,$str,2))[0];
|
||||
$longname =~ s/\00//g;
|
||||
|
||||
if ($longname ne "") {
|
||||
$item{name} = $longname;
|
||||
@ -613,6 +674,61 @@ sub parseFolderEntry {
|
||||
return %item;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
#
|
||||
#-----------------------------------------------------------
|
||||
sub parseDeviceEntry {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
|
||||
my $ofs = unpack("v",substr($data,4,2));
|
||||
my $tag = unpack("V",substr($data,6,4));
|
||||
|
||||
#-----------------------------------------------------
|
||||
# DEBUG
|
||||
# ::rptMsg("parseDeviceEntry, tag = ".$tag);
|
||||
#-----------------------------------------------------
|
||||
if ($tag == 0) {
|
||||
my $guid1 = parseGUID(substr($data,$ofs + 6,16));
|
||||
my $guid2 = parseGUID(substr($data,$ofs + 6 + 16,16));
|
||||
$item{name} = $guid1."\\".$guid2
|
||||
}
|
||||
elsif ($tag == 2) {
|
||||
$item{name} = substr($data,0x0a,($ofs + 6) - 0x0a);
|
||||
$item{name} =~ s/\00//g;
|
||||
}
|
||||
else {
|
||||
my $ver = unpack("C",substr($data,9,1));
|
||||
my $idx = unpack("C",substr($data,3,1));
|
||||
|
||||
if ($idx == 0x80) {
|
||||
$item{name} = parseGUID(substr($data,4,16));
|
||||
}
|
||||
# Version 3 = XP
|
||||
elsif ($ver == 3) {
|
||||
my $guid1 = parseGUID(substr($data,$ofs + 6,16));
|
||||
my $guid2 = parseGUID(substr($data,$ofs + 6 + 16,16));
|
||||
$item{name} = $guid1."\\".$guid2
|
||||
|
||||
}
|
||||
# Version 8 = Win7
|
||||
elsif ($ver == 8) {
|
||||
my $userlen = unpack("V",substr($data,30,4));
|
||||
my $devlen = unpack("V",substr($data,34,4));
|
||||
my $user = substr($data,0x28,$userlen * 2);
|
||||
$user =~ s/\00//g;
|
||||
my $dev = substr($data,0x28 + ($userlen * 2),$devlen * 2);
|
||||
$dev =~ s/\00//g;
|
||||
$item{name} = $user;
|
||||
}
|
||||
# Version unknown
|
||||
else {
|
||||
$item{name} = "Device Entry - Unknown Version";
|
||||
}
|
||||
}
|
||||
return %item;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# convertDOSDate()
|
||||
# subroutine to convert 4 bytes of binary data into a human-
|
||||
@ -701,4 +817,4 @@ sub printData {
|
||||
return @display;
|
||||
}
|
||||
|
||||
1;
|
||||
1;
|
127
thirdparty/rr-full/plugins/del.pl
vendored
127
thirdparty/rr-full/plugins/del.pl
vendored
@ -4,13 +4,15 @@
|
||||
#
|
||||
#
|
||||
# Change history
|
||||
# 20190506 - updated
|
||||
# 20140807 - created
|
||||
#
|
||||
# References:
|
||||
#
|
||||
# https://metacpan.org/pod/Parse::Win32Registry
|
||||
# https://github.com/msuhanov/regf/blob/master/Windows%20registry%20file%20format%20specification.md
|
||||
#
|
||||
#
|
||||
# copyright 2014 QAR, LLC
|
||||
# copyright 2019 QAR, LLC
|
||||
# Author: H. Carvey
|
||||
#-----------------------------------------------------------
|
||||
package del;
|
||||
@ -22,7 +24,7 @@ my %config = (hive => "All",
|
||||
hasRefs => 0,
|
||||
osmask => 22,
|
||||
category => "deleted",
|
||||
version => 20140807);
|
||||
version => 20190506);
|
||||
|
||||
sub getConfig{return %config}
|
||||
sub getShortDescr {
|
||||
@ -35,6 +37,19 @@ sub getVersion {return $config{version};}
|
||||
|
||||
my $VERSION = getVersion();
|
||||
|
||||
my %data_types = (0 => "REG_NONE",
|
||||
1 => "REG_SZ",
|
||||
2 => "REG_EXPAND_SZ",
|
||||
3 => "REG_BINARY",
|
||||
4 => "REG_DWORD",
|
||||
5 => "REG_DWORD_BIG_ENDIAN",
|
||||
6 => "REG_LINK",
|
||||
7 => "REG_MULTI_SZ",
|
||||
8 => "REG_RESOURCE_LIST",
|
||||
9 => "REG_FULL_RESOURCE_DESCRIPTOR",
|
||||
10 => "REG_RESOURCE_REQUIREMENTS_LIST",
|
||||
11 => "REG_QWORD");
|
||||
|
||||
my %regkeys;
|
||||
|
||||
sub pluginmain {
|
||||
@ -48,34 +63,92 @@ sub pluginmain {
|
||||
my $entry_iter = $reg->get_entry_iterator;
|
||||
while (defined(my $entry = $entry_iter->get_next)) {
|
||||
next if $entry->is_allocated;
|
||||
# printf "0x%x ", $entry->get_offset;
|
||||
# print $entry->unparsed()."\n";
|
||||
my $tag = $entry->get_tag();
|
||||
my $str = $entry->as_string();
|
||||
next if ($str eq "(unidentified entry)");
|
||||
|
||||
if ($tag eq "vk") {
|
||||
::rptMsg("Value: ".$str);
|
||||
}
|
||||
elsif ($tag eq "nk") {
|
||||
if ($entry->get_length() > 15) {
|
||||
my ($t0,$t1) = unpack("VV",substr($entry->get_raw_bytes(),8,16));
|
||||
my $lw = ::getTime($t0,$t1);
|
||||
::rptMsg("Key: ".parseDelKeyName($str)." LW: ".gmtime($lw)." Z");
|
||||
|
||||
}
|
||||
}
|
||||
else {}
|
||||
# printf "0x%x ", $entry->get_offset;
|
||||
# print $entry->unparsed()."\n";
|
||||
my $data = $entry->get_raw_bytes();
|
||||
my $len = length($data);
|
||||
next if ($len <= 8);
|
||||
::rptMsg("------------- Deleted Data ------------");
|
||||
# Value node header is 20 bytes, w/o name string
|
||||
# Key node header is 76 bytes, w/o name string
|
||||
if ($len >= 20) {
|
||||
my $cursor = 0;
|
||||
while ($cursor < $len) {
|
||||
if (unpack("v",substr($data,$cursor,2)) == 0x6b76) {
|
||||
# ::rptMsg("Value node found at ".$cursor);
|
||||
parseValueNode($data,$cursor);
|
||||
$cursor += 0x12;
|
||||
}
|
||||
elsif (unpack("v",substr($data,$cursor,2)) == 0x6b6e) {
|
||||
# ::rptMsg("Key node found at ".$cursor);
|
||||
parseKeyNode($data,$cursor);
|
||||
$cursor += 0x4a;
|
||||
}
|
||||
else {
|
||||
$cursor++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
::rptMsg($entry->unparsed());
|
||||
}
|
||||
}
|
||||
|
||||
sub parseDelKeyName {
|
||||
my $str = shift;
|
||||
my $name_str = (split(/\s\[/,$str))[0];
|
||||
my @list = split(/\\/,$name_str);
|
||||
shift(@list);
|
||||
return join('\\',@list);
|
||||
sub parseValueNode {
|
||||
my $data = shift;
|
||||
my $ofs = shift;
|
||||
|
||||
my $name_len = unpack("v",substr($data,$ofs + 0x02,2));
|
||||
my $data_len = unpack("V",substr($data,$ofs + 0x04,4));
|
||||
my $data_ofs = unpack("V",substr($data,$ofs + 0x08,4));
|
||||
my $data_type = unpack("V",substr($data,$ofs + 0x0c,4));
|
||||
my $data_flag = unpack("v",substr($data,$ofs + 0x10,2));
|
||||
|
||||
my $name;
|
||||
if (($ofs + 0x14 + $name_len) <= length($data)) {
|
||||
$name = substr($data,$ofs + 0x14,$name_len);
|
||||
::rptMsg("Value Name: ".$name);
|
||||
::rptMsg(sprintf "Data Length: 0x%x Data Offset: 0x%x Data Type: ".$data_types{$data_type},$data_len,$data_ofs);
|
||||
}
|
||||
}
|
||||
|
||||
sub parseKeyNode {
|
||||
my $data = shift;
|
||||
my $ofs = shift;
|
||||
my $len = length($data);
|
||||
|
||||
if ($len > 75 && $ofs >= 4) {
|
||||
|
||||
my $size = unpack("i",substr($data,$ofs - 4,4));
|
||||
$size = ($size * -1) if ($size < 0);
|
||||
# ::rptMsg("Key node size = ".$size);
|
||||
|
||||
my $type = unpack("v",substr($data,$ofs + 0x02,2));
|
||||
# ::rptMsg(sprintf "Node Type = 0x%x",$type);
|
||||
|
||||
my ($t1,$t2) = unpack("VV",substr($data,$ofs + 0x04,8));
|
||||
my $lw = ::getTime($t1,$t2);
|
||||
# ::rptMsg("Key LastWrite time = ".gmtime($lw)." UTC");
|
||||
|
||||
my $parent_ofs = unpack("V",substr($data,$ofs + 0x10,4));
|
||||
|
||||
my $sk = unpack("V",substr($data,$ofs + 0x14,4));
|
||||
# ::rptMsg("Number of subkeys: ".$sk);
|
||||
|
||||
my $vals = unpack("V",substr($data,$ofs + 0x24,4));
|
||||
# ::rptMsg("Number of values: ".$vals);
|
||||
|
||||
my $len_name = unpack("V",substr($data,$ofs + 0x48,4));
|
||||
# print "Name Length: ".$len_name."\n";
|
||||
|
||||
my $name;
|
||||
if (($ofs + 0x4c + $len_name) <= $len) {
|
||||
$name = substr($data,$ofs + 0x4c,$len_name);
|
||||
::rptMsg("Key name: ".$name);
|
||||
}
|
||||
::rptMsg("Key LastWrite time = ".gmtime($lw)." UTC");
|
||||
::rptMsg(sprintf "Offset to parent: 0x%x",$parent_ofs);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
90
thirdparty/rr-full/plugins/del_tln.pl
vendored
90
thirdparty/rr-full/plugins/del_tln.pl
vendored
@ -4,13 +4,15 @@
|
||||
#
|
||||
#
|
||||
# Change history
|
||||
# 20190506 - updated
|
||||
# 20140807 - created
|
||||
#
|
||||
# References:
|
||||
#
|
||||
# https://metacpan.org/pod/Parse::Win32Registry
|
||||
# https://github.com/msuhanov/regf/blob/master/Windows%20registry%20file%20format%20specification.md
|
||||
#
|
||||
#
|
||||
# copyright 2014 QAR, LLC
|
||||
# copyright 2019 QAR, LLC
|
||||
# Author: H. Carvey
|
||||
#-----------------------------------------------------------
|
||||
package del_tln;
|
||||
@ -22,7 +24,7 @@ my %config = (hive => "All",
|
||||
hasRefs => 0,
|
||||
osmask => 22,
|
||||
category => "deleted",
|
||||
version => 20140807);
|
||||
version => 20190506);
|
||||
|
||||
sub getConfig{return %config}
|
||||
sub getShortDescr {
|
||||
@ -41,38 +43,72 @@ sub pluginmain {
|
||||
my $class = shift;
|
||||
my $file = shift;
|
||||
my $reg = Parse::Win32Registry->new($file);
|
||||
my $root_key = $reg->get_root_key;
|
||||
# ::logMsg("Launching del v.".$VERSION);
|
||||
# ::rptMsg("del v.".$VERSION); # banner
|
||||
::logMsg("Launching del_tln v.".$VERSION);
|
||||
# ::rptMsg("del_tln v.".$VERSION); # banner
|
||||
# ::rptMsg("(".getHive().") ".getShortDescr()."\n"); # banner
|
||||
|
||||
my $entry_iter = $reg->get_entry_iterator;
|
||||
while (defined(my $entry = $entry_iter->get_next)) {
|
||||
next if $entry->is_allocated;
|
||||
# printf "0x%x ", $entry->get_offset;
|
||||
# print $entry->unparsed()."\n";
|
||||
my $tag = $entry->get_tag();
|
||||
my $str = $entry->as_string();
|
||||
next if ($str eq "(unidentified entry)");
|
||||
|
||||
if ($tag eq "nk") {
|
||||
if ($entry->get_length() > 15) {
|
||||
my ($t0,$t1) = unpack("VV",substr($entry->get_raw_bytes(),8,16));
|
||||
my $lw = ::getTime($t0,$t1);
|
||||
::rptMsg($lw."|REG|||[Deleted key]: ".parseDelKeyName($str));
|
||||
}
|
||||
}
|
||||
else {}
|
||||
|
||||
# printf "0x%x ", $entry->get_offset;
|
||||
# print $entry->unparsed()."\n";
|
||||
my $data = $entry->get_raw_bytes();
|
||||
my $len = length($data);
|
||||
next if ($len <= 8);
|
||||
# Key node header is 76 bytes, w/o name string
|
||||
if ($len >= 20) {
|
||||
my $cursor = 0;
|
||||
while ($cursor < $len) {
|
||||
if (unpack("v",substr($data,$cursor,2)) == 0x6b6e) {
|
||||
# ::rptMsg("Key node found at ".$cursor);
|
||||
parseKeyNode($data,$cursor);
|
||||
$cursor += 0x4a;
|
||||
}
|
||||
else {
|
||||
$cursor++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
# ::rptMsg($entry->unparsed());
|
||||
}
|
||||
}
|
||||
|
||||
sub parseDelKeyName {
|
||||
my $str = shift;
|
||||
my $name_str = (split(/\s\[/,$str))[0];
|
||||
my @list = split(/\\/,$name_str);
|
||||
shift(@list);
|
||||
return join('\\',@list);
|
||||
sub parseKeyNode {
|
||||
my $data = shift;
|
||||
my $ofs = shift;
|
||||
my $len = length($data);
|
||||
|
||||
if ($len > 75 && $ofs >= 4) {
|
||||
|
||||
my $size = unpack("i",substr($data,$ofs - 4,4));
|
||||
$size = ($size * -1) if ($size < 0);
|
||||
# ::rptMsg("Key node size = ".$size);
|
||||
|
||||
my $type = unpack("v",substr($data,$ofs + 0x02,2));
|
||||
# ::rptMsg(sprintf "Node Type = 0x%x",$type);
|
||||
|
||||
my ($t1,$t2) = unpack("VV",substr($data,$ofs + 0x04,8));
|
||||
my $lw = ::getTime($t1,$t2);
|
||||
# ::rptMsg("Key LastWrite time = ".gmtime($lw)." UTC");
|
||||
|
||||
my $parent_ofs = unpack("V",substr($data,$ofs + 0x10,4));
|
||||
|
||||
my $sk = unpack("V",substr($data,$ofs + 0x14,4));
|
||||
# ::rptMsg("Number of subkeys: ".$sk);
|
||||
|
||||
my $vals = unpack("V",substr($data,$ofs + 0x24,4));
|
||||
# ::rptMsg("Number of values: ".$vals);
|
||||
|
||||
my $len_name = unpack("V",substr($data,$ofs + 0x48,4));
|
||||
# print "Name Length: ".$len_name."\n";
|
||||
|
||||
my $name;
|
||||
if (($ofs + 0x4c + $len_name) <= $len) {
|
||||
$name = substr($data,$ofs + 0x4c,$len_name);
|
||||
}
|
||||
::rptMsg($lw."|||| Deleted key: ".$name);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
34
thirdparty/rr-full/plugins/disablelastaccess.pl
vendored
34
thirdparty/rr-full/plugins/disablelastaccess.pl
vendored
@ -1,8 +1,15 @@
|
||||
#-----------------------------------------------------------
|
||||
# disablelastaccess.pl
|
||||
#
|
||||
# History:
|
||||
# 20181207 - updated for Win10 v.1803 (Maxim, David Cohen)
|
||||
# 20090118 -
|
||||
#
|
||||
# References:
|
||||
# http://support.microsoft.com/kb/555041
|
||||
# https://twitter.com/errno_fail/status/1070838120545955840
|
||||
# https://dfir.ru/2018/12/08/the-last-access-updates-are-almost-back/
|
||||
# https://www.hecfblog.com/2018/12/daily-blog-557-changes-in.html
|
||||
# http://support.microsoft.com/kb/555041
|
||||
# http://support.microsoft.com/kb/894372
|
||||
#
|
||||
# copyright 2008 H. Carvey, keydet89@yahoo.com
|
||||
@ -15,10 +22,15 @@ my %config = (hive => "System",
|
||||
hasShortDescr => 1,
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
version => 20090118);
|
||||
version => 20181207);
|
||||
|
||||
sub getConfig{return %config}
|
||||
|
||||
my %dla = (0x80000000 => "(User Managed, Updates Enabled)",
|
||||
0x80000001 => "(User Managed, Updates Disabled)",
|
||||
0x80000002 => "(System Managed, Updates Enabled)",
|
||||
0x80000003 => "(System Managed, Updates Disabled)");
|
||||
|
||||
sub getShortDescr {
|
||||
return "Get NTFSDisableLastAccessUpdate value";
|
||||
}
|
||||
@ -48,7 +60,8 @@ sub pluginmain {
|
||||
$ccs = "ControlSet00".$current;
|
||||
}
|
||||
|
||||
$key_path = $ccs."\\Control\\FileSystem";
|
||||
my $key_path = $ccs."\\Control\\FileSystem";
|
||||
my $key;
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
::rptMsg("NtfsDisableLastAccessUpdate");
|
||||
::rptMsg($key_path);
|
||||
@ -57,8 +70,19 @@ sub pluginmain {
|
||||
if (scalar(@vals) > 0) {
|
||||
foreach my $v (@vals) {
|
||||
if ($v->get_name() eq "NtfsDisableLastAccessUpdate") {
|
||||
::rptMsg("NtfsDisableLastAccessUpdate = ".$v->get_data());
|
||||
my $dat = $v->get_data();
|
||||
::rptMsg(sprintf "NtfsDisableLastAccessUpdate = 0x%08x",$dat);
|
||||
$found = 1;
|
||||
|
||||
if ($dat > 1) {
|
||||
::rptMsg($dla{$dat});
|
||||
eval {
|
||||
my $thresh = $key->get_value("NtfsLastAccessUpdatePolicyVolumeSizeThreshold")->get_data();
|
||||
::rptMsg(sprintf "NtfsLastAccessUpdatePolicyVolumeSizeThreshold value = 0x%08x",$thresh);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
::rptMsg("NtfsDisableLastAccessUpdate value not found.") if ($found == 0);
|
||||
@ -71,4 +95,4 @@ sub pluginmain {
|
||||
::rptMsg($key_path." not found.");
|
||||
}
|
||||
}
|
||||
1;
|
||||
1;
|
2
thirdparty/rr-full/plugins/ie_zones.pl
vendored
2
thirdparty/rr-full/plugins/ie_zones.pl
vendored
@ -17,7 +17,7 @@
|
||||
package ie_zones;
|
||||
use strict;
|
||||
|
||||
my %config = (hive => "NTUSER\.DAT;Software",
|
||||
my %config = (hive => "NTUSER\.DAT,Software",
|
||||
hasShortDescr => 1,
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
|
11
thirdparty/rr-full/plugins/imagefile.pl
vendored
11
thirdparty/rr-full/plugins/imagefile.pl
vendored
@ -5,8 +5,10 @@
|
||||
# http://msdn2.microsoft.com/en-us/library/a329t4ed(VS\.80)\.aspx
|
||||
# CWDIllegalInDllSearch: http://support.microsoft.com/kb/2264107
|
||||
# http://carnal0wnage.attackresearch.com/2012/04/privilege-escalation-via-sticky-keys.html
|
||||
# 'Auto' value - https://docs.microsoft.com/en-us/windows/desktop/debug/configuring-automatic-debugging
|
||||
#
|
||||
# Change history:
|
||||
# 20190511 - added search for 'auto' value
|
||||
# 20131007 - added Carnal0wnage reference
|
||||
# 20130425 - added alertMsg() functionality
|
||||
# 20130410 - added Wow6432Node support
|
||||
@ -23,7 +25,7 @@ my %config = (hive => "Software",
|
||||
hasRefs => 0,
|
||||
osmask => 22,
|
||||
category => "malware",
|
||||
version => 20131007);
|
||||
version => 20190511);
|
||||
|
||||
sub getConfig{return %config}
|
||||
sub getShortDescr {
|
||||
@ -76,6 +78,11 @@ sub pluginmain {
|
||||
eval {
|
||||
$dllsearch = $s->get_value("CWDIllegalInDllSearch")->get_data();
|
||||
};
|
||||
# 20190511 - added search for 'auto' value
|
||||
eval {
|
||||
$debug{$name}{auto} = $s->get_value("Auto")->get_data();
|
||||
};
|
||||
|
||||
# If the eval{} throws an error, it's b/c the Debugger value isn't
|
||||
# found within the key, so we don't need to do anything w/ the error
|
||||
if ($dllsearch ne "") {
|
||||
@ -88,7 +95,7 @@ sub pluginmain {
|
||||
foreach my $d (keys %debug) {
|
||||
::rptMsg($d." LastWrite: ".gmtime($debug{$d}{lastwrite}));
|
||||
::rptMsg(" Debugger : ".$debug{$d}{debug}) if (exists $debug{$d}{debug});
|
||||
::alertMsg("Alert: imagefile: Debugger value found : ".$debug{$d}{debug}) if (exists $debug{$d}{debug});
|
||||
::rptMsg(" Auto : ".$debug{$d}{auto}) if (exists $debug{$d}{auto});
|
||||
::rptMsg(" CWDIllegalInDllSearch: ".$debug{$d}{dllsearch}) if (exists $debug{$d}{dllsearch});
|
||||
}
|
||||
}
|
||||
|
47
thirdparty/rr-full/plugins/knowndev.pl
vendored
47
thirdparty/rr-full/plugins/knowndev.pl
vendored
@ -2,12 +2,14 @@
|
||||
# knowndev.pl
|
||||
#
|
||||
# History
|
||||
# 20190714 - updated
|
||||
# 20140414 - created
|
||||
#
|
||||
# Registry entries created by devices that support device stage
|
||||
# Reference: http://nicoleibrahim.com/part-4-usb-device-research-usb-first-insert-results/
|
||||
#
|
||||
# Author: Jasmine Chua, babymagic06@gmail.com
|
||||
# updates: QAR, LLC (H. Carvey, keydet89@yahoo.com)
|
||||
#-----------------------------------------------------------------------------------------
|
||||
package knowndev;
|
||||
use strict;
|
||||
@ -17,7 +19,7 @@ my %config = (hive => "NTUSER\.DAT",
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
osmask => 22,
|
||||
version => 20140414);
|
||||
version => 20190714);
|
||||
|
||||
sub getConfig{return %config}
|
||||
sub getShortDescr {
|
||||
@ -50,43 +52,18 @@ sub pluginmain {
|
||||
if (scalar @subkeys > 0) {
|
||||
foreach my $s (@subkeys) {
|
||||
my $name = $s->get_name();
|
||||
if ($name =~ m/_COMP/) {
|
||||
my $m = (split(/#/,$name,3))[1];
|
||||
my $device = (split(/&/,$m,3))[0];
|
||||
my $model = (split(/&/,$m,3))[1];
|
||||
my $label;
|
||||
my $icon;
|
||||
eval {
|
||||
$label = $s->get_value('Label')->get_data();
|
||||
$icon = $s->get_value('Icon')->get_data();
|
||||
};
|
||||
my $time = gmtime($s->get_timestamp());
|
||||
::rptMsg("Device: ".$device);
|
||||
::rptMsg("Model: ".$model);
|
||||
::rptMsg("Label: ".$label) unless ($@);
|
||||
::rptMsg("Icon: ".$icon) unless ($@);
|
||||
::rptMsg("LastWrite Time: ".$time." (UTC)\n");
|
||||
}
|
||||
elsif ($name =~ m/_USB/) {
|
||||
my $vidpid = (split(/#/,$name,3))[1];
|
||||
my $serial = (split(/#/,$name,3))[2];
|
||||
my $label;
|
||||
my $icon;
|
||||
eval {
|
||||
$label = $s->get_value('Label')->get_data();
|
||||
$icon = $s->get_value('Icon')->get_data();
|
||||
};
|
||||
my $time = gmtime($s->get_timestamp());
|
||||
::rptMsg("VID&PID: ".$vidpid);
|
||||
::rptMsg("Serial: ".$serial);
|
||||
::rptMsg("Label: ".$label) unless ($@);
|
||||
::rptMsg("Icon: ".$icon) unless ($@);
|
||||
::rptMsg("LastWrite Time: ".$time." (UTC)\n");
|
||||
}
|
||||
my $lw = gmtime($s->get_timestamp());
|
||||
::rptMsg($name." ".$lw." Z");
|
||||
|
||||
eval {
|
||||
my $label = $s->get_value("Label")->get_data();
|
||||
::rptMsg("Label: ".$label);
|
||||
};
|
||||
::rptMsg("");
|
||||
}
|
||||
}
|
||||
else {
|
||||
::rptMsg($key_path." has no subkeys.");
|
||||
::rptMsg($key_path." has no subkeys.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
10
thirdparty/rr-full/plugins/lastloggedon.pl
vendored
10
thirdparty/rr-full/plugins/lastloggedon.pl
vendored
@ -6,9 +6,10 @@
|
||||
#
|
||||
#
|
||||
# History:
|
||||
# 20180614 - Updated by Michael Godfrey
|
||||
# 20160531 - created
|
||||
#
|
||||
# copyright 2016 Quantum Analytics Research, LLC
|
||||
# copyright 2018 Quantum Analytics Research, LLC
|
||||
# Author: H. Carvey, keydet89@yahoo.com
|
||||
#-----------------------------------------------------------
|
||||
package lastloggedon;
|
||||
@ -62,7 +63,12 @@ sub pluginmain {
|
||||
my $lastsamuser = $key->get_value("LastLoggedOnSAMUser")->get_data();
|
||||
::rptMsg("LastLoggedOnSAMUser = ".$lastsamuser);
|
||||
};
|
||||
}
|
||||
# Added by Michael Godfrey
|
||||
eval {
|
||||
my $lastsamuserSID = $key->get_value("LastLoggedOnUserSID")->get_data();
|
||||
::rptMsg("LastLoggedOnUserSID = ".$lastsamuserSID);
|
||||
}
|
||||
}
|
||||
else {
|
||||
::rptMsg($key_path." not found.");
|
||||
}
|
||||
|
13
thirdparty/rr-full/plugins/macaddr.pl
vendored
13
thirdparty/rr-full/plugins/macaddr.pl
vendored
@ -3,19 +3,23 @@
|
||||
# Attempt to locate MAC address in either Software or System hive files;
|
||||
# The plugin will determine which one its in and use the appropriate
|
||||
# code
|
||||
#
|
||||
# History:
|
||||
# 20190506 - updated
|
||||
# 20090118 - created
|
||||
#
|
||||
#
|
||||
# copyright 2008 H. Carvey, keydet89@yahoo.com
|
||||
# copyright 2019, QAR, LLC
|
||||
# Author: H. Carvey, keydet89@yahoo.com
|
||||
#-----------------------------------------------------------
|
||||
package macaddr;
|
||||
use strict;
|
||||
|
||||
my %config = (hive => "Software",
|
||||
my %config = (hive => "System,Software",
|
||||
osmask => 22,
|
||||
hasShortDescr => 1,
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
version => 20090118);
|
||||
version => 20190506);
|
||||
|
||||
sub getConfig{return %config}
|
||||
|
||||
@ -61,6 +65,7 @@ sub pluginmain {
|
||||
eval {
|
||||
$na = $key->get_subkey($name)->get_value("NetworkAddress")->get_data();
|
||||
::rptMsg(" ".$name.": NetworkAddress = ".$na);
|
||||
::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
|
||||
$found = 1;
|
||||
};
|
||||
}
|
||||
|
66
thirdparty/rr-full/plugins/malware.pl
vendored
66
thirdparty/rr-full/plugins/malware.pl
vendored
@ -8,6 +8,9 @@
|
||||
# <included inline>
|
||||
#
|
||||
# Change history:
|
||||
# 20190527 - updates
|
||||
# 20190107 - added remote UAC bypass check
|
||||
# 20180702 - added values to check for MS Defender being disabled
|
||||
# 20161210 - added WebRoot check
|
||||
# 20160615 - added new Sofacy persistence
|
||||
# 20160412 - added Ramdo checks
|
||||
@ -19,7 +22,7 @@
|
||||
# 20151008 - added keys
|
||||
# 20150828 - created
|
||||
#
|
||||
# copyright 2015 Quantum Analytics Research, LLC
|
||||
# copyright 2018 Quantum Analytics Research, LLC
|
||||
# Author: H. Carvey, keydet89@yahoo.com
|
||||
#-----------------------------------------------------------
|
||||
package malware;
|
||||
@ -31,7 +34,7 @@ my %config = (hive => "All",
|
||||
hasRefs => 0,
|
||||
osmask => 22,
|
||||
category => "malware",
|
||||
version => 20161210);
|
||||
version => 20190527);
|
||||
|
||||
sub getConfig{return %config}
|
||||
sub getShortDescr {
|
||||
@ -102,9 +105,29 @@ sub pluginmain {
|
||||
}
|
||||
};
|
||||
|
||||
# Added 20190527
|
||||
# https://www.praetorian.com/blog/mitigating-mimikatz-wdigest-cleartext-credential-theft?edition=2019
|
||||
eval {
|
||||
$key_path = "Control\\SecurityProviders\\WDigest";
|
||||
if ($key = $root_key->get_subkey($key_path)){
|
||||
my $ulc = $key->get_value("UseLogonCredential")->get_data();
|
||||
::rptMsg(" UseLogonCredential value = ".$ulc);
|
||||
}
|
||||
};
|
||||
|
||||
# Software Hive
|
||||
|
||||
# Added 20190527
|
||||
# https://www.stigviewer.com/stig/windows_7/2013-03-14/finding/V-3470
|
||||
eval {
|
||||
$key_path = "Policies\\Microsoft\\Windows NT\\Terminal Services\\";
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
my $fallow = $key->get_value("fAllowUnsolicited")->get_data();
|
||||
::rptMsg(" fAllowUnsolicited value = ".$fallow);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
# Check for several PlugX variants
|
||||
# http://www.symantec.com/security_response/earthlink_writeup.jsp?docid=2013-112101-0135-99
|
||||
# http://www.trendmicro.com/vinfo/us/threat-encyclopedia/malware/PLUGX
|
||||
@ -307,6 +330,45 @@ sub pluginmain {
|
||||
}
|
||||
};
|
||||
|
||||
# https://www.ghacks.net/2015/10/25/how-to-disable-windows-defender-in-windows-10-permanently/
|
||||
eval {
|
||||
$key_path = "Policies\\Microsoft\\Windows Defender";
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
my $dis = $key->get_value("DisableAntiSpyware")->get_data();
|
||||
if ($dis == 1) {
|
||||
::rptMsg($key_path);
|
||||
::rptMsg("LastWrite Time : ".gmtime($key->get_timestamp())." UTC");
|
||||
::rptMsg("DisableAntiSpyware value = 1");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
eval {
|
||||
$key_path = "Policies\\Microsoft\\Windows Defender\\Real-Time Protection";
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
my $dis = $key->get_value("DisableRealtimeMonitoring")->get_data();
|
||||
if ($dis == 1) {
|
||||
::rptMsg($key_path);
|
||||
::rptMsg("LastWrite Time : ".gmtime($key->get_timestamp())." UTC");
|
||||
::rptMsg("DisableRealtimeMonitoring value = 1");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
# Remote UAC bypass
|
||||
# https://support.microsoft.com/en-us/help/951016/description-of-user-account-control-and-remote-restrictions-in-windows
|
||||
eval {
|
||||
$key_path = "Microsoft\\Windows\\CurrentVersion\\Policies\\System";
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
my $uac = $key->get_value("LocalAccountTokenFilterPolicy")->get_data();
|
||||
if ($uac == 1) {
|
||||
::rptMsg($key_path);
|
||||
::rptMsg("LastWrite Time : ".gmtime($key->get_timestamp())." UTC");
|
||||
::rptMsg("LocalAccountTokenFilterPolicy value = 1; remote UAC bypass");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
# NTUSER.DAT/USRCLASS.DAT
|
||||
|
||||
# Possible PlugX
|
||||
|
17
thirdparty/rr-full/plugins/netsh.pl
vendored
17
thirdparty/rr-full/plugins/netsh.pl
vendored
@ -4,11 +4,15 @@
|
||||
#
|
||||
# References
|
||||
# http://www.adaptforward.com/2016/09/using-netshell-to-execute-evil-dlls-and-persist-on-a-host/
|
||||
# https://attack.mitre.org/techniques/T1128/
|
||||
# https://htmlpreview.github.io/?https://github.com/MatthewDemaske/blogbackup/blob/master/netshell.html
|
||||
#
|
||||
# Change history
|
||||
# 20190316 - updated references
|
||||
# 20160926 - created
|
||||
#
|
||||
# Copyright 2016 QAR, LLC
|
||||
# Copyright 2019 QAR, LLC
|
||||
# Author: H. Carvey, keydet89@yahoo.com
|
||||
#-----------------------------------------------------------
|
||||
package netsh;
|
||||
use strict;
|
||||
@ -18,7 +22,7 @@ my %config = (hive => "Software",
|
||||
hasShortDescr => 1,
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
version => 20160926);
|
||||
version => 20190316);
|
||||
|
||||
sub getConfig{return %config}
|
||||
|
||||
@ -45,12 +49,13 @@ sub pluginmain {
|
||||
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
::rptMsg($key_path);
|
||||
::rptMsg("LastWrite: ".gmtime($key->get_timestamp())." Z");
|
||||
::rptMsg("");
|
||||
::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
|
||||
my @vals = $key->get_list_of_values();
|
||||
if (scalar(@vals) > 0) {
|
||||
if (scalar @vals > 0) {
|
||||
::rptMsg("");
|
||||
::rptMsg(sprintf "%-15s %-25s","Name","DLL Name");
|
||||
foreach my $v (@vals) {
|
||||
::rptMsg(sprintf "%-15s %-30s",$v->get_name(),$v->get_data());
|
||||
::rptMsg(sprintf "%-15s %-25s",$v->get_name(),$v->get_data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
30
thirdparty/rr-full/plugins/networklist.pl
vendored
30
thirdparty/rr-full/plugins/networklist.pl
vendored
@ -5,6 +5,7 @@
|
||||
#
|
||||
#
|
||||
# Change History:
|
||||
# 20190128 - Added Nla\Wireless data
|
||||
# 20150812 - updated to include Nla\Cache data
|
||||
# 20120917 - updated to include NameType value
|
||||
# 20090812 - updated code to parse DateCreated and DateLastConnected
|
||||
@ -24,7 +25,7 @@ my %config = (hive => "Software",
|
||||
hasShortDescr => 1,
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
version => 20150812);
|
||||
version => 20190128);
|
||||
|
||||
sub getConfig{return %config}
|
||||
|
||||
@ -125,7 +126,7 @@ sub pluginmain {
|
||||
foreach my $n (keys %nl) {
|
||||
my $str = sprintf "%-15s Gateway Mac: ".$nl{$n}{DefaultGatewayMac},$nl{$n}{ProfileName};
|
||||
::rptMsg($nl{$n}{ProfileName});
|
||||
::rptMsg(" Key LastWrite : ".gmtime($nl{$n}{LastWrite})." Z");
|
||||
# ::rptMsg(" Key LastWrite : ".gmtime($nl{$n}{LastWrite})." Z");
|
||||
::rptMsg(" DateLastConnected: ".$nl{$n}{DateLastConnected});
|
||||
::rptMsg(" DateCreated : ".$nl{$n}{DateCreated});
|
||||
::rptMsg(" DefaultGatewayMac: ".$nl{$n}{DefaultGatewayMac});
|
||||
@ -147,9 +148,30 @@ sub pluginmain {
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
my @subkeys = $key->get_list_of_subkeys();
|
||||
if (scalar(@subkeys) > 0) {
|
||||
::rptMsg(sprintf "%-26s %-30s","Date","Domain/IP");
|
||||
# ::rptMsg(sprintf "%-26s %-30s","Date","Domain/IP");
|
||||
::rptMsg(sprintf "%-30s","Domain/IP");
|
||||
foreach my $s (@subkeys) {
|
||||
::rptMsg(sprintf "%-26s %-30s",gmtime($s->get_timestamp())." Z",$s->get_name());
|
||||
# ::rptMsg(sprintf "%-26s %-30s",gmtime($s->get_timestamp())." Z",$s->get_name());
|
||||
::rptMsg(sprintf "%-30s",$s->get_name());
|
||||
}
|
||||
}
|
||||
}
|
||||
::rptMsg("");
|
||||
# Added 20190128 - Nla\Wireless data
|
||||
$key_path = $base_path."\\Nla\\Wireless";
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
my @subkeys = $key->get_list_of_subkeys();
|
||||
if (scalar(@subkeys) > 0) {
|
||||
::rptMsg("");
|
||||
::rptMsg("Nla\\Wireless");
|
||||
foreach my $s (@subkeys) {
|
||||
my $str = $s->get_value("")->get_data();
|
||||
|
||||
my @list = unpack("(A2)*", $str);
|
||||
my @chars = map {chr hex} @list;
|
||||
my $new_str = join('',@chars);
|
||||
::rptMsg($new_str);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
298
thirdparty/rr-full/plugins/ntuser
vendored
298
thirdparty/rr-full/plugins/ntuser
vendored
@ -1,150 +1,148 @@
|
||||
# 20161213 *ALL* Plugins that apply on NTUSER hive, alphabetical order
|
||||
acmru
|
||||
adoberdr
|
||||
aim
|
||||
aports
|
||||
appcompatflags
|
||||
applets
|
||||
applets_tln
|
||||
appspecific
|
||||
ares
|
||||
arpcache
|
||||
attachmgr
|
||||
attachmgr_tln
|
||||
autoendtasks
|
||||
autorun
|
||||
bitbucket_user
|
||||
brisv
|
||||
cached
|
||||
cached_tln
|
||||
cain
|
||||
ccleaner
|
||||
cdstaginginfo
|
||||
clampi
|
||||
clampitm
|
||||
cmdproc
|
||||
cmdproc_tln
|
||||
comdlg32
|
||||
compdesc
|
||||
controlpanel
|
||||
cortana
|
||||
cpldontload
|
||||
ddo
|
||||
decaf
|
||||
dependency_walker
|
||||
domains
|
||||
environment
|
||||
fileexts
|
||||
filehistory
|
||||
gthist
|
||||
gtwhitelist
|
||||
haven_and_hearth
|
||||
identities
|
||||
iejava
|
||||
ie_main
|
||||
ie_settings
|
||||
ie_zones
|
||||
internet_explorer_cu
|
||||
internet_settings_cu
|
||||
itempos
|
||||
javafx
|
||||
kankan
|
||||
knowndev
|
||||
latentbot
|
||||
listsoft
|
||||
liveContactsGUID
|
||||
load
|
||||
logonusername
|
||||
menuorder
|
||||
mixer
|
||||
mixer_tln
|
||||
mmc
|
||||
mmc_tln
|
||||
mmo
|
||||
mndmru
|
||||
mndmru_tln
|
||||
mp2
|
||||
mp3
|
||||
mpmru
|
||||
mspaper
|
||||
muicache
|
||||
muicache_tln
|
||||
nero
|
||||
netassist
|
||||
ntusernetwork
|
||||
odysseus
|
||||
officedocs
|
||||
officedocs2010
|
||||
officedocs2010_tln
|
||||
oisc
|
||||
olsearch
|
||||
osversion
|
||||
osversion_tln
|
||||
outlook
|
||||
outlook2
|
||||
policies_u
|
||||
printermru
|
||||
printers
|
||||
privoxy
|
||||
profiler
|
||||
proxysettings
|
||||
publishingwizard
|
||||
putty
|
||||
rdphint
|
||||
reading_locations
|
||||
realplayer6
|
||||
realvnc
|
||||
recentdocs
|
||||
recentdocs_tln
|
||||
reveton
|
||||
rootkit_revealer
|
||||
runmru
|
||||
runmru_tln
|
||||
sevenzip
|
||||
shc
|
||||
shellbags_xp
|
||||
shellfolders
|
||||
skype
|
||||
snapshot_viewer
|
||||
ssh_host_keys
|
||||
startmenuinternetapps_cu
|
||||
startpage
|
||||
startup
|
||||
sysinternals
|
||||
sysinternals_tln
|
||||
trustrecords
|
||||
trustrecords_tln
|
||||
tsclient
|
||||
tsclient_tln
|
||||
typedpaths
|
||||
typedpaths_tln
|
||||
typedurls
|
||||
typedurlstime
|
||||
typedurlstime_tln
|
||||
typedurls_tln
|
||||
unreadmail
|
||||
urun_tln
|
||||
userassist
|
||||
userassist_tln
|
||||
userinfo
|
||||
userlocsvc
|
||||
user_run
|
||||
user_win
|
||||
vawtrak
|
||||
vista_bitbucket
|
||||
vmplayer
|
||||
vmware_vsphere_client
|
||||
vnchooksapplicationprefs
|
||||
vncviewer
|
||||
wallpaper
|
||||
warcraft3
|
||||
winlogon_u
|
||||
winrar
|
||||
winrar2
|
||||
winrar_tln
|
||||
winscp
|
||||
winscp_sessions
|
||||
winvnc
|
||||
winzip
|
||||
wordwheelquery
|
||||
yahoo_cu
|
||||
acmru
|
||||
adoberdr
|
||||
ahaha
|
||||
aim
|
||||
aports
|
||||
appassoc
|
||||
appcompatflags
|
||||
appkeys
|
||||
applets
|
||||
appspecific
|
||||
ares
|
||||
arpcache
|
||||
attachmgr
|
||||
autoendtasks
|
||||
autorun
|
||||
bitbucket_user
|
||||
brisv
|
||||
cached
|
||||
cain
|
||||
ccleaner
|
||||
cdstaginginfo
|
||||
clampi
|
||||
clampitm
|
||||
cmdproc
|
||||
comdlg32
|
||||
compdesc
|
||||
controlpanel
|
||||
cortana
|
||||
cpldontload
|
||||
ddo
|
||||
decaf
|
||||
dependency_walker
|
||||
disablemru
|
||||
domains
|
||||
environment
|
||||
eraser
|
||||
fileexts
|
||||
filehistory
|
||||
foxitrdr
|
||||
gthist
|
||||
gtwhitelist
|
||||
haven_and_hearth
|
||||
identities
|
||||
iejava
|
||||
ie_main
|
||||
ie_settings
|
||||
ie_zones
|
||||
imgburn1
|
||||
internet_explorer_cu
|
||||
internet_settings_cu
|
||||
itempos
|
||||
javafx
|
||||
jumplistdata
|
||||
kankan
|
||||
knowndev
|
||||
latentbot
|
||||
listsoft
|
||||
liveContactsGUID
|
||||
load
|
||||
logonstats
|
||||
logonusername
|
||||
menuorder
|
||||
mixer
|
||||
mmc
|
||||
mmo
|
||||
mndmru
|
||||
mp2
|
||||
mp3
|
||||
mpmru
|
||||
mspaper
|
||||
muicache
|
||||
mzthunderbird
|
||||
nation
|
||||
nero
|
||||
netassist
|
||||
ntusernetwork
|
||||
odysseus
|
||||
officedocs
|
||||
officedocs2010
|
||||
oisc
|
||||
olsearch
|
||||
osversion
|
||||
outlook
|
||||
outlook2
|
||||
policies_u
|
||||
printermru
|
||||
printers
|
||||
privoxy
|
||||
profiler
|
||||
proxysettings
|
||||
pslogging
|
||||
publishingwizard
|
||||
putty
|
||||
putty_sessions
|
||||
rdphint
|
||||
reading_locations
|
||||
realplayer6
|
||||
realvnc
|
||||
recentapps
|
||||
recentdocs
|
||||
recentdocs_timeline
|
||||
reveton
|
||||
rootkit_revealer
|
||||
runmru
|
||||
searchscopes
|
||||
sevenzip
|
||||
shc
|
||||
shellactivities
|
||||
shellbags_xp
|
||||
shellfolders
|
||||
skype
|
||||
snapshot_viewer
|
||||
ssh_host_keys
|
||||
startmenuinternetapps_cu
|
||||
startpage
|
||||
startup
|
||||
sysinternals
|
||||
thunderbirdinstalled
|
||||
trustrecords
|
||||
tsclient
|
||||
typedpaths
|
||||
typedurls
|
||||
typedurlstime
|
||||
uninstall
|
||||
unreadmail
|
||||
userassist
|
||||
userinfo
|
||||
userlocsvc
|
||||
user_run
|
||||
user_win
|
||||
utorrent
|
||||
vawtrak
|
||||
vista_bitbucket
|
||||
vmplayer
|
||||
vmware_vsphere_client
|
||||
vnchooksapplicationprefs
|
||||
vncviewer
|
||||
wallpaper
|
||||
warcraft3
|
||||
winlogon_u
|
||||
winrar
|
||||
winrar2
|
||||
winscp
|
||||
winscp_sessions
|
||||
winvnc
|
||||
winzip
|
||||
wordwheelquery
|
||||
yahoo_cu
|
||||
|
2
thirdparty/rr-full/plugins/rdphint.pl
vendored
2
thirdparty/rr-full/plugins/rdphint.pl
vendored
@ -7,7 +7,7 @@
|
||||
package rdphint;
|
||||
use strict;
|
||||
|
||||
my %config = (hive => "NTUSER",
|
||||
my %config = (hive => "NTUSER\.DAT",
|
||||
osmask => 22,
|
||||
hasShortDescr => 1,
|
||||
hasDescr => 0,
|
||||
|
@ -4,6 +4,7 @@
|
||||
#
|
||||
# Change history
|
||||
# 20140130 - created
|
||||
# 20190211 - added "paragraphID" int to hex conversion
|
||||
#
|
||||
# References
|
||||
# http://dfstream.blogspot.com/2014/01/ms-word-2013-reading-locations.html
|
||||
@ -66,7 +67,9 @@ sub pluginmain {
|
||||
|
||||
eval {
|
||||
my $p = $s->get_value("Position")->get_data();
|
||||
::rptMsg("Position: ".$p);
|
||||
my @ps = split(' ', $p);
|
||||
my $paraid = sprintf("%X", $ps[0]);
|
||||
::rptMsg("Position: ".$p." (ParagraphID: ".$paraid.")");
|
||||
};
|
||||
::rptMsg("");
|
||||
}
|
||||
|
4
thirdparty/rr-full/plugins/sam
vendored
4
thirdparty/rr-full/plugins/sam
vendored
@ -1,3 +1 @@
|
||||
# 20161213 *ALL* Plugins that apply on SAM hive, alphabetical order
|
||||
samparse
|
||||
samparse_tln
|
||||
samparse
|
||||
|
13
thirdparty/rr-full/plugins/security
vendored
13
thirdparty/rr-full/plugins/security
vendored
@ -1,8 +1,5 @@
|
||||
# 20161213 *ALL* Plugins that apply on SECURITY hive, alphabetical order
|
||||
auditpol
|
||||
auditpol_xp
|
||||
lsasecrets
|
||||
polacdms
|
||||
secrets
|
||||
secrets_tln
|
||||
securityproviders
|
||||
auditpol
|
||||
auditpol_xp
|
||||
lsasecrets
|
||||
polacdms
|
||||
secrets
|
||||
|
19
thirdparty/rr-full/plugins/shc.pl
vendored
19
thirdparty/rr-full/plugins/shc.pl
vendored
@ -3,8 +3,14 @@
|
||||
# This key may have something to do with the Start Menu Cache - nothing
|
||||
# definitive yet.
|
||||
#
|
||||
# In my tests *some* installers/applications populate this key on *some* systems
|
||||
# and Windows shows *some* of these items as "Recently Installed" at the top of
|
||||
# the start menu. More research is still needed. -Keith Twombley
|
||||
# ktwombley@gmail.com
|
||||
#
|
||||
# Change history
|
||||
# 20130412 - created - IN PROCESS; NOT COMPLETE
|
||||
# 20190305 - updated - outputs entries from shc
|
||||
#
|
||||
#
|
||||
# References
|
||||
@ -26,7 +32,7 @@ my %config = (hive => "NTUSER\.DAT",
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
osmask => 32, #Windows 8
|
||||
version => 20130412);
|
||||
version => 20190305);
|
||||
|
||||
sub getConfig{return %config}
|
||||
sub getShortDescr {
|
||||
@ -57,9 +63,16 @@ sub pluginmain {
|
||||
my @vals = $key->get_list_of_values();
|
||||
|
||||
if (scalar(@vals) > 0) {
|
||||
my %shc;
|
||||
|
||||
foreach my $v (@vals) {
|
||||
|
||||
|
||||
my $name = $v->get_name();
|
||||
my $data = $v->get_data();
|
||||
$shc{$name} = $data
|
||||
}
|
||||
|
||||
foreach my $u (sort {$a <=> $b} keys %shc) {
|
||||
::rptMsg(" ".$u." -> ".$shc{$u});
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
7
thirdparty/rr-full/plugins/shellbags_test.pl
vendored
7
thirdparty/rr-full/plugins/shellbags_test.pl
vendored
@ -2,7 +2,7 @@
|
||||
# shellbags_test.pl
|
||||
#
|
||||
#
|
||||
# License: GPL v3
|
||||
#
|
||||
# copyright 2012 Quantum Analytics Research, LLC
|
||||
# Author: H. Carvey, keydet89@yahoo.com
|
||||
#-----------------------------------------------------------
|
||||
@ -358,7 +358,6 @@ sub parseFolderItem {
|
||||
my $str = "";
|
||||
while($tag) {
|
||||
my $s = substr($data,$ofs_shortname + $cnt,1);
|
||||
return %item unless (defined $s);
|
||||
if ($s =~ m/\x00/ && ((($cnt + 1) % 2) == 0)) {
|
||||
$tag = 0;
|
||||
}
|
||||
@ -374,9 +373,7 @@ sub parseFolderItem {
|
||||
$tag = 1;
|
||||
$cnt = 0;
|
||||
while ($tag) {
|
||||
my $s = substr($data,$ofs + $cnt,2);
|
||||
return %item unless (defined $s);
|
||||
if (unpack("v",$s) == 0xbeef) {
|
||||
if (unpack("v",substr($data,$ofs + $cnt,2)) == 0xbeef) {
|
||||
$tag = 0;
|
||||
}
|
||||
else {
|
||||
|
142
thirdparty/rr-full/plugins/shellbags_tln.pl
vendored
142
thirdparty/rr-full/plugins/shellbags_tln.pl
vendored
@ -3,6 +3,7 @@
|
||||
# RR plugin to parse (Vista, Win7/Win2008R2) shell bags
|
||||
#
|
||||
# History:
|
||||
# 20180702 - code updates, including to parseGUID() function
|
||||
# 20120810 - added support for parsing Network types; added handling of
|
||||
# offsets for Folder types (ie, transition to long name offset),
|
||||
# based on OS version (Vista, Win7); tested against one Win2008R2
|
||||
@ -26,7 +27,7 @@
|
||||
# Moore for writing the shell bag parser for Registry Decoder, as well as
|
||||
# assistance with some parsing.
|
||||
#
|
||||
# License: GPL v3
|
||||
#
|
||||
# copyright 2012 Quantum Analytics Research, LLC
|
||||
# Author: H. Carvey, keydet89@yahoo.com
|
||||
#-----------------------------------------------------------
|
||||
@ -42,12 +43,12 @@ my %config = (hive => "USRCLASS\.DAT",
|
||||
hasShortDescr => 1,
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
version => 20120810);
|
||||
version => 20180702);
|
||||
|
||||
sub getConfig{return %config}
|
||||
|
||||
sub getShortDescr {
|
||||
return "Shell/BagMRU traversal in Win7 USRCLASS.DAT hives";
|
||||
return "Shell/BagMRU traversal in Win7 USRCLASS\.DAT hives";
|
||||
}
|
||||
sub getDescr{}
|
||||
sub getRefs {}
|
||||
@ -84,6 +85,7 @@ my %cp_guids = ("{bb64f8a7-bee7-4e1a-ab8d-7d8273f7fdb6}" => "Action Center",
|
||||
"{a3dd4f92-658a-410f-84fd-6fbbbef2fffe}" => "Internet Options",
|
||||
"{a304259d-52b8-4526-8b1a-a1d6cecc8243}" => "iSCSI Initiator",
|
||||
"{725be8f7-668e-4c7b-8f90-46bdb0936430}" => "Keyboard",
|
||||
"{bf782cc9-5a52-4a17-806c-2a894ffeeac5}" => "Language Settings",
|
||||
"{e9950154-c418-419e-a90a-20c5287ae24b}" => "Location and Other Sensors",
|
||||
"{1fa9085f-25a2-489b-85d4-86326eedcd87}" => "Manage Wireless Networks",
|
||||
"{6c8eec18-8d75-41b2-a177-8831d59d2d50}" => "Mouse",
|
||||
@ -356,7 +358,6 @@ sub parseVariableEntry {
|
||||
while($tag) {
|
||||
my $sz = unpack("V",substr($stuff,$cnt,4));
|
||||
my $id = unpack("V",substr($stuff,$cnt + 4,4));
|
||||
return %item unless (defined $sz);
|
||||
#--------------------------------------------------------------
|
||||
# sub-segment types
|
||||
# 0x0a - file name
|
||||
@ -372,7 +373,7 @@ sub parseVariableEntry {
|
||||
|
||||
my $num = unpack("V",substr($stuff,$cnt + 13,4));
|
||||
my $str = substr($stuff,$cnt + 13 + 4,($num * 2));
|
||||
$str =~ s/\x00//g;
|
||||
$str =~ s/\00//g;
|
||||
$item{name} = $str;
|
||||
}
|
||||
$cnt += $sz;
|
||||
@ -387,7 +388,6 @@ sub parseVariableEntry {
|
||||
# my $sz = unpack("V",substr($stuff,$cnt,4));
|
||||
# my $id = unpack("V",substr($stuff,$cnt + 4,4));
|
||||
#
|
||||
# return %item unless (defined $sz);
|
||||
# if ($sz == 0x00) {
|
||||
# $tag = 0;
|
||||
# next;
|
||||
@ -396,7 +396,7 @@ sub parseVariableEntry {
|
||||
#
|
||||
# my $num = unpack("V",substr($stuff,$cnt + 13,4));
|
||||
# my $str = substr($stuff,$cnt + 13 + 4,($num * 2));
|
||||
# $str =~ s/\x00//g;
|
||||
# $str =~ s/\00//g;
|
||||
# $item{name} = $str;
|
||||
# }
|
||||
# $cnt += $sz;
|
||||
@ -410,12 +410,12 @@ sub parseVariableEntry {
|
||||
elsif ($tag == 0x7b || $tag == 0xbb || $tag == 0xfb) {
|
||||
my ($sz1,$sz2,$sz3) = unpack("VVV",substr($data,0x3e,12));
|
||||
$item{name} = substr($data,0x4a,$sz1 * 2);
|
||||
$item{name} =~ s/\x00//g;
|
||||
$item{name} =~ s/\00//g;
|
||||
}
|
||||
elsif ($tag == 0x02 || $tag == 0x03) {
|
||||
my ($sz1,$sz2,$sz3,$sz4) = unpack("VVVV",substr($data,0x26,16));
|
||||
$item{name} = substr($data,0x36,$sz1 * 2);
|
||||
$item{name} =~ s/\x00//g;
|
||||
$item{name} =~ s/\00//g;
|
||||
}
|
||||
else {
|
||||
$item{name} = "Unknown Type";
|
||||
@ -432,7 +432,7 @@ sub parseNetworkEntry {
|
||||
my %item = ();
|
||||
$item{type} = unpack("C",substr($data,2,1));
|
||||
|
||||
my @n = split(/\x00/,substr($data,4,length($data) - 4));
|
||||
my @n = split(/\00/,substr($data,4,length($data) - 4));
|
||||
$item{name} = $n[0];
|
||||
return %item;
|
||||
}
|
||||
@ -449,13 +449,13 @@ sub parseZipSubFolderItem {
|
||||
|
||||
# Get the opened/accessed date/time
|
||||
$item{datetime} = substr($data,0x24,6);
|
||||
$item{datetime} =~ s/\x00//g;
|
||||
$item{datetime} =~ s/\00//g;
|
||||
if ($item{datetime} eq "N/A") {
|
||||
|
||||
}
|
||||
else {
|
||||
$item{datetime} = substr($data,0x24,40);
|
||||
$item{datetime} =~ s/\x00//g;
|
||||
$item{datetime} =~ s/\00//g;
|
||||
my ($date,$time) = split(/\s+/,$item{datetime},2);
|
||||
my ($mon,$day,$yr) = split(/\//,$date,3);
|
||||
my ($hr,$min,$sec) = split(/:/,$time,3);
|
||||
@ -468,9 +468,9 @@ sub parseZipSubFolderItem {
|
||||
my $sz2 = unpack("V",substr($data,0x58,4));
|
||||
|
||||
my $str1 = substr($data,0x5C,$sz *2) if ($sz > 0);
|
||||
$str1 =~ s/\x00//g;
|
||||
$str1 =~ s/\00//g;
|
||||
my $str2 = substr($data,0x5C + ($sz * 2),$sz2 *2) if ($sz2 > 0);
|
||||
$str2 =~ s/\x00//g;
|
||||
$str2 =~ s/\00//g;
|
||||
|
||||
if ($sz2 > 0) {
|
||||
$item{name} = $str1."\\".$str2;
|
||||
@ -509,10 +509,10 @@ sub parseURIEntry {
|
||||
|
||||
my $sz = unpack("V",substr($data,0x2a,4));
|
||||
my $uri = substr($data,0x2e,$sz);
|
||||
$uri =~ s/\x00//g;
|
||||
$uri =~ s/\00//g;
|
||||
|
||||
my $proto = substr($data,length($data) - 6, 6);
|
||||
$proto =~ s/\x00//g;
|
||||
$proto =~ s/\00//g;
|
||||
|
||||
$item{name} = $proto."://".$uri;
|
||||
|
||||
@ -562,26 +562,81 @@ sub parseGUID {
|
||||
my $d3 = unpack("v",substr($data,6,2));
|
||||
my $d4 = unpack("H*",substr($data,8,2));
|
||||
my $d5 = unpack("H*",substr($data,10,6));
|
||||
return sprintf "{%08x-%x-%x-$d4-$d5}",$d1,$d2,$d3;
|
||||
return sprintf "{%08x-%04x-%04x-$d4-$d5}",$d1,$d2,$d3;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
#
|
||||
#-----------------------------------------------------------
|
||||
#sub parseDeviceEntry {
|
||||
# my $data = shift;
|
||||
# my %item = ();
|
||||
#
|
||||
# my $userlen = unpack("V",substr($data,30,4));
|
||||
# my $devlen = unpack("V",substr($data,34,4));
|
||||
#
|
||||
# my $user = substr($data,0x28,$userlen * 2);
|
||||
# $user =~ s/\00//g;
|
||||
#
|
||||
# my $dev = substr($data,0x28 + ($userlen * 2),$devlen * 2);
|
||||
# $dev =~ s/\00//g;
|
||||
#
|
||||
# $item{name} = $user;
|
||||
# return %item;
|
||||
#}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
#
|
||||
#-----------------------------------------------------------
|
||||
sub parseDeviceEntry {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
|
||||
my $ofs = unpack("v",substr($data,4,2));
|
||||
my $tag = unpack("V",substr($data,6,4));
|
||||
|
||||
my $userlen = unpack("V",substr($data,30,4));
|
||||
my $devlen = unpack("V",substr($data,34,4));
|
||||
|
||||
my $user = substr($data,0x28,$userlen * 2);
|
||||
$user =~ s/\x00//g;
|
||||
|
||||
my $dev = substr($data,0x28 + ($userlen * 2),$devlen * 2);
|
||||
$dev =~ s/\x00//g;
|
||||
|
||||
$item{name} = $user;
|
||||
#-----------------------------------------------------
|
||||
# DEBUG
|
||||
# ::rptMsg("parseDeviceEntry, tag = ".$tag);
|
||||
#-----------------------------------------------------
|
||||
if ($tag == 0) {
|
||||
my $guid1 = parseGUID(substr($data,$ofs + 6,16));
|
||||
my $guid2 = parseGUID(substr($data,$ofs + 6 + 16,16));
|
||||
$item{name} = $guid1."\\".$guid2
|
||||
}
|
||||
elsif ($tag == 2) {
|
||||
$item{name} = substr($data,0x0a,($ofs + 6) - 0x0a);
|
||||
$item{name} =~ s/\00//g;
|
||||
}
|
||||
else {
|
||||
my $ver = unpack("C",substr($data,9,1));
|
||||
my $idx = unpack("C",substr($data,3,1));
|
||||
|
||||
if ($idx == 0x80) {
|
||||
$item{name} = parseGUID(substr($data,4,16));
|
||||
}
|
||||
# Version 3 = XP
|
||||
elsif ($ver == 3) {
|
||||
my $guid1 = parseGUID(substr($data,$ofs + 6,16));
|
||||
my $guid2 = parseGUID(substr($data,$ofs + 6 + 16,16));
|
||||
$item{name} = $guid1."\\".$guid2
|
||||
|
||||
}
|
||||
# Version 8 = Win7
|
||||
elsif ($ver == 8) {
|
||||
my $userlen = unpack("V",substr($data,30,4));
|
||||
my $devlen = unpack("V",substr($data,34,4));
|
||||
my $user = substr($data,0x28,$userlen * 2);
|
||||
$user =~ s/\00//g;
|
||||
my $dev = substr($data,0x28 + ($userlen * 2),$devlen * 2);
|
||||
$dev =~ s/\00//g;
|
||||
$item{name} = $user;
|
||||
}
|
||||
# Version unknown
|
||||
else {
|
||||
$item{name} = "Device Entry - Unknown Version";
|
||||
}
|
||||
}
|
||||
return %item;
|
||||
}
|
||||
|
||||
@ -647,15 +702,14 @@ sub parseFolderEntry {
|
||||
($item{mtime_str},$item{mtime}) = convertDOSDate($m[0],$m[1]);
|
||||
|
||||
# Need to read in short name; nul-term ASCII
|
||||
# $item{shortname} = (split(/\x00/,substr($data,12,length($data) - 12),2))[0];
|
||||
# $item{shortname} = (split(/\00/,substr($data,12,length($data) - 12),2))[0];
|
||||
$ofs_shortname = $ofs_mdate + 6;
|
||||
my $tag = 1;
|
||||
my $cnt = 0;
|
||||
my $str = "";
|
||||
while($tag) {
|
||||
my $s = substr($data,$ofs_shortname + $cnt,1);
|
||||
return %item unless (defined $s);
|
||||
if ($s =~ m/\x00/ && ((($cnt + 1) % 2) == 0)) {
|
||||
if ($s =~ m/\00/ && ((($cnt + 1) % 2) == 0)) {
|
||||
$tag = 0;
|
||||
}
|
||||
else {
|
||||
@ -663,16 +717,14 @@ sub parseFolderEntry {
|
||||
$cnt++;
|
||||
}
|
||||
}
|
||||
# $str =~ s/\x00//g;
|
||||
# $str =~ s/\00//g;
|
||||
my $shortname = $str;
|
||||
my $ofs = $ofs_shortname + $cnt + 1;
|
||||
# Read progressively, 1 byte at a time, looking for 0xbeef
|
||||
$tag = 1;
|
||||
$cnt = 0;
|
||||
my $tag = 1;
|
||||
my $cnt = 0;
|
||||
while ($tag) {
|
||||
my $s = substr($data,$ofs + $cnt,2);
|
||||
return %item unless (defined $s);
|
||||
if (unpack("v",$s) == 0xbeef) {
|
||||
if (unpack("v",substr($data,$ofs + $cnt,2)) == 0xbeef) {
|
||||
$tag = 0;
|
||||
}
|
||||
else {
|
||||
@ -682,10 +734,10 @@ sub parseFolderEntry {
|
||||
$item{extver} = unpack("v",substr($data,$ofs + $cnt - 4,2));
|
||||
$ofs = $ofs + $cnt + 2;
|
||||
|
||||
@m = unpack("vv",substr($data,$ofs,4));
|
||||
my @m = unpack("vv",substr($data,$ofs,4));
|
||||
($item{ctime_str},$item{ctime}) = convertDOSDate($m[0],$m[1]);
|
||||
$ofs += 4;
|
||||
@m = unpack("vv",substr($data,$ofs,4));
|
||||
my @m = unpack("vv",substr($data,$ofs,4));
|
||||
($item{atime_str},$item{atime}) = convertDOSDate($m[0],$m[1]);
|
||||
|
||||
my $jmp;
|
||||
@ -695,12 +747,16 @@ sub parseFolderEntry {
|
||||
elsif ($item{extver} == 0x08) {
|
||||
$jmp = 30;
|
||||
}
|
||||
elsif ($item{extver} == 0x09) {
|
||||
$jmp = 34;
|
||||
}
|
||||
else {}
|
||||
|
||||
$ofs += $jmp;
|
||||
|
||||
$str = substr($data,$ofs,length($data) - 30);
|
||||
my $longname = (split(/\x00\x00/,$str,2))[0];
|
||||
$longname =~ s/\x00//g;
|
||||
my $str = substr($data,$ofs,length($data) - 30);
|
||||
my $longname = (split(/\00\00/,$str,2))[0];
|
||||
$longname =~ s/\00//g;
|
||||
|
||||
if ($longname ne "") {
|
||||
$item{name} = $longname;
|
||||
@ -750,7 +806,7 @@ sub parseNetworkEntry {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
$item{type} = unpack("C",substr($data,2,1));
|
||||
my @names = split(/\x00/,substr($data,5,length($data) - 5));
|
||||
my @names = split(/\00/,substr($data,5,length($data) - 5));
|
||||
$item{name} = $names[0];
|
||||
return %item;
|
||||
}
|
||||
@ -797,4 +853,4 @@ sub printData {
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
1;
|
16
thirdparty/rr-full/plugins/shellbags_xp.pl
vendored
16
thirdparty/rr-full/plugins/shellbags_xp.pl
vendored
@ -29,7 +29,7 @@
|
||||
# Moore for writing the shell bag parser for Registry Decoder, as well as
|
||||
# assistance with some parsing.
|
||||
#
|
||||
# License: GPL v3
|
||||
#
|
||||
# copyright 2012 Quantum Analytics Research, LLC
|
||||
# Author: H. Carvey, keydet89@yahoo.com
|
||||
#-----------------------------------------------------------
|
||||
@ -397,8 +397,7 @@ sub parseVariableEntry {
|
||||
# 0x0e, 0x0f, 0x10 - mod date, create date, access date(?)
|
||||
# 0x0c - size
|
||||
#--------------------------------------------------------------
|
||||
return %item unless (defined $sz);
|
||||
if ($sz == 0x00) {
|
||||
if ($sz == 0x00) {
|
||||
$tag = 0;
|
||||
next;
|
||||
}
|
||||
@ -420,7 +419,7 @@ sub parseVariableEntry {
|
||||
# while($tag) {
|
||||
# my $sz = unpack("V",substr($stuff,$cnt,4));
|
||||
# my $id = unpack("V",substr($stuff,$cnt + 4,4));
|
||||
# return %item unless (defined $sz);
|
||||
#
|
||||
# if ($sz == 0x00) {
|
||||
# $tag = 0;
|
||||
# next;
|
||||
@ -726,7 +725,6 @@ sub parseFolderEntry {
|
||||
my $str = "";
|
||||
while($tag) {
|
||||
my $s = substr($data,$ofs_shortname + $cnt,1);
|
||||
return %item unless (defined $s);
|
||||
if ($s =~ m/\x00/ && ((($cnt + 1) % 2) == 0)) {
|
||||
$tag = 0;
|
||||
}
|
||||
@ -742,9 +740,7 @@ sub parseFolderEntry {
|
||||
$tag = 1;
|
||||
$cnt = 0;
|
||||
while ($tag) {
|
||||
my $s = substr($data,$ofs + $cnt,2);
|
||||
return %item unless (defined $s);
|
||||
if (unpack("v",$s) == 0xbeef) {
|
||||
if (unpack("v",substr($data,$ofs + $cnt,2)) == 0xbeef) {
|
||||
$tag = 0;
|
||||
}
|
||||
else {
|
||||
@ -833,9 +829,7 @@ sub parseFolderEntry2 {
|
||||
my $tag = 1;
|
||||
|
||||
while ($tag) {
|
||||
my $s = substr($data,$ofs,2);
|
||||
return %item unless (defined $s);
|
||||
if (unpack("v",$s) == 0xbeef) {
|
||||
if (unpack("v",substr($data,$ofs,2)) == 0xbeef) {
|
||||
$tag = 0;
|
||||
}
|
||||
else {
|
||||
|
46
thirdparty/rr-full/plugins/shimcache.pl
vendored
46
thirdparty/rr-full/plugins/shimcache.pl
vendored
@ -5,6 +5,8 @@
|
||||
# works within an analysis process.
|
||||
#
|
||||
# History:
|
||||
# 20190112 - updated parsing for Win8.1
|
||||
# 20180311 - updated for more recent version of Win10/Win2016
|
||||
# 20160528 - updated
|
||||
# 20160502 - created
|
||||
#
|
||||
@ -32,7 +34,7 @@ my %config = (hive => "System",
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
osmask => 31,
|
||||
version => 20160528);
|
||||
version => 20190112);
|
||||
|
||||
sub getConfig{return %config}
|
||||
sub getShortDescr {
|
||||
@ -110,7 +112,10 @@ sub pluginmain {
|
||||
elsif ($sig == 0x80) {
|
||||
appWin8($app_data);
|
||||
}
|
||||
elsif ($sig == 0x30) {
|
||||
elsif ($sig == 0x0) {
|
||||
appWin81($app_data);
|
||||
}
|
||||
elsif ($sig == 0x30 || $sig == 0x34) {
|
||||
appWin10($app_data);
|
||||
}
|
||||
else {
|
||||
@ -283,7 +288,6 @@ sub appWin8 {
|
||||
|
||||
while($ofs < $len) {
|
||||
my $tag = unpack("V",substr($data,$ofs,4));
|
||||
last unless (defined $tag);
|
||||
# 32-bit
|
||||
if ($tag == 0x73746f72) {
|
||||
$jmp = unpack("V",substr($data,$ofs + 8,4));
|
||||
@ -315,6 +319,38 @@ sub appWin8 {
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# appWin81()
|
||||
#
|
||||
#-----------------------------------------------------------
|
||||
sub appWin81 {
|
||||
my $data = shift;
|
||||
my $len = length($data);
|
||||
my ($tag, $sz, $t0, $t1, $name, $name_len);
|
||||
my $ct = 0;
|
||||
# my $ofs = unpack("V",substr($data,0,4));
|
||||
my $ofs = 0x80;
|
||||
|
||||
while ($ofs < $len) {
|
||||
$tag = substr($data,$ofs,4);
|
||||
if ($tag eq "10ts") {
|
||||
|
||||
$sz = unpack("V",substr($data,$ofs + 0x08,4));
|
||||
$name_len = unpack("v",substr($data,$ofs + 0x0c,2));
|
||||
my $name = substr($data,$ofs + 0x0e,$name_len);
|
||||
$name =~ s/\00//g;
|
||||
# ($t0,$t1) = unpack("VV",substr($data,$ofs + 0x03 + $name_len,8));
|
||||
($t0,$t1) = unpack("VV",substr($data,$ofs + 0x0e + $name_len + 0x0a,8));
|
||||
$files{$ct}{filename} = $name;
|
||||
$files{$ct}{modtime} = ::getTime($t0,$t1);
|
||||
|
||||
$ct++;
|
||||
$ofs += ($sz + 0x0c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# appWin10()
|
||||
# Ref: http://binaryforay.blogspot.com/2015/04/appcompatcache-changes-in-windows-10.html
|
||||
@ -324,11 +360,11 @@ sub appWin10 {
|
||||
my $len = length($data);
|
||||
my ($tag, $sz, $t0, $t1, $name, $name_len);
|
||||
my $ct = 0;
|
||||
my $ofs = 0x30;
|
||||
my $ofs = unpack("V",substr($data,0,4));
|
||||
# my $ofs = 0x30;
|
||||
|
||||
while ($ofs < $len) {
|
||||
$tag = substr($data,$ofs,4);
|
||||
last unless (defined $tag);
|
||||
if ($tag eq "10ts") {
|
||||
|
||||
$sz = unpack("V",substr($data,$ofs + 0x08,4));
|
||||
|
78
thirdparty/rr-full/plugins/shimcache_tln.pl
vendored
78
thirdparty/rr-full/plugins/shimcache_tln.pl
vendored
@ -5,6 +5,8 @@
|
||||
# works within an analysis process.
|
||||
#
|
||||
# History:
|
||||
# 20190112 - updated parsing for Win8.1
|
||||
# 20180311 - updated for more recent version of Win10/Win2016
|
||||
# 20160528 - created
|
||||
#
|
||||
# References:
|
||||
@ -31,7 +33,7 @@ my %config = (hive => "System",
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
osmask => 31,
|
||||
version => 20160528);
|
||||
version => 20190112);
|
||||
|
||||
sub getConfig{return %config}
|
||||
sub getShortDescr {
|
||||
@ -109,7 +111,10 @@ sub pluginmain {
|
||||
elsif ($sig == 0x80) {
|
||||
appWin8($app_data);
|
||||
}
|
||||
elsif ($sig == 0x30) {
|
||||
elsif ($sig == 0x0) {
|
||||
appWin81($app_data);
|
||||
}
|
||||
elsif ($sig == 0x30 || $sig == 0x34) {
|
||||
appWin10($app_data);
|
||||
}
|
||||
else {
|
||||
@ -118,14 +123,16 @@ sub pluginmain {
|
||||
|
||||
foreach my $f (keys %files) {
|
||||
my $str;
|
||||
if (exists $files{$f}{executed}) {
|
||||
$str = "M... [Program Execution] AppCompatCache - ".$files{$f}{filename};
|
||||
}
|
||||
else {
|
||||
$str = "M... AppCompatCache - ".$files{$f}{filename};
|
||||
next if ($files{$f}{modtime} == 0);
|
||||
if (exists $files{$f}{updtime}) {
|
||||
# $str = "[Program Execution] AppCompatCache - ".$files{$f}{filename};
|
||||
next if ($files{$f}{updtime} == 0);
|
||||
::rptMsg($files{$f}{updtime}."|REG|||[Program Execution] - ".$files{$f}{filename});
|
||||
}
|
||||
|
||||
$str = "M... AppCompatCache - ".$files{$f}{filename};
|
||||
$str .= " [Size = ".$files{$f}{size}." bytes]" if (exists $files{$f}{size});
|
||||
$str .= " [Executed]" if (exists $files{$f}{executed});
|
||||
|
||||
::rptMsg($files{$f}{modtime}."|REG|||".$str);
|
||||
}
|
||||
}
|
||||
@ -148,8 +155,8 @@ sub appXP32Bit {
|
||||
|
||||
foreach my $i (0..($num_entries - 1)) {
|
||||
my $x = substr($data,(400 + ($i * 552)),552);
|
||||
my $file = (split(/\x00\x00/,substr($x,0,488)))[0];
|
||||
$file =~ s/\x00//g;
|
||||
my $file = (split(/\00\00/,substr($x,0,488)))[0];
|
||||
$file =~ s/\00//g;
|
||||
$file =~ s/^\\\?\?\\//;
|
||||
my ($mod1,$mod2) = unpack("VV",substr($x,528,8));
|
||||
my $modtime = ::getTime($mod1,$mod2);
|
||||
@ -192,7 +199,7 @@ sub appWin2k3 {
|
||||
my ($len,$max_len,$ofs,$t0,$t1,$f0,$f1) = unpack("vvVVVVV",$struct);
|
||||
|
||||
my $file = substr($data,$ofs,$len);
|
||||
$file =~ s/\x00//g;
|
||||
$file =~ s/\00//g;
|
||||
$file =~ s/^\\\?\?\\//;
|
||||
my $t = ::getTime($t0,$t1);
|
||||
$files{$i}{filename} = $file;
|
||||
@ -203,7 +210,7 @@ sub appWin2k3 {
|
||||
elsif ($struct_sz == 32) {
|
||||
my ($len,$max_len,$padding,$ofs0,$ofs1,$t0,$t1,$f0,$f1) = unpack("vvVVVVVVV",$struct);
|
||||
my $file = substr($data,$ofs0,$len);
|
||||
$file =~ s/\x00//g;
|
||||
$file =~ s/\00//g;
|
||||
$file =~ s/^\\\?\?\\//;
|
||||
my $t = ::getTime($t0,$t1);
|
||||
$files{i}{filename} = $file;
|
||||
@ -245,7 +252,7 @@ sub appWin7 {
|
||||
if ($struct_sz == 32) {
|
||||
my ($len,$max_len,$ofs,$t0,$t1,$f0,$f1) = unpack("vvV5x8",$struct);
|
||||
my $file = substr($data,$ofs,$len);
|
||||
$file =~ s/\x00//g;
|
||||
$file =~ s/\00//g;
|
||||
$file =~ s/^\\\?\?\\//;
|
||||
my $t = ::getTime($t0,$t1);
|
||||
$files{$i}{filename} = $file;
|
||||
@ -255,7 +262,7 @@ sub appWin7 {
|
||||
else {
|
||||
my ($len,$max_len,$padding,$ofs0,$ofs1,$t0,$t1,$f0,$f1) = unpack("vvV7x16",$struct);
|
||||
my $file = substr($data,$ofs0,$len);
|
||||
$file =~ s/\x00//g;
|
||||
$file =~ s/\00//g;
|
||||
$file =~ s/^\\\?\?\\//;
|
||||
my $t = ::getTime($t0,$t1);
|
||||
$files{$i}{filename} = $file;
|
||||
@ -277,14 +284,13 @@ sub appWin8 {
|
||||
|
||||
while($ofs < $len) {
|
||||
my $tag = unpack("V",substr($data,$ofs,4));
|
||||
last unless (defined $tag);
|
||||
# 32-bit
|
||||
if ($tag == 0x73746f72) {
|
||||
$jmp = unpack("V",substr($data,$ofs + 8,4));
|
||||
($t0,$t1) = unpack("VV",substr($data,$ofs + 12,8));
|
||||
$sz = unpack("v",substr($data,$ofs + 20,2));
|
||||
$name = substr($data,$ofs + 22,$sz);
|
||||
$name =~ s/\x00//g;
|
||||
$name =~ s/\00//g;
|
||||
$files{$ct}{filename} = $name;
|
||||
$files{$ct}{modtime} = ::getTime($t0,$t1);
|
||||
$ct++;
|
||||
@ -295,7 +301,7 @@ sub appWin8 {
|
||||
$jmp = unpack("V",substr($data,$ofs + 8,4));
|
||||
$sz = unpack("v",substr($data,$ofs + 0x0C,2));
|
||||
$name = substr($data,$ofs + 0x0E,$sz + 2);
|
||||
$name =~ s/\x00//g;
|
||||
$name =~ s/\00//g;
|
||||
($t0,$t1) = unpack("VV",substr($data,($ofs + 0x0E + $sz +2 + 8),8));
|
||||
$files{$ct}{filename} = $name;
|
||||
$files{$ct}{modtime} = ::getTime($t0,$t1);
|
||||
@ -309,6 +315,38 @@ sub appWin8 {
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# appWin81()
|
||||
#
|
||||
#-----------------------------------------------------------
|
||||
sub appWin81 {
|
||||
my $data = shift;
|
||||
my $len = length($data);
|
||||
my ($tag, $sz, $t0, $t1, $name, $name_len);
|
||||
my $ct = 0;
|
||||
# my $ofs = unpack("V",substr($data,0,4));
|
||||
my $ofs = 0x80;
|
||||
|
||||
while ($ofs < $len) {
|
||||
$tag = substr($data,$ofs,4);
|
||||
if ($tag eq "10ts") {
|
||||
|
||||
$sz = unpack("V",substr($data,$ofs + 0x08,4));
|
||||
$name_len = unpack("v",substr($data,$ofs + 0x0c,2));
|
||||
my $name = substr($data,$ofs + 0x0e,$name_len);
|
||||
$name =~ s/\00//g;
|
||||
# ($t0,$t1) = unpack("VV",substr($data,$ofs + 0x03 + $name_len,8));
|
||||
($t0,$t1) = unpack("VV",substr($data,$ofs + 0x0e + $name_len + 0x0a,8));
|
||||
$files{$ct}{filename} = $name;
|
||||
$files{$ct}{modtime} = ::getTime($t0,$t1);
|
||||
|
||||
$ct++;
|
||||
$ofs += ($sz + 0x0c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# appWin10()
|
||||
# Ref: http://binaryforay.blogspot.com/2015/04/appcompatcache-changes-in-windows-10.html
|
||||
@ -318,17 +356,17 @@ sub appWin10 {
|
||||
my $len = length($data);
|
||||
my ($tag, $sz, $t0, $t1, $name, $name_len);
|
||||
my $ct = 0;
|
||||
my $ofs = 0x30;
|
||||
my $ofs = unpack("V",substr($data,0,4));
|
||||
# my $ofs = 0x30;
|
||||
|
||||
while ($ofs < $len) {
|
||||
$tag = substr($data,$ofs,4);
|
||||
last unless (defined $tag);
|
||||
if ($tag eq "10ts") {
|
||||
|
||||
$sz = unpack("V",substr($data,$ofs + 0x08,4));
|
||||
$name_len = unpack("v",substr($data,$ofs + 0x0c,2));
|
||||
my $name = substr($data,$ofs + 0x0e,$name_len);
|
||||
$name =~ s/\x00//g;
|
||||
$name =~ s/\00//g;
|
||||
# ($t0,$t1) = unpack("VV",substr($data,$ofs + 0x03 + $name_len,8));
|
||||
($t0,$t1) = unpack("VV",substr($data,$ofs + 0x0e + $name_len,8));
|
||||
$files{$ct}{filename} = $name;
|
||||
|
100
thirdparty/rr-full/plugins/sizes.pl
vendored
100
thirdparty/rr-full/plugins/sizes.pl
vendored
@ -6,6 +6,8 @@
|
||||
# sizes; change $min_size value to suit your needs
|
||||
#
|
||||
# Change history
|
||||
# 20180817 - updated to include brief output, based on suggestion from J. Wood
|
||||
# 20180607 - modified based on Meterpreter input from Mari DeGrazia
|
||||
# 20150527 - Created
|
||||
#
|
||||
# copyright 2015 QAR, LLC
|
||||
@ -14,16 +16,19 @@
|
||||
package sizes;
|
||||
use strict;
|
||||
|
||||
my $min_size = 5000;
|
||||
my $output_size = 48;
|
||||
|
||||
my %config = (hive => "All",
|
||||
hasShortDescr => 1,
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
osmask => 22,
|
||||
version => 20150527);
|
||||
version => 20180817);
|
||||
|
||||
sub getConfig{return %config}
|
||||
sub getShortDescr {
|
||||
return "Scans a hive file looking for binary value data of a min size";
|
||||
return "Scans a hive file looking for binary value data of a min size (".$min_size.")";
|
||||
}
|
||||
sub getDescr{}
|
||||
sub getRefs {}
|
||||
@ -31,7 +36,7 @@ sub getHive {return $config{hive};}
|
||||
sub getVersion {return $config{version};}
|
||||
|
||||
my $VERSION = getVersion();
|
||||
my $min_size = 50000;
|
||||
my $count = 0;
|
||||
|
||||
sub pluginmain {
|
||||
my $class = shift;
|
||||
@ -40,8 +45,16 @@ sub pluginmain {
|
||||
my $root_key = $reg->get_root_key;
|
||||
::logMsg("Launching sizes v.".$VERSION);
|
||||
::rptMsg("sizes v.".$VERSION);
|
||||
::rptMsg("(".getHive().") ".getShortDescr()."\n");
|
||||
::rptMsg("(".getHive().") ".getShortDescr()."\n");
|
||||
|
||||
my $start = time;
|
||||
|
||||
traverse($root_key);
|
||||
|
||||
my $finish = time;
|
||||
|
||||
::rptMsg("Scan completed: ".($finish - $start)." sec");
|
||||
::rptMsg("Total values : ".$count);
|
||||
}
|
||||
|
||||
sub traverse {
|
||||
@ -49,8 +62,9 @@ sub traverse {
|
||||
# my $ts = $key->get_timestamp();
|
||||
|
||||
foreach my $val ($key->get_list_of_values()) {
|
||||
$count++;
|
||||
my $type = $val->get_type();
|
||||
if ($type == 0 || $type == 3) {
|
||||
if ($type == 0 || $type == 3 || $type == 1 || $type == 2) {
|
||||
my $data = $val->get_data();
|
||||
my $len = length($data);
|
||||
if ($len > $min_size) {
|
||||
@ -59,10 +73,19 @@ sub traverse {
|
||||
$name[0] = "";
|
||||
$name[0] = "\\" if (scalar(@name) == 1);
|
||||
my $path = join('\\',@name);
|
||||
::rptMsg("Key : ".$path." Value: ".$val->get_name()." Size: ".$len." bytes");
|
||||
|
||||
# Data type "none", "Reg_SZ", "Reg_Expand_SZ"
|
||||
if ($type == 0 || $type == 1 || $type == 2) {
|
||||
::rptMsg("Data Sample (first ".$output_size." bytes) : ".substr($data,0,$output_size)."...");
|
||||
}
|
||||
|
||||
# Binary data
|
||||
if ($type == 3) {
|
||||
my $out = substr($data,0,$output_size);
|
||||
probe($out);
|
||||
}
|
||||
|
||||
::rptMsg("Key : ".$path);
|
||||
::rptMsg("Value: ".$val->get_name());
|
||||
::rptMsg("Size : ".$len." bytes.");
|
||||
::rptMsg("");
|
||||
}
|
||||
}
|
||||
@ -73,4 +96,65 @@ sub traverse {
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# probe()
|
||||
#
|
||||
# Code the uses printData() to insert a 'probe' into a specific
|
||||
# location and display the data
|
||||
#
|
||||
# Input: binary data of arbitrary length
|
||||
# Output: Nothing, no return value. Displays data to the console
|
||||
#-----------------------------------------------------------
|
||||
sub probe {
|
||||
my $data = shift;
|
||||
my @d = printData($data);
|
||||
::rptMsg("");
|
||||
foreach (0..(scalar(@d) - 1)) {
|
||||
::rptMsg($d[$_]);
|
||||
}
|
||||
::rptMsg("");
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# printData()
|
||||
# subroutine used primarily for debugging; takes an arbitrary
|
||||
# length of binary data, prints it out in hex editor-style
|
||||
# format for easy debugging
|
||||
#
|
||||
# Usage: see probe()
|
||||
#-----------------------------------------------------------
|
||||
sub printData {
|
||||
my $data = shift;
|
||||
my $len = length($data);
|
||||
|
||||
my @display = ();
|
||||
|
||||
my $loop = $len/16;
|
||||
$loop++ if ($len%16);
|
||||
|
||||
foreach my $cnt (0..($loop - 1)) {
|
||||
# How much is left?
|
||||
my $left = $len - ($cnt * 16);
|
||||
|
||||
my $n;
|
||||
($left < 16) ? ($n = $left) : ($n = 16);
|
||||
|
||||
my $seg = substr($data,$cnt * 16,$n);
|
||||
my $lhs = "";
|
||||
my $rhs = "";
|
||||
foreach my $i ($seg =~ m/./gs) {
|
||||
# This loop is to process each character at a time.
|
||||
$lhs .= sprintf(" %02X",ord($i));
|
||||
if ($i =~ m/[ -~]/) {
|
||||
$rhs .= $i;
|
||||
}
|
||||
else {
|
||||
$rhs .= ".";
|
||||
}
|
||||
}
|
||||
$display[$cnt] = sprintf("0x%08X %-50s %s",$cnt,$lhs,$rhs);
|
||||
}
|
||||
return @display;
|
||||
}
|
||||
|
||||
1;
|
200
thirdparty/rr-full/plugins/software
vendored
200
thirdparty/rr-full/plugins/software
vendored
@ -1,98 +1,102 @@
|
||||
# 20161213 *ALL* Plugins that apply on SOFTWARE hive, alphabetical order
|
||||
ahaha
|
||||
appinitdlls
|
||||
apppaths
|
||||
apppaths_tln
|
||||
assoc
|
||||
at
|
||||
at_tln
|
||||
audiodev
|
||||
banner
|
||||
bho
|
||||
bitbucket
|
||||
btconfig
|
||||
clsid
|
||||
cmd_shell
|
||||
cmd_shell_tln
|
||||
codeid
|
||||
ctrlpnl
|
||||
dcom
|
||||
dfrg
|
||||
direct
|
||||
direct_tln
|
||||
disablesr
|
||||
drivers32
|
||||
drwatson
|
||||
emdmgmt
|
||||
esent
|
||||
etos
|
||||
gauss
|
||||
gpohist
|
||||
gpohist_tln
|
||||
handler
|
||||
ie_version
|
||||
ie_zones
|
||||
imagefile
|
||||
init_dlls
|
||||
inprocserver
|
||||
installedcomp
|
||||
installer
|
||||
javasoft
|
||||
kb950582
|
||||
landesk
|
||||
landesk_tln
|
||||
lastloggedon
|
||||
lazyshell
|
||||
licenses
|
||||
logmein
|
||||
logmein_tln
|
||||
macaddr
|
||||
mrt
|
||||
msis
|
||||
netsh
|
||||
networkcards
|
||||
networklist
|
||||
networklist_tln
|
||||
networkuid
|
||||
opencandy
|
||||
port_dev
|
||||
product
|
||||
profilelist
|
||||
regback
|
||||
removdev
|
||||
renocide
|
||||
schedagent
|
||||
secctr
|
||||
sfc
|
||||
shellexec
|
||||
shellext
|
||||
shelloverlay
|
||||
snapshot
|
||||
soft_run
|
||||
spp_clients
|
||||
sql_lastconnect
|
||||
srun_tln
|
||||
ssid
|
||||
startmenuinternetapps_lm
|
||||
susclient
|
||||
svchost
|
||||
systemindex
|
||||
teamviewer
|
||||
tracing
|
||||
tracing_tln
|
||||
trappoll
|
||||
uac
|
||||
uninstall
|
||||
uninstall_tln
|
||||
urlzone
|
||||
virut
|
||||
volinfocache
|
||||
wbem
|
||||
winbackup
|
||||
win_cv
|
||||
winevt
|
||||
winlogon
|
||||
winlogon_tln
|
||||
winnt_cv
|
||||
winver
|
||||
yahoo_lm
|
||||
ahaha
|
||||
appcompatflags
|
||||
appinitdlls
|
||||
appkeys
|
||||
apppaths
|
||||
assoc
|
||||
at
|
||||
audiodev
|
||||
banner
|
||||
bho
|
||||
bitbucket
|
||||
btconfig
|
||||
clsid
|
||||
cmd_shell
|
||||
codeid
|
||||
ctrlpnl
|
||||
dcom
|
||||
defbrowser
|
||||
dfrg
|
||||
direct
|
||||
disablesr
|
||||
drivers32
|
||||
drwatson
|
||||
emdmgmt
|
||||
esent
|
||||
etos
|
||||
execpolicy
|
||||
gauss
|
||||
gpohist
|
||||
handler
|
||||
ie_version
|
||||
ie_zones
|
||||
imagefile
|
||||
init_dlls
|
||||
inprocserver
|
||||
installedcomp
|
||||
installer
|
||||
javasoft
|
||||
kankan
|
||||
kb950582
|
||||
landesk
|
||||
lastloggedon
|
||||
lazyshell
|
||||
licenses
|
||||
logmein
|
||||
macaddr
|
||||
mrt
|
||||
msis
|
||||
netsh
|
||||
networkcards
|
||||
networklist
|
||||
networkuid
|
||||
opencandy
|
||||
port_dev
|
||||
product
|
||||
profilelist
|
||||
pslogging
|
||||
psscript
|
||||
regback
|
||||
removdev
|
||||
renocide
|
||||
runonceex
|
||||
sbs
|
||||
schedagent
|
||||
secctr
|
||||
sfc
|
||||
shellexec
|
||||
shellext
|
||||
shelloverlay
|
||||
silentprocessexit
|
||||
snapshot
|
||||
soft_run
|
||||
spp_clients
|
||||
sql_lastconnect
|
||||
ssid
|
||||
startmenuinternetapps_lm
|
||||
susclient
|
||||
svchost
|
||||
systemindex
|
||||
teamviewer
|
||||
termserv
|
||||
thunderbirdinstalled
|
||||
tracing
|
||||
trappoll
|
||||
uac
|
||||
uninstall
|
||||
updates
|
||||
urlzone
|
||||
virut
|
||||
volinfocache
|
||||
watp
|
||||
wbem
|
||||
webroot
|
||||
winbackup
|
||||
winevt
|
||||
winlogon
|
||||
winnt_cv
|
||||
winver
|
||||
win_cv
|
||||
wow64
|
||||
wsh_settings
|
||||
yahoo_lm
|
||||
|
2
thirdparty/rr-full/plugins/svc_plus.pl
vendored
2
thirdparty/rr-full/plugins/svc_plus.pl
vendored
@ -25,7 +25,7 @@ my %config = (hive => "System",
|
||||
|
||||
sub getConfig{return %config}
|
||||
sub getShortDescr {
|
||||
return "Lists services/drivers in Services key by LastWrite times in a short format with warnings for type mismatches\n^^^^ Indicates non-standard Type\n<<<< Indicates Start mismatch for Driver\n**** Indicates ObjectName mismatch for Driver\n>>>> Indicates Start mismatch for Service\n++++ Indicates nonstandard ObjectName for Service.";
|
||||
return "Lists services/drivers in Services key by LastWrite times in a short format with warnings for type mismatches; ^^^^ Indicates non-standard Type, <<<< Indicates Start mismatch for Driver, **** Indicates ObjectName mismatch for Driver, >>>> Indicates Start mismatch for Service, ++++ Indicates nonstandard ObjectName for Service.";
|
||||
}
|
||||
sub getDescr{}
|
||||
sub getRefs {}
|
||||
|
141
thirdparty/rr-full/plugins/system
vendored
141
thirdparty/rr-full/plugins/system
vendored
@ -1,70 +1,71 @@
|
||||
# 20161213 *ALL* Plugins that apply on SYSTEM hive, alphabetical order
|
||||
appcertdlls
|
||||
appcompatcache
|
||||
appcompatcache_tln
|
||||
auditfail
|
||||
backuprestore
|
||||
bthport
|
||||
comfoo
|
||||
compname
|
||||
crashcontrol
|
||||
ddm
|
||||
devclass
|
||||
diag_sr
|
||||
disablelastaccess
|
||||
dllsearch
|
||||
dnschanger
|
||||
eventlog
|
||||
eventlogs
|
||||
fw_config
|
||||
hibernate
|
||||
ide
|
||||
imagedev
|
||||
kbdcrash
|
||||
legacy
|
||||
legacy_tln
|
||||
lsa_packages
|
||||
mountdev
|
||||
mountdev2
|
||||
netsvcs
|
||||
network
|
||||
nic
|
||||
nic2
|
||||
nic_mst2
|
||||
nolmhash
|
||||
pagefile
|
||||
pending
|
||||
phdet
|
||||
prefetch
|
||||
processor_architecture
|
||||
productpolicy
|
||||
producttype
|
||||
rdpnla
|
||||
rdpport
|
||||
regin
|
||||
remoteaccess
|
||||
routes
|
||||
safeboot
|
||||
securityproviders
|
||||
services
|
||||
shares
|
||||
shimcache
|
||||
shimcache_tln
|
||||
shutdown
|
||||
shutdowncount
|
||||
stillimage
|
||||
svc
|
||||
svcdll
|
||||
svc_plus
|
||||
svc_tln
|
||||
systemindex
|
||||
termcert
|
||||
termserv
|
||||
timezone
|
||||
usb
|
||||
usbdevices
|
||||
usbstor
|
||||
usbstor2
|
||||
usbstor3
|
||||
wpdbusenum
|
||||
xpedition
|
||||
angelfire
|
||||
appcertdlls
|
||||
appcompatcache
|
||||
auditfail
|
||||
backuprestore
|
||||
bam
|
||||
bthport
|
||||
comfoo
|
||||
compname
|
||||
crashcontrol
|
||||
dafupnp
|
||||
ddm
|
||||
devclass
|
||||
diag_sr
|
||||
disablelastaccess
|
||||
dllsearch
|
||||
dnschanger
|
||||
eventlog
|
||||
eventlogs
|
||||
fw_config
|
||||
hibernate
|
||||
ide
|
||||
imagedev
|
||||
kbdcrash
|
||||
legacy
|
||||
lsa_packages
|
||||
macaddr
|
||||
mountdev
|
||||
mountdev2
|
||||
netlogon
|
||||
netsvcs
|
||||
network
|
||||
nic
|
||||
nic2
|
||||
nic_mst2
|
||||
nolmhash
|
||||
pagefile
|
||||
pending
|
||||
phdet
|
||||
prefetch
|
||||
processor_architecture
|
||||
productpolicy
|
||||
producttype
|
||||
profiler
|
||||
rdpnla
|
||||
rdpport
|
||||
regin
|
||||
remoteaccess
|
||||
routes
|
||||
safeboot
|
||||
securityproviders
|
||||
services
|
||||
shares
|
||||
shimcache
|
||||
shutdown
|
||||
shutdowncount
|
||||
source_os
|
||||
stillimage
|
||||
svc
|
||||
svcdll
|
||||
svc_plus
|
||||
termcert
|
||||
termserv
|
||||
timezone
|
||||
usb
|
||||
usbdevices
|
||||
usbstor
|
||||
usbstor2
|
||||
usbstor3
|
||||
wpdbusenum
|
||||
xpedition
|
||||
|
53
thirdparty/rr-full/plugins/termserv.pl
vendored
53
thirdparty/rr-full/plugins/termserv.pl
vendored
@ -3,6 +3,7 @@
|
||||
# Plugin for Registry Ripper;
|
||||
#
|
||||
# Change history
|
||||
# 20190527 - Added checks in Software hive
|
||||
# 20160224 - added SysProcs info
|
||||
# 20131007 - updated with Sticky Keys info
|
||||
# 20130307 - updated with autostart locations
|
||||
@ -27,16 +28,16 @@
|
||||
package termserv;
|
||||
use strict;
|
||||
|
||||
my %config = (hive => "System",
|
||||
my %config = (hive => "System, Software",
|
||||
hasShortDescr => 1,
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
osmask => 22,
|
||||
version => 20160224);
|
||||
version => 20190527);
|
||||
|
||||
sub getConfig{return %config}
|
||||
sub getShortDescr {
|
||||
return "Gets Terminal Server values from System hive";
|
||||
return "Gets Terminal Server settings from System and Software hives";
|
||||
}
|
||||
sub getDescr{}
|
||||
sub getRefs {}
|
||||
@ -66,8 +67,6 @@ sub pluginmain {
|
||||
::rptMsg($ts_path);
|
||||
::rptMsg("LastWrite Time ".gmtime($ts->get_timestamp())." (UTC)");
|
||||
::rptMsg("");
|
||||
::rptMsg("Reference: http://support.microsoft.com/kb/243215");
|
||||
::rptMsg("");
|
||||
|
||||
my $ver;
|
||||
eval {
|
||||
@ -151,6 +150,14 @@ sub pluginmain {
|
||||
};
|
||||
::rptMsg(" InitialProgram value not found\.") if ($@);
|
||||
|
||||
# Added 20190527
|
||||
eval {
|
||||
my $sec = $ts->get_subkey("WinStations\\RDP-Tcp")->get_value("SecurityLayer")->get_data();
|
||||
::rptMsg("WinStations\\RDP-Tcp key");
|
||||
::rptMsg(" SecurityLayer: ".$sec);
|
||||
::rptMsg("Analysis Tip: Maybe be empty; appears as '{blank}'");
|
||||
};
|
||||
|
||||
# Added 20160224
|
||||
eval {
|
||||
my $sys = $ts->get_subkey("SysProcs");
|
||||
@ -185,5 +192,41 @@ sub pluginmain {
|
||||
else {
|
||||
::rptMsg($key_path." not found.");
|
||||
}
|
||||
|
||||
# Added 20190527
|
||||
$key_path = "Policies\\Microsoft\\Windows NT\\Terminal Services";
|
||||
if ($key = $root_key->get_subkey($key_path)) {
|
||||
my $lw = $key->get_timestamp();
|
||||
::rptMsg($key_path);
|
||||
::rptMsg("LastWrite: ".gmtime($lw)." Z");
|
||||
::rptMsg("");
|
||||
|
||||
# Note: fDenyTSConnections was added here because I've seen it used by bad actors,
|
||||
# not due to any MS documentation
|
||||
eval {
|
||||
my $deny = $key->get_value("fDenyTSConnections")->get_data();
|
||||
::rptMsg("fDenyTSConnections value = ".$deny);
|
||||
};
|
||||
|
||||
eval {
|
||||
my $fallow = $key->get_value("fAllowUnsolicited")->get_data();
|
||||
::rptMsg("fAllowUnsolicited value = ".$fallow);
|
||||
};
|
||||
|
||||
|
||||
eval {
|
||||
my $fallowfc = $key->get_value("fAllowUnsolicitedFullControl")->get_data();
|
||||
::rptMsg("fAllowUnsolicitedFullControl value = ".$fallowfc);
|
||||
};
|
||||
|
||||
eval {
|
||||
my $user = $key->get_value("UserAuthentication")->get_data();
|
||||
::rptMsg("UserAuthentication value = ".$user);
|
||||
};
|
||||
|
||||
}
|
||||
else {
|
||||
::rptMsg($key_path." not found.");
|
||||
}
|
||||
}
|
||||
1;
|
22
thirdparty/rr-full/plugins/trustrecords.pl
vendored
22
thirdparty/rr-full/plugins/trustrecords.pl
vendored
@ -4,10 +4,15 @@
|
||||
# the default security settings for the application
|
||||
#
|
||||
# Change history
|
||||
# 20190626 - updated to more recent versions of Office
|
||||
# 20160224 - modified per Mari's blog post
|
||||
# 20120716 - created
|
||||
#
|
||||
# References
|
||||
# 20190626 updates
|
||||
# https://decentsecurity.com/block-office-macros
|
||||
# https://gist.github.com/PSJoshi/749cf1733217d8791cf956574a3583a2
|
||||
#
|
||||
# http://az4n6.blogspot.com/2016/02/more-on-trust-records-macros-and.html
|
||||
# ForensicArtifacts.com posting by Andrew Case:
|
||||
# http://forensicartifacts.com/2012/07/ntuser-trust-records/
|
||||
@ -25,7 +30,7 @@ my %config = (hive => "NTUSER\.DAT",
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
osmask => 22,
|
||||
version => 20160224);
|
||||
version => 20190626);
|
||||
|
||||
sub getConfig{return %config}
|
||||
sub getShortDescr {
|
||||
@ -76,7 +81,7 @@ sub pluginmain {
|
||||
# Now that we have the most recent version of Office installed, let's
|
||||
# start looking at the various subkeys
|
||||
my @apps = ("Word","PowerPoint","Excel","Access");
|
||||
$key_path = "Software\\Microsoft\\Office\\".$office_version;
|
||||
my $key_path = "Software\\Microsoft\\Office\\".$office_version;
|
||||
|
||||
foreach my $app (@apps) {
|
||||
::rptMsg("**".$app."**");
|
||||
@ -90,11 +95,22 @@ sub pluginmain {
|
||||
::rptMsg("");
|
||||
}
|
||||
};
|
||||
|
||||
# Added 20190626
|
||||
eval {
|
||||
if (my $sec = $root_key->get_subkey($app_path)) {
|
||||
my $blk = $sec->get_value("blockcontentexecutionfrominternet")->get_data();
|
||||
::rptMsg("blockcontentexecutionfrominternet = ".$blk);
|
||||
::rptMsg("");
|
||||
}
|
||||
};
|
||||
|
||||
# Trusted Documents/Trust Records
|
||||
$app_path = $key_path."\\".$app."\\Security\\Trusted Documents";
|
||||
if (my $app_key = $root_key->get_subkey($app_path)) {
|
||||
if (my $trust = $app_key->get_subkey("TrustRecords")) {
|
||||
my @vals = $trust->get_list_of_values();
|
||||
::rptMsg("TrustRecords");
|
||||
foreach my $v (@vals) {
|
||||
my $data = $v->get_data();
|
||||
my ($t0,$t1) = (unpack("VV",substr($data,0,8)));
|
||||
@ -110,4 +126,4 @@ sub pluginmain {
|
||||
|
||||
}
|
||||
}
|
||||
1;
|
||||
1;
|
19
thirdparty/rr-full/plugins/userassist_tln.pl
vendored
19
thirdparty/rr-full/plugins/userassist_tln.pl
vendored
@ -5,6 +5,7 @@
|
||||
# UserAssist values
|
||||
#
|
||||
# Change history
|
||||
# 20180710 - removed alert functionality
|
||||
# 20130603 - added alert functionality
|
||||
# 20110516 - created, modified from userassist2.pl
|
||||
# 20100322 - Added CLSID list reference
|
||||
@ -24,12 +25,7 @@ my %config = (hive => "NTUSER\.DAT",
|
||||
hasDescr => 0,
|
||||
hasRefs => 0,
|
||||
osmask => 22,
|
||||
version => 20130603);
|
||||
|
||||
my @paths = ("recycle","globalroot","temp","system volume information","appdata",
|
||||
"application data");
|
||||
|
||||
my @alerts = ();
|
||||
version => 20180710);
|
||||
|
||||
sub getConfig{return %config}
|
||||
sub getShortDescr {
|
||||
@ -113,19 +109,8 @@ sub processKey {
|
||||
foreach my $t (reverse sort {$a <=> $b} keys %ua) {
|
||||
foreach my $i (@{$ua{$t}}) {
|
||||
::rptMsg($t."|REG|||[Program Execution] UserAssist - ".$i);
|
||||
|
||||
my $lci = lc($i);
|
||||
foreach my $a (@paths) {
|
||||
push(@alerts,$t."|ALERT|||UserAssist: ".$a." found in path: ".$i) if (grep(/$a/,$lci));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (scalar(@alerts) > 0) {
|
||||
foreach (@alerts) {
|
||||
::alertMsg($_);
|
||||
}
|
||||
}
|
||||
}
|
||||
1;
|
13
thirdparty/rr-full/plugins/usrclass
vendored
13
thirdparty/rr-full/plugins/usrclass
vendored
@ -1,5 +1,8 @@
|
||||
# 20161213 *ALL* Plugins that apply on USRCLASS hive, alphabetical order
|
||||
cmd_shell_u
|
||||
photos
|
||||
shellbags
|
||||
shellbags_tln
|
||||
assoc
|
||||
cmd_shell_u
|
||||
msedge_win10
|
||||
muicache
|
||||
photos
|
||||
photos_win10
|
||||
shellbags
|
||||
shellbags_test
|
||||
|
BIN
thirdparty/rr-full/rip.exe
vendored
BIN
thirdparty/rr-full/rip.exe
vendored
Binary file not shown.
74
thirdparty/rr-full/rip.pl
vendored
74
thirdparty/rr-full/rip.pl
vendored
@ -8,6 +8,9 @@
|
||||
# Usage: see "_syntax()" function
|
||||
#
|
||||
# Change History
|
||||
# 20190318 - modified code to allow the .exe to be run from anywhere within the file system
|
||||
# 20190128 - added Time::Local, modifications to module Key.pm
|
||||
# 20180406 - added "-uP" switch to update profiles
|
||||
# 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
|
||||
@ -18,15 +21,14 @@
|
||||
# 20080419 - added '-g' switch (experimental)
|
||||
# 20080412 - added '-c' switch
|
||||
#
|
||||
# copyright 2013 Quantum Analytics Research, LLC
|
||||
# copyright 2013-2019 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 Time::Local;
|
||||
use File::Spec;
|
||||
|
||||
# Included to permit compiling via Perl2Exe
|
||||
@ -46,7 +48,7 @@ use File::Spec;
|
||||
|
||||
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));
|
||||
GetOptions(\%config,qw(reg|r=s file|f=s csv|c guess|g user|u=s sys|s=s plugin|p=s update|uP list|l help|?|h));
|
||||
|
||||
# Code updated 20090102
|
||||
my @path;
|
||||
@ -55,15 +57,17 @@ my $str = $0;
|
||||
: (@path = split(/\//,$0));
|
||||
$str =~ s/($path[scalar(@path) - 1])//;
|
||||
|
||||
# Suggested addition by Hal Pomeranz for compatibility with
|
||||
# Linux
|
||||
# Suggested addition by Hal Pomeranz for compatibility with Linux
|
||||
#push(@INC,$str);
|
||||
|
||||
# code updated 20190318
|
||||
my $plugindir;
|
||||
($^O eq "MSWin32") ? ($plugindir = $str."plugins/")
|
||||
: ($plugindir = File::Spec->catfile("plugins"));
|
||||
#my $plugindir = $str."plugins/";
|
||||
my $plugindir = File::Spec->catfile("plugins");
|
||||
#my $plugindir = File::Spec->catfile("plugins");
|
||||
#print "Plugins Dir = ".$plugindir."\n";
|
||||
# End code update
|
||||
my $VERSION = "2\.8_20130801";
|
||||
my $VERSION = "2\.8_20190318";
|
||||
my @alerts = ();
|
||||
|
||||
if ($config{help} || !%config) {
|
||||
@ -107,6 +111,55 @@ if ($config{list}) {
|
||||
exit;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------
|
||||
#
|
||||
#-------------------------------------------------------------
|
||||
if ($config{update}) {
|
||||
my @plugins;
|
||||
opendir(DIR,$plugindir) || die "Could not open $plugindir: $!\n";
|
||||
@plugins = readdir(DIR);
|
||||
closedir(DIR);
|
||||
# hash of lists to hold plugin names
|
||||
my %files = ();
|
||||
|
||||
foreach my $p (@plugins) {
|
||||
next unless ($p =~ m/\.pl$/);
|
||||
# $pkg = name of plugin
|
||||
my $pkg = (split(/\./,$p,2))[0];
|
||||
# $p = $plugindir.$p;
|
||||
$p = File::Spec->catfile($plugindir,$p);
|
||||
eval {
|
||||
require $p;
|
||||
my $hive = $pkg->getHive();
|
||||
my @hives = split(/,/,$hive);
|
||||
foreach my $h (@hives) {
|
||||
my $lch = lc($h);
|
||||
$lch =~ s/\.dat$//;
|
||||
$lch =~ s/^\s+//;
|
||||
|
||||
push(@{$files{$lch}},$pkg);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
print "Error: $@\n" if ($@);
|
||||
}
|
||||
|
||||
# once hash of lists is populated, print files
|
||||
foreach my $f (keys %files) {
|
||||
my $filepath = $plugindir."\\".$f;
|
||||
open(FH,">",$filepath) || die "Could not open ".$filepath." to write: $!";
|
||||
|
||||
for my $i (0..$#{$files{$f}}) {
|
||||
next if ($files{$f}[$i] =~ m/tln$/);
|
||||
print FH $files{$f}[$i]."\n";
|
||||
}
|
||||
|
||||
close(FH);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------
|
||||
#
|
||||
#-------------------------------------------------------------
|
||||
@ -199,6 +252,7 @@ Parse Windows Registry files, using either a single module, or a plugins file.
|
||||
-c ................Output list in CSV format (use with -l)
|
||||
-s system name.....Server name (TLN support)
|
||||
-u username........User name (TLN support)
|
||||
-uP ...............Update profiles
|
||||
-h.................Help (print this information)
|
||||
|
||||
Ex: C:\\>rip -r c:\\case\\system -f system
|
||||
@ -207,7 +261,7 @@ Ex: C:\\>rip -r c:\\case\\system -f system
|
||||
|
||||
All output goes to STDOUT; use redirection (ie, > or >>) to output to a file\.
|
||||
|
||||
copyright 2013 Quantum Analytics Research, LLC
|
||||
copyright 2019 Quantum Analytics Research, LLC
|
||||
EOT
|
||||
}
|
||||
|
||||
|
BIN
thirdparty/rr-full/rip_bulk.zip
vendored
Normal file
BIN
thirdparty/rr-full/rip_bulk.zip
vendored
Normal file
Binary file not shown.
BIN
thirdparty/rr-full/rr.exe
vendored
BIN
thirdparty/rr-full/rr.exe
vendored
Binary file not shown.
10
thirdparty/rr-full/rr.pl
vendored
10
thirdparty/rr-full/rr.pl
vendored
@ -8,6 +8,7 @@
|
||||
# version
|
||||
#
|
||||
# Change History:
|
||||
# 20190128 - added Time::Local, modifications to module Key.pm
|
||||
# 20130429 - minor updates, including not adding .txt files to Profile list
|
||||
# 20130425 - added alertMsg() functionality, updated to v2.8
|
||||
# 20120505 - Updated to v2.5
|
||||
@ -34,14 +35,13 @@
|
||||
# Functionality:
|
||||
# - plugins file is selectable
|
||||
#
|
||||
# copyright 2013 Quantum Research Analytics, LLC
|
||||
# copyright 2013-2019 Quantum Research Analytics, 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 Win32::GUI();
|
||||
use Time::Local;
|
||||
use Parse::Win32Registry qw(:REG_);
|
||||
|
||||
# Included to permit compiling via Perl2Exe
|
||||
@ -61,7 +61,7 @@ use Parse::Win32Registry qw(:REG_);
|
||||
#-----------------------------------------------------------
|
||||
# Global variables
|
||||
#-----------------------------------------------------------
|
||||
my $VERSION = "2\.8";
|
||||
my $VERSION = "2\.8_20190128";
|
||||
my %env;
|
||||
my @alerts = ();
|
||||
|
||||
@ -318,7 +318,7 @@ sub RR_OnAbout {
|
||||
"Parses Registry hive (NTUSER\.DAT, System, etc.) files, placing pertinent info in a report ".
|
||||
"file in a readable manner.\r\n".
|
||||
"\r\n".
|
||||
"Copyright 2013 Quantum Analytics Research, LLC.\r\n".
|
||||
"Copyright 2019 Quantum Analytics Research, LLC.\r\n".
|
||||
"H\. Carvey, keydet89\@yahoo\.com",
|
||||
"About...",
|
||||
MB_ICONINFORMATION | MB_OK,
|
||||
|
6064
thirdparty/rr-full/sample.txt
vendored
Normal file
6064
thirdparty/rr-full/sample.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
835
thirdparty/rr-full/shellitems.pl
vendored
Normal file
835
thirdparty/rr-full/shellitems.pl
vendored
Normal file
@ -0,0 +1,835 @@
|
||||
#-----------------------------------------------------------
|
||||
# shellitems.pl
|
||||
# Perl script to parse shell items; access via 'require' pragma
|
||||
#
|
||||
# History:
|
||||
# 20130923 - updated printData() code with (what I hope is) more stable
|
||||
# code
|
||||
# 20130522 - created
|
||||
#
|
||||
# References
|
||||
# Andrew's Python code for Registry Decoder
|
||||
# http://code.google.com/p/registrydecoder/source/browse/trunk/templates/template_files/ShellBagMRU.py
|
||||
# Joachim Metz's shell item format specification
|
||||
# http://download.polytechnic.edu.na/pub4/download.sourceforge.net/pub/
|
||||
# sourceforge/l/project/li/liblnk/Documentation/Windows%20Shell%20Item%20format/
|
||||
# Windows%20Shell%20Item%20format.pdf
|
||||
# Converting DOS Date format
|
||||
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms724274(v=VS.85).aspx
|
||||
#
|
||||
# Thanks to Willi Ballenthin and Joachim Metz for the documentation they
|
||||
# provided, Andrew Case for posting the Registry Decoder code, and Kevin
|
||||
# Moore for writing the shell bag parser for Registry Decoder, as well as
|
||||
# assistance with some parsing.
|
||||
#
|
||||
#
|
||||
# copyright 2012 Quantum Analytics Research, LLC
|
||||
# Author: H. Carvey, keydet89@yahoo.com
|
||||
#-----------------------------------------------------------
|
||||
use Time::Local;
|
||||
|
||||
my %guids = ("{bb64f8a7-bee7-4e1a-ab8d-7d8273f7fdb6}" => "Action Center",
|
||||
"{7a979262-40ce-46ff-aeee-7884ac3b6136}" => "Add Hardware",
|
||||
"{d20ea4e1-3957-11d2-a40b-0c5020524153}" => "Administrative Tools",
|
||||
"{c57a6066-66a3-4d91-9eb9-41532179f0a5}" => "AppSuggestedLocations",
|
||||
"{9c60de1e-e5fc-40f4-a487-460851a8d915}" => "AutoPlay",
|
||||
"{b98a2bea-7d42-4558-8bd1-832f41bac6fd}" => "Backup and Restore Center",
|
||||
"{0142e4d0-fb7a-11dc-ba4a-000ffe7ab428}" => "Biometric Devices",
|
||||
"{d9ef8727-cac2-4e60-809e-86f80a666c91}" => "BitLocker Drive Encryption",
|
||||
"{56784854-c6cb-462b-8169-88e350acb882}" => "Contacts",
|
||||
"{26ee0668-a00a-44d7-9371-beb064c98683}" => "Control Panel (Cat. View)",
|
||||
"{b2c761c6-29bc-4f19-9251-e6195265baf1}" => "Color Management",
|
||||
"{1206f5f1-0569-412c-8fec-3204630dfb70}" => "Credential Manager",
|
||||
"{e2e7934b-dce5-43c4-9576-7fe4f75e7480}" => "Date and Time",
|
||||
"{00c6d95f-329c-409a-81d7-c46c66ea7f33}" => "Default Location",
|
||||
"{17cd9488-1228-4b2f-88ce-4298e93e0966}" => "Default Programs",
|
||||
"{37efd44d-ef8d-41b1-940d-96973a50e9e0}" => "Desktop Gadgets",
|
||||
"{74246bfc-4c96-11d0-abef-0020af6b0b7a}" => "Device Manager",
|
||||
"{a8a91a66-3a7d-4424-8d24-04e180695c7a}" => "Devices and Printers",
|
||||
"{c555438b-3c23-4769-a71f-b6d3d9b6053a}" => "Display",
|
||||
"{d555645e-d4f8-4c29-a827-d93c859c4f2a}" => "Ease of Access Center",
|
||||
"{1777f761-68ad-4d8a-87bd-30b759fa33dd}" => "Favorites",
|
||||
"{323ca680-c24d-4099-b94d-446dd2d7249e}" => "Favorites",
|
||||
"{6dfd7c5c-2451-11d3-a299-00c04f8ef6af}" => "Folder Options",
|
||||
"{93412589-74d4-4e4e-ad0e-e0cb621440fd}" => "Fonts",
|
||||
"{259ef4b1-e6c9-4176-b574-481532c9bce8}" => "Game Controllers",
|
||||
"{15eae92e-f17a-4431-9f28-805e482dafd4}" => "Get Programs",
|
||||
"{cb1b7f8c-c50a-4176-b604-9e24dee8d4d1}" => "Getting Started",
|
||||
"{67ca7650-96e6-4fdd-bb43-a8e774f73a57}" => "HomeGroup",
|
||||
"{b4fb3f98-c1ea-428d-a78a-d1f5659cba93}" => "HomeGroup",
|
||||
"{87d66a43-7b11-4a28-9811-c86ee395acf7}" => "Indexing Options",
|
||||
"{a0275511-0e86-4eca-97c2-ecd8f1221d08}" => "Infrared",
|
||||
"{a3dd4f92-658a-410f-84fd-6fbbbef2fffe}" => "Internet Options",
|
||||
"{a304259d-52b8-4526-8b1a-a1d6cecc8243}" => "iSCSI Initiator",
|
||||
"{725be8f7-668e-4c7b-8f90-46bdb0936430}" => "Keyboard",
|
||||
"{bfb9d5e0-c6a9-404c-b2b2-ae6db6af4968}" => "Links",
|
||||
"{e9950154-c418-419e-a90a-20c5287ae24b}" => "Location and Other Sensors",
|
||||
"{1fa9085f-25a2-489b-85d4-86326eedcd87}" => "Manage Wireless Networks",
|
||||
"{6c8eec18-8d75-41b2-a177-8831d59d2d50}" => "Mouse",
|
||||
"{2112ab0a-c86a-4ffe-a368-0de96e47012e}" => "Music Library",
|
||||
"{7007acc7-3202-11d1-aad2-00805fc1270e}" => "Network Connections",
|
||||
"{8e908fc9-becc-40f6-915b-f4ca0e70d03d}" => "Network and Sharing Center",
|
||||
"{05d7b0f4-2121-4eff-bf6b-ed3f69b894d9}" => "Notification Area Icons",
|
||||
"{d24f75aa-4f2b-4d07-a3c4-469b3d9030c4}" => "Offline Files",
|
||||
"{96ae8d84-a250-4520-95a5-a47a7e3c548b}" => "Parental Controls",
|
||||
"{f82df8f7-8b9f-442e-a48c-818ea735ff9b}" => "Pen and Input Devices",
|
||||
"{5224f545-a443-4859-ba23-7b5a95bdc8ef}" => "People Near Me",
|
||||
"{78f3955e-3b90-4184-bd14-5397c15f1efc}" => "Performance Information and Tools",
|
||||
"{ed834ed6-4b5a-4bfe-8f11-a626dcb6a921}" => "Personalization",
|
||||
"{40419485-c444-4567-851a-2dd7bfa1684d}" => "Phone and Modem",
|
||||
"{f0d63f85-37ec-4097-b30d-61b4a8917118}" => "Photo Stream",
|
||||
"{025a5937-a6be-4686-a844-36fe4bec8b6d}" => "Power Options",
|
||||
"{2227a280-3aea-1069-a2de-08002b30309d}" => "Printers",
|
||||
"{fcfeecae-ee1b-4849-ae50-685dcf7717ec}" => "Problem Reports and Solutions",
|
||||
"{7b81be6a-ce2b-4676-a29e-eb907a5126c5}" => "Programs and Features",
|
||||
"{22877a6d-37a1-461a-91b0-dbda5aaebc99}" => "Recent Places",
|
||||
"{9fe63afd-59cf-4419-9775-abcc3849f861}" => "Recovery",
|
||||
"{62d8ed13-c9d0-4ce8-a914-47dd628fb1b0}" => "Regional and Language Options",
|
||||
"{241d7c96-f8bf-4f85-b01f-e2b043341a4b}" => "RemoteApp and Desktop Connections",
|
||||
"{4c5c32ff-bb9d-43b0-b5b4-2d72e54eaaa4}" => "Saved Games",
|
||||
"{7d1d3a04-debb-4115-95cf-2f29da2920da}" => "Saved Searches",
|
||||
"{00f2886f-cd64-4fc9-8ec5-30ef6cdbe8c3}" => "Scanners and Cameras",
|
||||
"{e211b736-43fd-11d1-9efb-0000f8757fcd}" => "Scanners and Cameras",
|
||||
"{d6277990-4c6a-11cf-8d87-00aa0060f5bf}" => "Scheduled Tasks",
|
||||
"{f2ddfc82-8f12-4cdd-b7dc-d4fe1425aa4d}" => "Sound",
|
||||
"{58e3c745-d971-4081-9034-86e34b30836a}" => "Speech Recognition Options",
|
||||
"{9c73f5e5-7ae7-4e32-a8e8-8d23b85255bf}" => "Sync Center",
|
||||
"{e413d040-6788-4c22-957e-175d1c513a34}" => "Sync Center Conflict Delegate Folder",
|
||||
"{bc48b32f-5910-47f5-8570-5074a8a5636a}" => "Sync Results Delegate Folder",
|
||||
"{f1390a9a-a3f4-4e5d-9c5f-98f3bd8d935c}" => "Sync Setup Delegate Folder",
|
||||
"{bb06c0e4-d293-4f75-8a90-cb05b6477eee}" => "System",
|
||||
"{80f3f1d5-feca-45f3-bc32-752c152e456e}" => "Tablet PC Settings",
|
||||
"{0df44eaa-ff21-4412-828e-260a8728e7f1}" => "Taskbar and Start Menu",
|
||||
"{d17d1d6d-cc3f-4815-8fe3-607e7d5d10b3}" => "Text to Speech",
|
||||
"{c58c4893-3be0-4b45-abb5-a63e4b8c8651}" => "Troubleshooting",
|
||||
"{60632754-c523-4b62-b45c-4172da012619}" => "User Accounts",
|
||||
"{be122a0e-4503-11da-8bde-f66bad1e3f3a}" => "Windows Anytime Upgrade",
|
||||
"{78cb147a-98ea-4aa6-b0df-c8681f69341c}" => "Windows CardSpace",
|
||||
"{d8559eb9-20c0-410e-beda-7ed416aecc2a}" => "Windows Defender",
|
||||
"{4026492f-2f69-46b8-b9bf-5654fc07e423}" => "Windows Firewall",
|
||||
"{3e7efb4c-faf1-453d-89eb-56026875ef90}" => "Windows Marketplace",
|
||||
"{5ea4f148-308c-46d7-98a9-49041b1dd468}" => "Windows Mobility Center",
|
||||
"{087da31b-0dd3-4537-8e23-64a18591f88b}" => "Windows Security Center",
|
||||
"{e95a4861-d57a-4be1-ad0f-35267e261739}" => "Windows SideShow",
|
||||
"{36eef7db-88ad-4e81-ad49-0e313f0c35f8}" => "Windows Update",
|
||||
"{724ef170-a42d-4fef-9f26-b60e846fba4f}" => "Administrative Tools",
|
||||
"{d0384e7d-bac3-4797-8f14-cba229b392b5}" => "Common Administrative Tools",
|
||||
"{de974d24-d9c6-4d3e-bf91-f4455120b917}" => "Common Files",
|
||||
"{c1bae2d0-10df-4334-bedd-7aa20b227a9d}" => "Common OEM Links",
|
||||
"{5399e694-6ce5-4d6c-8fce-1d8870fdcba0}" => "Control Panel",
|
||||
"{21ec2020-3aea-1069-a2dd-08002b30309d}" => "Control Panel",
|
||||
"{1ac14e77-02e7-4e5d-b744-2eb1ae5198b7}" => "CSIDL_SYSTEM",
|
||||
"{b4bfcc3a-db2c-424c-b029-7fe99a87c641}" => "Desktop",
|
||||
"{7b0db17d-9cd2-4a93-9733-46cc89022e7c}" => "Documents Library",
|
||||
"{fdd39ad0-238f-46af-adb4-6c85480369c7}" => "Documents",
|
||||
"{374de290-123f-4565-9164-39c4925e467b}" => "Downloads",
|
||||
"{de61d971-5ebc-4f02-a3a9-6c82895e5c04}" => "Get Programs",
|
||||
"{a305ce99-f527-492b-8b1a-7e76fa98d6e4}" => "Installed Updates",
|
||||
"{871c5380-42a0-1069-a2ea-08002b30309d}" => "Internet Explorer (Homepage)",
|
||||
"{031e4825-7b94-4dc3-b131-e946b44c8dd5}" => "Libraries",
|
||||
"{49bf5420-fa7f-11cf-8011-00a0c90a8f78}" => "Mobile Device", #MS KB836152
|
||||
"{4bd8d571-6d19-48d3-be97-422220080e43}" => "Music",
|
||||
"{20d04fe0-3aea-1069-a2d8-08002b30309d}" => "My Computer",
|
||||
"{450d8fba-ad25-11d0-98a8-0800361b1103}" => "My Documents",
|
||||
"{fc9fb64a-1eb2-4ccf-af5e-1a497a9b5c2d}" => "My Shared Folders",
|
||||
# "{5e591a74-df96-48d3-8d67-1733bcee28ba}" => "My Documents",
|
||||
"{ed228fdf-9ea8-4870-83b1-96b02cfe0d52}" => "My Games",
|
||||
"{208d2c60-3aea-1069-a2d7-08002b30309d}" => "My Network Places",
|
||||
"{f02c1a0d-be21-4350-88b0-7367fc96ef3c}" => "Network",
|
||||
"{33e28130-4e1e-4676-835a-98395c3bc3bb}" => "Pictures",
|
||||
"{a990ae9f-a03b-4e80-94bc-9912d7504104}" => "Pictures",
|
||||
"{7c5a40ef-a0fb-4bfc-874a-c0f2e0b9fa8e}" => "Program Files (x86)",
|
||||
"{905e63b6-c1bf-494e-b29c-65b732d3d21a}" => "Program Files",
|
||||
"{df7266ac-9274-4867-8d55-3bd661de872d}" => "Programs and Features",
|
||||
"{3214fab5-9757-4298-bb61-92a9deaa44ff}" => "Public Music",
|
||||
"{b6ebfb86-6907-413c-9af7-4fc2abf07cc5}" => "Public Pictures",
|
||||
"{2400183a-6185-49fb-a2d8-4a392a602ba3}" => "Public Videos",
|
||||
"{4336a54d-38b-4685-ab02-99bb52d3fb8b}" => "Public",
|
||||
"{491e922f-5643-4af4-a7eb-4e7a138d8174}" => "Public",
|
||||
"{dfdf76a2-c82a-4d63-906a-5644ac457385}" => "Public",
|
||||
"{645ff040-5081-101b-9f08-00aa002f954e}" => "Recycle Bin",
|
||||
"{e17d4fc0-5564-11d1-83f2-00a0c90dc849}" => "Search Results",
|
||||
"{d65231b0-b2f1-4857-a4ce-a8e7c6ea7d27}" => "System32 (x86)",
|
||||
"{9e52ab10-f80d-49df-acb8-4330f5687855}" => "Temporary Burn Folder",
|
||||
"{f3ce0f7c-4901-4acc-8648-d5d44b04ef8f}" => "Users Files",
|
||||
"{59031a47-3f72-44a7-89c5-5595fe6b30ee}" => "User Files",
|
||||
"{59031a47-3f72-44a7-89c5-5595fe6b30ee}" => "Users",
|
||||
"{18989b1d-99b5-455b-841c-ab7c74e4ddfc}" => "Videos",
|
||||
"{f38bf404-1d43-42f2-9305-67de0b28fc23}" => "Windows");
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# parseVariableEntry()
|
||||
# type = 0x00
|
||||
#-----------------------------------------------------------
|
||||
sub parseVariableEntry {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
|
||||
$item{type} = unpack("C",substr($data,2,1));
|
||||
my $tag = unpack("C",substr($data,0x0A,1));
|
||||
|
||||
if (unpack("v",substr($data,4,2)) == 0x1A) {
|
||||
my $guid = parseGUID(substr($data,14,16));
|
||||
|
||||
if (exists $folder_types{$guid}) {
|
||||
$item{name} = $folder_types{$guid};
|
||||
}
|
||||
else {
|
||||
$item{name} = $guid;
|
||||
}
|
||||
}
|
||||
elsif (grep(/1SPS/,$data)) {
|
||||
my @seg = split(/1SPS/,$data);
|
||||
|
||||
my %segs = ();
|
||||
foreach my $s (0..(scalar(@seg) - 1)) {
|
||||
my $guid = parseGUID(substr($seg[$s],0,16));
|
||||
$segs{$guid} = $seg[$s];
|
||||
}
|
||||
|
||||
if (exists $segs{"{b725f130-47ef-101a-a5f1-02608c9eebac}"}) {
|
||||
# Ref: http://msdn.microsoft.com/en-us/library/aa965725(v=vs.85).aspx
|
||||
my $stuff = $segs{"{b725f130-47ef-101a-a5f1-02608c9eebac}"};
|
||||
|
||||
my $tag = 1;
|
||||
my $cnt = 0x10;
|
||||
while($tag) {
|
||||
my $sz = unpack("V",substr($stuff,$cnt,4));
|
||||
my $id = unpack("V",substr($stuff,$cnt + 4,4));
|
||||
#--------------------------------------------------------------
|
||||
# sub-segment types
|
||||
# 0x0a - file name
|
||||
# 0x14 - short name
|
||||
# 0x0e, 0x0f, 0x10 - mod date, create date, access date(?)
|
||||
# 0x0c - size
|
||||
#--------------------------------------------------------------
|
||||
if ($sz == 0x00) {
|
||||
$tag = 0;
|
||||
next;
|
||||
}
|
||||
elsif ($id == 0x0a) {
|
||||
|
||||
my $num = unpack("V",substr($stuff,$cnt + 13,4));
|
||||
my $str = substr($stuff,$cnt + 13 + 4,($num * 2));
|
||||
$str =~ s/\x00//g;
|
||||
$item{name} = $str;
|
||||
}
|
||||
$cnt += $sz;
|
||||
}
|
||||
}
|
||||
|
||||
# if (exists $segs{"{5cbf2787-48cf-4208-b90e-ee5e5d420294}"}) {
|
||||
# my $stuff = $segs{"{5cbf2787-48cf-4208-b90e-ee5e5d420294}"};
|
||||
# my $tag = 1;
|
||||
# my $cnt = 0x10;
|
||||
# while($tag) {
|
||||
# my $sz = unpack("V",substr($stuff,$cnt,4));
|
||||
# my $id = unpack("V",substr($stuff,$cnt + 4,4));
|
||||
#
|
||||
# if ($sz == 0x00) {
|
||||
# $tag = 0;
|
||||
# next;
|
||||
# }
|
||||
# elsif ($id == 0x19) {
|
||||
#
|
||||
# my $num = unpack("V",substr($stuff,$cnt + 13,4));
|
||||
# my $str = substr($stuff,$cnt + 13 + 4,($num * 2));
|
||||
# $str =~ s/\x00//g;
|
||||
# $item{name} = $str;
|
||||
# }
|
||||
# $cnt += $sz;
|
||||
# }
|
||||
# }
|
||||
}
|
||||
elsif (substr($data,4,4) eq "AugM") {
|
||||
|
||||
my @beef = split(/\xef\xbe/,$data);
|
||||
if (scalar (@beef) < 3) {
|
||||
# %item = parseFolderEntry($data);
|
||||
$item{name} = "Test";
|
||||
}
|
||||
else {
|
||||
my $temp = substr($beef[2],22,length($beef[2]) - 22);
|
||||
my $temp2 = substr($temp,12,length($temp) - 12);
|
||||
$item{name} = (split(/\x00\x00/,$temp2))[0];
|
||||
$item{name} =~ s/\x00//g;
|
||||
}
|
||||
|
||||
}
|
||||
# Following two entries are for Device Property data
|
||||
elsif ($tag == 0x7b || $tag == 0xbb || $tag == 0xfb) {
|
||||
my ($sz1,$sz2,$sz3) = unpack("VVV",substr($data,0x3e,12));
|
||||
$item{name} = substr($data,0x4a,$sz1 * 2);
|
||||
$item{name} =~ s/\x00//g;
|
||||
}
|
||||
elsif ($tag == 0x02 || $tag == 0x03) {
|
||||
my ($sz1,$sz2,$sz3,$sz4) = unpack("VVVV",substr($data,0x26,16));
|
||||
$item{name} = substr($data,0x36,$sz1 * 2);
|
||||
$item{name} =~ s/\x00//g;
|
||||
}
|
||||
else {
|
||||
$item{name} = "Unknown Type";
|
||||
}
|
||||
return %item;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# parseNetworkEntry()
|
||||
#
|
||||
#-----------------------------------------------------------
|
||||
sub parseNetworkEntry {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
$item{type} = unpack("C",substr($data,2,1));
|
||||
|
||||
my @n = split(/\x00/,substr($data,5,length($data) - 5));
|
||||
$item{name} = $n[0];
|
||||
return %item;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# parseZipSubFolderItem()
|
||||
# parses what appears to be Zip file subfolders; this type
|
||||
# appears to contain the date and time of when the subfolder
|
||||
# was accessed/opened, in string format.
|
||||
#-----------------------------------------------------------
|
||||
sub parseZipSubFolderItem {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
|
||||
# Get the opened/accessed date/time
|
||||
$item{datetime} = substr($data,0x24,6);
|
||||
$item{datetime} =~ s/\x00//g;
|
||||
if ($item{datetime} eq "N/A") {
|
||||
|
||||
}
|
||||
else {
|
||||
$item{datetime} = substr($data,0x24,40);
|
||||
$item{datetime} =~ s/\x00//g;
|
||||
my ($date,$time) = split(/\s+/,$item{datetime},2);
|
||||
my ($mon,$day,$yr) = split(/\//,$date,3);
|
||||
my ($hr,$min,$sec) = split(/:/,$time,3);
|
||||
|
||||
my $gmtime = timegm($sec,$min,$hr,$day,($mon - 1),$yr);
|
||||
$item{datetime} = "$yr-$mon-$day $hr:$min:$sec";
|
||||
# ::rptMsg("[Access_Time]: ".gmtime($gmtime));
|
||||
}
|
||||
|
||||
my $sz = unpack("V",substr($data,0x54,4));
|
||||
my $sz2 = unpack("V",substr($data,0x58,4));
|
||||
|
||||
my $str1 = substr($data,0x5C,$sz *2) if ($sz > 0);
|
||||
$str1 =~ s/\x00//g;
|
||||
|
||||
if ($sz2 > 0) {
|
||||
my $str2 = substr($data,0x5C + ($sz * 2),$sz2 *2);
|
||||
$str2 =~ s/\x00//g;
|
||||
$item{name} = $str1."\\".$str2;
|
||||
}
|
||||
else {
|
||||
$item{name} = $str1;
|
||||
}
|
||||
return %item;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# parse01ShellItem()
|
||||
# I honestly have no idea what to do with this data; there's really
|
||||
# no reference for or description of the format of this data. For
|
||||
# now, this is just a place holder
|
||||
#-----------------------------------------------------------
|
||||
sub parse01ShellItem {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
$item{type} = unpack("C",substr($data,2,1));;
|
||||
$item{name} = "";
|
||||
# ($item{val0},$item{val1}) = unpack("VV",substr($data,2,length($data) - 2));
|
||||
return %item;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# parseXPShellDeviceItem()
|
||||
#
|
||||
#-----------------------------------------------------------
|
||||
sub parseXPShellDeviceItem {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
my ($t0,$t1) = unpack("VV",substr($data,0x04,8));
|
||||
if ($t0 == 0 && $t1 == 0) {
|
||||
$item{timestamp} = 0;
|
||||
}
|
||||
else {
|
||||
$item{timestamp} = ::getTime($t0,$t1);
|
||||
}
|
||||
# starting at offset 0x18, read the null-term. string as the name value
|
||||
my $str = substr($data,0x18,length($data) - 0x18);
|
||||
$item{name} = (split(/\x00/,$str))[0];
|
||||
return %item;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# parseType64Item()
|
||||
# Parses types 0x64, 0x65, 0x69
|
||||
#-----------------------------------------------------------
|
||||
sub parseType64Item {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
|
||||
$item{name} = substr($data,4,length($data) - 4);
|
||||
$item{name} =~ s/\x00//g;
|
||||
|
||||
return %item;
|
||||
}
|
||||
#-----------------------------------------------------------
|
||||
#
|
||||
#-----------------------------------------------------------
|
||||
sub parseURIEntry {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
$item{type} = unpack("C",substr($data,2,1));
|
||||
|
||||
my ($lo,$hi) = unpack("VV",substr($data,0x0e,8));
|
||||
$item{uritime} = ::getTime($lo,$hi);
|
||||
|
||||
my $sz = unpack("V",substr($data,0x2a,4));
|
||||
my $uri = substr($data,0x2e,$sz);
|
||||
$uri =~ s/\x00//g;
|
||||
|
||||
my $proto = substr($data,length($data) - 6, 6);
|
||||
$proto =~ s/\x00//g;
|
||||
|
||||
$item{name} = $proto."://".$uri." [".gmtime($item{uritime})."]";
|
||||
|
||||
return %item;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
#
|
||||
#-----------------------------------------------------------
|
||||
sub parseSystemFolderEntry {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
|
||||
my %vals = (0x00 => "Explorer",
|
||||
0x42 => "Libraries",
|
||||
0x44 => "Users",
|
||||
0x4c => "Public",
|
||||
0x48 => "My Documents",
|
||||
0x50 => "My Computer",
|
||||
0x58 => "My Network Places",
|
||||
0x60 => "Recycle Bin",
|
||||
0x68 => "Explorer",
|
||||
0x70 => "Control Panel",
|
||||
0x78 => "Recycle Bin",
|
||||
0x80 => "My Games");
|
||||
|
||||
$item{type} = unpack("C",substr($data,2,1));
|
||||
$item{id} = unpack("C",substr($data,3,1));
|
||||
if (exists $vals{$item{id}}) {
|
||||
$item{name} = $vals{$item{id}};
|
||||
}
|
||||
else {
|
||||
$item{name} = parseGUID(substr($data,4,16));
|
||||
}
|
||||
return %item;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# parseGUID()
|
||||
# Takes 16 bytes of binary data, returns a string formatted
|
||||
# as an MS GUID.
|
||||
#-----------------------------------------------------------
|
||||
sub parseGUID {
|
||||
my $data = shift;
|
||||
my $d1 = unpack("V",substr($data,0,4));
|
||||
my $d2 = unpack("v",substr($data,4,2));
|
||||
my $d3 = unpack("v",substr($data,6,2));
|
||||
my $d4 = unpack("H*",substr($data,8,2));
|
||||
my $d5 = unpack("H*",substr($data,10,6));
|
||||
my $guid = sprintf "{%08x-%04x-%04x-$d4-$d5}",$d1,$d2,$d3;
|
||||
|
||||
if (exists $guids{$guid}) {
|
||||
return "CLSID_".$guids{$guid};
|
||||
}
|
||||
else {
|
||||
return $guid;
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
#
|
||||
#-----------------------------------------------------------
|
||||
sub parseDeviceEntry {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
|
||||
my $ofs = unpack("v",substr($data,4,2));
|
||||
my $tag = unpack("V",substr($data,6,4));
|
||||
|
||||
if ($tag == 0) {
|
||||
my $guid1 = parseGUID(substr($data,$ofs + 6,16));
|
||||
my $guid2 = parseGUID(substr($data,$ofs + 6 + 16,16));
|
||||
$item{name} = $guid1."\\".$guid2
|
||||
}
|
||||
elsif ($tag == 2) {
|
||||
$item{name} = substr($data,0x0a,($ofs + 6) - 0x0a);
|
||||
$item{name} =~ s/\x00//g;
|
||||
}
|
||||
else {
|
||||
my $ver = unpack("C",substr($data,9,1));
|
||||
|
||||
# Version 3 = XP
|
||||
if ($ver == 3) {
|
||||
my $guid1 = parseGUID(substr($data,$ofs + 6,16));
|
||||
my $guid2 = parseGUID(substr($data,$ofs + 6 + 16,16));
|
||||
$item{name} = $guid1."\\".$guid2
|
||||
|
||||
}
|
||||
# Version 8 = Win7
|
||||
elsif ($ver == 8) {
|
||||
my $userlen = unpack("V",substr($data,30,4));
|
||||
my $devlen = unpack("V",substr($data,34,4));
|
||||
my $user = substr($data,0x28,$userlen * 2);
|
||||
$user =~ s/\x00//g;
|
||||
my $dev = substr($data,0x28 + ($userlen * 2),$devlen * 2);
|
||||
$dev =~ s/\x00//g;
|
||||
$item{name} = $user;
|
||||
}
|
||||
else {
|
||||
# Version unknown
|
||||
|
||||
}
|
||||
}
|
||||
return %item;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
#
|
||||
#-----------------------------------------------------------
|
||||
sub parseDriveEntry {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
$item{type} = unpack("C",substr($data,2,1));;
|
||||
$item{name} = substr($data,3,3);
|
||||
return %item;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
#
|
||||
#-----------------------------------------------------------
|
||||
sub parseControlPanelEntry {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
$item{type} = unpack("C",substr($data,2,1));
|
||||
my $guid = parseGUID(substr($data,14,16));
|
||||
if (exists $guids{$guid}) {
|
||||
$item{name} = $guids{$guid};
|
||||
}
|
||||
else {
|
||||
$item{name} = $guid;
|
||||
}
|
||||
return %item;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
#
|
||||
#-----------------------------------------------------------
|
||||
sub parseFolderEntry {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
|
||||
$item{type} = unpack("C",substr($data,2,1));
|
||||
# Type 0x74 folders have a slightly different format
|
||||
|
||||
my $ofs_mdate;
|
||||
my $ofs_shortname;
|
||||
|
||||
if ($item{type} == 0x74) {
|
||||
$ofs_mdate = 0x12;
|
||||
}
|
||||
elsif (substr($data,4,4) eq "AugM") {
|
||||
$ofs_mdate = 0x1c;
|
||||
}
|
||||
else {
|
||||
$ofs_mdate = 0x08;
|
||||
}
|
||||
# some type 0x32 items will include a file size
|
||||
if ($item{type} == 0x32) {
|
||||
my $size = unpack("V",substr($data,4,4));
|
||||
if ($size != 0) {
|
||||
$item{filesize} = $size;
|
||||
}
|
||||
}
|
||||
|
||||
my @m = unpack("vv",substr($data,$ofs_mdate,4));
|
||||
($item{mtime_str},$item{mtime}) = convertDOSDate($m[0],$m[1]);
|
||||
|
||||
# Need to read in short name; nul-term ASCII
|
||||
# $item{shortname} = (split(/\x00/,substr($data,12,length($data) - 12),2))[0];
|
||||
$ofs_shortname = $ofs_mdate + 6;
|
||||
my $tag = 1;
|
||||
my $cnt = 0;
|
||||
my $str = "";
|
||||
while($tag) {
|
||||
my $s = substr($data,$ofs_shortname + $cnt,1);
|
||||
if ($s =~ m/\x00/ && ((($cnt + 1) % 2) == 0)) {
|
||||
$tag = 0;
|
||||
}
|
||||
else {
|
||||
$str .= $s;
|
||||
$cnt++;
|
||||
}
|
||||
}
|
||||
# $str =~ s/\x00//g;
|
||||
my $shortname = $str;
|
||||
my $ofs = $ofs_shortname + $cnt + 1;
|
||||
|
||||
# Read progressively, 1 byte at a time, looking for 0xbeef
|
||||
$tag = 1;
|
||||
$cnt = 0;
|
||||
while ($tag) {
|
||||
if (unpack("v",substr($data,$ofs + $cnt,2)) == 0xbeef) {
|
||||
$tag = 0;
|
||||
}
|
||||
else {
|
||||
$cnt++;
|
||||
}
|
||||
}
|
||||
$item{extver} = unpack("v",substr($data,$ofs + $cnt - 4,2));
|
||||
$ofs = $ofs + $cnt + 2;
|
||||
|
||||
@m = unpack("vv",substr($data,$ofs,4));
|
||||
($item{ctime_str},$item{ctime}) = convertDOSDate($m[0],$m[1]);
|
||||
$ofs += 4;
|
||||
@m = unpack("vv",substr($data,$ofs,4));
|
||||
($item{atime_str},$item{atime}) = convertDOSDate($m[0],$m[1]);
|
||||
|
||||
my $jmp;
|
||||
if ($item{extver} == 0x03) {
|
||||
$jmp = 8;
|
||||
}
|
||||
elsif ($item{extver} == 0x07) {
|
||||
$jmp = 26;
|
||||
}
|
||||
elsif ($item{extver} == 0x08) {
|
||||
$jmp = 30;
|
||||
}
|
||||
else {}
|
||||
|
||||
if ($item{extver} >= 0x07) {
|
||||
my @n = unpack("Vvv",substr($data,$ofs + 8, 8));
|
||||
$item{mft_rec_num} = getNum48($n[0],$n[1]);
|
||||
$item{mft_seq_num} = $n[2];
|
||||
}
|
||||
|
||||
$ofs += $jmp;
|
||||
|
||||
$str = substr($data,$ofs,length($data) - 30);
|
||||
my $longname = (split(/\x00\x00/,$str,2))[0];
|
||||
$longname =~ s/\x00//g;
|
||||
|
||||
if ($longname ne "") {
|
||||
$item{name} = $longname;
|
||||
}
|
||||
else {
|
||||
$item{name} = $shortname;
|
||||
}
|
||||
return %item;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# convertDOSDate()
|
||||
# subroutine to convert 4 bytes of binary data into a human-
|
||||
# readable format. Returns both a string and a Unix-epoch
|
||||
# time.
|
||||
#-----------------------------------------------------------
|
||||
sub convertDOSDate {
|
||||
my $date = shift;
|
||||
my $time = shift;
|
||||
|
||||
if ($date == 0x00 || $time == 0x00){
|
||||
return (0,0);
|
||||
}
|
||||
else {
|
||||
my $sec = ($time & 0x1f) * 2;
|
||||
$sec = "0".$sec if (length($sec) == 1);
|
||||
if ($sec == 60) {$sec = 59};
|
||||
my $min = ($time & 0x7e0) >> 5;
|
||||
$min = "0".$min if (length($min) == 1);
|
||||
my $hr = ($time & 0xF800) >> 11;
|
||||
$hr = "0".$hr if (length($hr) == 1);
|
||||
my $day = ($date & 0x1f);
|
||||
$day = "0".$day if (length($day) == 1);
|
||||
my $mon = ($date & 0x1e0) >> 5;
|
||||
$mon = "0".$mon if (length($mon) == 1);
|
||||
my $yr = (($date & 0xfe00) >> 9) + 1980;
|
||||
my $gmtime = timegm($sec,$min,$hr,$day,($mon - 1),$yr);
|
||||
return ("$yr-$mon-$day $hr:$min:$sec",$gmtime);
|
||||
# return gmtime(timegm($sec,$min,$hr,$day,($mon - 1),$yr));
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# parseFolderEntry2()
|
||||
#
|
||||
# Initial code for parsing type 0x35
|
||||
#-----------------------------------------------------------
|
||||
sub parseFolderEntry2 {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
|
||||
my $ofs = 0;
|
||||
my $tag = 1;
|
||||
|
||||
while ($tag) {
|
||||
if (unpack("v",substr($data,$ofs,2)) == 0xbeef) {
|
||||
$tag = 0;
|
||||
}
|
||||
else {
|
||||
$ofs++;
|
||||
}
|
||||
}
|
||||
$item{extver} = unpack("v",substr($data,$ofs - 4,2));
|
||||
# Move offset over to end of where the ctime value would be
|
||||
$ofs += 4;
|
||||
|
||||
my $jmp;
|
||||
if ($item{extver} == 0x03) {
|
||||
$jmp = 8;
|
||||
}
|
||||
elsif ($item{extver} == 0x07) {
|
||||
$jmp = 26;
|
||||
}
|
||||
elsif ($item{extver} == 0x08) {
|
||||
$jmp = 30;
|
||||
}
|
||||
else {}
|
||||
|
||||
$ofs += $jmp;
|
||||
|
||||
my $str = substr($data,$ofs,length($data) - 30);
|
||||
|
||||
$item{name} = (split(/\x00\x00/,$str,2))[0];
|
||||
$item{name} =~ s/\x13\x20/\x2D\x00/;
|
||||
$item{name} =~ s/\x00//g;
|
||||
|
||||
return %item;
|
||||
}
|
||||
#-----------------------------------------------------------
|
||||
#
|
||||
#-----------------------------------------------------------
|
||||
sub parseFolderEntry3 {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
$item{name} = substr($data,4,length($data) - 4);
|
||||
$item{name} =~ s/\x00//g;
|
||||
return %item;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
#
|
||||
#-----------------------------------------------------------
|
||||
sub parseDatePathItem {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
$item{datestr} = substr($data,0x18,30);
|
||||
my ($file,$dir) = split(/\x00\x00/,substr($data,0x44,length($data) - 0x44));
|
||||
$file =~ s/\x00//g;
|
||||
$dir =~ s/\x00//g;
|
||||
$item{name} = $dir.$file;
|
||||
return %item;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# parseTypex53()
|
||||
#-----------------------------------------------------------
|
||||
sub parseTypex53 {
|
||||
my $data = shift;
|
||||
my %item = ();
|
||||
|
||||
my $item1 = parseGUID(substr($data,0x14,16));
|
||||
my $item2 = parseGUID(substr($data,0x24,16));
|
||||
|
||||
$item{name} = $item1."\\".$item2;
|
||||
|
||||
return %item;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# probe()
|
||||
#
|
||||
# Code the uses printData() to insert a 'probe' into a specific
|
||||
# location and display the data
|
||||
#
|
||||
# Input: binary data of arbitrary length
|
||||
# Output: Nothing, no return value. Displays data to the console
|
||||
#-----------------------------------------------------------
|
||||
sub probe {
|
||||
my $data = shift;
|
||||
my @d = printData($data);
|
||||
::rptMsg("");
|
||||
foreach (0..(scalar(@d) - 1)) {
|
||||
::rptMsg($d[$_]);
|
||||
}
|
||||
::rptMsg("");
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# printData()
|
||||
# subroutine used primarily for debugging; takes an arbitrary
|
||||
# length of binary data, prints it out in hex editor-style
|
||||
# format for easy debugging
|
||||
#
|
||||
# Usage: see probe()
|
||||
#-----------------------------------------------------------
|
||||
sub printData {
|
||||
my $data = shift;
|
||||
my $len = length($data);
|
||||
|
||||
my @display = ();
|
||||
|
||||
my $loop = $len/16;
|
||||
$loop++ if ($len%16);
|
||||
|
||||
foreach my $cnt (0..($loop - 1)) {
|
||||
# How much is left?
|
||||
my $left = $len - ($cnt * 16);
|
||||
|
||||
my $n;
|
||||
($left < 16) ? ($n = $left) : ($n = 16);
|
||||
|
||||
my $seg = substr($data,$cnt * 16,$n);
|
||||
my $lhs = "";
|
||||
my $rhs = "";
|
||||
foreach my $i ($seg =~ m/./gs) {
|
||||
# This loop is to process each character at a time.
|
||||
$lhs .= sprintf(" %02X",ord($i));
|
||||
if ($i =~ m/[ -~]/) {
|
||||
$rhs .= $i;
|
||||
}
|
||||
else {
|
||||
$rhs .= ".";
|
||||
}
|
||||
}
|
||||
$display[$cnt] = sprintf("0x%08X %-50s %s",$cnt,$lhs,$rhs);
|
||||
}
|
||||
return @display;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# getNum48()
|
||||
# borrowed from David Cowen's code
|
||||
#-----------------------------------------------------------
|
||||
sub getNum48 {
|
||||
my $n1 = shift;
|
||||
my $n2 = shift;
|
||||
if ($n2 == 0) {
|
||||
return $n1;
|
||||
}
|
||||
else {
|
||||
$n2 = ($n2 *16777216);
|
||||
return $n1 + $n2;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
89
thirdparty/rr-full/time.pl
vendored
Normal file
89
thirdparty/rr-full/time.pl
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
#-------------------------------------------------------------
|
||||
# time.pl
|
||||
# This file contains helper functions for translating time values
|
||||
# into something readable. This file is accessed by the main UI
|
||||
# code via the 'require' pragma.
|
||||
#
|
||||
# Note: The main UI code (GUI or CLI) must 'use' the Time::Local
|
||||
# module.
|
||||
#
|
||||
# Change history:
|
||||
# 20120925 - created
|
||||
#
|
||||
# copyright 2012 Quantum Analytics Research, LLC
|
||||
# Author: H. Carvey, keydet89@yahoo.com
|
||||
#-------------------------------------------------------------
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# getTime()
|
||||
# Translate FILETIME object (2 DWORDS) to Unix time, to be passed
|
||||
# to gmtime() or localtime()
|
||||
#
|
||||
# The code was borrowed from Andreas Schuster's excellent work
|
||||
#-------------------------------------------------------------
|
||||
sub getTime($$) {
|
||||
my $lo = $_[0];
|
||||
my $hi = $_[1];
|
||||
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;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# convertDOSDate()
|
||||
# subroutine to convert 4 bytes of binary data into a human-
|
||||
# readable format. Returns both a string and a Unix-epoch
|
||||
# time.
|
||||
#-----------------------------------------------------------
|
||||
sub convertDOSDate {
|
||||
my $date = shift;
|
||||
my $time = shift;
|
||||
|
||||
if ($date == 0x00 || $time == 0x00){
|
||||
return (0,0);
|
||||
}
|
||||
else {
|
||||
my $sec = ($time & 0x1f) * 2;
|
||||
$sec = "0".$sec if (length($sec) == 1);
|
||||
if ($sec == 60) {$sec = 59};
|
||||
my $min = ($time & 0x7e0) >> 5;
|
||||
$min = "0".$min if (length($min) == 1);
|
||||
my $hr = ($time & 0xF800) >> 11;
|
||||
$hr = "0".$hr if (length($hr) == 1);
|
||||
my $day = ($date & 0x1f);
|
||||
$day = "0".$day if (length($day) == 1);
|
||||
my $mon = ($date & 0x1e0) >> 5;
|
||||
$mon = "0".$mon if (length($mon) == 1);
|
||||
my $yr = (($date & 0xfe00) >> 9) + 1980;
|
||||
my $gmtime = timegm($sec,$min,$hr,$day,($mon - 1),$yr);
|
||||
return ("$yr-$mon-$day $hr:$min:$sec",$gmtime);
|
||||
# return gmtime(timegm($sec,$min,$hr,$day,($mon - 1),$yr));
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# convertSystemTime()
|
||||
# Converts 128-bit SYSTEMTIME object to readable format
|
||||
#-----------------------------------------------------------
|
||||
sub convertSystemTime {
|
||||
my $date = $_[0];
|
||||
my @months = ("Jan","Feb","Mar","Apr","May","Jun","Jul",
|
||||
"Aug","Sep","Oct","Nov","Dec");
|
||||
my @days = ("Sun","Mon","Tue","Wed","Thu","Fri","Sat");
|
||||
my ($yr,$mon,$dow,$dom,$hr,$min,$sec,$ms) = unpack("v*",$date);
|
||||
$hr = "0".$hr if ($hr < 10);
|
||||
$min = "0".$min if ($min < 10);
|
||||
$sec = "0".$sec if ($sec < 10);
|
||||
my $str = $days[$dow]." ".$months[$mon - 1]." ".$dom." ".$hr.":".$min.":".$sec." ".$yr;
|
||||
return $str;
|
||||
}
|
||||
|
||||
1;
|
232
thirdparty/rr-full/updates.txt
vendored
Normal file
232
thirdparty/rr-full/updates.txt
vendored
Normal file
@ -0,0 +1,232 @@
|
||||
20141112
|
||||
-created mixer.pl,mixer_tln.pl,audiodev.pl
|
||||
|
||||
21041111
|
||||
-updated usb.pl, usbstor.pl, wpdbusenum.pl
|
||||
|
||||
20141103
|
||||
-updated inprocserver.pl to include detection for PowerLiks
|
||||
|
||||
20141015
|
||||
-updated/modified usb.pl, usbstor.pl, wpdbusenum.pl
|
||||
|
||||
20140821
|
||||
-created at.pl, at_tln.pl
|
||||
|
||||
20140808
|
||||
-updated inprocserver.pl, removed inprocserver_u.pl
|
||||
|
||||
20140807
|
||||
-created del.pl, del_tln.pl
|
||||
|
||||
20140730
|
||||
-updated winzip.pl
|
||||
-updated ares.pl (G. Nieves submission)
|
||||
-updated lsa_packages.pl & shares.pl (S. Kelm submission)
|
||||
-created secrets.pl, based on input from Jamie Levy
|
||||
|
||||
20140724
|
||||
-updated appcompatcache.pl w/ 64-bit Win8.1 support, based on
|
||||
data provided by Shafik Punja
|
||||
|
||||
20140723
|
||||
-updated applets.pl
|
||||
-updated ie_version.pl
|
||||
|
||||
20140721
|
||||
-update to mountdev2.pl submitted/incorporated
|
||||
|
||||
------------------------------------------------------------
|
||||
20140512
|
||||
-updated uninstall.pl, uninstall_tln.pl
|
||||
|
||||
20140510
|
||||
-added profiler.pl
|
||||
|
||||
20140501 (These plugins were added to the available online archive)
|
||||
-added processor_architecture.pl, wevtx.pl (C. Harrell)
|
||||
-updated pagefile.pl (C. Harrell)
|
||||
|
||||
20140416
|
||||
-updated usbdevices.pl (updates by J. Chau)
|
||||
|
||||
20140415
|
||||
-added winevt.pl (C. Harrell)
|
||||
-removed winlivemail.pl, winlivemsn.pl (errors)
|
||||
-removed streammru.pl, streams.pl
|
||||
|
||||
20140414
|
||||
-added knowndev.pl, ddo.pl (J. Chau)
|
||||
-RELEASED
|
||||
|
||||
20140408
|
||||
-updated lsasecrets.pl (improved error message)
|
||||
|
||||
20140326
|
||||
-created susclient.pl
|
||||
|
||||
20142020
|
||||
-updated recentdocs_tln.pl
|
||||
|
||||
20140203
|
||||
-added winscp.pl (not associated with winscp_sessions.pl)
|
||||
|
||||
20140131
|
||||
-added reading_locations.pl, from Jason Hale
|
||||
|
||||
20140115
|
||||
-updated user_run.pl to look for odd char in paths
|
||||
|
||||
20131210
|
||||
-updated crashcontrol.pl
|
||||
-updated amcache.pl
|
||||
|
||||
20131118
|
||||
-created cdstaginginfo.pl
|
||||
|
||||
20131108
|
||||
-updated svc.pl to look for WOW64 value in service keys;
|
||||
indicative of a 32-bit EXE running on a 64-bit OS
|
||||
|
||||
20131025
|
||||
-created startup.pl
|
||||
|
||||
20131011
|
||||
-created kankan.pl plugin
|
||||
|
||||
20131010
|
||||
-created vawtrak.pl
|
||||
-updated svcll.pl with Derbusi detection
|
||||
-updated svc.pl (Backdoor.Kopdel checks)
|
||||
|
||||
20131009
|
||||
-created ahaha.pl
|
||||
|
||||
20131008
|
||||
-created opencandy.pl plugin
|
||||
|
||||
20131007
|
||||
-created lazyshell.pl, comfoo.pl
|
||||
-updated imagefile.pl with carnal0wnage link to sticky keys info
|
||||
|
||||
20130930
|
||||
-updated appcompatflags.pl to support Win8 Store key
|
||||
|
||||
20130925
|
||||
-retired compatassist.pl; functionality rolled into appcompatflags.pl
|
||||
|
||||
20130911
|
||||
-updated svc.pl/svc_tln.pl to alert on FailureAction value
|
||||
-updated installedcomp.pl to look for StubPath values that point to
|
||||
rundll32, but point to other than a .dll (i.e., some malware points to
|
||||
.cpl files)
|
||||
|
||||
20130910
|
||||
-updated winlogon.pl/winlogon_tln.pl to check for GinaDLL value
|
||||
|
||||
20130905
|
||||
-removed winlivemsn.pl from ntuser profile - Module dependencies make it
|
||||
throw errors (if I had test data, I'd rewrite it)
|
||||
-updated installedcomp.pl to make the output more searchable
|
||||
-created netsvcs.pl plugin
|
||||
|
||||
20130904
|
||||
-created rlo.pl plugin (all hives)
|
||||
-updated backuprestore.pl (cleaned up code)
|
||||
|
||||
20130830
|
||||
-updated timezone.pl, based on findings from Mike W.
|
||||
|
||||
20130801
|
||||
-added initial Win8 support to appcompatcache.pl
|
||||
-added cross-platform support to rip.pl (File::Spec)
|
||||
|
||||
20130731
|
||||
-updated ie_settings.pl
|
||||
|
||||
20130711
|
||||
-created pending.pl
|
||||
|
||||
20130706
|
||||
-updated appcompatflags.pl to retrieve values from Persisted key
|
||||
|
||||
20130630
|
||||
-updated usbstor.pl - added parsing of Properties values (Win7)
|
||||
-updated devclass.pl - added additional device class check
|
||||
|
||||
20130603
|
||||
-updated alert code (new alert function & check for ADSs)
|
||||
-appcompatcache.pl,inprocserver.pl,clsid.pl
|
||||
-appcompatcache_tln.pl,soft_run.pl,user_run.pl,srun_tln.pl,urun_tln.pl
|
||||
-svc.pl,svcdll.pl,svc_tln.pl
|
||||
|
||||
20130530
|
||||
-updated mountdev.pl to address endian issues in display of disk signatures
|
||||
|
||||
20130522
|
||||
-minor changes to attachmgr.pl, attachmgr_tln.pl
|
||||
|
||||
20130514
|
||||
-updated itempos.pl to parse ItemPos* value data beneath ShellNoRoam\Bags subkeys
|
||||
|
||||
20130513
|
||||
-updated userinfo.pl to include UserName value beneath "Common" subkey
|
||||
|
||||
20130509
|
||||
-added alert and warnings to appcompatcache.pl, appcompatcache_tln.pl
|
||||
-updated svc.pl, retired svc2.pl
|
||||
-created svc_tln.pl, based on svc.pl
|
||||
|
||||
20130504
|
||||
-added alert to Run key plugins to check for %AppData% paths (malware)
|
||||
|
||||
20130429
|
||||
-created winlogon_tln.pl, applets_tln.pl
|
||||
|
||||
-added alertMsg() func. to:
|
||||
-brisv.pl, inprocserver.pl, inprocserver_u.pl, iejava.pl,
|
||||
spp_clients.pl
|
||||
|
||||
-retired scanwithav.pl (func. included in attachmgr.pl)
|
||||
-retired taskman.pl (func. included in winlogon.pl)
|
||||
-retired vista_wireless.pl (func. in networklist.pl)
|
||||
|
||||
20130425
|
||||
-RegRipper and rip updated to v2.8; added alertMsg() capability
|
||||
-retired userinit.pl (functionality included in winlogon.pl)
|
||||
-created new plugins
|
||||
-srun_tln.pl, urun_tln.pl,cmdproc_tln.pl
|
||||
-cmd_shell_tln.pl,muicache_tln.pl
|
||||
|
||||
-added alertMsg() functionality to rip.pl, rr.pl, and plugins
|
||||
-appcompatcache.pl, appcompatcache_tln.pl
|
||||
-appinitdlls.pl
|
||||
-soft_run.pl, user_run.pl
|
||||
-imagefile.pl
|
||||
-winlogon.pl, winlogon_u.pl
|
||||
-muicache.pl (look for values with "[Tt]emp" paths)
|
||||
-attachmgr.pl (look for values per KB 883260)
|
||||
-virut.pl
|
||||
-cmdproc.pl, cmd_shell.pl
|
||||
|
||||
20130411
|
||||
-retired specaccts.pl & notify.pl; incorporated functionality into
|
||||
winlogon.pl
|
||||
|
||||
20130410
|
||||
-retired taskman.pl; merged into winlogon.pl
|
||||
-updated winlogon.pl (Wow6432Node support, etc.)
|
||||
-updated winlogon_u.pl (Wow6432Node support)
|
||||
-updated shellexec.pl, imagefile.pl, installedcomp.pl (Wow6432Node support)
|
||||
|
||||
20130409
|
||||
-added drivers32.pl (C. Harrell) to the archive
|
||||
|
||||
20130408
|
||||
-updated bho.pl to support Wow6432Node
|
||||
|
||||
20130405
|
||||
-updated cmd_shell.pl to include Clients subkey in the Software hive
|
||||
-created cmd_shell_u.pl
|
||||
-fixed issue with rip.exe syntax info containing 'rr'
|
||||
-fixed banner in findexes.pl
|
Loading…
x
Reference in New Issue
Block a user