Skip to content

Instantly share code, notes, and snippets.

@ecapuano
Last active March 11, 2024 15:39
Show Gist options
  • Star 61 You must be signed in to star a gist
  • Fork 12 You must be signed in to fork a gist
  • Save ecapuano/daee6f3704273c2c8b527f522c1725db to your computer and use it in GitHub Desktop.
Save ecapuano/daee6f3704273c2c8b527f522c1725db to your computer and use it in GitHub Desktop.
Live Incident Response with Velociraptor - Handout

Live Incident Response with Velociraptor - Handout

@eric_capuano

Watch the recorded talk here: https://www.youtube.com/watch?v=Q1IoGX--814

This handout is meant to accompany the live talk, but contains many useful notebook examples for post-processing Velociraptor hunt results.


Hunting for phish victims

Objective: Using the name of a suspicious email attachment, we can quickly identify which users/systems may have been impacted.

Hunt Artifact: Windows.Search.FileFinder

Parameters:

  • SearchFilesGlob: C:\Users\**\Security_Protocol*

Notebook:

SELECT Fqdn,FullPath,BTime AS CreatedTime,MTime as ModifiedTime, Hash,
label(client_id=ClientId, labels="phish_victim", op="set") // label all systems with detections
FROM source()

Lateral Movement

Objective: When dealing with advanced adversaries, it is safe to assume the breach has expanded beyond the initial victims of the phish campaign... Let's launch a quick hunt to find possible lateral movement using the usernames of the phish victims

Hunt Artifact: Windows.EventLogs.RDPAuth

Notebook:

SELECT EventTime,Computer,Channel,EventID,UserName,LogonType,SourceIP,Description,Message,Fqdn FROM source()
WHERE ( // excluded logons of the user on their own system
(UserName =~ "Chad.Chan" AND NOT Computer =~ "ACC-01") 
OR (UserName =~ "Jean.Owen" AND NOT Computer =~ "ACC-05")
OR (UserName =~ "Albert.Willoughby" AND NOT Computer =~ "ACC-09")
OR (UserName =~ "Anna.Ward" AND NOT Computer =~ "ACC-04")
)
AND NOT EventID = 4634 // less interested in logoff events
AND NOT (Computer =~ "dc" OR Computer =~ "exchange" OR Computer =~ "fs1")
ORDER BY EventTime

Process Analysis

Objective: Find potentially compromised systems by baselining all running processes in the environment. This notebook returns processes marked as untrusted by Authenticode.

Hunt Artifact: Windows.System.Pslist

Notebook:

SELECT Name,Exe,CommandLine,Hash.SHA256 AS SHA256, Authenticode.Trusted, Username, Fqdn, count() AS Count FROM source()
WHERE Authenticode.Trusted = "untrusted" // unsigned binaries
// List of environment-specific processes to exclude
AND NOT Exe = "C:\\Program Files\\filebeat-rss\\filebeat.exe"
AND NOT Exe = "C:\\Program Files\\filebeat\\filebeat.exe"
AND NOT Exe = "C:\\Program Files\\winlogbeat-rss\\winlogbeat.exe"
AND NOT Exe = "C:\\Program Files\\winlogbeat\\winlogbeat.exe"
AND NOT Exe = "C:\\user-automation\\user.exe"
AND NOT Exe = "C:\\salt\\bin\\python.exe"
// Stack for prevalence analysis
GROUP BY Exe
// Sort results ascending
ORDER BY Count

Objective: Leverage VirusTotal to quickly check untrusted processes for detections. Be mindful that free VT API is limited to 4 lookups / min & 500 / day so we'll be as efficient as possible with what we query against VT.

Hunt Artifact: Windows.System.Pslist

Notebook:

// Get a free VT api key
LET VTKey <= "<your_api_key>"
// Build the list of untrusted processes first
Let Results = SELECT Name,CommandLine,Exe,Hash.SHA256 AS SHA256, count() AS Count FROM source()
WHERE Authenticode.Trusted = "untrusted"
AND SHA256 // only entries with the required SHA256
// List of environment-specific processes to exclude
AND NOT Exe = "C:\\user-automation\\user.exe"
GROUP BY Exe,SHA256
// Now combine the previous query with the Server Enrichment query
SELECT *, {SELECT VTRating FROM Artifact.Server.Enrichment.Virustotal(VirustotalKey=VTKey, Hash=SHA256) } AS VTResults FROM foreach(row=Results) WHERE Count < 10
ORDER BY VTResults DESC

