Oct 15, 2024 by Thibault Debatty | 418 views
https://cylab.be/blog/365/create-your-own-plugin-for-regripper
RegRipper is a collection of powerful perl scripts that allow to dump the content of a registry hive file into readable text. RegRipper relies on a plugin mechanism. Hence in this post I will show how to create your own plugin for RegRipper. The example will be very basic, and will extract the value of the Current ControlSet.
On most Debian based distributions, you can install RegRipper with
sudo apt install regripper
After a few seconds, regripper
will be installed in /usr/bin/regripper
, and the plugins in /usr/lib/regripper/plugins/
As mentioned earlier, RegRipper and plugins are written in Perl. The language is relatively comprehensible, but here are a few key concepts. If you are already familiar with Perl, you can safely skip this Section.
Perl relies on packages, and ::
is the the package separator used to access variables, subroutines, or other items from a specific package or namespace. For example ::rptMsg
refers to a subroutine named rptMsg
in the main package (since no package name precedes the ::
) and Parse::Win32Registry
refers to Win32Registry
in the Parse
package.
The my
keyword declares a variable with lexical scoping, which means it is limited to the block or file where it is declared. This is similar to let
in JavaScript for example.
The %
sign allows to declare a variable which is hash (or a associative array). For example
my %config = (
'host' => 'localhost',
'port' => 8080);
Likewize, the @
declares an array:
my @nics = ('eth0', 'wlan0', 'lo');
Finally, the dollar sign $
is used to indicate that the variable is a scalar, which means it holds a single value. It is also used when accessing a value from an array or a hash:
foreach my $nic (@nics) {
print "Network interface: $nic\n";
}
The eval { ... }
block is used to execute a block of code and trap any runtime errors. If an error occurs, Perl captures the error message in the special variable $@
. This allows to handle exceptions or errors gracefully without causing the program to crash.
The control set registry branch records information that is needed to start Windows and devices related information that is used to run Windows (Windows Services). Windows stores at least two control sets in the registry: HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001
and HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002
.
Usually, both of them have the same information. However, if a fundamental change is made to the system such as a change of the hardware, there is the possibility that Windows cannot boot up anymore because of a faulty entry in the registry’s control set. Thus, only one of the copies is changed. If Windows manages to boot up correctly, it copies the newer control set over the older so that both are in sync again.
It is thus important to know, for a forensics investigation, which is the currently valid ControlSet. This value is recorded into the Current
key that is available in the registry under HKEY_LOCAL_MACHINE\SYSTEM\Select
.
For this tutorial, we will create a small plugin that extracts and shows this value.
To create a RegRipper plugin, you will have to write a perl package, with a few required subroutines: getConfig
, getShortDescr
, getDescr
, getRefs
, getHive
, getVersion
and pluginmain
.
To create a plugin that extracts the Current ControlSet value, create the file /usr/lib/regripper/plugins/currentcontrolset.pl
with the following content:
#-----------------------------------------------------------
# currentcontrolset.pl
#
# https://cylab.be/blog/365/create-your-own-plugin-for-regripper
#
#-----------------------------------------------------------
package currentcontrolset;
use strict;
my %config = (hive => "System",
hasShortDescr => 1,
hasDescr => 0,
hasRefs => 0,
version => 20241015);
sub getConfig{ return %config; }
sub getShortDescr {
return "Gets CurrentControlSet from System hive";
}
sub getDescr{}
sub getRefs {}
sub getHive {return $config{hive};}
sub getVersion {return $config{version};}
my $VERSION = getVersion();
sub pluginmain {
# get subroutine arguments
my $class = shift;
my $hive = shift;
# ::logMsg will send message to stderr
::logMsg("Launching currentcontrolset v.".$VERSION);
# ::rptMsg will send message to stdout
::rptMsg("currentcontrolset v.".$VERSION);
::rptMsg("(".getHive().") ".getShortDescr()."\n");
# Load HKEY_LOCAL_MACHINE\SYSTEM
my $system = Parse::Win32Registry->new($hive)->get_root_key;
my $current;
eval {
$current = $system->get_subkey("Select")->get_value("Current")->get_data();
};
::rptMsg("CurrentControlSet: ".$current);
}
Your plugin should now appear in the list of available plugins:
regripper -l | grep -A 2 current
If you want to test, you can also
hives-01.zip
from https://cylab.be/s/Q2zQ0
regripper -f system -p currentcontrolset
This blog post is licensed under CC BY-SA 4.0