#-----------------------------------------------------------
# malware.pl
#
# This plugin is essentially a 'container' for a lot of other individual
#  plugins, running the queries against any hive.
#
# References:
#  <included inline>
#
# Change history:
#  20151203 - added DCOM port config detection
#  20151013 - added Warood.B
#  20151012 - 9002 ref/checks added
#  20151008 - added keys
#  20150828 - created
#
# copyright 2015 Quantum Analytics Research, LLC
# Author: H. Carvey, keydet89@yahoo.com
#-----------------------------------------------------------
package malware;
use strict;

my %config = (hive          => "All",
              hasShortDescr => 1,
              hasDescr      => 0,
              hasRefs       => 0,
              osmask        => 22,
              category      => "malware",
              version       => 20151013);

sub getConfig{return %config}
sub getShortDescr {
	return "Checks for malware-related keys/values";	
}
sub getDescr{}
sub getRefs {}
sub getHive {return $config{hive};}
sub getVersion {return $config{version};}

my $VERSION = getVersion();

sub pluginmain {
	my $class = shift;
	my $hive = shift;
	::logMsg("Launching malware v.".$VERSION);
	::rptMsg("malware v.".$VERSION); # banner
  ::rptMsg("(".getHive().") ".getShortDescr()."\n"); # banner
	my $reg = Parse::Win32Registry->new($hive);
	my $root_key = $reg->get_root_key;
	my $key_path;
	my $key;

# Security Hive
# This is the same code as the secrets.pl plugin - provides an indication
# regarding the use of GSecDump on systems; see "The Art of Memory Forensics",
# 

	eval {
		$key_path = "Policy\\Secrets";
		$key;
		if ($key = $root_key->get_subkey($key_path)) {
			::rptMsg($key_path);
			::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
			::rptMsg("");
		}
	};


# System Hive
# First, need to get the value for the CurrentControlSet
	my $ccs;
	my $current;
	eval {
		if ($key = $root_key->get_subkey("Select")) {
			$current = $key->get_value("Current")->get_data();
			$ccs = "ControlSet00".$current;
		}
	};
	
# If we've got a populated $ccs value, other checks will now likely work	
# Look for known/observed PlugX services
	my @services = ("RasTLS","Macfee MC","usta","emproxy","mproxysvr3","gzQkNtWeabrwf","brwTRsulGqj","sock5proxy");
	eval {
		foreach my $svc (@services) {
			if ($key = $root_key->get_subkey($ccs."\\services\\".$svc)) {
				::rptMsg("Possible PlugX variant found in ".$svc." service");
				
				eval {
					::rptMsg("  ImagePath  : ".$key->get_value("ImagePath")->get_data());
				};
				
				eval {
					::rptMsg("  Description: ".$key->get_value("Description")->get_data());
				};
				
			}
		}
	}; 
	

# Software Hive

# 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
	eval {
		$key_path = "Classes\\FAST";
		if ($key = $root_key->get_subkey($key_path)) {
			::rptMsg("Possible PlugX variant (".$key_path.") found.");
			::rptMsg("  LastWrite time: ".gmtime($key->get_timestamp()));
		}
	};
	
	eval {
		$key_path = "Classes\\XXXX";
		if ($key = $root_key->get_subkey($key_path)) {
			::rptMsg("Possible PlugX variant (".$key_path.") found.");
			::rptMsg("  LastWrite time: ".gmtime($key->get_timestamp()));
		}
	};
	
	eval {
		$key_path = "BINARY";
		if ($key = $root_key->get_subkey($key_path)) {
			::rptMsg("Possible PlugX variant (".$key_path.") found.");
			::rptMsg("  LastWrite time: ".gmtime($key->get_timestamp()));
			if ($key->get_value("SXLOC\.ZAP")) {
				::rptMsg("Value SXLOC\.ZAP found.");
			}
		}
	};

# https://www.sophos.com/en-us/threat-center/threat-analyses/viruses-and-spyware/Troj~DwnLdr-GWF/detailed-analysis.aspx
  eval {
		$key_path = "Begin";
		if ($key = $root_key->get_subkey($key_path)) {
			::rptMsg("Possible Downloader variant (".$key_path.") found.");
			::rptMsg("  LastWrite time: ".gmtime($key->get_timestamp()));
		}
	};


# check Classes\Network\SharingHandler default value for modification
# in most cases, it's "ntshrui.dll"
# http://www.trendmicro.com/vinfo/us/threat-encyclopedia/malware/worm_cosmu.elg
	eval { 
		$key_path = "Classes\\Network\\SharingHandler";
		if ($key = $root_key->get_subkey($key_path)) {
			::rptMsg($key_path);
			::rptMsg("  LastWrite Time : ".gmtime($key->get_timestamp())." (UTC)");
			::rptMsg("  (Default) value: ".$key->get_value("")->get_data());
			::rptMsg("If the (Default) value is not ntshrui\.dll, there may be an infection.");
		}
	};
	
# Poison Ivy variant
# http://blog.jpcert.or.jp/2015/07/poisonivy-adapts-to-communicate-through-authentication-proxies.html
	eval {
		$key_path = "Classes\\BJ\\Static";
		if ($key = $root_key->get_subkey($key_path)) {
			::rptMsg($key_path);
			::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
			if ($key->get_value("MessageFile")) {
				::rptMsg("MessageFile value found.");
			}
			::rptMsg("");
		}
	};

# Warood.A
# https://www.microsoft.com/security/portal/threat/encyclopedia/entry.aspx?Name=Backdoor:Win32/Warood.A#tab=2
  eval {
		$key_path = "Clients\\Netrau";
		if ($key = $root_key->get_subkey($key_path)) {
			::rptMsg($key_path);
			::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
			if ($key->get_value("HostGUID") || $key->get_value("InstallTime")) {
				::rptMsg("Warood.A value(s) found.");
			}
			::rptMsg("");
		}
	};

# Warood.B	
# https://www.microsoft.com/security/portal/threat/encyclopedia/entry.aspx?Name=Backdoor:Win32/Warood.B#tab=2
  eval {
		$key_path = "Clients\\sdata";
		if ($key = $root_key->get_subkey($key_path)) {
			::rptMsg($key_path);
			::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
			if ($key->get_value("sdata")) {
				::rptMsg("sdata value found.");
			}
			::rptMsg("");
		}
	};

# From FireEye APT30 report, ShipShape malware
  eval {
		$key_path = "Microsoft\\ShipUp";
		if ($key = $root_key->get_subkey($key_path)) {
			::rptMsg("Possible ShipShape malware found: ".$key_path);
			::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
			if ($key->get_value("lnk")) {
				::rptMsg("lnk value found.");
			}
			::rptMsg("");
		}
	};

# From FireEye APT30 report, SpaceShip malware
  eval {
		$key_path = "Microsoft\\ShipTr";
		if ($key = $root_key->get_subkey($key_path)) {
			::rptMsg("Possible SpaceShip malware found: ".$key_path);
			::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
			if ($key->get_value("lnk")) {
				::rptMsg("lnk value found.");
			}
			::rptMsg("");
		}
	};
	
# From MIRCon 2014 presentation on WMI
  eval {
		$key_path = "Microsoft\\WBEM\\ESSV/./root/CIMV2\\Win32ClockProvider";
		if ($key = $root_key->get_subkey($key_path)) {
			::rptMsg("Possible use of Win32_LocalTime found: ".$key_path);
			::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
			::rptMsg("");
		}
	};	
	
# Bledoor/RbDoor - added 20151117
# https://www.microsoft.com/security/portal/threat/encyclopedia/entry.aspx?Name=Trojan:Win64/Bledoor.A#tab=2	
	eval {
		$key_path = "Microsoft\\HTMLHelp";
		if ($key = $root_key->get_subkey($key_path)) {	
			if ($key->get_value("data")) {
				::rptMsg("Possible BleDoor/Rbdoor malware found: ".$key_path);
				::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
				::rptMsg("data value found: ".$key->get_value("data")->get_value());
			}
			::rptMsg("");
		}
	};

# Detect DCOM port change
# https://www.blackhat.com/docs/us-15/materials/us-15-Graeber-Abusing-Windows-Management
#    -Instrumentation-WMI-To-Build-A-Persistent%20Asynchronous-And-Fileless-Backdoor-wp.pdf	
# http://blog.backslasher.net/setting-dynamic-rpc-port-ranges.html
	eval {
		$key_path = "Microsoft\\Rpc\\Internet";
		if ($key = $root_key->get_subkey($key_path)) {	
			if ($key->get_value("Ports")) {
				::rptMsg("Possible DCOM port config change found: ".$key_path);
				::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
				::rptMsg("Ports value: ".$key->get_value("Ports")->get_value());
			}
			::rptMsg("");
		}
	};
	
# NTUSER.DAT/USRCLASS.DAT		

# Possible PlugX
# http://www.symantec.com/security_response/earthlink_writeup.jsp?docid=2013-112101-0135-99
	eval {
		$key_path = "Software\\BINARY";
		if ($key = $root_key->get_subkey($key_path)) {
			::rptMsg("Possible PlugX variant (".$key_path.") found.");
			::rptMsg("  LastWrite time: ".gmtime($key->get_timestamp()));
			if ($key->get_value("SXLOC\.ZAP")) {
				::rptMsg("Value SXLOC\.ZAP found.");
			}
		}
	};
	
# Nflog, et al.
# http://www.microsoft.com/security/portal/threat/encyclopedia/entry.aspx?name=TROJAN:WIN32/NFLOG.A#tab=2
# https://www.sophos.com/en-us/threat-center/threat-analyses/viruses-and-spyware/Troj~DwnLdr-GWF/detailed-analysis.aspx	
	eval {
		$key_path = "Software\\Microsoft\\Clock";
		if ($key = $root_key->get_subkey($key_path)) {
			::rptMsg("Possible Nflog variant (".$key_path.") found.");
			::rptMsg("  LastWrite time: ".gmtime($key->get_timestamp()));
			if ($key->get_value("HID")) {
				::rptMsg("Value HID found: ".$key->get_value("HID")->get_data());
			}
		}
	};

# 9002 RAT
# http://researchcenter.paloaltonetworks.com/2015/09/chinese-actors-use-3102-malware-in-attacks-on-us-government-and-eu-media/
# http://blog.cylance.com/another-9002-trojan-variant
	eval {
		$key_path = "Software\\TransPan";
		if ($key = $root_key->get_subkey($key_path)) {
			::rptMsg("Possible 9002 RAT variant (".$key_path.") found.");
			::rptMsg("  LastWrite time: ".gmtime($key->get_timestamp()));
			if ($key->get_value("RunPath") || $key->get_value("mshtm")) {
				::rptMsg("  Possible 9002 config value(s) found.");
			}
		}
	};
	
# From FireEye report on APT30/BackSpace RAT
	eval {
		$key_path = "Software\\Microsoft\\CurrentHalInf";
		if ($key = $root_key->get_subkey($key_path)) {
			::rptMsg("Possible BACKSPACE RAT variant (".$key_path.") found.");
			::rptMsg("  LastWrite time: ".gmtime($key->get_timestamp()));
			if ($key->get_value("hFlag")) {
				::rptMsg("  Possible hFlag value found: ".$key->get_value("hFlag")->get_data());
			}
		}
	};	
	
	eval {
		$key_path = "Software\\Microsoft\\CurrentPnpSetup";
		if ($key = $root_key->get_subkey($key_path)) {
			::rptMsg("Possible BACKSPACE RAT variant (".$key_path.") found.");
			::rptMsg("  LastWrite time: ".gmtime($key->get_timestamp()));
			if ($key->get_value("lnk") || $key->get_value("hostid")) {
				::rptMsg("  Possible BACKSPACE value(s) found.");
			}
		}
	};	
	
}
1;