Road to Detection: YARA-L Examples — Part 4 of 3
Note: this blog series now exists in a cleaned-up full whitepaper form at https://hubs.ly/H0pvD_30
Upon reading all of Part 1, Part 2 and Part 3 of my blog series that revealed our (Chronicle) approach to detection, many of you asked for more YARA-L detection language examples.
Some of you also asked for a detailed language specification — it will take a few months to complete as our engine matures and we refine the detection logic a bit.
More examples with my explanations follow below;
Example 2 (see example 1 here) CLI Magic
The example below relies on regex match to a Windows command line (our UDM field udm.process.command_line). Where may such data appear? Typically, Endpoint Detection and Response (EDR) tools and/or sysmon. Today, many Chronicle customers send EDR and sysmon data into the platform. Note that not every EDR has detections for all the threats (naturally!) hence such post-processing of EDR data with YARA-L does deliver value. A traditional SIEM is not likely to even have a field for a command line arguments, by the way.
profile susp_powershell_download_file
{
meta:
author = “Chronicle Security”
description = “Rule to detect PowerShell one-liner to download a file”
version = “0.01”
created = “2019–12–16”
reference = “https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Windows%20-%20Download%20and%20Execute.md"
condition:
if re.regex(strings.lower(udm.process.command_line), “.*powershell.*net.webclient.*”) then
outcome.match()
end
}
Example 3 More EDR-ing
This is another simple rule that runs on EDR (or sysmon) data and relies on command line matching and also path matching (see udm.process.path below). It showcases conditions for grouping and flexible matching to several variables such as command line and process path. It also detects rather well and have been used to uncover things…
profile susp_process_with_variation_of_svchost
{
meta:
author = “Chronicle Security”
description = “Rule to detect process paths or command line execution of files with variations on svchost”
version = “0.01”
created = “2019–12–16”
function:
func CheckSvchostVariations()
if (
re.regex(strings.lower(udm.process.command_line), “.*(svch0st|svh0st|svhost|svchst|svchot|svchostexe)\.exe.*”) or
re.regex(strings.lower(udm.process.path), “.*(svch0st|svh0st|svhost|svchst|svchot|svchostexe)\.exe.*”)
) then
return true
end
return false
end
condition:
if ( CheckSvchostVariations() )
then
outcome.match()
end
}
Example 4 Registry Mess
This rule focuses on registry monitoring. Windows event logs or EDR data are the most likely source for this. The rule mixes event types with specific field values to detect interesting registry operations. This and many other rules are mapped to MITRE ATT&CK framework.
profile mitre_T1198_registry_modification_to_trusted_provider_list
{
meta:
author = “Chronicle Security”
description = “Detection for registry changes keys associated with Trusted providers”
reference = “https://attack.mitre.org/techniques/T1198/"
version = “0.01”
created = “2019–12–13”
function:
func ProviderListRegChange()
if ( (udm.metadata.event_type == “REGISTRY_MODIFICATION” or udm.metadata.event_type == “REGISTRY_CREATION” ) and
(
udm.target.Registry.registry_key == “HKLM\\SOFTWARE\\Microsoft\\Cryptography\\OID” or
udm.target.Registry.registry_key == “HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Cryptography\\OID” or
udm.target.Registry.registry_key == “HKLM\\SOFTWARE\\Microsoft\\Cryptography\\Providers\\Trust” or
udm.target.Registry.registry_key == “HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Cryptography\\Providers\\Trust”) )
then
return true
end
return false
end
condition:
if ( ProviderListRegChange() ) then
outcome.match()
end
}
Example 5 Too Late? Better Late Than Never
The rule below looks for ransomware dropping a ransom note. This may come from a wide range of data sources, centered on an endpoint (again, EDR and sysmon, as well as Windows logs — in some cases). Now, some of you may say “a ransom note? Isn’t it kinda the definition of ‘too late’?”
Well, sort of. I think this may mean detecting before more machines are infected, or (with some luck) detecting before the ransomware hits the proverbial open shares on your network.
profile ransomware_ryuk_ransomnote_created {
meta:
author = “blevene”
description = “Identify when a Ryuk Ransomware ransomnote has been written.”
version = “0.01”
created = “2019–12–16”
condition:
if (
udm.metadata.event_type == “FILE_WRITE”
and ( strings.to_lower(udm.target.file) = “RyukReadMe.html”)
or
strings.to_lower(udm.target.file) = “RyukReadMe.txt”
)
then
outcome.match()
end
}
Example 6 Detection Choices
This rule perhaps does not have much magic, but it does showcase a few more functions of the YARA-L language today. If you have multiple ways to detect something but want to channel them all into one detection as a result, this is an example of such a rule.
profile malware_powershell_empire
{
meta:
author = “Chronicle Security “
description = “Detection activity related to the OWAAuth malware”
reference = “https://attack.mitre.org/software/S0072/"
version = “1.2”
created = “2019–12–13”
updated = “2020–01–20”
function:
func ScheduledTaskSet()
if re.regex(strings.to_lower(udm.principal.process.command_line), “.*schtasks .*/tn updater.*”) then
return true
end
return false
end
func WritePayload()
if re.regex(strings.to_lower(udm.principal.process.command_line), “.*sal a new-object;iex\\(a io\\.streamreader\\(\\(a io\\.compression\\.deflatestream\\(\\[io.memorystream\\]\\[convert\\]::frombase64string\\(.*\\),\\[io\\.compression\\.compressionmode\\]::decompress\\)\\),\\[text.encoding\\]::ascii.*”)
then
return true
end
return false
end
condition:
if ScheduledTaskSet() or WritePayload() then
outcome.match()
end
}
Example 7 More Malware
This one matches more endpoint logs across multiple fields. In my view, this one demonstrates the YARA origin of the YARA-L language here (reminder: they are different languages for different purposes). Note that all of the fields below are matched via regexs, you don’t have to do it, but you have that choice.
Now this rule may have magic because it may trigger vs telemetry that does not actually constant the text below.
profile malware_win_dropper_sload
{
meta:
author = “Chronicle Security”
description = “Detection for sLoad dropper marker files”
reference = “https://www.microsoft.com/security/blog/2019/12/12/multi-stage-downloader-trojan-sload-abuses-bits-almost-exclusively-for-malicious-activities/"
version = “1.1”
created = “2019–12–16”
updated = “2020–01–28”
function:
func Marker()
if udm.metadata.event_type == “FILE_CREATION” and re.regex(strings.to_lower(udm.target.file.full_path), “.*\\_in\\$”)
and re.regex(strings.to_lower(udm.principal.process.command_line), “.*powershell.*”)
then
return true
end
return false
end
condition:
if Marker()
then
outcome.match()
end
}
Previous posts: