Deployable detection rules
6 vendor-native detections · ready to paste into your SIEM · cross-linked to ATT&CK
◈
Detections
6 shown of 6IP address of Windows host encoded in web request
'This detection will identify network requests in HTTP proxy data that contains Base64 encoded IP addresses. After identifying candidates the query joins with DeviceNetworkEvents to idnetify any machine within the network using that IP address. Alerts indicate that the IP address of a machine within your network was seen with it's IP address base64 encoded in an outbound web request. This method of egressing the IP was seen used in POLONIUM's RunningRAT tool, however the detection is generic.'
Show query
// Extracts plaintext IPv4 addresses
let ipv4_plaintext_extraction_regex = @"((?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.)){3}(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]){1,3})";
// Identified base64 encoded IPv4 addresses
let ipv4_encoded_identification_regex = @"\=([a-zA-Z0-9\/\+]*(?:(?:MC|Au|wL|MS|Eu|xL|Mi|Iu|yL|My|Mu|zL|NC|Qu|0L|NS|Uu|1L|Ni|Yu|2L|Ny|cu|3L|OC|gu|4L|OS|ku|5L){1}[a-zA-Z0-9\/\+]{2,4}){3}[a-zA-Z0-9\/\+\=]*)";
// Extractes IPv4 addresses as hex values
let ipv4_decoded_hex_extract = @"((?:(?:61|62|63|64|65|66|67|68|69|6a|6b|6c|6d|6e|6f|70|71|72|73|74|75|76|77|78|79|7a|41|42|43|44|45|46|47|48|49|4a|4b|4c|4d|4e|4f|50|51|52|53|54|55|56|57|58|59|5a|2f|2b|3d),){7,15})";
CommonSecurityLog
| where isnotempty(RequestURL)
// Identify requests with encoded IPv4 addresses
| where RequestURL matches regex ipv4_encoded_identification_regex
| project TimeGenerated, RequestURL
// Extract IP candidates in their base64 encoded format, significantly reducing the dataset
| extend extracted_encoded_ip_candidate = extract_all(ipv4_encoded_identification_regex, RequestURL)
// We could have more than one candidate, expand them out
| mv-expand extracted_encoded_ip_candidate to typeof(string)
| summarize Start=min(TimeGenerated), End=max(TimeGenerated), make_set(RequestURL) by extracted_encoded_ip_candidate
// Pad if we need to
| extend extracted_encoded_ip_candidate = iff(strlen(extracted_encoded_ip_candidate) % 2 == 0, extracted_encoded_ip_candidate, strcat(extracted_encoded_ip_candidate, "="))
// Now decode the candidate to a long array, we cannot go straight to string as it cannot handle non-UTF8, we need to strip that first
| extend extracted_encoded_ip_candidate = tostring(base64_decode_toarray(extracted_encoded_ip_candidate))
// Extract the IP candidates from the array
| extend hex_extracted = extract_all(ipv4_decoded_hex_extract, extracted_encoded_ip_candidate)
// Expand, it's still possible that we might have more than 1 IP
| mv-expand hex_extracted
// Now we should have a clean string. We need to put it back into a dynamic array to convert back to a string.
| extend hex_extracted = trim_end(",", tostring(hex_extracted))
| extend hex_extracted = strcat("[",hex_extracted,"]")
| extend hex_extracted = todynamic(hex_extracted)
| extend extracted_encoded_ip_candidate = todynamic(extracted_encoded_ip_candidate)
// Convert the array back into a string
| extend decoded_ip_candidate = make_string(hex_extracted)
| summarize by decoded_ip_candidate, tostring(set_RequestURL), Start, End
// Now the IP candidates will be in plaintext, extract the IPs using a regex
| extend ipmatch = extract_all(ipv4_plaintext_extraction_regex, decoded_ip_candidate)
// If it's not an IP, throw it out
| where isnotnull(ipmatch)
| mv-expand ipmatch to typeof(string)
// Join with DeviceNetworkEvents to find instances where an IP of a machine in our MDE estate sent it's IP in a base64 encoded string
| join (
DeviceNetworkEvents
| summarize make_set(DeviceId), make_set(DeviceName) by RemoteIP
) on $left.ipmatch == $right.RemoteIP
| project Start, End, IPmatch=ipmatch, RequestURL=set_RequestURL, DeviceNames=set_DeviceName, DeviceIds=set_DeviceId, RemoteIP
RunningRAT request parameters
'This detection will alert when RunningRAT URI parameters or paths are detect in an HTTP request.
Id the device blocked this communication presence of this alert means the RunningRAT implant is likely still executing on the source host.'
Show query
let runningRAT_parameters = dynamic(['/ui/chk', 'mactok=', 'UsRnMe=', 'IlocalP=', 'kMnD=']); CommonSecurityLog | where RequestMethod == "GET" | project TimeGenerated, DeviceVendor, DeviceProduct, DeviceAction, DestinationDnsDomain, DestinationIP, RequestURL, SourceIP, SourceHostName, RequestClientApplication | where RequestURL has_any (runningRAT_parameters)
Windows host username encoded in base64 web request
'This detection will identify network requests in HTTP proxy data that contains Base64 encoded usernames from machines in the DeviceEvents table.
This technique was seen usee by POLONIUM in their RunningRAT tool.'
Show query
let accountLookback = 3d;
let requestLookback = 3d;
let extraction_regex = @"(?:\?|&)[a-zA-Z0-9\%]*=([a-zA-Z0-9\/\+\=]*)";
// Collect account names and base64 encode them
DeviceEvents
| where TimeGenerated > ago(accountLookback)
| summarize make_set(DeviceId), make_set(DeviceName) by InitiatingProcessAccountName
| where isnotempty(InitiatingProcessAccountName)
| extend base64_user = base64_encode_tostring(InitiatingProcessAccountName)
| join (
// Collect requests and extract base64 parameters
CommonSecurityLog
| where TimeGenerated > ago(requestLookback)
| where isnotempty(RequestURL)
// Summarize early on the RequestURL
| summarize FirstRequest=min(TimeGenerated), LastRequest=max(TimeGenerated), NumberOfRequests=count() by RequestURL
| extend base64_candidate = extract_all(extraction_regex, RequestURL)
| mv-expand base64_candidate to typeof(string)
) on $left.base64_user == $right.base64_candidate
| project FirstRequest, LastRequest, NumberOfRequests, RequestURL, DeviceIds=set_DeviceId, DeviceNames=set_DeviceName, UserName=InitiatingProcessAccountName
Detect SNICat SNI Exfiltration
The following analytic identifies the use of SNICat tool commands within the TLS SNI field, indicating potential data exfiltration attempts. It leverages Zeek SSL data to detect specific SNICat commands such as LIST, LS, SIZE, LD, CB, EX, ALIVE, EXIT, WHERE, and finito in the server_name field. This activity is significant as SNICat is a known tool for covert data exfiltration using TLS. If confirmed malicious, this could allow attackers to exfiltrate sensitive data undetected, posing a severe threat to data confidentiality and integrity.
Show query
`zeek_ssl`
| rex field=server_name "(?<snicat>(LIST|LS|SIZE|LD|CB|CD|EX|ALIVE|EXIT|WHERE|finito)-[A-Za-z0-9]{16}\.)"
| stats count BY src_ip dest_ip server_name snicat
| where count>0
| table src_ip dest_ip server_name snicat
| `detect_snicat_sni_exfiltration_filter`Windows Exfiltration Over C2 Via Invoke RestMethod
The following analytic detects potential data exfiltration using PowerShell's Invoke-RestMethod. It leverages PowerShell Script Block Logging to identify scripts that attempt to upload files via HTTP POST requests. This activity is significant as it may indicate an attacker is exfiltrating sensitive data, such as desktop screenshots or files, to an external command and control (C2) server. If confirmed malicious, this could lead to data breaches, loss of sensitive information, and further compromise of the affected systems. Immediate investigation is recommended to determine the intent and scope of the activity.
Show query
`powershell` EventCode=4104 ScriptBlockText = "*Invoke-RestMethod *" AND ScriptBlockText = "* -Uri *" AND ScriptBlockText = "* -Method *" AND ScriptBlockText = "* Post *" AND ScriptBlockText = "* -InFile *"
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY dest signature signature_id
user_id vendor_product EventID
Guid Opcode Name
Path ProcessID ScriptBlockId
ScriptBlockText
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `windows_exfiltration_over_c2_via_invoke_restmethod_filter`Windows Exfiltration Over C2 Via Powershell UploadString
The following analytic identifies potential data exfiltration using the PowerShell `net.webclient` command with the `UploadString` method. It leverages PowerShell Script Block Logging to detect instances where this command is executed. This activity is significant as it may indicate an attempt to upload sensitive data, such as desktop screenshots or files, to an external or internal URI, often associated with malware like Winter-Vivern. If confirmed malicious, this could lead to unauthorized data transfer, compromising sensitive information and potentially leading to further exploitation of the compromised host.
Show query
`powershell` EventCode=4104 ScriptBlockText = "*Net.webclient*" AND ScriptBlockText = "*.UploadString*"
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY dest signature signature_id
user_id vendor_product EventID
Guid Opcode Name
Path ProcessID ScriptBlockId
ScriptBlockText
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `windows_exfiltration_over_c2_via_powershell_uploadstring_filter`Showing 1-6 of 6