# T1204 - User Execution

## SOC Recommendation
Investigate User Execution activity in the context of Execution: confirm scope, affected host/identity, and whether it matches expected administrative behaviour before deciding this is benign.

## D3FEND Mappings
| D3FEND Technique | Relationship | Practical SOC Action |
|---|---|---|
| Relay Pattern Analysis | Detect | Monitor for Relay Pattern Analysis indicators relevant to this technique. |
| File Encryption | Harden | Apply File Encryption to reduce this technique's viability before an incident occurs. |
| File Eviction | Evict | Use File Eviction to remove the adversary's foothold once this technique is confirmed. |
| Outbound Traffic Filtering | Isolate | Apply Outbound Traffic Filtering to contain the blast radius once this technique is observed. |

## Investigation Steps
1. A binary in %TEMP% or %APPDATA%? → Almost certainly malicious
2. An encoded PowerShell command? → Decode immediately (see GEN-EX-001)
3. A legitimate binary with suspicious arguments?

## Evidence to Collect
- Host or resource affected
- Account or identity involved
- Timestamp of the activity
- Related process, file, or network artifact
- Any preceding or follow-on alerts

## Response Actions
| Action | Risk | Automation Safe | Approval Required |
|---|---|---|---|
| Delete the malicious scheduled task via MDE Live Response or | Low | No | Yes |
| Quarantine any binary the task would have executed | Low | No | Yes |
| Trace back to initial delivery — correlate with other alerts | Low | No | Yes |
| Check for additional persistence (registry run keys, service | Low | Yes | No |

## KQL
```kql
let ISOExecution = (
    DeviceProcessEvents
    | where TimeGenerated >= ago(5m)
    | where InitiatingProcessFolderPath has_any (":\\", "volume{")
    | where FolderPath has_any ("AppData", "Temp", "Downloads", "Desktop")
    | where InitiatingProcessFileName in~ (
        "explorer.exe", "cmd.exe", "powershell.exe", "wscript.exe",
        "cscript.exe", "mshta.exe", "regsvr32.exe", "rundll32.exe"
    )
    | project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine,
        InitiatingProcessFolderPath, SHA256
    | extend DetectionType = "ISO_Execution"
);
let LNKExecution = (
    DeviceProcessEvents
    | where TimeGenerated >= ago(5m)
    | where InitiatingProcessFileName =~ "explorer.exe"
    | where FileName in~ (
        "powershell.exe", "cmd.exe", "wscript.exe", "cscript.exe",
        "mshta.exe", "regsvr32.exe", "rundll32.exe", "certutil.exe"
    )
    | where ProcessCommandLine has_any (
        "-EncodedCommand", "-enc ", "IEX", "DownloadString",
        "WebClient", "FromBase64String", "hidden"
    )
    | project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine,
        InitiatingProcessFolderPath = "", SHA256
    | extend DetectionType = "LNK_LOLBin"
);
let OneNoteExec = (
    DeviceProcessEvents
    | where TimeGenerated >= ago(5m)
    | where InitiatingProcessFileName =~ "ONENOTE.EXE"
    | where FileName in~ ("cmd.exe", "powershell.exe", "wscript.exe", "cscript.exe", "mshta.exe")
    | project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine,
        InitiatingProcessFolderPath = "", SHA256
    | extend DetectionType = "OneNote_Macro"
);
ISOExecution
| union LNKExecution
| union OneNoteExec
| extend timestamp = TimeGenerated,
         HostCustomEntity = DeviceName,
         AccountCustomEntity = AccountName
| order by TimeGenerated desc
```
```kql
let TorNodes = (
externaldata (TorIP:string)
[h@'https://firewalliplists.gypthecat.com/lists/kusto/kusto-tor-exit.csv.zip']
with (ignoreFirstRecord=true));
AWSCloudTrail
| where SourceIpAddress in (TorNodes) and isempty(ErrorCode) and isempty(ErrorMessage)
| extend UserIdentityArn = iif(isempty(UserIdentityArn), tostring(parse_json(Resources)[0].ARN), UserIdentityArn)
| extend UserName = tostring(split(UserIdentityArn, '/')[-1])
| extend AccountName = case( UserIdentityPrincipalid == "Anonymous", "Anonymous", isempty(UserIdentityUserName), UserName, UserIdentityUserName)
| extend AccountName = iif(AccountName contains "@", tostring(split(AccountName, '@', 0)[0]), AccountName),
    AccountUPNSuffix = iif(AccountName contains "@", tostring(split(AccountName, '@', 1)[0]), "")
| project TimeGenerated, SourceIpAddress, AccountName, AccountUPNSuffix, UserIdentityArn, UserIdentityUserName, UserIdentityPrincipalid, EventName, EventSource, AWSRegion, RecipientAccountId
```
```kql
let TimeWindow   = 90d;    // How far back to look 
let HitThreshold = 10;     // Minimum hits to alert per SourceIp + Category
let MinSeverity  = 1;      // Set Minimum Severity
let EnableCategoryFilter    = true;   // Filter 1: use CategoriesOfInterest
let EnableDescriptionFilter = false;  // Filter 2: use DescriptionsOfInterest
let EnableActionFilter      = false;  // Filter 3: use MatchActions
let CategoriesOfInterest    = dynamic([
    "Targeted Malicious Activity was Detected",
    "Exploit Kit Activity Detected",
    "Domain Observed Used for C2 Detected",
    "Successful Credential Theft Detected",
    "Malware Command and Control Activity Detected",
    "Executable code was detected",
    "A Network Trojan was detected"
]);
let DescriptionsOfInterest  = dynamic([
    "targeted-activity",
    "exploit-kit",
    "domain-c2",
    "credential-theft",
    "command-and-control",
    "shellcode-detect",
    "trojan-activity"
]);
let MatchActions = dynamic(["Deny", "alert"]);
AZFWIdpsSignature
| where TimeGenerated >= ago(TimeWindow)
| where Severity >= MinSeverity
// Filter 1: Category filter (optional)
| where (EnableCategoryFilter == false) or (Category has_any (CategoriesOfInterest))
// Filter 2: Description filter (optional)
| where (EnableDescriptionFilter == false) or (Description has_any (DescriptionsOfInterest))
// Filter 3: Action filter (optional)
| where (EnableActionFilter == false) or (Action in~ (MatchActions))
| summarize
    StartTime   = min(TimeGenerated),
    EndTime     = max(TimeGenerated),
    TotalHits   = count(),
    MaxSeverity = max(Severity),
    Actions     = make_set(Action, 5),
    Signatures  = make_set(SignatureId, 20),
    Description = make_set(substring(tostring(Description), 0, 120), 3)
    by SourceIp, ThreatCategory = Category
| where TotalHits >= HitThreshold
| project
    StartTime,
    EndTime,
    SourceIp,
    ThreatCategory,
    TotalHits,
    MaxSeverity,
    Actions,
    Signatures,
    Description
| order by MaxSeverity desc, TotalHits desc
```

## Escalation Criteria
- User Execution activity observed on a privileged account or critical system.
- Activity follows or precedes other suspicious behaviour in the same investigation.
- Automated triage cannot confidently rule out malicious intent.

## False Positive Considerations
- Legitimate administrative or maintenance activity matching this pattern.
- Approved security testing or red team exercise.
- Known benign software producing similar telemetry.

Generated by SOC Response Atlas by Basyrix.
