Query Details

Behaviour Apt28commands

Query

# APT28 Commands

## Query Information

#### Description
This KQL query can be used to hunt for APT 28 commands in your environment. The *threshold* can be used to adjust the amount of unique executed APT28 commands to be found within the defined *BinSize*, the *BinSize* is the timeframe in which the *threshold* needs to be reached. All the calculations are done for each device. The more APT28 commands are found on a device, the more likely it is that the device has been compromised. 

#### Risk
APT28 has gotten access to one of your devices and executes malicious payloads. 

#### References
- https://cert.gov.ua/article/6276894

## Defender For Endpoint
```KQL
let APT28Commands = dynamic(['Get-Content', '-w hid -nop', '-windowstyle hidden -encodedCommand', 'start-process ssh.exe', 'Get-Content -Encoding', 'Compress-Archive', 'Get-WinEvent -FilterHashtable', 'net time', 'Get-ADDomainController', 'Get-DnsClientServerAddress', 'Get-NetAdapter', 'Get-NetAdapterBinding', 'Get-NetIPConfiguration', 'Resolve-DNSName', 'ipconfig /flushdns', 'net start dnscache', 'net stop dnscache']);
let Threshold = 3;
let BinSize = 1d;
DeviceProcessEvents
| where ProcessCommandLine has_any (APT28Commands)
| extend CommandParameter = case(ProcessCommandLine contains "Get-Content", "Get-Content",
                                ProcessCommandLine contains "-w hid -nop", "-w hid -nop",
                                ProcessCommandLine contains "-windowstyle hidden -encodedCommand", "-windowstyle hidden -encodedCommand",
                                ProcessCommandLine contains "start-process ssh.exe", "start-process ssh.exe",
                                ProcessCommandLine contains "Get-Content -Encoding", "Get-Content -Encoding",
                                ProcessCommandLine contains "Compress-Archive", "Compress-Archive",
                                ProcessCommandLine contains "Get-WinEvent -FilterHashtable", "Get-WinEvent -FilterHashtable",
                                ProcessCommandLine contains "net time", "net time",
                                ProcessCommandLine contains "Get-ADDomainController", "Get-ADDomainController",
                                ProcessCommandLine contains "Get-DnsClientServerAddress", "Get-DnsClientServerAddress",
                                ProcessCommandLine contains "Get-NetAdapter", "Get-NetAdapter",
                                ProcessCommandLine contains "Get-NetAdapterBinding", "Get-NetAdapterBinding",
                                ProcessCommandLine contains "Get-NetIPConfiguration", "Get-NetIPConfiguration",
                                ProcessCommandLine contains "Resolve-DNSName", "Resolve-DNSName",
                                ProcessCommandLine contains "ipconfig /flushdns", "ipconfig /flushdns",
                                ProcessCommandLine contains "net start dnscache", "net start dnscache",
                                ProcessCommandLine contains "net stop dnscache", "net stop dnscache",
                                "Other")
| summarize UniqueATP28Commands = dcount(CommandParameter), APT28CommandParameters = make_set(CommandParameter), UniqueCommands = dcount(ProcessCommandLine), Commandlines = make_set(ProcessCommandLine) by DeviceId, DeviceName, bin(Timestamp, BinSize)
| where UniqueATP28Commands >= Threshold
```
## Sentinel
```KQL
let APT28Commands = dynamic(['Get-Content', '-w hid -nop', '-windowstyle hidden -encodedCommand', 'start-process ssh.exe', 'Get-Content -Encoding', 'Compress-Archive', 'Get-WinEvent -FilterHashtable', 'net time', 'Get-ADDomainController', 'Get-DnsClientServerAddress', 'Get-NetAdapter', 'Get-NetAdapterBinding', 'Get-NetIPConfiguration', 'Resolve-DNSName', 'ipconfig /flushdns', 'net start dnscache', 'net stop dnscache']);
let Threshold = 3;
let BinSize = 1d;
DeviceProcessEvents
| where ProcessCommandLine has_any (APT28Commands)
| extend CommandParameter = case(ProcessCommandLine contains "Get-Content", "Get-Content",
                                ProcessCommandLine contains "-w hid -nop", "-w hid -nop",
                                ProcessCommandLine contains "-windowstyle hidden -encodedCommand", "-windowstyle hidden -encodedCommand",
                                ProcessCommandLine contains "start-process ssh.exe", "start-process ssh.exe",
                                ProcessCommandLine contains "Get-Content -Encoding", "Get-Content -Encoding",
                                ProcessCommandLine contains "Compress-Archive", "Compress-Archive",
                                ProcessCommandLine contains "Get-WinEvent -FilterHashtable", "Get-WinEvent -FilterHashtable",
                                ProcessCommandLine contains "net time", "net time",
                                ProcessCommandLine contains "Get-ADDomainController", "Get-ADDomainController",
                                ProcessCommandLine contains "Get-DnsClientServerAddress", "Get-DnsClientServerAddress",
                                ProcessCommandLine contains "Get-NetAdapter", "Get-NetAdapter",
                                ProcessCommandLine contains "Get-NetAdapterBinding", "Get-NetAdapterBinding",
                                ProcessCommandLine contains "Get-NetIPConfiguration", "Get-NetIPConfiguration",
                                ProcessCommandLine contains "Resolve-DNSName", "Resolve-DNSName",
                                ProcessCommandLine contains "ipconfig /flushdns", "ipconfig /flushdns",
                                ProcessCommandLine contains "net start dnscache", "net start dnscache",
                                ProcessCommandLine contains "net stop dnscache", "net stop dnscache",
                                "Other")
| summarize UniqueATP28Commands = dcount(CommandParameter), APT28CommandParameters = make_set(CommandParameter), UniqueCommands = dcount(ProcessCommandLine), Commandlines = make_set(ProcessCommandLine) by DeviceId, DeviceName, bin(TimeGenerated, BinSize)
| where UniqueATP28Commands >= Threshold
```

Explanation

This query is used to search for APT28 commands in your system. The query calculates the number of unique APT28 commands executed on each device within a specified timeframe. The more APT28 commands found on a device, the higher the likelihood that the device has been compromised. The query uses a list of predefined APT28 commands and checks if any of these commands are present in the process command lines. If the number of unique APT28 commands exceeds a specified threshold, the query returns the device information. This query can be used in both Defender for Endpoint and Sentinel.

Details

Bert-Jan Pals profile picture

Bert-Jan Pals

Released: January 12, 2024

Tables

DeviceProcessEvents

Keywords

Keywords:APT28Commands,Threshold,BinSize,DeviceProcessEvents,ProcessCommandLine,CommandParameter,UniqueATP28Commands,APT28CommandParameters,UniqueCommands,Commandlines,DeviceId,DeviceName,Timestamp,TimeGenerated

Operators

has_anycontainscasesummarizedcountmake_setbywhereextendbin

Actions