Skip to content

Commit e73563d

Browse files
authored
Merge pull request #2550 from sebix/doc-modify
Update and fix modify bot docs
2 parents 98df0cd + d472682 commit e73563d

File tree

1 file changed

+61
-50
lines changed

1 file changed

+61
-50
lines changed

docs/user/bots.md

Lines changed: 61 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3229,7 +3229,7 @@ This bots allows you to change arbitrary field values of events using a configur
32293229

32303230
(optional, boolean) Overwrite any existing fields by matching rules. Defaults to false.
32313231

3232-
**Configuration File**
3232+
#### Configuration File Format
32333233

32343234
The modify expert bot allows you to change arbitrary field values of events just using a configuration file. Thus it is
32353235
possible to adapt certain values or adding new ones only by changing JSON-files without touching the code of many other
@@ -3240,43 +3240,84 @@ The configuration is called `modify.conf` and looks like this:
32403240
```json
32413241
[
32423242
{
3243-
"rulename": "Standard Protocols http",
3243+
"rulename": "Name of Rule 1",
32443244
"if": {
3245-
"source.port": "^(80|443)$"
3245+
"fieldname": "comparison_value"
32463246
},
32473247
"then": {
3248-
"protocol.application": "http"
3248+
"fieldname": "newvalue"
32493249
}
32503250
},
3251+
[...]
3252+
]
3253+
```
3254+
3255+
Each rule consists of a *rule name*, *conditions* and *actions*:
3256+
The rule name is for your own documentation and only used in debugging output.
3257+
Conditions and actions are dictionaries holding the field names of
3258+
events and regular expressions to match values (selection) or set values (action). All matching rules will be applied in
3259+
the given order. The actions of a rule are only performed if all conditions of the rule apply.
3260+
3261+
One configuration file can contain an arbitrary number of rules.
3262+
3263+
#### Condition
3264+
3265+
* **Empty string**: If the value for a condition is an empty string, the bot checks if the field does not exist. This is useful to apply default values for empty fields.
3266+
* A non-empty **string**: The matching uses [regular expressions](https://docs.python.org/3/library/re.html#re.search) to match the field. Use explicit beginning and end markers to match the full string instead of a substring: `^regex$`.
3267+
If the field is not a string, it will be converted to a string first. This allows for matching numeric values with regular expressions.
3268+
To escape a character in the regular expression, JSON requires you to double-escape, for example, in `"extra.version": "^10\\.0"` the `.` is matched as literal character.
3269+
* All **other types**: boolean, integer, float, etc: Direct equality comparison
3270+
3271+
To check for the existence of a field, you can therefore always use the condition `"."`.
3272+
3273+
#### Action
3274+
3275+
You can set the value of the field to a string literal or number.
3276+
3277+
In addition you can use the [standard Python string format syntax](https://docs.python.org/3/library/string.html#format-string-syntax) to access the values from the processed event as `msg` and the match groups of the conditions as `matches`, see the bitdefender example above. Group 0 ([`0`]) contains the full matching string. See also the documentation on [re.Match.group](https://docs.python.org/3/library/re.html?highlight=re%20search#re.Match.group).
3278+
3279+
Setting a field to an empty string deletes the field, for example:
3280+
```json
3281+
[
32513282
{
3283+
"rulename": "Delete NAICS",
3284+
"if": {
3285+
"extra.naics": "."
3286+
},
3287+
"then": {
3288+
"extra.naics": ""
3289+
}
3290+
}
3291+
]
3292+
```
3293+
The same effect can be achieved with the [Field Reducer Expert](#intelmq.bots.experts.field_reducer.expert).
3294+
3295+
#### Examples
3296+
3297+
```json
3298+
[
3299+
{
32523300
"rulename": "Spamhaus Cert conficker",
32533301
"if": {
3302+
"feed.name": "^Spamhaus Cert$",
32543303
"malware.name": "^conficker(ab)?$"
32553304
},
32563305
"then": {
32573306
"classification.identifier": "conficker"
32583307
}
32593308
},
32603309
{
3261-
"rulename": "bitdefender",
3310+
"rulename": "Spamhaus Cert bitdefender",
32623311
"if": {
3312+
"feed.name": "^Spamhaus Cert$",
32633313
"malware.name": "bitdefender-(.*)$"
32643314
},
32653315
"then": {
32663316
"malware.name": "{matches[malware.name][1]}"
32673317
}
32683318
},
32693319
{
3270-
"rulename": "urlzone",
3271-
"if": {
3272-
"malware.name": "^urlzone2?$"
3273-
},
3274-
"then": {
3275-
"classification.identifier": "urlzone"
3276-
}
3277-
},
3278-
{
3279-
"rulename": "default",
3320+
"rulename": "Spamhaus Cert default",
32803321
"if": {
32813322
"feed.name": "^Spamhaus Cert$"
32823323
},
@@ -3287,44 +3328,14 @@ The configuration is called `modify.conf` and looks like this:
32873328
]
32883329
```
32893330

3290-
In our example above we have five groups labeled `Standard Protocols http`, `Spamhaus Cert conficker`,
3291-
`bitdefender`, `urlzone` and `default`. All sections will be considered, in the given order (from top to bottom).
3292-
3293-
Each rule consists of *conditions* and *actions*. Conditions and actions are dictionaries holding the field names of
3294-
events and regular expressions to match values (selection) or set values (action). All matching rules will be applied in
3295-
the given order. The actions are only performed if all selections apply.
3296-
3297-
If the value for a condition is an empty string, the bot checks if the field does not exist. This is useful to apply
3298-
default values for empty fields.
3299-
3300-
**Actions**
3301-
3302-
You can set the value of the field to a string literal or number.
3303-
3304-
In addition you can use the [standard Python string format syntax](https://docs.python.org/3/library/string.html#format-string-syntax) to access the values from the processed event as `msg` and the match groups of the conditions as `matches`, see the bitdefender example above. Group 0 ([`0`]) contains the full matching string. See also the documentation on [re.Match.group](https://docs.python.org/3/library/re.html?highlight=re%20search#re.Match.group).
3305-
3306-
Note that `matches` will also contain the match groups from the default conditions if there were any.
3307-
3308-
**Examples**
3309-
3310-
We have an event with `feed.name = Spamhaus Cert` and `malware.name = confickerab`. The expert loops over all sections
3311-
in the file and eventually enters section `Spamhaus Cert`. First, the default condition is checked, it matches!
3312-
OK, going on. Otherwise the expert would have selected a different section that has not yet been considered. Now, go
3313-
through the rules, until we hit the rule `conficker`. We combine the conditions of this rule with the default
3314-
conditions, and both rules match! So we can apply the action: `classification.identifier` is set to `conficker`, the
3315-
trivial name.
3316-
3317-
Assume we have an event with `feed.name = Spamhaus Cert` and `malware.name = feodo`. The default condition matches, but
3318-
no others. So the default action is applied. The value for `classification.identifier` will be set to `feodo`
3319-
by `{msg[malware.name]}`.
3331+
In our example above we have three rules named `Spamhaus Cert conficker`,
3332+
`Spamhaus Cert bitdefender` and `Spamhaus Cert default`.
33203333

3321-
**Types**
3334+
Assume we have an event with `feed.name = Spamhaus Cert` and `malware.name = confickerab`, and `maximum_matches` is set to 1.
33223335

3323-
If the rule is a string, a regular expression search is performed, also for numeric values (`str()` is called on them).
3324-
If the rule is numeric for numeric values, a simple comparison is done. If other types are mixed, a warning will be
3325-
thrown.
3336+
The expert loops over all sections in the file, and the first matching one is `Spamhaus Cert conficker`. It applies the action, setting the new `classification.identifier` and then stops, as the maximum matches has been reached.
33263337

3327-
For boolean values, the comparison value needs to be `true` or `false` as in JSON they are written all-lowercase.
3338+
Assume we have an event with `feed.name = Spamhaus Cert` and `malware.name = feodo`. The first and only matching rule is the `default`. So the default action is applied. The value for `classification.identifier` will be set to `feodo` by `{msg[malware.name]}`.
33283339

33293340
---
33303341

0 commit comments

Comments
 (0)