Updates to the DPD framework.

- Removed the ProtocolViolation notice.  I'd like to hear
  if someone actually used that notice for something.
- Folded the dyn-disable functionality into the dpd/base script.
- Other small cleanup.
This commit is contained in:
Seth Hall 2011-06-30 21:26:30 -04:00
parent e3f6909b93
commit b4b990cfb5
5 changed files with 55 additions and 57 deletions

View file

@ -1,3 +1,2 @@
@load dpd/base
@load dpd/dyn-disable
@load dpd/packet-segment-logging

View file

@ -1,4 +1,5 @@
##! Activates port-independent protocol detection.
##! Activates port-independent protocol detection and selectively disables
##! analyzers if protocol violations occur.
@load functions
@load signatures
@ -6,19 +7,34 @@
module DPD;
## Add the DPD signatures to the signature framework.
redef signature_files += "dpd/dpd.sig";
redef signature_files += "frameworks/dpd/dpd.sig";
export {
redef enum Log::ID += { DPD };
type Info: record {
## Timestamp for when protocol analysis failed.
ts: time &log;
## Connection unique ID.
uid: string &log;
## Connection ID.
id: conn_id &log;
## Transport protocol for the violation.
proto: transport_proto &log;
## The analyzer that generated the violation.
analyzer: string &log;
## The textual reason for the analysis failure.
failure_reason: string &log;
## Disabled analyzer IDs. This is only for internal tracking
## so as to not attempt to disable analyzers multiple times.
# TODO: This is waiting on ticket #460 to remove the '0'.
disabled_aids: set[count] &default=set(0);
};
## Ignore violations which go this many bytes into the connection.
## Set to 0 to never ignore protocol violations.
const ignore_violations_after = 10 * 1024 &redef;
}
redef record connection += {
@ -29,6 +45,7 @@ event bro_init()
{
Log::create_stream(DPD, [$columns=Info]);
# Populate the internal DPD analysis variable.
for ( a in dpd_config )
{
for ( p in dpd_config[a]$ports )
@ -42,31 +59,53 @@ event bro_init()
event protocol_confirmation(c: connection, atype: count, aid: count) &priority=10
{
if ( fmt("-%s",analyzer_name(atype)) in c$service )
delete c$service[fmt("-%s", analyzer_name(atype))];
local analyzer = analyzer_name(atype);
add c$service[analyzer_name(atype)];
if ( fmt("-%s",analyzer) in c$service )
delete c$service[fmt("-%s", analyzer)];
add c$service[analyzer];
}
event protocol_violation(c: connection, atype: count, aid: count,
reason: string) &priority=5
reason: string) &priority=10
{
if ( analyzer_name(atype) in c$service )
delete c$service[analyzer_name(atype)];
add c$service[fmt("-%s", analyzer_name(atype))];
local analyzer = analyzer_name(atype);
# If the service hasn't been confirmed yet, don't generate a log message
# for the protocol violation.
if ( analyzer !in c$service )
return;
delete c$service[analyzer];
add c$service[fmt("-%s", analyzer)];
local info: Info;
info$ts=network_time();
info$uid=c$uid;
info$id=c$id;
info$proto=get_conn_transport_proto(c$id);
info$analyzer=analyzer_name(atype);
info$analyzer=analyzer;
info$failure_reason=reason;
c$dpd = info;
}
event protocol_violation(c: connection, atype: count, aid: count, reason: string) &priority=5
{
if ( !c?$dpd || aid in c$dpd$disabled_aids )
return;
local size = c$orig$size + c$resp$size;
if ( ignore_violations_after > 0 && size > ignore_violations_after )
return;
# Disable the analyzer that raised the last core-generated event.
disable_analyzer(c$id, aid);
add c$dpd$disabled_aids[aid];
}
event protocol_violation(c: connection, atype: count, aid: count,
reason: string) &priority=-5
{
if ( c?$dpd )
Log::write(DPD, c$dpd);
}

View file

@ -1,42 +0,0 @@
##! When this script is loaded, analyzers that raise protocol_violation events
##! are disabled for the affected connection.
@load dpd/base
@load notice
module DPD;
export {
redef enum Notice::Type += {
ProtocolViolation
};
redef record DPD::Info += {
## Disabled analyzer IDs.
# TODO: This is waiting on ticket #460 to remove the '0'.
disabled_aids: set[count] &default=set(0);
};
## Ignore violations which go this many bytes into the connection.
const max_data_volume = 10 * 1024 &redef;
}
event protocol_violation(c: connection, atype: count, aid: count,
reason: string) &priority=5
{
if ( aid in c$dpd$disabled_aids )
return;
local size = c$orig$size + c$resp$size;
if ( max_data_volume > 0 && size > max_data_volume )
return;
# Disable the analyzer that raised the last core-generated event.
disable_analyzer(c$id, aid);
add c$dpd$disabled_aids[aid];
NOTICE([$note=ProtocolViolation, $conn=c,
$msg=fmt("%s disabled due to protocol violation", analyzer_name(atype)),
$sub=reason, $n=atype]);
}

View file

@ -10,6 +10,8 @@ module DPD;
export {
redef record Info += {
## A chunk of the payload the most likely resulted in the protocol
## violation.
packet_segment: string &optional &log;
};
@ -21,5 +23,7 @@ export {
event protocol_violation(c: connection, atype: count, aid: count,
reason: string) &priority=4
{
if ( ! c?$dpd ) return;
c$dpd$packet_segment=fmt("%s", sub_bytes(get_current_packet()$data, 0, packet_segment_size));
}

View file

@ -5,7 +5,6 @@
# Load the policy scripts where the notices are defined.
@load frameworks/notice/weird
@load dpd
# Remove these notices from logging since they can be too noisy.
redef Notice::ignored_types += {
@ -13,5 +12,4 @@ redef Notice::ignored_types += {
Weird::AckAboveHole,
Weird::RetransmissionInconsistency,
Weird::WeirdActivity, # Only allow these to go in the weird log.
DPD::ProtocolViolation,
};