Create your own plugin for RegRipper

Oct 15, 2024 by Thibault Debatty | 541 views

Forensics Windows Linux

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.

regripper.webp

Installation

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/

regripper-1.png

regripper-2.png

A few words about Perl

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.

Registry ControlSets

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.

registry-control-sets.png

For this tutorial, we will create a small plugin that extracts and shows this value.

CurentControlSet plugin

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

Testing

Your plugin should now appear in the list of available plugins:

regripper -l | grep -A 2 current

regripper-3.png

If you want to test, you can also

  1. download hives-01.zip from https://cylab.be/s/Q2zQ0
  2. extract the archive
  3. run the plugin with
regripper -f system -p currentcontrolset

regripper-current-controlset.png

This blog post is licensed under CC BY-SA 4.0

This website uses cookies. More information about the use of cookies is available in the cookies policy.
Accept