Update Changed plugins

Update Plugins that have changed from Autopsy's last version of Regripper.
This commit is contained in:
Mark McKinnon 2020-04-29 10:50:49 -04:00
parent ac34265b9e
commit 78042da4c7
58 changed files with 11161 additions and 936 deletions

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
View 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
View 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
View 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
View 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.

View File

@ -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.

View File

@ -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

View File

@ -1,2 +1 @@
#20161213 *ALL* Plugins that apply on any amcache, alphabetical order
amcache
amcache

View File

@ -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;

View File

@ -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;

View File

@ -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));

View File

@ -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));

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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)) {

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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});
}
}

View File

@ -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 {

View File

@ -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.");
}

View File

@ -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;
};
}

View File

@ -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

View File

@ -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());
}
}
}

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -7,7 +7,7 @@
package rdphint;
use strict;
my %config = (hive => "NTUSER",
my %config = (hive => "NTUSER\.DAT",
osmask => 22,
hasShortDescr => 1,
hasDescr => 0,

View File

@ -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("");
}

View File

@ -1,3 +1 @@
# 20161213 *ALL* Plugins that apply on SAM hive, alphabetical order
samparse
samparse_tln
samparse

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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;

View File

@ -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 {

View File

@ -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));

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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 {}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

Binary file not shown.

View File

@ -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

Binary file not shown.

Binary file not shown.

View File

@ -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

File diff suppressed because it is too large Load Diff

835
thirdparty/rr-full/shellitems.pl vendored Normal file
View 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
View 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
View 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