Stage Capabilities
This detection identifies adversary activity consistent with staging capabilities on external infrastructure prior to targeting. Because T1608 is a pre-compromise technique conducted on adversary-controlled infrastructure, direct detection is not possible from victim telemetry alone. Instead, this detection focuses on the victim-side observable: endpoints or users connecting to known or suspected staging infrastructure and downloading executable artifacts. Detectable signals include connections to file-sharing platforms (Pastebin, transfer.sh, Discord CDN, GitHub raw), downloads of executable file types from these platforms, and use of living-off-the-land binaries (certutil, bitsadmin, curl) to retrieve staged payloads. Threat intelligence correlation against known staging domains and IPs supplements behavioral heuristics to surface high-confidence staging delivery events.
What is T1608 Stage Capabilities?
Stage Capabilities (T1608) maps to the Resource Development tactic — the adversary is trying to establish resources they can use to support operations in MITRE ATT&CK.
This page provides production-ready detection logic for Stage Capabilities, covering the data sources and telemetry it touches: Microsoft Defender for Endpoint. The queries below are rated high severity at medium confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.
MITRE ATT&CK
- Tactic
- Resource Development
- Technique
- T1608 Stage Capabilities
- Canonical reference
- https://attack.mitre.org/techniques/T1608/
let LookbackPeriod = 1d;
let SuspiciousStagingDomains = dynamic([
"pastebin.com", "paste.ee", "pastecode.io", "pasteio.com",
"transfer.sh", "filebin.net", "gofile.io", "temp.sh", "anonfiles.com",
"raw.githubusercontent.com", "gist.githubusercontent.com",
"dl.dropboxusercontent.com", "cdn.discordapp.com",
"storage.googleapis.com", "s3.amazonaws.com"
]);
let ExecutableExtensions = dynamic(["exe", "dll", "ps1", "vbs", "hta", "bat", "cmd", "msi", "jar", "bin", "scr", "pif"]);
let LolBins = dynamic([
"certutil.exe", "bitsadmin.exe", "curl.exe", "wget.exe",
"powershell.exe", "pwsh.exe", "wscript.exe", "cscript.exe",
"mshta.exe", "regsvr32.exe", "rundll32.exe", "msiexec.exe"
]);
DeviceNetworkEvents
| where TimeGenerated >= ago(LookbackPeriod)
| where ActionType in ("ConnectionSuccess", "HttpConnectionInspected")
| extend ParsedUrl = parse_url(RemoteUrl)
| extend HostDomain = tostring(ParsedUrl["Host"])
| extend FilePath = tostring(ParsedUrl["Path"])
| extend FileExt = tolower(extract(@"\.([a-zA-Z0-9]{2,4})(?:\?|#|$)", 1, FilePath))
| where HostDomain has_any (SuspiciousStagingDomains)
and FileExt in (ExecutableExtensions)
| join kind=leftouter (
DeviceFileEvents
| where TimeGenerated >= ago(LookbackPeriod)
| where ActionType == "FileCreated"
| project DeviceId, FileCreatedTime = TimeGenerated, FileName, FolderPath,
SHA256, FileSize, FileInitiatingProcessId = InitiatingProcessId
) on DeviceId, $left.InitiatingProcessId == $right.FileInitiatingProcessId
| extend RiskScore = case(
HostDomain has "pastebin", 85,
HostDomain has "paste", 80,
HostDomain has "transfer.sh", 85,
HostDomain has "anonfiles", 90,
HostDomain has "gofile", 75,
HostDomain has "temp.sh", 80,
HostDomain has "discordapp", 60,
HostDomain has "dropbox", 50,
HostDomain has "raw.githubusercontent", 45,
HostDomain has "storage.googleapis", 55,
HostDomain has "s3.amazonaws", 50,
55
)
| extend LolBinUsed = iff(InitiatingProcessFileName in~ (LolBins), true, false)
| extend AdjustedRisk = RiskScore + iff(LolBinUsed, 15, 0)
| where AdjustedRisk >= 45
| project TimeGenerated, DeviceName, DeviceId,
StagingDomain = HostDomain,
RemoteUrl, RemoteIP, FileExt,
InitiatingProcessFileName, InitiatingProcessCommandLine,
InitiatingProcessAccountName, InitiatingProcessAccountDomain,
DroppedFile = FileName, DroppedFilePath = FolderPath, SHA256,
LolBinUsed, AdjustedRisk
| order by AdjustedRisk desc, TimeGenerated desc Detects endpoint connections to known capability-staging platforms (paste sites, file-transfer services, cloud storage CDNs) where the retrieved URL path targets an executable file type. Scoring is adjusted upward when a living-off-the-land binary initiates the connection. Correlated file creation events from the same process provide SHA256 hashes for threat intelligence lookups.
Data Sources
Required Tables
False Positives
- Developers legitimately downloading build artifacts, scripts, or tools from GitHub raw content or cloud storage during CI/CD workflows
- IT administrators using certutil or curl to download approved software packages from cloud storage buckets
- Security researchers or red teamers running authorized testing from internal systems that happen to pull tools from public staging platforms
- Automated deployment pipelines or configuration management tools (Ansible, Chef, Puppet) that fetch scripts from blob storage
Sigma rule & cross-platform mapping
The detection logic for Stage Capabilities (T1608) above is provided in a vendor-neutral
form so you can deploy it on any SIEM. The same logic is shipped here as native
KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the
following logsource:
logsource:
category: network_connection
product: windows Browse the community-maintained Sigma rules for this technique:
Platform-specific guides for T1608
References (8)
- https://attack.mitre.org/techniques/T1608/
- https://www.proofpoint.com/us/blog/threat-insight/ta416-goes-ground-and-returns-golang-plugx-malware-loader/
- https://attack.mitre.org/techniques/T1608/001/
- https://attack.mitre.org/techniques/T1608/002/
- https://attack.mitre.org/techniques/T1608/003/
- https://attack.mitre.org/techniques/T1608/004/
- https://attack.mitre.org/techniques/T1608/005/
- https://attack.mitre.org/techniques/T1608/006/
Testing Methodology
Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Stage and Retrieve Benign Payload via Pastebin (Simulated)
Expected signal: Sysmon Event ID 1 (Process Create) for certutil.exe with -decode arguments. DeviceProcessEvents entry for certutil.exe. DeviceFileEvents showing file creation in %TEMP%. PowerShell ScriptBlock log (Event ID 4104) showing the staging simulation commands.
- Test 2Download Simulated Tool from GitHub Raw Content
Expected signal: Sysmon Event ID 3 (Network Connection) for powershell.exe connecting to raw.githubusercontent.com on port 443. Sysmon Event ID 11 (File Create) for the downloaded file. DeviceNetworkEvents in Defender for Endpoint showing powershell.exe initiating connection. DeviceFileEvents showing file write in TEMP.
- Test 3Simulate Drive-by Staging Infrastructure via Local Web Server
Expected signal: Linux audit logs showing curl process spawning with HTTP connection to 127.0.0.1:8888. Syslog entries for the Python HTTP server serving the request. File creation event for downloaded_payload.exe in /tmp. If auditd is enabled: syscall records for execve (python3, curl) and open/write for file creation.
Response Playbook
Triage
- Step 1: Identify the full staging URL — extract the exact path and filename. Run the SHA256 of any downloaded file against VirusTotal, MalwareBazaar, and internal threat intelligence. A known-malicious hash immediately elevates to Incident.
- Step 2: Determine the initiating process. Was it a LOLBin (certutil, bitsadmin, curl)? LOLBin usage strongly suggests an automated malicious download. Was it a browser? Check if the user clicked a phishing link (correlate with email gateway logs from the same timeframe ±10 minutes).
- Step 3: Check DeviceFileEvents for file creation events triggered by the same process around the same time. Determine where the file was written — Temp, AppData, Downloads. A write to a non-standard temp directory (not %USERPROFILE%\Downloads) indicates likely adversary automation.
- Step 4: Query DeviceProcessEvents for any child processes spawned by the initiating process or by the downloaded file within 5 minutes of the download. Use: DeviceProcessEvents | where InitiatingProcessFileName =~ "<downloaded_file>" | where TimeGenerated between (download_time .. download_time + 5m).
- Step 5: Expand the blast radius — query all devices in the environment for connections to the same staging domain/IP over the past 30 days. Multiple hosts connecting to the same staging infrastructure indicates a coordinated campaign.
- Step 6: Check if the staging domain or IP appears in threat intelligence feeds (Defender TI, MISP, or commercial TI). Look for associated campaigns, malware families, and threat actor TTPs.
- Step 7: Correlate with phishing or initial access events. Check OfficeActivity for email delivery to the affected user from external senders within the preceding 24 hours. Cross-reference with MX gateway logs for attachment/link delivery.
Containment
- If the downloaded file was executed (confirmed child process): immediately isolate the endpoint via Microsoft Defender for Endpoint (Isolate device action) or equivalent EDR response.
- Block the staging domain and IP at the proxy/firewall level across the organization. Submit to proxy block list and DNS sinkhole if available.
- If the downloaded file was not executed (download only): quarantine the file via EDR response, prevent execution, and continue investigation before isolating.
- Disable the affected user account if credential compromise is suspected or if the download was initiated by a scripting process (not a user browser session).
- Revoke active sessions and force re-authentication for the affected user across all cloud services (M365, Entra ID) if account compromise is suspected.
Evidence Collection
- Export full DeviceNetworkEvents and DeviceFileEvents for the affected device from T-1h to T+1h around the staging download event.
- Collect the downloaded file (if still on disk) for static and dynamic analysis. Compute MD5, SHA1, SHA256.
- Export DeviceProcessEvents for the affected device for 30 minutes post-download to capture execution chain.
- Pull proxy/DNS logs for the staging domain from the past 30 days to establish when the domain was first contacted in the environment.
- Capture memory dump of any process that executed the downloaded payload using EDR response capabilities.
- Export email headers and body of any phishing email delivered to the affected user around the download timeframe (OfficeActivity, Exchange message trace).
- Collect prefetch files from the endpoint (C:\Windows\Prefetch\) to establish execution history for the downloaded binary.
Escalation Criteria
- ! Escalate to Incident if the downloaded file has a known-malicious hash or is detected as malware by EDR.
- ! Escalate if child processes were spawned from the downloaded file, indicating successful execution.
- ! Escalate if three or more endpoints in the environment connected to the same staging infrastructure, indicating an active campaign.
- ! Escalate if the staging domain was registered within the past 30 days (new domain = higher probability of purpose-built attack infrastructure).
- ! Escalate if lateral movement indicators are observed on the affected host within 60 minutes of the staging download.
- ! Escalate if a C2 beacon pattern (regular periodic network connections) is detected from the affected host post-download.
Investigation Guide
Forensic Artifacts
- >
Browser history and download records (Chrome: %LOCALAPPDATA%\Google\Chrome\User Data\Default\History, Edge: %LOCALAPPDATA%\Microsoft\Edge\User Data\Default\History) - >
Windows Prefetch files (C:\Windows\Prefetch\) for execution evidence of downloaded binaries - >
Zone.Identifier Alternate Data Stream on downloaded files — records source URL for files downloaded via browser - >
PowerShell script block logging (Event ID 4104) if PowerShell was used to retrieve staged payload - >
BITSAdmin job history (bitsadmin /list /allusers) if BITS was used for staged download - >
Certutil cache (C:\Users\<user>\AppData\LocalLow\Microsoft\CryptnetUrlCache\) if certutil was used to decode/download - >
Proxy server access logs with full URI including path and query string - >
DNS resolution logs for staging domain showing when each host first queried the domain - >
EDR process tree for the download event and any child processes - >
Email gateway logs (header analysis, attachment/link inspection records) for phishing delivery correlation
Tuning Guidance
The most effective tuning approach is building an allowlist of approved software distribution domains (vendor update CDNs, internal artifact repositories, approved cloud storage buckets). Scope the detection to business units where users have no legitimate reason to download executables from public paste or file-transfer sites. For environments with heavy developer activity, exclude DeviceName or AccountName values associated with engineering workstations. The risk scoring thresholds can be adjusted based on environment sensitivity — tighten to score >=60 to reduce volume in high-noise environments, or loosen to >=30 for environments requiring maximum coverage. Correlate with email gateway data to auto-close alerts where the download was triggered by a link in a known-benign internal email (e.g., IT service desk sending approved tool links).
Hunting Queries
Hunts for LOLBin-initiated network connections that download executable file types from any external host, not limited to the known staging domain list. Surfaces previously unknown staging infrastructure by focusing on the delivery mechanism rather than the destination.
// Hunt: LOLBin-initiated downloads from any external host, not limited to known staging domains
let LookbackPeriod = 14d;
let LolBins = dynamic(["certutil.exe", "bitsadmin.exe", "curl.exe", "wget.exe", "powershell.exe", "pwsh.exe"]);
let ExecutableExts = dynamic(["exe", "dll", "ps1", "vbs", "hta", "bat", "msi"]);
DeviceNetworkEvents
| where TimeGenerated >= ago(LookbackPeriod)
| where InitiatingProcessFileName in~ (LolBins)
| where ActionType == "ConnectionSuccess"
| extend ParsedUrl = parse_url(RemoteUrl)
| extend HostDomain = tostring(ParsedUrl["Host"])
| extend FilePath = tostring(ParsedUrl["Path"])
| extend FileExt = tolower(extract(@"\.([a-zA-Z0-9]{2,4})(?:\?|$)", 1, FilePath))
| where FileExt in (ExecutableExts)
// Exclude known-good software distribution CDNs
| where HostDomain !has "microsoft.com"
and HostDomain !has "windowsupdate.com"
and HostDomain !has "symantec.com"
and HostDomain !has "sophos.com"
and HostDomain !has "crowdstrike.com"
| summarize
DownloadCount = count(),
UniqueHosts = dcount(DeviceName),
AffectedDevices = make_set(DeviceName, 10),
DownloadedURLs = make_set(RemoteUrl, 10),
FirstSeen = min(TimeGenerated),
LastSeen = max(TimeGenerated)
by InitiatingProcessFileName, HostDomain, FileExt
| order by UniqueHosts desc, DownloadCount desc index=* sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=3
| eval lolbin=if(match(lower(Image), "certutil|bitsadmin|curl|wget|powershell|pwsh"), 1, 0)
| where lolbin=1
| eval file_ext=lower(replace(mvindex(split(mvindex(split(DestinationHostname, "."), -1), "?"), 0), "[^a-z0-9]", ""))
| rex field=Image "\\(?<process_name>[^\\]+)$"
| stats count as connection_count, dc(ComputerName) as unique_hosts,
values(ComputerName) as affected_hosts,
values(DestinationIp) as dest_ips,
earliest(_time) as first_seen, latest(_time) as last_seen
by process_name, DestinationHostname
| where NOT match(DestinationHostname, "microsoft\.com|windowsupdate\.com|symantec\.com|sophos\.com|crowdstrike\.com")
| sort -unique_hosts -connection_count
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen, "%Y-%m-%d %H:%M:%S")
| table first_seen, last_seen, process_name, DestinationHostname, unique_hosts, affected_hosts, dest_ips, connection_count Hunts using Sysmon Event ID 15 (FileCreateStreamHash) which captures Zone.Identifier alternate data streams written when browsers download files. The Zone 3 marker (Internet zone) combined with the embedded source URL reveals exactly which external domain delivered the file, surfacing staging infrastructure not captured by network telemetry.
// Hunt: Files written with Zone.Identifier ADS sourced from unusual external domains
let LookbackPeriod = 14d;
DeviceFileEvents
| where TimeGenerated >= ago(LookbackPeriod)
| where ActionType == "FileCreated"
| where FileName endswith ":Zone.Identifier" or AdditionalFields has "ZoneTransfer"
| extend ParsedAdditional = parse_json(AdditionalFields)
| extend ZoneId = tostring(ParsedAdditional.ZoneId)
| extend ReferrerUrl = tostring(ParsedAdditional.ReferrerUrl)
| extend HostUrl = tostring(ParsedAdditional.HostUrl)
| where ZoneId == "3" // Zone 3 = Internet zone
| extend SourceDomain = extract(@"https?://([^/]+)/", 1, HostUrl)
| where isnotempty(SourceDomain)
and SourceDomain !has "microsoft.com"
and SourceDomain !has "office.com"
and SourceDomain !has "windows.com"
| extend CleanFileName = replace_string(FileName, ":Zone.Identifier", "")
| extend FileExt = tolower(extract(@"\.([a-zA-Z0-9]{2,4})$", 1, CleanFileName))
| where FileExt in ("exe", "dll", "msi", "ps1", "vbs", "hta", "bat", "cmd", "jar")
| project TimeGenerated, DeviceName, CleanFileName, FolderPath, SourceDomain,
HostUrl, ReferrerUrl, InitiatingProcessFileName, InitiatingProcessAccountName
| order by TimeGenerated desc index=* sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=15
| rex field=Contents "ZoneId=(?<zone_id>\d+)"
| rex field=Contents "ReferrerUrl=(?<referrer_url>[^\r\n]+)"
| rex field=Contents "HostUrl=(?<host_url>[^\r\n]+)"
| where zone_id=3
| rex field=host_url "https?://(?<source_domain>[^/]+)/"
| where NOT match(source_domain, "microsoft\.com|office\.com|windows\.com|apple\.com|adobe\.com")
| rex field=TargetFilename "(?<clean_filename>[^\\]+)$"
| eval file_ext=lower(mvindex(split(mvindex(split(clean_filename, "."), -1), ":"), 0))
| where match(file_ext, "^(exe|dll|msi|ps1|vbs|hta|bat|cmd|jar)$")
| stats count as downloads, values(TargetFilename) as filenames,
values(host_url) as source_urls, earliest(_time) as first_seen
by ComputerName, source_domain, file_ext
| sort -downloads
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S")
| table first_seen, ComputerName, source_domain, file_ext, downloads, filenames, source_urls Hunts for domains serving executable files that have never been observed in the environment before the past 7 days. New domains delivering executables are a high-fidelity signal for freshly staged attack infrastructure, as legitimate software distribution typically uses established, previously observed domains.
// Hunt: Newly observed external domains first appearing in environment within past 7 days that deliver executables
let BaselinePeriod = 90d;
let HuntPeriod = 7d;
let ExecutableExts = dynamic(["exe", "dll", "ps1", "vbs", "hta", "msi", "bat"]);
let HistoricalDomains = DeviceNetworkEvents
| where TimeGenerated between (ago(BaselinePeriod) .. ago(HuntPeriod))
| extend ParsedUrl = parse_url(RemoteUrl)
| extend HostDomain = tostring(ParsedUrl["Host"])
| where isnotempty(HostDomain)
| summarize by HostDomain;
DeviceNetworkEvents
| where TimeGenerated >= ago(HuntPeriod)
| extend ParsedUrl = parse_url(RemoteUrl)
| extend HostDomain = tostring(ParsedUrl["Host"])
| extend FilePath = tostring(ParsedUrl["Path"])
| extend FileExt = tolower(extract(@"\.([a-zA-Z0-9]{2,4})(?:\?|$)", 1, FilePath))
| where FileExt in (ExecutableExts)
| join kind=leftanti HistoricalDomains on HostDomain // Only domains not seen before
| summarize
FirstSeen = min(TimeGenerated),
HitCount = count(),
AffectedDevices = make_set(DeviceName, 20),
DeviceCount = dcount(DeviceName),
SampleURLs = make_set(RemoteUrl, 5)
by HostDomain, FileExt
| order by DeviceCount desc, FirstSeen asc index=* sourcetype="stream:http" earliest=-90d@d latest=-7d@d
| stats dc(src_ip) as historical_count by dest_hostname
| eval is_historical=1
| append [
search index=* sourcetype="stream:http" earliest=-7d@d
| eval file_ext=lower(replace(mvindex(split(mvindex(split(uri_path, "."), -1), "?"), 0), "[^a-z0-9]", ""))
| where match(file_ext, "^(exe|dll|ps1|vbs|hta|msi|bat)$")
| stats count as recent_hits, values(uri_path) as paths, dc(src_ip) as affected_hosts,
earliest(_time) as first_seen by dest_hostname, file_ext
| eval is_recent=1
]
| stats values(is_historical) as seen_historically, values(recent_hits) as recent_hits,
values(paths) as paths, values(affected_hosts) as affected_hosts,
values(first_seen) as first_seen
by dest_hostname, file_ext
| where isnull(seen_historically) AND isnotnull(recent_hits)
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S")
| sort -affected_hosts
| table first_seen, dest_hostname, file_ext, recent_hits, affected_hosts, paths Atomic Red Team Tests
Simulates an adversary staging a payload on a paste site and retrieving it via certutil, a common LOLBin used for staging delivery. Uses a benign Base64-encoded text file to avoid triggering malware alerts while validating detection telemetry.
Command
# Step 1: Create a benign test payload and encode it
$testPayload = "This is a simulated staged payload for detection testing - $(Get-Date)"
$encoded = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($testPayload))
Write-Output "Encoded payload: $encoded"
# Step 2: Write encoded content to a temp file to simulate a paste URL response
$stageFile = "$env:TEMP\staged_payload.txt"
$encoded | Out-File -FilePath $stageFile
# Step 3: Use certutil to decode (simulates certutil -decode used against a staging URL)
certutil -decode $stageFile "$env:TEMP\decoded_payload.txt"
Write-Output "Decoded file written to $env:TEMP\decoded_payload.txt" Cleanup
Remove-Item -Path "$env:TEMP\staged_payload.txt" -Force -ErrorAction SilentlyContinue
Remove-Item -Path "$env:TEMP\decoded_payload.txt" -Force -ErrorAction SilentlyContinue Expected Telemetry
Sysmon Event ID 1 (Process Create) for certutil.exe with -decode arguments. DeviceProcessEvents entry for certutil.exe. DeviceFileEvents showing file creation in %TEMP%. PowerShell ScriptBlock log (Event ID 4104) showing the staging simulation commands.
Expected Detection
Alert should fire on LOLBin (certutil.exe) creating a file in TEMP directory. The KQL query will catch certutil in the initiating process field correlated with file creation.
Simulates an adversary who has staged a tool on GitHub and delivers it to a victim via PowerShell Invoke-WebRequest. This is a documented TTP used by multiple threat actors including those staging tools at raw.githubusercontent.com.
Command
# Download a well-known benign tool from GitHub raw (use an open-source security tool repo)
# This simulates T1608.002 Upload Tool followed by T1105 Ingress Tool Transfer
$stagingUrl = "https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/LICENSE.txt"
$outputPath = "$env:TEMP\staged_tool_test.txt"
# Method 1: PowerShell (most common adversary method)
Invoke-WebRequest -Uri $stagingUrl -OutFile $outputPath
Write-Output "Downloaded to: $outputPath"
# Method 2: Also test with curl (if available)
if (Get-Command curl.exe -ErrorAction SilentlyContinue) {
curl.exe -o "$env:TEMP\staged_curl_test.txt" $stagingUrl
Write-Output "curl download complete"
} Cleanup
Remove-Item -Path "$env:TEMP\staged_tool_test.txt" -Force -ErrorAction SilentlyContinue
Remove-Item -Path "$env:TEMP\staged_curl_test.txt" -Force -ErrorAction SilentlyContinue Expected Telemetry
Sysmon Event ID 3 (Network Connection) for powershell.exe connecting to raw.githubusercontent.com on port 443. Sysmon Event ID 11 (File Create) for the downloaded file. DeviceNetworkEvents in Defender for Endpoint showing powershell.exe initiating connection. DeviceFileEvents showing file write in TEMP.
Expected Detection
Alert fires on the GitHub raw domain appearing in DeviceNetworkEvents with powershell.exe as initiating process. SPL query will score this as github-raw + powershell = 45+15=60 risk score.
Simulates an adversary staging malicious web resources on infrastructure they control. Sets up a local Python HTTP server to host a benign executable-extension file, then uses certutil to retrieve it — mimicking the victim-side detection signal without touching real staging infrastructure.
Command
#!/bin/bash
# Create a benign test file with executable extension
echo '#!/bin/bash\necho "Simulated staged payload - detection test"' > /tmp/staged_payload.sh
chmod +x /tmp/staged_payload.sh
# Also create a fake .exe (text content, .exe extension) to trigger extension-based detection
echo 'MZ - simulated PE header for detection testing only' > /tmp/test_payload.exe
# Start a local staging server on port 8888 in background
cd /tmp && python3 -m http.server 8888 &
STAGING_PID=$!
echo "Staging server PID: $STAGING_PID"
sleep 2
# Simulate victim downloading from staging server (use curl as the LOLBin)
curl -o /tmp/downloaded_payload.exe http://127.0.0.1:8888/test_payload.exe
echo "Download complete"
# Cleanup background server
kill $STAGING_PID 2>/dev/null Cleanup
rm -f /tmp/staged_payload.sh /tmp/test_payload.exe /tmp/downloaded_payload.exe
pkill -f 'python3 -m http.server 8888' 2>/dev/null || true Expected Telemetry
Linux audit logs showing curl process spawning with HTTP connection to 127.0.0.1:8888. Syslog entries for the Python HTTP server serving the request. File creation event for downloaded_payload.exe in /tmp. If auditd is enabled: syscall records for execve (python3, curl) and open/write for file creation.
Expected Detection
SPL query on linux_secure or auditd sourcetype will detect curl downloading a .exe file. The local IP won't match staging domain patterns but the file extension and LOLBin combination will score positive.