We've wanted to support rule overrides for a while. This PR attempts to do so in a basic way by storing matched rules in a map (both the original and the override should match) and then dropping the original rule if an override exists. For now, we'll allow for severity overrides and then store the combined descriptions of the two rules for later display.
For example,
This YARA:
rule send {
meta:
description = "send a message to a socket"
ref = "https://linux.die.net/man/2/send"
syscall = "send"
strings:
$send = "send" fullword
$socket = "socket" fullword
condition:
all of them
}
rule send_override {
meta:
description = "this overrides the send rule"
ref = "https://linux.die.net/man/2/send"
syscall = "send"
strings:
$send = "send" fullword
$socket = "socket" fullword
condition:
all of them
}
Results in this output:
$ go run . analyze out/samples-84a2015439ad84d3005fa57d06d7a925acb9f2a3/javascript/clean/connection.js
out/samples-84a2015439ad84d3005fa57d06d7a925acb9f2a3/javascript/clean/connection.js [⚠️ MEDIUM]
---------------------------------------------------------------------------------------------------------------------------------
RISK KEY DESCRIPTION EVIDENCE
---------------------------------------------------------------------------------------------------------------------------------
LOW encoding/base64 Supports base64 encoded strings base64
LOW fd/write writes to a file handle outgoingMessageStream.write(message)
LOW net/dns Uses DNS (Domain Name Service) require("dns")
LOW net/socket/send this overrides the send rule, send a message to a send
socket socket
LOW ref/site/url contains embedded HTTPS URLs https://github.com/pekim/tedious/issues/24
LOW ref/words/password references a 'password' UsernamePasswordCredential
directory-password
MED data/embedded/base64/terms Contains base64 content FkZHJlc3::$address
RpcmVjdG9ye::$directory
YWRkcmVzc::$address
ZGlyZWN0b3J5::$directory
aHRtb::$html
hZGRyZXNz::$address
kaXJlY3Rvcn::$directory
MED data/embedded/base64/url Contains base64 url aHR0cDovL::$http
h0dHA6Ly::$http
h0dHBzOi8v::$https
odHRwOi8v::$http
odHRwczovL::$https
MED evasion/hex converts hex data to ASCII toString('hex');
---------------------------------------------------------------------------------------------------------------------------------
The important part:
LOW net/socket/send this overrides the send rule, send a message to a send
socket socket
Severity overrides also work:
rule send_override : critical {
meta:
description = "send a message to a socket but critical"
ref = "https://linux.die.net/man/2/send"
syscall = "send"
strings:
$send = "send" fullword
$socket = "socket" fullword
condition:
all of them
}
⬇️
go run . analyze out/samples-84a2015439ad84d3005fa57d06d7a925acb9f2a3/javascript/clean/connection.js
out/samples-84a2015439ad84d3005fa57d06d7a925acb9f2a3/javascript/clean/connection.js [🚨 CRITICAL]
-------------------------------------------------------------------------------------------------------------------------------
RISK KEY DESCRIPTION EVIDENCE
-------------------------------------------------------------------------------------------------------------------------------
LOW encoding/base64 Supports base64 encoded strings base64
LOW fd/write writes to a file handle outgoingMessageStream.write(message)
LOW net/dns Uses DNS (Domain Name Service) require("dns")
LOW ref/site/url contains embedded HTTPS URLs https://github.com/pekim/tedious/issues/24
LOW ref/words/password references a 'password' UsernamePasswordCredential
directory-password
MED data/embedded/base64/terms Contains base64 content FkZHJlc3::$address
RpcmVjdG9ye::$directory
YWRkcmVzc::$address
ZGlyZWN0b3J5::$directory
aHRtb::$html
hZGRyZXNz::$address
kaXJlY3Rvcn::$directory
MED data/embedded/base64/url Contains base64 url aHR0cDovL::$http
h0dHA6Ly::$http
h0dHBzOi8v::$https
odHRwOi8v::$http
odHRwczovL::$https
MED evasion/hex converts hex data to ASCII toString('hex');
CRIT net/socket/send send a message to a socket but critical, send a send
message to a socket socket
-------------------------------------------------------------------------------------------------------------------------------
Additionally, we'll now filter out false_positive and ignore tags by default.
Given:
rule send : ignore {
meta:
description = "send a message to a socket"
ref = "https://linux.die.net/man/2/send"
syscall = "send"
strings:
$send = "send" fullword
$socket = "socket" fullword
condition:
all of them
}
or:
rule send : false_positive {
meta:
description = "send a message to a socket"
ref = "https://linux.die.net/man/2/send"
syscall = "send"
strings:
$send = "send" fullword
$socket = "socket" fullword
condition:
all of them
}
The output will no longer contain that match:
$ go run . analyze out/samples-84a2015439ad84d3005fa57d06d7a925acb9f2a3/javascript/clean/connection.js
out/samples-84a2015439ad84d3005fa57d06d7a925acb9f2a3/javascript/clean/connection.js [⚠️ MEDIUM]
---------------------------------------------------------------------------------------------------------------
RISK KEY DESCRIPTION EVIDENCE
---------------------------------------------------------------------------------------------------------------
LOW encoding/base64 Supports base64 encoded strings base64
LOW fd/write writes to a file handle outgoingMessageStream.write(message)
LOW net/dns Uses DNS (Domain Name Service) require("dns")
LOW ref/site/url contains embedded HTTPS URLs https://github.com/pekim/tedious/issues/24
LOW ref/words/password references a 'password' UsernamePasswordCredential
directory-password
MED data/embedded/base64/terms Contains base64 content FkZHJlc3::$address
RpcmVjdG9ye::$directory
YWRkcmVzc::$address
ZGlyZWN0b3J5::$directory
aHRtb::$html
hZGRyZXNz::$address
kaXJlY3Rvcn::$directory
MED data/embedded/base64/url Contains base64 url aHR0cDovL::$http
h0dHA6Ly::$http
h0dHBzOi8v::$https
odHRwOi8v::$http
odHRwczovL::$https
MED evasion/hex converts hex data to ASCII toString('hex');
---------------------------------------------------------------------------------------------------------------
Closes #471
We've wanted to support rule overrides for a while. This PR attempts to do so in a basic way by storing matched rules in a map (both the original and the override should match) and then dropping the original rule if an override exists. For now, we'll allow for severity overrides and then store the combined descriptions of the two rules for later display.
For example,
This YARA:
Results in this output:
The important part:
Severity overrides also work:
⬇️
Additionally, we'll now filter out
false_positive
andignore
tags by default.Given:
or:
The output will no longer contain that match: