Home

Awesome

PowerSponse - PowerShell module for containment and remediation

PowerSponse - PowerShell Module for Containment and Remediation

PowerSponse is a PowerShell module for targeted containment and remediation during incident response.

Please see Command Documentation, Wiki and CHANGELOG.


<!-- vim-markdown-toc GFM --> <!-- vim-markdown-toc -->

What is PowerSponse?

PowerSponse is a PowerShell module for targeted containment and remediation.

The following features are implemented in PowerSponse:

PowerSponse can be used in the containment and remediation phase (deny, degrade and disrupt) of an incident. Of course, the containment part contradicts with the forensic soundness, which means that the source evidence (infected machine) is not altered in any way. The question is always: Would you like to limit the damage during an attack and control the communication flow to the attacker's servers or would you like to collect more information from the attacker by just passive monitoring?

Different methods are used to connect and run the commands on remote hosts: WMI, WinRM, PsExec, Windows' system tools.

Every action outputs the same PowerSponse object format for easy post processing: which command was run, target hostname, timestamp and status of the command.

The following use cases were in mind when implementing PowerSponse:

Example

Dridex (yeah, old stuff, the example is from 2016) creates some files, injects itself into explorer and adds a scheduled task. Taken from Detecting and removing Dridex, the manual steps for containment are as follows:

  1. Kill explorer.exe process using taskkill /f /im explorer.exe
  2. Remove all tmp files from C:\users\username\data\locallow, del %userprofile%\appdata\locallow*.tmp. There could be more than one user on a computer and you’d better traverse through all user profile folders to check for Dridex files.
  3. Remove Dridex task using schtasks /delete /tn “User_Feed_Synchronization-{Dridex-Random-Hex-GUID}” /f
  4. Reboot the PC.

With PowerSponse you could use these cmdlets directly (@() is used to concatenate the output of all the commands).

PS> $ret = @()
PS> $ret += Stop-Process -ComputerName comp1 -Name "explorer"
PS> $ret += Remove-File -ComputerName comp1 -Path "C:\users\*\appdata\locallow\*.tmp
PS> $ret += Disable-ScheduledTask -ComputerName comp1 -TaskName "User_F.*_S.*-\{.{8}-(.{4}-){3}.{12}\}"
PS> $ret += Restart-Computer -ComputerName comp1
PS> $ret | select time, action, computername, status, reason

Time                Action                  ComputerName  Status Reason
----                ------                  ------------  ------ ------
08.01.2017 16:41:36 Stop-Process            comp1         pass   Stopped
08.01.2017 16:41:47 Remove-File             comp1         pass   Removed
08.01.2017 16:41:52 Disable-ScheduledTask   comp1         pass   Disabled
08.01.2017 16:41:54 Restart-Computer        comp1         pass   Rebooted

Or create a corresponding CoRe rule and use the rule in combination with Invoke-PowerSponse or New-CleanupPackage.

{
    "PowerSponse": [
        {
            "id" : "12341234-1234-1234-1234-123412341234",
            "name" : "Dridex June 2016",
            "date" : "2016-06-01",
            "author" : "Mr. Evil",
            "description" : "Dridex cleanup rule.",
            "action" : [
                {
                    "type" : "ProcessItem",
                    "name" : "explorer.exe"
                },
                {
                    "type" : "FileItem",
                    "Path" : "C:\\users\\*\\appdata\\locallow\\*.tmp"
                },
                {
                    "type" : "TaskItem",
                    "searchstring" : "User_F.*_S.*-\\{.{8}-(.{4}-){3}.{12}\\}"
                },
                {
                    "type" : "ComputerItem",
                    "action" : "reboot"
                }
            ]
        }
    ]
}
PS> Invoke-PowerSponse -ComputerName comp1 -Rule dridex-201606.json
PS> New-CleanupPackage -Rule dridex-201606.json

Instead of running the commands directly against the target computers, you can use New-CleanupPackage which concatenates all scripts and commands into a new PowerShell script and therefore allows an offline deployment to the target host without having a direct network connection.

Requirements

To run PowerSponse commands via network you need remote administrator rights and need some ports open on the target machine, depending which method (WinRM, WMI, PsExec, ...) the remote management protocols use 135 TCP, 139 TCP, 445 TCP, 5985 TCP, 5986 TCP. Alternatively, run the commands and PowerSponse scripts directly on the target (localhost) by importing the module on the target machine or by using the New-CleanupPackage in combination with a CoRe rule.

Installation

Update March 2022: Install PowerSponse from PowerShell Gallery was only supported until March 2022. Afterwards, only manual install through GitHub is provided. See CHANGELOG for more details about versions.

Usage

Use command -<tab> to tab between the available parameters or use command -<ctrl+space> to display a list of all paremeters.

Disclaimer: The command interface is inconsistent, that means that some commands can have a -Credential parameter (WMI and WinRM can handle credential objects) and other commands which rely on external tools do not (passwords in logs are bad, very bad). Some commands have a WMI implementation, others do only have an implementation using an external tool. Read through the docs, try the commands out and make a pull request for missing functionality. There are a lot of missing commands...That said, enjoy mitigating the evil.

Authentication

Import

If PowerSponse was saved inside the module path run the following command:

Import-Module PowerSponse -force

If PowerSponse was saved outside the module path run the command:

Import-Module <path to module>\PowerSponse.psd1 -force

Cmdlets

Please see docs and the wiki for the list of all available commands.

Use the common parameters like -WhatIf or -Verbose for troubleshooting and to see what the commands would do. WhatIf is implemented for every function which makes any changes.

List available PowerSponse commands.

get-command -Module PowerSponse

List all PowerSponse commands for tasks

get-command -Module PowerSponse | sls task

Help

Use help <command> to get the help for a command.

PS> help Get-ScheduledTask

NAME
    Get-ScheduledTask

OVERVIEW
    Find scheduled tasks based on regex.

SYNTAX
    Get-ScheduledTask [-BinPath <String>] [-ComputerList <String>] [-ComputerName <String[]>] [-Confirm] [-Credential <PSCredential>] [-PrintXML] [-Session <PSSession>[]>] [-WhatIf] [-NoRemoteRegistry] [-OnlyTaskName] [-SearchString <String>] [-Method <String>] [-OnlineCheck] [<CommonParameters>]

DESCRIPTION
    Find scheduled tasks based on a literal or regex.
...

Use help <command> -Examples to get examples for a command.

PS> help Get-ScheduledTask -Examples

NAME
    Get-ScheduledTask

OVERVIEW
    Find scheduled tasks based on literal or regex.

    Example 1

    PS> Get-ScheduledTask -SearchString ".*-S-\d{1}-\d{1}" -NoRemoteRegistry -OnlyTaskName


    Time         : 06.01.2017 10:31:29
    Action       : Get-ScheduledTask
    ComputerName : localhost
    Arguments    : TaskName: .*-S-\d{1}-\d{1}
    Status       : pass
    Reason       : \G2MUpdateTask-S-1-5-21-111111111-2222222222-333333333-444444 ; \G2MUploadTask-S-1-5-21-111111111-2222222222-333333333-444444

...

Some commands have the same name as the native cmdlets (e.g. Stop-Service). For these cmdlets you need to prefix the cmdlet name with the specific module when using help: help powersponse\stop-service.

Contributing

See CONTRIBUTING for general guidelines.

Inspiration

References