APT28 Commands
Behaviour Apt28commands
Query
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 >= ThresholdAbout this query
Explanation
This KQL query is designed to help identify potentially malicious activity associated with APT28 (a known threat group) on devices within your network. Here's a simplified breakdown of what the query does:
-
APT28 Commands List: The query defines a list of specific command-line actions that are associated with APT28's known behavior. These include commands like
Get-Content,start-process ssh.exe,Compress-Archive, and others. -
Threshold and BinSize:
- Threshold: This is set to 3, meaning that if a device executes 3 or more unique APT28 commands within a specified timeframe, it will be flagged.
- BinSize: This is set to 1 day (
1d), which is the timeframe in which the threshold needs to be met.
-
Query Execution:
- The query searches through device process events to find any command lines that match the APT28 commands list.
- It extends the data to identify which specific command parameters were used.
-
Summarization:
- The query summarizes the data by counting the number of unique APT28 commands executed on each device.
- It also collects the specific command parameters and command lines used.
-
Filtering:
- Finally, it filters the results to show only those devices where the number of unique APT28 commands executed meets or exceeds the threshold (3 or more).
In essence, this query helps detect devices that might be compromised by APT28 by looking for patterns of command execution that are characteristic of this threat actor. If a device executes multiple unique commands from the APT28 list within a day, it could indicate a potential security breach.
Details

Bert-Jan Pals
Released: October 20, 2024
Tables
Keywords
Operators