Skip to content

KQL Cafe - February 2023

Recording and Presentation

Hosts

Guests

News

What did you do with KQL this month?

Tampering Events

DeviceEvents
| where TimeGenerated > ago (30d)
| where ActionType == @"TamperingAttempt"
| extend AF = parse_json(AdditionalFields)
| evaluate bag_unpack(AF)
DeviceEvents
| where TimeGenerated > ago (30d)
| where ActionType == @"TamperingAttempt"
| extend AF = parse_json(AdditionalFields)
| evaluate bag_unpack(AF,columnsConflict='keep_source') : (DeviceName:string,TimeGenerated:datetime,ActionType:string,Status:string, TamperingAction:long,Target:string)

Parse Commandline

DeviceEvents
| where ActionType contains "PowerShell"
| project TimeGenerated, DeviceName, InitiatingProcessCommandLine
| extend Cmd1 = parse_command_line(InitiatingProcessCommandLine,"windows")
| mv-expand Cmd1
| summarize count() by tostring(Cmd1)
DeviceNetworkEvents
| extend Cmd1 = parse_command_line(InitiatingProcessCommandLine,"windows")
| where Cmd1 contains "Download"
| mv-expand Cmd1
| project Cmd1, RemoteUrl

Go HUnt - ABC of threat hunting

A

// Was there a new sign-on using the credential?​
let AccountDomainToResearch = '';// leave blank for local accounts​
let AccountNameToResearch = ''; ​
DeviceLogonEvents​
| where iff(isempty(AccountDomainToResearch), AccountDomain == DeviceName, AccountDomain =~ AccountDomainToResearch) and AccountName =~ AccountNameToResearch​
| summarize EarliestTimestamp = min(Timestamp), LatestTimestamp = max(Timestamp), Attempts = count() by ActionType, DeviceId, DeviceName, RemoteIP, Protocol​
| order by EarliestTimestamp desc ​
​
let AccountDomainToResearch = '';​
let AccountNameToResearch = ''; ​
IdentityLogonEvents​
| where ​
    AccountName =~ AccountNameToResearch and ​
    AccountDomain =~ AccountDomainToResearch​
| summarize EarliestTimestamp = min(Timestamp), LatestTimestamp = max(Timestamp), Attempts = count() by ActionType, Application, LogonType,DeviceName, IPAddress, DestinationDeviceName, DestinationIPAddress, DestinationPort​
| project-reorder EarliestTimestamp, LatestTimestamp​
| order by EarliestTimestamp desc​

​​// Were any other credentials potentially compromised?​
AlertInfo​
| where AttackTechniques contains "T1557" // Adversary-in-the-Middle​
    or AttackTechniques contains "T1110" // Brute Force​
    or AttackTechniques contains "T1555" // Credentials from Password Stores​
    or AttackTechniques contains "T1212" // Exploitation for Credential Access​
    or AttackTechniques contains "T1187" // Forced Authentication​
    or AttackTechniques contains "T1606" // Forge Web Credentials​
    or AttackTechniques contains "T1056" // Input Capture​
    or AttackTechniques contains "T1556" // Modify Authentication Process​
    or AttackTechniques contains "T1111" // Multi-Factor Authentication Interception​
    or AttackTechniques contains "T1621" // Multi-Factor Authentication Request generation​
    or AttackTechniques contains "T1040" // Network Sniffing​
    or AttackTechniques contains "T1003" // OS Credential Dumping​
    or AttackTechniques contains "T1528" // Steal Application Access Token​
    or AttackTechniques contains "T1558" // Steal or Forge Kerberos Tickets​
    or AttackTechniques contains "T1539" // Steal Web Session Cookie​
    or AttackTechniques contains "T1552" // Unsecured Credentials​
