F. Custom Plugin Development - Asymmetric-InfoSec/Power-Response GitHub Wiki
One of the benefits of Power-Response is the ability to create whatever plugins you want for the platform to use during your incident response and/or data collection efforts. Use the guidelines below when creating your plugins to make sure they gel with the framework. Also, if you create a plugin, please consider submitting a pull request so we can share that plugin with the rest of the community.
Plugin Format
Although not explicitly required for the use of plugins in the Power-Response framework, if you are going to submit a plugin pull request, we ask that you follow these guidelines:
1. Plugin Template
There is a plugin template that is located in $PSScriptRoot\Extras
that will provide you with the basic format for plugins that the creators use.
2. Plugin Naming Convention
The naming convention we have chosen helps analysts easily identify what a plugin is going to do and how it is going to do it. Please follow these guidelines for naming:
Collect-PluginName: For plugins that do not deploy binaries or retrieve files from the remote system. These will run using simultaneous PSRemoting sessions on target hosts. These will run in a context that is local to the framework, not your local data collection machine.
Retrieve-PluginName: For plugins that deploy binaries or retrieve files from the remote system. These will run using PSRemoting by handing sessions directly to the plugin for execution. These will run in a context local to your data collection machine.
Analyze-PluginName: For plugins that are intended to analyze data from either Collect or Retrieve plugin. These will run in a context that is local to your data collection/analysis machine.
Triage-PluginName: For plugins that call other plugins. These plugins are for mass data collection and ease of use. Any type of plugin can be called from a triage plugin.
Hunt-PluginName: For plugins that are using in a hunting capacity. The plugin name cannot share the same descriptor as any other plugin (i.e. Hunt-Processes is not allowed since we already have Collect-Processes).
Scope-PluginName: For plugins that are used during the scoping of an incident. The plugin name cannot share the same descriptor as any other plugin (i.e. Scope-Processes is not allowed since we already have Collect-Processes).
Eradicate-PluginName: For plugins that are used during the eradication phase of an incident. The plugin name cannot share the same descriptor as any other plugin (i.e. Eradicate-Processes is not allowed since we already have Collect-Processes).
Parameters
1. Collect Plugins
Collect plugins are not intended to have any parameters. The framework handles all parameters. Collect plugins should be written as though you are executing the script on a local system for collection.
Note: If you have any parameters listed in a Collect plugin, the framework may not be able to honor them when running on a remote machine
2. Retrieve Plugins
Retrieve plugins require a [System.Management.Automation.Runspaces.PSSession]$Session
parameter. The Power-Response framework uses this session parameter to run the Retrieve plugin correctly. Additional parameters may be used with Retrieve plugins and are aware of the local system when running.
3. Analyze Plugins
Retrieve plugins require a [System.Management.Automation.Runspaces.PSSession]$Session
parameter. The Power-Response framework uses this session parameter to run the Analysis plugins correctly. Additional parameters maybe used with Analysis plugins. Analysis plugins are aware of the local system when running.
4. Triage Plugins
Triage plugins require a [System.Management.Automation.Runspaces.PSSession]$Session
parameter. These plugins are created to call other plugins from a master triage plugin (plugin-ception). Triage plugins follow the same general rules as retrieve plugins, however, they can be used to call any time of plugin. These plugins are great for consolidating many plugins into one single plugin for ease of use.
5. Hunt Plugins
Hunt Plugins require two parameters. Hunt plugins require a [System.Management.Automation.Runspaces.PSSession]$Session
parameter. Additionally, they require a [String]$HuntName
parameter which is used to properly store retrieved data to ensure it is analyzed properly. Additional parameters may be used with Retrieve plugins and are aware of the local system when running.
6. Scope Plugins
Scope Plugins require two parameters. Scope plugins require a [System.Management.Automation.Runspaces.PSSession]$Session
parameter. Additionally, they require a [String]$ScopeName
parameter which is used to properly store retrieved data to ensure it is analyzed properly. Additional parameters may be used with Retrieve plugins and are aware of the local system when running.
7. Eradicate Plugins
Eradicate plugins require a [System.Management.Automation.Runspaces.PSSession]$Session
parameter. The Power-Response framework uses this session parameter to run the Retrieve plugin correctly. Additional parameters may be used with Retrieve plugins and are aware of the local system when running.
Power-Response Paths
The Get-PRPath function built in to Power-Response can provide the working path for all paths that are built into Power-Response. See the list below for how to reference specific paths:
Get-PRPath -Bin
resolves to theBIN
directory of Power-ResponseGet-PRPath -Logs
resolves to theLogs
directory of Power-ResponseGet-PRPath -Output
resolves to theOutput
directory of Power-ResponseGet-PRPath -Plugins
resolves to thePlugins
directory of Power-Response
Note: See the section below for how to use Get-PRPath
to specify a custom output location within Output
Plugin Inception (Calling plugins from plugins)
Power-Response allows you to call plugins from other plugins inception style using the Invoke-PRPlugin
.
To call plugins from within plugins, the plugin doing the calling must be configured and structured as a Retrieve
, Hunt
, or Analyze
plugin. You can call any Power-Response plugin from another Retrieve
, Hunt
, or Analyze
plugin. When doing this, the plugins will run as if you were running the plugin directly from Power-Response normally. The Invoke-PRPlugin
function requires either a plugin Path
or plugin Name
and also requires that you have a Session
parameter identified as well (in the plugin and specified as a parameter when calling in the plugin). Note: For Hunt
plugins, you must also provide the HuntName
parameter.
Note: You must satisfy all other parameters of the plugin you are calling or make sure the required parameters have default values.
Example: Invoke-PRPlugin -Name Retrieve-RecycleBin.ps1 -Session $Session
Example: Invoke-PRPlugin -Name 'Collect-ScheduledTaskInfo' -Session $Session -HuntName $HuntName
Note: The Invoke-PRPlugin function also includes the NoAnalyze
flag. This allows you to call a plugin without processing for the corresponding default analysis plugin. This option is great when used for plugins similar to Retrieve-ShimCache, where the registry files need to be collected. In this case, you would use the Invoke-PRPlugin function to call the Retrieve-RegistryHives plugin to obtain the necessary files relevant to ShimCache. Using the NoAnalyze
flag will allow for you to collect the registry hive files without processing the Analyze-RegistryHives plugin.
Binary Deployments
7za and Velociraptor are common to many plugins in Power-Response. When calling plugins in Triage plugins, it was undesirable for every plugin to deploy and remove these binaries on the remote machine (and inefficient). To solve this, we built in binary checks into all plugins that use 7za and Velociraptor to determine if the binaries exist on the remote host already or not. If they exist, nothing is done and they continue to run. They also leave the binaries put when finishing. If they are not present, the binaries will be deployed and removed as the plugin runs. This allows the triage plugin to control the 7za and Velociraptor dependencies.
All other binaries specific to a plugin will be deployed and removed by the plugin that requires the binary dependency.
Output
1. Custom Output Paths
Retrieve and Analysis plugins support custom output paths using the Get-PRPath
function built into the Power-Response framework. When using the Output-Specific parameter set, the function will allow for the analyst to specify the desired output path. The function has three parameters when using this parameter set ComputerName
, Plugin
, and/or Directory
. The string type parameter ComputerName
parameter is used to specify which machine sub-directory the output should be placed in. The string parameter Plugin
will mirror the path of a specified plugin (just enter the name of the plugin to mirror, ex: Collect-Processes.ps1) or will be taken from the current plugin running. The string type parameter Directory
parameter allows you to specify an additional custom named directory that the output should be placed in. Many of the retrieve plugins use this function to create custom directories to place retrieved files into. See Retrieve-Items.ps1
and Retrieve-Shimcache.ps1
for an example of how this function can be used.
Note: This functionality should not be used with Hunt plugins.
2. Custom Output Names
Retrieve and Analysis plugins support custom output names using the Out-PRFile
function built into the Power-Response framework. Out-PRFile
can be used to append specific names onto output that you would like to handle within the plugin and not at the framework level. It is recommended that this be used sparingly since the framework can handle output gracefully in most circumstances (see below for more details). The Out-PRFile
function has one string type parameter of Append
where you can specify the custom string to append onto the output name.
3. Framework Handling of Data (Use PS Objects for All Data)
Power-Response is great at handling PowerShell objects and will do so with ease. However, do to some of the limitations of Powershell, the handling of strings does not go so well. With this in mind, it is recommended that you output everything as a PowerShell Object. In many cases, it is simple to parse a string object into a PowerShell custom object using [PSCustomObject]
. In many cases, we have used hash tables to still achieve a nice format for data that is parsed from strings.
At the end of the day, use PowerShell objects for output and you will be good to go.
Writing Warnings, Errors, and Messages to Console and Logs
There are several functions that have been created that allow plugin authors to write errors, warnings, and messages to console and logs simultaneously that improve console feedback and logging. Each of the following functions can be used in custom plugins:
Write-PRHost
: This function performs a Write-Host
to output a message to console and also utilizes Write-PRLog
function to write the same message to the log file.
Write-PRWarning
: This function performs a Write-Warning
to output a warning to console and also utilizes the Write-PRLog
function to write the warning to the log file.
Write-PRError
: This function performs a Write-Error
to output an error to console and also utilizes the Write-PRLog
function to write the error to the log file.