# T1137 - Office Application Startup

## SOC Recommendation
Investigate Office Application Startup activity in the context of Persistence: 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 |
|---|---|---|
| File Analysis | Detect | Monitor for File 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. |
| Content Filtering | Isolate | Apply Content Filtering to contain the blast radius once this technique is observed. |

## Investigation Steps
1. Review Defender for Endpoint / Defender XDR alerts and timeline for the affected host or identity.
2. Check Sentinel analytics rules and incidents correlated with this technique.
3. Review Entra ID sign-in and audit logs if the technique involves an identity or cloud resource.

## 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 |
|---|---|---|---|
| Contain the affected host or account | Medium | No | Yes |
| Collect and preserve evidence | Low | Yes | No |

## KQL
```kql
let iocs = externaldata(DateAdded:string,IoC:string,Type:string) [@"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/ActiniumIOC.csv"] with (format="csv", ignoreFirstRecord=True);
let domains = (iocs | where Type =~ "domainname"| project IoC);
let sha256Hashes = (iocs | where Type =~ "sha256" | project IoC);
(union isfuzzy=true
(DeviceProcessEvents
| where InitiatingProcessSHA256 in (sha256Hashes) or SHA256 in (sha256Hashes) or  (ProcessCommandLine has ('schtasks.exe /CREATE /sc minute /mo 12 /tn')  and ProcessCommandLine has ('/tr "wscript.exe') and ProcessCommandLine has ('"%PUBLIC%\\Pictures\\') and ProcessCommandLine has ('//e:VBScript //b" /F')) or (ProcessCommandLine has ('wscript.exe C:\\Users\\') and ProcessCommandLine has ('.wav') and  ProcessCommandLine has ('//e:VBScript //b') 
or (ProcessCommandLine has_all ("schtasks.exe", "create", "wscript", "e:vbscript", ".wav")))
| project TimeGenerated, ActionType, DeviceId, DeviceName, ProcessCommandLine, InitiatingProcessAccountName, InitiatingProcessCommandLine, FolderPath, InitiatingProcessFolderPath, ProcessId, InitiatingProcessId, InitiatingProcessParentFileName, InitiatingProcessFileName,  InitiatingProcessSHA256, Type, AccountName, SHA256, FileName
| extend Account = AccountName, Computer = DeviceName,  FileHash = case(InitiatingProcessSHA256 in (sha256Hashes), "InitiatingProcessSHA256", SHA256 in (sha256Hashes), "SHA256", "No Match")
| extend timestamp = TimeGenerated, HostCustomEntity = Computer , AccountCustomEntity = Account, ProcessCustomEntity = FileName, FileHashCustomEntity = case(FileHash == "InitiatingProcessSHA256", InitiatingProcessSHA256, FileHash == "SHA256", SHA256, "No Match"), AlgorithmCustomEntity = "SHA256"
),
( SecurityEvent
| where EventID == 4688
| where (CommandLine has ('schtasks.exe /CREATE /sc minute /mo 12 /tn')  and CommandLine has ('/tr "wscript.exe') and CommandLine has ('"%PUBLIC%\\Pictures\\') and CommandLine has ('//e:VBScript //b" /F')) or (CommandLine has ('wscript.exe C:\\Users\\') and CommandLine has ('.wav') and  CommandLine has ('//e:VBScript //b'))
| project TimeGenerated, Computer, NewProcessName, ParentProcessName, Account, NewProcessId, Type, EventID
| extend timestamp = TimeGenerated, HostCustomEntity = Computer , AccountCustomEntity = Account, ProcessCustomEntity = NewProcessName
),
( CommonSecurityLog
| where FileHash in (sha256Hashes)
| project TimeGenerated, Message, SourceUserID, FileHash, Type
| extend timestamp = TimeGenerated, FileHashCustomEntity = FileHash, Account = SourceUserID, AlgorithmCustomEntity = "SHA256"
),
( imFileEvent
| where Hash in~ (sha256Hashes) or  (ActingProcessCommandLine  has ('schtasks.exe /CREATE /sc minute /mo 12 /tn')  and ActingProcessCommandLine  has ('/tr "wscript.exe') and ActingProcessCommandLine  has ('"%PUBLIC%\\Pictures\\') and ActingProcessCommandLine  has ('//e:VBScript //b" /F')) or (ActingProcessCommandLine  has ('wscript.exe C:\\Users\\') and ActingProcessCommandLine  has ('.wav') and  ActingProcessCommandLine  has ('//e:VBScript //b') 
 or (ActingProcessCommandLine has_all ("schtasks.exe", "create", "wscript", "e:vbscript", ".wav")))
| extend Account = ActorUsername, Computer = DvcHostname, IPAddress = SrcIpAddr, CommandLine = ActingProcessCommandLine, FileHash = Hash
| project Type, TimeGenerated, Computer, Account, IPAddress, CommandLine, FileHash
| extend timestamp = TimeGenerated, AccountCustomEntity = Account, HostCustomEntity = Computer, FileHashCustomEntity = FileHash, AlgorithmCustomEntity = "SHA256"
),
(Event
| where Source == "Microsoft-Windows-Sysmon"
| where EventID == 1
| extend EvData = parse_xml(EventData)
| extend EventDetail = EvData.DataItem.EventData.Data
| extend Image = EventDetail.[4].["#text"],  CommandLine = EventDetail.[10].["#text"], Hashes = tostring(EventDetail.[17].["#text"])
| extend Hashes = extract_all(@"(?P<key>\w+)=(?P<value>[a-zA-Z0-9]+)", dynamic(["key","value"]), Hashes)
| extend Hashes = column_ifexists("Hashes", ""), CommandLine = column_ifexists("CommandLine", "")
| extend Hashes = todynamic(Hashes) | mv-expand Hashes
| where (Hashes[0] =~ "SHA256" and Hashes[1] has_any (sha256Hashes)) or (CommandLine has ('schtasks.exe /CREATE /sc minute /mo 12 /tn')  and CommandLine has ('/tr "wscript.exe') and CommandLine has ('"%PUBLIC%\\Pictures\\') and CommandLine has ('//e:VBScript //b" /F')) or (CommandLine has ('wscript.exe C:\\Users\\') and CommandLine has ('.wav') and  CommandLine has ('//e:VBScript //b') or (CommandLine has_all ("schtasks.exe", "create", "wscript", "e:vbscript", ".wav")))
| project TimeGenerated, EventDetail, UserName, Computer, Type, Source, Hashes, CommandLine, Image
| extend Type = strcat(Type, ": ", Source)
| extend timestamp = TimeGenerated, HostCustomEntity = Computer , AccountCustomEntity = UserName, ProcessCustomEntity = tostring(split(Image, '\\', -1)[-1]), FileHashCustomEntity = tostring(Hashes[1]), AlgorithmCustomEntity = "SHA256"
),
(DnsEvents
| where Name in~ (domains)  
| project TimeGenerated, Computer, IPAddresses, Name, ClientIP, Type
| extend DestinationIPAddress = IPAddresses, DNSName = Name, Computer 
| extend timestamp = TimeGenerated, IPCustomEntity = DestinationIPAddress
),
(VMConnection
| where RemoteDnsCanonicalNames has_any (domains)
| parse RemoteDnsCanonicalNames with * '["' DNSName '"]' *
| project TimeGenerated, Computer, Direction, ProcessName, SourceIp, DestinationIp, DestinationPort, RemoteDnsQuestions, DNSName,BytesSent, BytesReceived, RemoteCountry, Type
| extend timestamp = TimeGenerated, IPCustomEntity = DestinationIp, File = ProcessName
),
(AzureDiagnostics 
| where ResourceType == "AZUREFIREWALLS"
| where Category == "AzureFirewallApplicationRule"
| project TimeGenerated,Resource, msg_s, Type
| parse msg_s with Protocol 'request from ' SourceHost ':' SourcePort 'to ' DestinationHost ':' DestinationPort '. Action:' Action
| where isnotempty(DestinationHost)
| where DestinationHost has_any (domains)  
| extend timestamp = TimeGenerated, DNSName = DestinationHost, IPCustomEntity = SourceHost
),
(AzureDiagnostics
| where ResourceType == "AZUREFIREWALLS"
| where Category == "AzureFirewallDnsProxy"
| project TimeGenerated,Resource, msg_s, Type
| parse msg_s with "DNS Request: " ClientIP ":" ClientPort " - " QueryID " " Request_Type " " Request_Class " " Request_Name ". " Request_Protocol " " Request_Size " " EDNSO_DO " " EDNS0_Buffersize " " Responce_Code " " Responce_Flags " " Responce_Size " " Response_Duration
| where  Request_Name  has_any (domains)
| extend timestamp = TimeGenerated, DNSName = Request_Name, IPCustomEntity = ClientIP
),
(AZFWApplicationRule
| where isnotempty(Fqdn)
| where Fqdn has_any (domains)  
| extend timestamp = TimeGenerated, DNSName = Fqdn, IPCustomEntity = SourceIp
),
(AZFWDnsQuery
| where isnotempty(QueryName)
| where QueryName has_any (domains)
| extend timestamp = TimeGenerated, DNSName = QueryName, IPCustomEntity = SourceIp
),
(DeviceNetworkEvents 
| where isnotempty(RemoteUrl) 
| where RemoteUrl  in~ (domains)  
| project Type, TimeGenerated, DeviceName, RemoteIP, RemoteUrl, InitiatingProcessAccountName
| extend timestamp = TimeGenerated, HostCustomEntity = DeviceName , AccountCustomEntity = InitiatingProcessAccountName, DNSName = RemoteUrl, IPCustomEntity = RemoteIP
)
)
```
```kql
let iocs = externaldata(DateAdded:string,IoC:string,Type:string) [@"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/ActiniumIOC.csv"] with (format="csv", ignoreFirstRecord=True);
let AVHits = (iocs | where Type =~ "AVDetection"| project IoC);
SecurityAlert
| where ProviderName == 'MDATP'
| extend ThreatName_ = tostring(parse_json(ExtendedProperties).ThreatName)
| where ThreatName_ has_any (AVHits)
| extend Directory = tostring(parse_json(Entities)[0].Directory), SHA256 = tostring(parse_json(tostring(parse_json(Entities)[0].FileHashes))[2].Value), FileName = tostring(parse_json(Entities)[0].Name), Hostname = tostring(parse_json(Entities)[6].FQDN)| extend AccountName = tostring(parse_json(tostring(parse_json(Entities)[6].LoggedOnUsers))[0].AccountName)
| project TimeGenerated, AlertName, ThreatName_, ProviderName, AlertSeverity, Description, RemediationSteps, ExtendedProperties, Entities, FileName,SHA256, Directory, Hostname, AccountName
| extend FileHash = SHA256, FileHashType = "SHA256"
| extend Name = tostring(split(AccountName, "@")[0]), AccountUPNSuffix = tostring(split(AccountName, "@")[1])
| extend Host = tostring(split(Hostname, ".")[0]), DomainIndex = toint(indexof(Hostname, '.'))
| extend HostNameDomain = iff(DomainIndex != -1, substring(Hostname, DomainIndex + 1), Hostname)
```

## Escalation Criteria
- Office Application Startup 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.
