T1587

Develop Capabilities

Resource Development Last updated:

This detection identifies indicators that adversaries have deployed custom-developed capabilities within the target environment. Because T1587 (Develop Capabilities) occurs outside the victim network during the adversary lifecycle, direct detection is impossible; instead, this rule focuses on second-order indicators: unsigned or self-signed executables executing from non-standard paths, low-prevalence binaries making network connections, and novel tooling patterns associated with bespoke malware frameworks. Groups such as Kimsuky, Moonstone Sleet, and Contagious Interview are known to develop custom tools—including malicious NPM packages, spearphishing toolkits, and custom implants—that exhibit these characteristics upon deployment. The detection correlates signature anomalies, environmental prevalence, and behavioral signals to surface likely custom-developed tools used in targeted intrusions.

What is T1587 Develop Capabilities?

Develop Capabilities (T1587) 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 Develop Capabilities, covering the data sources and telemetry it touches: Microsoft Defender for Endpoint. The queries below are rated high severity at low confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.

MITRE ATT&CK

Tactic
Resource Development
Technique
T1587 Develop Capabilities
Canonical reference
https://attack.mitre.org/techniques/T1587/
Microsoft Sentinel / Defender
kusto
let ExcludedPaths = dynamic([
    @"C:\Windows\System32",
    @"C:\Windows\SysWOW64",
    @"C:\Program Files",
    @"C:\Program Files (x86)",
    @"C:\Windows\WinSxS"
]);
let SuspiciousSignatureStates = dynamic(["Unsigned", "SignedByUntrustedCertificate", "SignedByInvalidCertificate"]);
let LookbackWindow = ago(1d);
// Step 1: Find low-prevalence unsigned executables executing from non-standard paths
let UnsignedExecs = DeviceProcessEvents
| where TimeGenerated > LookbackWindow
| where ProcessSignatureStatus in (SuspiciousSignatureStates)
| where not(FolderPath has_any (ExcludedPaths))
| extend SuspiciousLocation = case(
    FolderPath startswith @"C:\Users\" and FolderPath has "\AppData\Local\Temp", true,
    FolderPath startswith @"C:\Users\" and FolderPath has "\Downloads", true,
    FolderPath startswith @"C:\ProgramData\", true,
    FolderPath startswith @"C:\Temp\", true,
    FolderPath startswith @"C:\Windows\Temp\", true,
    false
)
| extend RiskScore = case(
    ProcessSignatureStatus == "Unsigned" and SuspiciousLocation == true, 40,
    ProcessSignatureStatus == "SignedByUntrustedCertificate" and SuspiciousLocation == true, 35,
    ProcessSignatureStatus == "SignedByInvalidCertificate", 30,
    ProcessSignatureStatus == "Unsigned" and SuspiciousLocation == false, 20,
    10
)
| where RiskScore >= 30
| project TimeGenerated, DeviceName, AccountName, FileName, FolderPath, ProcessCommandLine, SHA256, ProcessSignatureStatus, InitiatingProcessFileName, InitiatingProcessCommandLine, RiskScore;
// Step 2: Correlate with network events to identify beaconing custom implants
let UnsignedWithNetwork = UnsignedExecs
| join kind=leftouter (
    DeviceNetworkEvents
    | where TimeGenerated > LookbackWindow
    | where RemoteIPType != "Private"
    | summarize NetworkConnections=count(), UniqueRemoteIPs=dcount(RemoteIP), RemoteIPList=make_set(RemoteIP, 5), RemotePorts=make_set(RemotePort, 5) by InitiatingProcessSHA256
) on $left.SHA256 == $right.InitiatingProcessSHA256
| extend NetworkRiskBonus = case(
    NetworkConnections > 10, 20,
    NetworkConnections > 0, 10,
    0
)
| extend TotalRisk = RiskScore + NetworkRiskBonus;
// Step 3: Deduplicate by SHA256 to surface unique custom tools
UnsignedWithNetwork
| summarize
    AlertCount = count(),
    AffectedDevices = dcount(DeviceName),
    DeviceList = make_set(DeviceName, 5),
    FirstSeen = min(TimeGenerated),
    LastSeen = max(TimeGenerated),
    SampleCommandLine = take_any(ProcessCommandLine),
    SampleInitiatingProcess = take_any(InitiatingProcessFileName),
    MaxRisk = max(TotalRisk),
    HasNetworkActivity = max(NetworkConnections) > 0
    by FileName, SHA256, FolderPath, ProcessSignatureStatus
| where AffectedDevices < 5  // Low environmental prevalence — likely custom tooling
| order by MaxRisk desc, AffectedDevices asc

Detects execution of unsigned or untrusted-certificate-signed binaries from non-standard filesystem paths with low environmental prevalence, optionally correlated with external network connections. This pattern is characteristic of custom-developed malware or bespoke implants deployed by threat actors following their own capability development phase. The query scores each observed binary by signature state and execution path suspiciousness, then surfaces only low-prevalence samples (seen on fewer than 5 devices) to minimize commodity software noise.

high severity low confidence

Data Sources

Microsoft Defender for Endpoint

Required Tables

DeviceProcessEvents DeviceNetworkEvents

False Positives

  • Internal development teams executing locally compiled utilities or test binaries that have not yet been signed
  • Open-source or portable applications distributed without code signing (e.g., command-line utilities, Python scripts compiled with PyInstaller)
  • Legitimate penetration testing tools (Cobalt Strike, Metasploit, custom scripts) used by authorized red team engagements
  • Software distributed via internal package managers or deployment tools that bypasses standard code signing workflows
  • Vendor-supplied diagnostic utilities that are unsigned by design

Sigma rule & cross-platform mapping

The detection logic for Develop Capabilities (T1587) 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: process_creation
  product: windows

Browse the community-maintained Sigma rules for this technique:


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.

  1. Test 1Execute Self-Signed Binary from User-Writable Path (Windows)

    Expected signal: DeviceProcessEvents: FileName=custom_capability_test.exe, ProcessSignatureStatus=SignedByUntrustedCertificate, FolderPath contains \AppData\Local\Temp. DeviceImageLoadEvents showing DLLs loaded with self-signed parent process.

  2. Test 2Deploy Malicious NPM Post-Install Script (Cross-Platform)

    Expected signal: Sysmon EventCode=1 (Linux auditd execve): process spawned with ParentImage=/usr/bin/node, Image=/bin/sh or /bin/id. audit.log entries showing execve syscall from node process with working directory in node_modules path.

  3. Test 3Compile and Execute Custom ELF Binary with Network Connection (Linux)

    Expected signal: auditd: EXECVE record for /tmp/atomic_custom_tool with ppid matching shell. SOCKADDR audit record showing connect() call to 192.0.2.1:4444. Sysmon for Linux EventCode=3 (Network Connect) if deployed. /proc/<pid>/exe pointing to /tmp path.

Unlock Pro Content

Get the full detection package for T1587 including response playbook, investigation guide, and atomic red team tests.

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections