Skip to content

Commit af2b8ce

Browse files
committed
ENH: Add option to extend default info
1 parent 07e44d6 commit af2b8ce

File tree

4 files changed

+53
-7
lines changed

4 files changed

+53
-7
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
- Allow saving messages in bulks instead of refreshing the feed immediately (PR#2509 by Kamil Mankowski).
4040
- Add `attribute_mapping` parameter to allow selecting a subset of event attributes as well as additional attribute parameters (PR#2509 by Kamil Mankowski).
4141
- Add `event_separator` parameter to allow keeping IntelMQ events in separated MISP Events based on a given field (PR#2509 by Kamil Mankowski).
42+
- Add `additional_info` parameter to extend the default description of MISP Events (PR#2509 by Kamil Mankowski).
4243
- `intelmq.bots.outputs.smtp_batch.output`: Documentation on multiple recipients added (PR#2501 by Edvard Rejthar).
4344

4445
### Documentation

docs/user/bots.md

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4629,9 +4629,30 @@ as not usable for IDS.
46294629

46304630
**`event_separator`
46314631

4632-
(optional, string): If set to a field name from IntelMQ event, the bot will group incoming messages
4633-
in separated MISP events, based on the value of this field. The `interval_event` parameter acts
4634-
for all grouping events together.
4632+
(optional, string): If set to a field name from IntelMQ event, the bot will work in parallel on a few
4633+
events instead of saving all incomming messages to a one. Each unique value from the field will
4634+
use its own MISP Event. This is useful if your feed provides data about multiple entities you would
4635+
like to group, for example IPs of C2 servers from different botnets. For a given value, the bot will
4636+
use the same MISP Event as long as it's allowed by the `interval_event`.
4637+
4638+
**`additional_info`
4639+
4640+
(optional, string): If set, the generated MISP Event will use it in the `info` field of the event,
4641+
in addition to the standard IntelMQ description with the time frame (you cannot remove it as the bot
4642+
depends of datetimes saved there). If you use `event_separator`, you may want to use `{separator}`
4643+
placeholder which will be then replaced with the value of the separator.
4644+
4645+
For example, the following configuration can be used to create MISP Feed with IPs of C2 servers
4646+
of different botnets, having each botnet in a separated MISP Events with an appropiate description.
4647+
Each MISP Event will contain objects with the `source.ip` field only, and the events' info will look
4648+
like *C2 Servers for botnet-1. IntelMQ event 2024-07-09T14:51:10.825123 - 2024-07-10T14:51:10.825123*
4649+
4650+
```yaml
4651+
event_separator: malware.name
4652+
additional_info: C2 Servers for {separator}.
4653+
attribute_mapping:
4654+
source.ip:
4655+
```
46354656

46364657
**Usage in MISP**
46374658

intelmq/bots/outputs/misp/output_feed.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,11 @@ class MISPFeedOutputBot(OutputBot, CacheMixin):
3333
bulk_save_count: int = None
3434
misp_org_name = None
3535
misp_org_uuid = None
36-
output_dir: str = (
37-
"/opt/intelmq/var/lib/bots/mispfeed-output" # TODO: should be path
38-
)
36+
output_dir: str = "/opt/intelmq/var/lib/bots/mispfeed-output" # TODO: should be path
3937
_is_multithreadable: bool = False
4038
attribute_mapping: dict = None
4139
event_separator: str = None
40+
additional_info: str = None
4241

4342
@staticmethod
4443
def check_output_dir(dirname):
@@ -141,10 +140,14 @@ def process(self):
141140

142141
def _generate_new_event(self, key):
143142
self.current_events[key] = MISPEvent()
144-
self.current_events[key].info = "IntelMQ event {begin} - {end}" "".format(
143+
info = "IntelMQ event {begin} - {end}" "".format(
145144
begin=self.min_time_current.isoformat(),
146145
end=self.max_time_current.isoformat(),
147146
)
147+
if self.additional_info:
148+
info = f"{self.additional_info.format(separator=key)} {info}"
149+
150+
self.current_events[key].info = info
148151
self.current_events[key].set_date(datetime.date.today())
149152
self.current_events[key].Orgc = self.misp_org
150153
self.current_events[key].uuid = str(uuid4())

intelmq/tests/bots/outputs/misp/test_output_feed.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,27 @@ def test_event(self):
6464
objects = json.load(f).get("Event", {}).get("Object", [])
6565
assert len(objects) == 1
6666

67+
def test_additional_info(self):
68+
self.run_bot(parameters={"additional_info": "This is my custom info."})
69+
70+
current_event = open(f"{self.directory.name}/.current").read()
71+
with open(current_event) as f:
72+
info: str = json.load(f).get("Event", {}).get("info", "")
73+
assert info.startswith("This is my custom info. IntelMQ event ")
74+
75+
def test_additional_info_with_separator(self):
76+
self.run_bot(
77+
parameters={
78+
"additional_info": "Event related to {separator}.",
79+
"event_separator": "malware.name",
80+
}
81+
)
82+
83+
current_events = json.loads(open(f"{self.directory.name}/.current").read())
84+
with open(current_events["salityp2p"]) as f:
85+
info: str = json.load(f).get("Event", {}).get("info", "")
86+
assert info.startswith("Event related to salityp2p. IntelMQ event ")
87+
6788
def test_accumulating_events(self):
6889
self.input_message = [EXAMPLE_EVENT, EXAMPLE_EVENT]
6990
self.run_bot(iterations=2, parameters={"bulk_save_count": 3})

0 commit comments

Comments
 (0)