-
Notifications
You must be signed in to change notification settings - Fork 226
Known_Vulnerability_Rules
The known_vulnerabilities
plugin is intended as a meta plugin to combine arbitrary analysis results into vulnerability definitions.
As an example: Say we have a plugin to parse config files and find out we have a running ssh server with root login permission. Now another plugin finds that the root password is hardcoded an the hash was cracked. In combination this leads to a trivial root login backdoor, but in general the plugins don't share their results.
Pseudo code for such a vulnerability rule would look something like (config_plugin.ssh_root == open) && (password_plugin.passwords.root.exists)
.
A similar rule can be created using the known_vulnerabilities
plugin given the two plugins exist and create useable results.
🐍 The vulnerability definition works in python.
The relevant file is the rulebook.py
in the internal folder inside the plugin file tree.
Defining a vulnerability consists of two steps:
- Defining the rule, using results of other analysis plugins
- Adding meta information to the rule to describe the vulnerability
Step 1 can make use of three classes SingleRule
, MetaRule
and SubPathRule
.
SingleRule is used to specify a condition regarding exactly one value.
In the example above that would be either the config_plugin.ssh_root == open
condition or the password_plugin.passwords.root.exists
condition.
SingleRules are initialized with three parameters:
-
value_path
(config_plugin.ssh_root) -
relation
(equals) -
comparison
(open)
The suppported relations are: exists, equals, is, gt, lt, in, reverse_in and intersection. More on all relations can be read at the bottom.
The value_path is a dot separated path to an analysis result.
Compare the advanced_search page for an insight into building a proper path.
Note that the leading processed_analysis
, which would be found in a database query is not considered here.
The comparison value specified the value, which is considered vulnerable or critical. For the relations in and intersection the value should be an iterable. In case relation is exists, the comparison value may be empty.
A MetaRule is used to combine two or more SingleRules. The instantiation requires two values: A list of SingleRule objects and a relation. The only applicable relations are any and all, directly corresponding to the python built-in functions of same name and meaning.
The idea behind the SubPathRule is the occurrence of analysis results with dictionaries nested inside lists.
SubPathRules are instantiated with two parameters, base_path
and meta_rule
.
Consider this example, loosely based on how the ip_and_uri_finder plugin stores its data:
{
'ip_plugin': {
'timestamp': 1000000,
'ip_v4': [
{
'address': '192.168.1.2',
'location': [12345, -13131]
},
{
'address': '192.168.178.1',
'location': [51442, 31337]
}
]
}
}
Since the value of ip_v4
is a list, the address
and location
values cannot be addressed using the dot separated value paths.
The SubPathRule allows to give a base path, in this case ip_plugin.ip_v4
combined with a SingleRule or MetaRule to then match inside the target field.
Given the SingleRule ("address", "equals", "192.168.178.1")
, each element in the ip results list is considered, evaluating to true on the second element.
Alternatively you can simply write a yara rule for a given vulnerability if that's possible. The syntax is as follows:
rule NAME_OF_RULE
{
meta:
description = "short description"
reliability = "range(0, 101)"
score = "low / medium / high"
link = "http://link.to.vulnerability.description/ or empty string"
strings:
$a = /REGULAR_EXPRESSION/ nocase ascii wide
condition:
$a
}
You can add a new rule by simply adding it to the vulnerabilities.yara file in the signatures folder inside the known_vulnerabilities plugin (src/plugins/analysis/known_vulnerabilities/signatures/vulnerabilities.yara).
src/compile_yara_signatures.py
script to update the compiled signatures.
Otherwise changes or new rules will not take effect.
Some of the relations are self explanatory like gt (greater than), lt (less than), exists or intersection.
For gt and lt note that the comparison is the second operand.
I.e. ("ssl_version", "gt", 1)
is true if the value of "ssl_version" is at least float(1.1).
Intersection is true if there is an intersection between the target value and the comparison iterable.
The rule checker will convert both iterable to a set.
Relations is and equals look equal but are not actually.
In python the is
operator will check on object equality by reference, not value.
This means a string comparison of "hello world" is "hello world"
would fail, as the operands describe two different objects with the same value.
Using the equals, python ==
operator solves this issue.
Here the value of two objects are compared, thus "hello world" == "hello world"
resolves to true.
Finally in and reverse_in can be used when either a single value should be compared with a list of possible targets or the other way around.
Consider ("found_cves", "in", "CVE-2018-00001")
.
This will be true if the iterable stored as result of "found_cves" contains "CVE-2018-00001".
In reverse, consider ("software.lighttp.version", "reverse_in", ["vulnerable.version.1", "vulnerable.version.2"])
.
Now this will be true if the software analysis found lighttp in one of the two specified versions.