Mark McKinnon ac34265b9e Plugins new to our copy of Regripper
Plugins that are new to our copy of Regripper.
2020-04-24 14:30:34 -04:00

301 lines
7.4 KiB
Perl

#-----------------------------------------------------------
# webroot.pl
# Plugin to parse webroot antivirus registry data
# I have only extracted some of the data from the root key "WOW6432Node\\WRData", manual review is recommended
# I also do not know what a number of fields mean, so further work may be required to fully exploit the data in this key.
#
# Change history
# 20191230 - initial commit
#
# References
#
# copyright 2019 Phill Moore
#-----------------------------------------------------------
package webroot;
use strict;
my %config = (hive => "SOFTWARE",
hasShortDescr => 1,
hasDescr => 0,
hasRefs => 0,
osmask => 22,
version => 20191230);
sub getConfig{return %config}
sub getShortDescr {
return "Provides *some* of the webroot data in the registry, manual review is still recommended. Particularly surrounding the root key";
}
sub getDescr{}
sub getRefs {}
sub getHive {return $config{hive};}
sub getVersion {return $config{version};}
sub displayActions {
::rptMsg("---------------------------------------------------------------");
my $root_key = shift;
my $key_path = "WOW6432Node\\WRData\\Actions";
my $key;
if ($key = $root_key->get_subkey($key_path)){
::rptMsg("");
::rptMsg($key_path);
::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
::rptMsg("");
my @vals = $key->get_list_of_values();
foreach my $val (@vals) {
my $d = $val->get_data();
my $v = $val->get_name();
my $str = $v.":\t".$d;
::rptMsg($str);
}
}
else {
::rptMsg($key_path." not found.");
}
}
sub displayJournal {
::rptMsg("---------------------------------------------------------------");
my $root_key = shift;
my $key_path = "WOW6432Node\\WRData\\Journal";
my $key;
if ($key = $root_key->get_subkey($key_path)){
::rptMsg("");
::rptMsg($key_path . " - ". gmtime($key->get_timestamp())." (UTC)");
::rptMsg("");
my @vals = $key->get_list_of_values();
::rptMsg("filename,md5,timestamp");
foreach my $val (@vals) {
#format = "filename=$filename,md5=$md5,timestamp=$timestamp"
my @d = split (/,/, $val->get_data());
my $fn=(split(/\=/,$d[0]))[1];
my $md5= (split(/\=/,$d[1]))[1];
my $ts=(split(/\=/,$d[2]))[1];
my $timestamp=gmtime($ts);
my $str = $fn.",".$md5.",".$ts.",".$timestamp;
::rptMsg($str);
}
}
else {
::rptMsg($key_path." not found.");
}
}
sub displayStatus {
::rptMsg("---------------------------------------------------------------");
my $root_key = shift;
my $key_path = "WOW6432Node\\WRData\\Status";
my $key;
if ($key = $root_key->get_subkey($key_path)){
::rptMsg("");
::rptMsg($key_path);
::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
::rptMsg("");
my @vals = $key->get_list_of_values();
foreach my $val (@vals) {
my $d = $val->get_data();
my $v = $val->get_name();
#if $v is in the following list then convert timestamp
my @timestamp_fields = ["AgentStartupTime", "ExpirationDate", "LastDeepScan", "LastScan", "LastThreatSeen", "SystemStateUpdated", "UpdateTime", "UpdateTime"];
$d = $d." (".gmtime($d).")" if ($v ~~ @timestamp_fields);
my $str = $v.":\t".$d;
::rptMsg($str);
}
}
else {
::rptMsg($key_path." not found.");
}
}
sub displayFileFlags {
::rptMsg("---------------------------------------------------------------");
my $root_key = shift;
my $key_path = "WOW6432Node\\WRData\\FileFlags";
my $key;
if ($key = $root_key->get_subkey($key_path)){
::rptMsg("");
::rptMsg($key_path);
::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
::rptMsg("");
::rptMsg("MD5 hash:\t\t\t\taction, last changed");
my @vals = $key->get_list_of_values();
foreach my $val (@vals) {
my $d = $val->get_data();
my $v = $val->get_name();
my @split_d = split (/\,/, $d);
my @changetime = split (/\=/, $split_d[1]);
my $str = $v.":\t".$d."(".gmtime($changetime[1]).")";
::rptMsg($str);
}
}
else {
::rptMsg($key_path." not found.");
}
}
sub displayIPM {
::rptMsg("---------------------------------------------------------------");
my $root_key = shift;
my $key_path = "WOW6432Node\\WRData\\IPM";;
my $key;
if ($key = $root_key->get_subkey($key_path)){
::rptMsg("");
::rptMsg($key_path);
::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
::rptMsg("");
my @vals = $key->get_list_of_values();
foreach my $val (@vals) {
my $d = $val->get_data();
my $v = $val->get_name();
my $d = $d." (".gmtime($d).")"if ($v eq "ILU");
my $str = $v.":\t".$d;
::rptMsg($str);
}
}
else {
::rptMsg($key_path." not found.");
}
}
sub dumpAllVals {
::rptMsg("---------------------------------------------------------------");
my $root_key = shift;
my $key_path = shift;
my $key;
if ($key = $root_key->get_subkey($key_path)){
::rptMsg("");
::rptMsg($key_path);
::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
::rptMsg("");
my @vals = $key->get_list_of_values();
foreach my $val (@vals) {
my $d = $val->get_data();
my $v = $val->get_name();
my $str = $v.":\t".$d;
::rptMsg($str);
}
}
else {
::rptMsg($key_path." not found.");
}
}
sub dumpThreatsVals {
::rptMsg("---------------------------------------------------------------");
my $root_key = shift;
my $key_path = shift;
my $key;
my $v;
my $str;
if ($key = $root_key->get_subkey($key_path)){
::rptMsg("");
::rptMsg($key_path);
::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
::rptMsg("");
my @vals = sort ($key->get_list_of_values());
foreach my $val (@vals) {
my $v = $val->get_name();
my $d = $val->get_data();
if ($v eq "Count"){
$str = $v.":\t".$d;
}
else {
my @split_d = split (/\|/, $d);
my $path = $split_d[0];
my $detection = $split_d[1];
my $ts = $split_d[2];
my $timestamp = gmtime(hex($ts));
$str = $v.":\t".$path."|".$detection."|".$ts." (".$timestamp.")";
}
::rptMsg($str);
}
}
else {
::rptMsg($key_path." not found.");
}
}
sub displayThreats {
my $root_key = shift;
my $key_path = "WOW6432Node\\WRData\\Threats";
dumpAllVals($root_key, $key_path);
my @threats = ($key_path."\\Active", $key_path."\\History");
foreach my $k (@threats){
#::rptMsg($k);
dumpThreatsVals($root_key, $k);
}
}
my $VERSION = getVersion();
my $PLUGIN = "webroot";
sub pluginmain {
my $class = shift;
my $hive = shift;
my $infected = 0;
::logMsg("Launching ".$PLUGIN." v.".$VERSION);
::rptMsg($PLUGIN." v.".$VERSION); # banner
::rptMsg("(".getHive().") ".getShortDescr()."\n"); # banner
my $reg = Parse::Win32Registry->new($hive);
my $root_key = $reg->get_root_key;
my $key_path = "WOW6432Node\\WRData";
my $key;
if ($key = $root_key->get_subkey($key_path)) {
::rptMsg("");
::rptMsg($key_path);
::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
::rptMsg("");
#my @vals = $key->get_list_of_values();
my @vals = ("AVP", "BMV", "GWord", "HPL", "InstallDir", "InstalledVersion", "InstallTime", "LastInfection", "OIT");
foreach my $v (@vals) {
my $d = $key->get_value($v)->get_data();
my $str = $v.":\t".$d;
::rptMsg($str);
}
displayActions($root_key);
displayFileFlags($root_key);
displayIPM($root_key);
displayJournal($root_key);
displayStatus($root_key);
displayThreats($root_key);
dumpAllVals($root_key, "WOW6432Node\\WRData\\wrURL");
}
else {
::rptMsg($key_path." not found.");
::rptMsg("");
}
}1;