forked from JustinAzoff/bro-react
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconn-bulk.bro
104 lines (84 loc) · 2.89 KB
/
conn-bulk.bro
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
##! A detection script for Bulk Flows
@load base/protocols/conn
module Bulk;
export {
## Number of bytes transferred before marking a connection as bulk
const size_threshold = 134217728 &redef; #128 megabytes
## Max number of times to check whether a connection's size exceeds the
## :bro:see:`Bulk::size_threshold`.
const max_poll_count = 30 &redef;
## Base amount of time between checking whether a data connection
## has transferred more than :bro:see:`Bulk::size_threshold` bytes.
const poll_interval_1 = 500msec &redef;
const poll_interval_2 = 30sec &redef;
## Raised when a Bulk data channel is detected.
##
## c: The connection pertaining to the Bulk data channel.
global connection_detected: event(c: connection);
## The initial criteria used to determine whether to start polling
## the connection for the :bro:see:`Bulk::size_threshold` to have
## been exceeded.
## c: The connection which may possibly be a Bulk data channel.
##
## Returns: true if the connection should be further polled for an
## exceeded :bro:see:`Bulk::size_threshold`, else false.
const bulk_initial_criteria: function(c: connection): bool &redef;
type PortRange: record {
ports: set[port] &optional;
port_min: port &default=1/tcp;
port_max: port &default=65535/tcp;
};
const hosts: table[subnet] of PortRange = {[0.0.0.0/0] = PortRange()} &redef;
}
redef record Conn::Info += {
bulk: bool &optional &default=F;
};
function size_callback(c: connection, cnt: count): interval
{
if ( c$orig$size > size_threshold || c$resp$size > size_threshold )
{
#c$conn$bulk = T;
event Bulk::connection_detected(c);
return -1sec;
}
if ( cnt >= max_poll_count )
return -1sec;
#at first delay for poll_interval_1, later for poll_interval_2
return (cnt < max_poll_count/3) ? poll_interval_1 : poll_interval_2;
}
function bulk_initial_criteria(c: connection): bool
{
local pr: PortRange;
if(c$id$orig_h in hosts)
pr = hosts[c$id$orig_h];
else if(c$id$resp_h in hosts)
pr = hosts[c$id$resp_h];
else
return F;
if(pr?$ports) {
return (c$id$resp_p in pr$ports);
}
return (pr$port_min <= c$id$resp_p && c$id$resp_p <= pr$port_max);
}
event new_connection(c: connection) &priority=-3
{
if ( bulk_initial_criteria(c) )
ConnPolling::watch(c, size_callback, 0, 0secs);
}
event connection_state_remove(c: connection)
{
if(c$conn$bulk)
return;
if ( bulk_initial_criteria(c) && (c$orig$size > size_threshold || c$resp$size > size_threshold ))
c$conn$bulk = T;
}
event bro_init()
{
Log::add_filter(Conn::LOG, [
$name = "conn-bulk",
$path = "conn_bulk",
$pred(rec: Conn::Info) = {
return rec$bulk;
}
]);
}