Objective: Get process ancestry for known malware. Here we learn important details about how the malware was launched.

Hunt Artifact: Generic.System.Pstree with

Parameters:

  • Process Regex: .*(tkg|mshta|Security_Protocol).*

Notebook: none required


Persistence

Objective: Use a builtin artifact to hunt for potential persistence mechanisms.

Hunt Artifact: Windows.Sys.StartupItems

Notebook:

LET Results = SELECT count() AS Count, Fqdn, Name, FullPath, Command FROM source()
// filter common FPs
WHERE NOT FullPath =~ "bginfo.lnk"
AND NOT FullPath =~ "desktop.ini"
AND NOT FullPath =~ "Outlook.lnk"
AND NOT FullPath =~ "chrome.lnk"
AND NOT (Name =~ "OneDrive" AND FullPath =~ "OneDrive" AND Command =~ "OneDrive")
// end common FPs
GROUP BY Name, FullPath, Command // stack them
SELECT * FROM Results
WHERE Count < 10
ORDER BY Count // sorts ascending

Objective: Use a builtin artifact to hunt for potential persistence mechanisms.

Hunt Artifact: Windows.System.TaskScheduler

Notebook:

LET Results = SELECT FullPath,Command,Arguments,Fqdn, count() AS Count FROM source()
WHERE Command AND Arguments
AND NOT Command =~ "OneDriveStandaloneUpdater.exe"
AND NOT (Command = "C:\\Windows\\System32\\Essentials\\RunTask.exe" AND FullPath =~ "Essentials")
AND NOT Command =~ "MpCmdRun.exe"
AND NOT Arguments =~ "sildailycollector.vbs"
AND NOT Command = "C:\\Windows\\system32\\vssadmin.exe"
AND NOT FullPath =~ "BPA Scheduled Scan"
AND NOT Arguments =~ "CheckDatabaseRedundancy"
AND NOT Arguments =~ "silcollector.cmd"
GROUP BY FullPath,Command,Arguments
SELECT * FROM Results
WHERE Count < 5
ORDER BY Count // sorts ascending

Objective: Leverage Sysinternals Autorunsc to hunt for potential persistence mechanisms.

Hunt Artifact: Windows.Sysinternals.Autoruns

Notebook:

LET Results = SELECT count() AS Count, Fqdn, Entry,Category,Profile,Description,`Image Path` AS ImagePath,`Launch String` AS LaunchString,`SHA-256` AS SHA256 FROM source()
WHERE NOT Signer
AND Enabled = "enabled"
GROUP BY ImagePath,LaunchString
SELECT * FROM Results
WHERE Count < 5 // return entries present on fewer than 5 systems
ORDER BY Count

Scoping with known malware locations

Objective: Find all systems with suspected malware on disk

Hunt Artifact: Windows.Search.FileFinder

Parameters:

  • SearchFilesGlobTable:
    - C:\**\msxsl.exe
    - C:\**\*.hta
    - C:\**\drivers\svchost.exe
    - C:\**\tkg.exe
    - C:\**\Security_Protocol*
    - C:\**\XKnqbpzl.txt

Notebook:

SELECT Fqdn,FullPath,MTime AS ModifiedTime,BTime as CreationTime, Hash,
label(client_id=ClientId, labels="compromised", op="set") // label all systems with detections
FROM source()

Let's just find CobaltStrike already

Objective: Leveraging the power of Yara, let's just sweep all processes in memory for signatures matching the popular Cobalt Strike attack tool.

Hunt Artifact: Windows.Detection.Yara.Process

Parameters:

  • Default yara signature is Cobalt Strike

Notebook:

SELECT Fqdn, ProcessName, Pid, Rule,
label(client_id=ClientId, labels="cobaltstrike", op="set") // label all systems with detections
FROM source()

Remediation - Quarantine

Objective: Now that we have a solid grasp on the scope of the intrusion, lets quarantine all impacted systems to prevent further damage.

Hunt Artifact: Windows.Remediation.Quarantine (run against all systems labeled compromised)

Notebook: none required


Begin Forensics

Objective: Now that compromised systems are quarantined, lets pull back forensics data for deeper analysis

Hunt Artifact: Windows.KapeFiles.Targets (run against all systems labeled compromised)

Paramenters:

  • Kape targets: _SANS_Triage

Notebook: none required

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment