Events are records, composed of fields, that the various input and dissection modules provide to the Orchids detection engine. Those are ordinary, regular events.
Orchids also allows you to create new events during the execution of a rule. Those events are called synthetic events, or metaevents. It is the purpose of the metaevent module to provide primitives to post such synthetic events.
Posting synthetic events is useful to make detection hierarchical. For an example, imagine that attempting to unduly connect to some machine $host is detected by a rule connect_attempt.rule, and that you would like to detect when the same intruder tries to connect to two machines. One possibility is to write connect_attempt.rule as a rule that, instead of reporting, would post a synthetic event containing the offending intruder identity and the $host it tried to connect to. That can be done by writing:
inject_event (.{.meta.host = $host, .meta.intruder = $attacker});
in the connect_attempt.rule rule, posting the synthetic event given as argument to inject_event. (Any list of records enclosed between .{ and } is a synthetic event, see “synthetic event” in the expressions page. The meta module does not exist: this is a so-called virtual module, see below. Also the list of fields was kept minimal for the illustration.)
Then a second rule that tries to detect two connection attempts by the same intruder might include code such as:
state first_connection {
expect (defined(.meta.host)) goto second_connection;
}
state second_connection {
$host1 = .meta.host;
$attacker = .meta.intruder; // record data from first connection
expect (.meta.intruder==$attacker)
// wait for another meta event with the same $attacker
// (no need to check defined(.meta.host) here)
goto alert;
}
state alert! {
$host2 = .meta.host;
report();
}
Virtual modules
So what is meta in that example?
Just like the generic module, the metaevent module is a meta-module, one that allows you to define new, so-called virtual modules. Any event field in Orchids is of the form .module-name.field-name, so you cannot just write any random event field: either you use fields from some existing modules (which is not what we want to do here), or you create some fresh, specifically designed, virtual modules.
Such virtual modules are declared inside the configuration options for the metaevent module. Contrarily to the generic module, we do not specify regular expressions here, just lists of fields with their types.
Configuration options
<module metaevent>
contains a list of declarations of virtual modules. Virtual modules work exactly like actual modules, except you do not need to load any shared library at start-up time to start them. You start each virtual module by a declaration of the form:
<vmod module-name>
Inside such a declaration, you can declare fields with their names and types:
str_fieldfield-name description: a field of typestr(string)bstr_fieldfield-name description: a field of typebstr(binary string)int_fieldfield-name description: a field of typeintuint_fieldfield-name description: a field of typeuint(unsigned int)float_fieldfield-name description: a field of typefloat(floating-point number)ipv4_fieldfield-name description: a field of typeipv4(IPv4 address)ipv6_fieldfield-name description: a field of typeipv4(IPv6 address)ctime_fieldfield-name description: a field of typectime(Unix date)timeval_fieldfield-name description: a field of typetimeval(duration)snmpoid_fieldfield-name description: a field of typesnmpoid(SNMP object identifier)
Example:
<vmod meta> str_field host "The current host" str_field action "A text description of the action done" ipv4_field intruder "The attacker's IP address" ctime_field time "The detection time" </vmod>
Note that you are not forced to use all the fields declared in a given virtual module. It is perfectly fair to build events with only some of the fields, just as we did with the meta virtual module.
</vmod>
</module>
Primitives
inject_event:event→int
inject the given event into the Orchids event queue; the event can be a synthetic event, or one obtained bycurrent_event, possibly enriched: see synthetic events on the expressions page- returns: 1 (true)
current_event: →event
the current event