| join kind=leftouter AlertEvidence on AlertId​
// Did the identity have administrator or root permissions to the device? ​
let AccountNameToResearch = '';​
let AccountDomainToResearch = ''; // Leave blank if local​
DeviceInfo​
| where OSPlatform startswith "Windows" and OnboardingStatus == 'Onboarded'​
| join kind=rightsemi DeviceProcessEvents on DeviceId​
//| where AccountName =~ AccountNameToResearch and iff(isempty(AccountDomainToResearch), AccountDomain =~ DeviceId, AccountDomain =~ AccountDomainToResearch)​
| extend IsElevated = (ProcessTokenElevation != 'None')​
| summarize IsAdmin = max(IsElevated) by AccountDomain, AccountName​
// Does the identity have administrator or root permissions to other devices or to your authentication service​
let AccountNameToResearch = '';​
let AccountDomainToResearch = ''; // Leave blank if local​
DeviceInfo​
| where OSPlatform startswith "Windows" and OnboardingStatus == 'Onboarded'​
| join kind=rightsemi DeviceProcessEvents on DeviceId​
//| where AccountName =~ AccountNameToResearch and iff(isempty(AccountDomainToResearch), AccountDomain =~ DeviceId, AccountDomain =~ AccountDomainToResearch)​
| extend IsElevated = (ProcessTokenElevation != 'None')​
| summarize IsAdmin = max(IsElevated) by DeviceId, DeviceName​
| order by IsAdmin desc

B

// Was the suspicious activity associated with any known malware?​
let DeviceIdToResearch = ''; ​
DeviceEvents​
| where DeviceId =~ DeviceIdToResearch and ​
    ActionType startswith "AntivirusDetection"​
| extend AdditionalFields = parse_json(AdditionalFields)​
| extend ThreatName = tostring(AdditionalFields.ThreatName), ​
    WasExecutingWhileDetected = tobool(AdditionalFields.WasExecutingWhileDetected),​
    WasRemediated = tobool(AdditionalFields.WasRemediated)​
| project-reorder Timestamp, ThreatName, WasExecutingWhileDetected, WasRemediated, FolderPath, SHA256, InitiatingProcessAccountDomain, InitiatingProcessAccountName​
```​

```kql
// Were any suspicious auto-start entries created by the identity?​
let AccountNameToResearch = '';​
let AccountDomainToResearch = ''; // leave blank for local accounts​
let DeviceIdToResearch = ''; // leave blank for all devices​
union DeviceRegistryEvents,​
(​
    DeviceEvents​
    | where ActionType in ('ServiceInstalled','DriverLoad','ScheduledTaskCreated','ScheduledTaskUpdated')​
)​
| where (isempty(DeviceIdToResearch) or DeviceId =~ DeviceIdToResearch) and ​
    InitiatingProcessAccountName =~ AccountNameToResearch and ​
    iff(isempty(AccountDomainToResearch), InitiatingProcessAccountDomain =~ DeviceName, InitiatingProcessAccountDomain =~ AccountDomainToResearch)
// Were any new accounts created?​
let DeviceIdToResearch = ''; ​
DeviceEvents​
| where DeviceId =~ DeviceIdToResearch and ​
    ActionType == 'UserAccountCreated'
```​

```kql
// Is the backdoor associated with any other alerts?​
let BackdoorSha256 = '';​
AlertEvidence​
| where SHA256 =~ BackdoorSha256​
| join kind=rightsemi AlertInfo on AlertId​

// Is the backdoor present on any other devices?​
let BackdoorSha256 = '';​
union (​
    DeviceProcessEvents​
    | where SHA256 =~ BackdoorSha256​
), (​
    DeviceFileEvents​
    | where InitiatingProcessSHA256 =~ BackdoorSha256​
)​
​
// What network connections were made by the backdoor?​
let BackdoorSha256 = '';​
DeviceNetworkEvents​
| where InitiatingProcessSHA256 =~ BackdoorSha256​

C

// Did the communication occur with an intended capability, an unintended capability, or an attacker installed backdoor?​
// Was the communication inbound, outbound, or did it use a proxy or other intermediary?​
let RemoteIpToResearch = '';​
DeviceNetworkEvents​
| where RemoteIP == RemoteIpToResearch​
```​

```kql
// Was authentication performed during the communication?​
let RemoteIpToResearch = '';​
DeviceLogonEvents​
| where RemoteIP == RemoteIpToResearch​
```​

```kql
// What is the earliest and latest timeframe associated with the communication?​
let RemoteIpToResearch = '';​
DeviceNetworkEvents​
| where RemoteIP == RemoteIpToResearch​
| summarize EarliestCommunication = min(Timestamp), LatestCommunication = max(Timestamp) by DeviceId, DeviceName, LocalIP, LocalPort​
| order by EarliestCommunication asc​
​// Are there any other potential backdoors associated with the communication?​
let RemoteIpToResearch = '';​
DeviceNetworkEvents​
| where RemoteIP == RemoteIpToResearch​
| summarize DistinctDevices = dcount(DeviceId), Events = count() by InitiatingProcessFolderPath, InitiatingProcessSHA256​