Merge remote-tracking branch 'origin/topic/seth/dhcp-update'

* origin/topic/seth/dhcp-update:
  Rework to the DHCP analyzer.
  First step of DHCP analyzer rearchitecture.
  Add .btest scripts for dhck_ack and dhcp_discover messages verifying that new options are correctly reported in dhcp.log records.
  Extend DHCP protocol analyzer with new options.

BIT-1924 #merged

Additional changes:

* Removed known-hosts.bro as the only thing populating its table was
  the already-removed known-hosts-and-devices.bro.  So a
  known_devices.log will no longer be generated.

* In dhcp-options.pac, the process_relay_agent_inf_option had a memleak
  and also process_auto_proxy_config_option looked like it accessed one
  byte past the end of the available bytestring, so fixed those.
This commit is contained in:
Jon Siwek 2018-05-01 17:57:15 -05:00
commit 81133f3116
42 changed files with 1688 additions and 722 deletions

View file

@ -1,37 +0,0 @@
##! Tracks MAC address with hostnames seen in DHCP traffic. They are logged into
##! ``devices.log``.
@load policy/misc/known-devices
module Known;
export {
redef record DevicesInfo += {
## The value of the DHCP host name option, if seen.
dhcp_host_name: string &log &optional;
};
}
event dhcp_request(c: connection, msg: dhcp_msg, req_addr: addr, serv_addr: addr, host_name: string)
{
if ( msg$h_addr == "" )
return;
if ( msg$h_addr !in known_devices )
{
add known_devices[msg$h_addr];
Log::write(Known::DEVICES_LOG, [$ts=network_time(), $mac=msg$h_addr, $dhcp_host_name=host_name]);
}
}
event dhcp_inform(c: connection, msg: dhcp_msg, host_name: string)
{
if ( msg$h_addr == "" )
return;
if ( msg$h_addr !in known_devices )
{
add known_devices[msg$h_addr];
Log::write(Known::DEVICES_LOG, [$ts=network_time(), $mac=msg$h_addr, $dhcp_host_name=host_name]);
}
}

View file

@ -0,0 +1,21 @@
##! Add a field that logs the order of hosts sending messages
##! using the same DHCP transaction ID. This information is
##! occasionally needed on some networks to fully explain the
##! DHCP sequence.
@load base/protocols/dhcp
module DHCP;
export {
redef record DHCP::Info += {
## The address that originated each message from the
## `msg_types` field.
msg_orig: vector of addr &log &default=addr_vec();
};
}
event DHCP::aggregate_msgs(ts: time, id: conn_id, uid: string, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options) &priority=3
{
log_info$msg_orig[|log_info$msg_orig|] = is_orig ? id$orig_h : id$resp_h;
}

View file

@ -0,0 +1,63 @@
##! Software identification and extraction for DHCP traffic.
@load base/protocols/dhcp
@load base/frameworks/software
module DHCP;
export {
redef enum Software::Type += {
## Identifier for web servers in the software framework.
DHCP::SERVER,
## Identifier for web browsers in the software framework.
DHCP::CLIENT,
};
redef record DHCP::Info += {
## Software reported by the client in the `vendor_class` option.
client_software: string &log &optional;
## Software reported by the server in the `vendor_class` option.
server_software: string &log &optional;
};
}
event DHCP::aggregate_msgs(ts: time, id: conn_id, uid: string, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options) &priority=5
{
if ( options?$vendor_class )
{
if ( is_orig )
log_info$client_software = options$vendor_class;
else
{
log_info$server_software = options$vendor_class;
Software::found(id, [$unparsed_version=options$vendor_class,
$host=id$resp_h,
$software_type=DHCP::SERVER]);
}
}
}
event DHCP::log_dhcp(rec: DHCP::Info)
{
if ( rec?$assigned_addr && rec?$server_addr &&
(rec?$client_software || rec?$server_software) )
{
# Not quite right to just blindly use 67 and 68 as the ports
local id: conn_id = [$orig_h=rec$assigned_addr, $orig_p=68/udp,
$resp_h=rec$server_addr, $resp_p=67/udp];
if ( rec?$client_software && rec$assigned_addr != 255.255.255.255 )
{
Software::found(id, [$unparsed_version=rec$client_software,
$host=rec$assigned_addr,
$software_type=DHCP::CLIENT]);
}
if ( rec?$server_software )
{
Software::found(id, [$unparsed_version=rec$server_software,
$host=rec$server_addr,
$software_type=DHCP::SERVER]);
}
}
}

View file

@ -0,0 +1,45 @@
@load base/protocols/dhcp
module DHCP;
export {
redef record DHCP::Info += {
## Added by DHCP relay agents which terminate switched or
## permanent circuits. It encodes an agent-local identifier
## of the circuit from which a DHCP client-to-server packet was
## received. Typically it should represent a router or switch
## interface number.
circuit_id: string &log &optional;
## A globally unique identifier added by relay agents to identify
## the remote host end of the circuit.
agent_remote_id: string &log &optional;
## The subscriber ID is a value independent of the physical
## network configuration so that a customer's DHCP configuration
## can be given to them correctly no matter where they are
## physically connected.
subscriber_id: string &log &optional;
};
}
event DHCP::aggregate_msgs(ts: time, id: conn_id, uid: string, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options)
{
if ( options?$sub_opt )
{
for ( i in options$sub_opt )
{
local sub_opt = options$sub_opt[i];
if ( sub_opt$code == 1 )
DHCP::log_info$circuit_id = sub_opt$value;
else if ( sub_opt$code == 2 )
DHCP::log_info$agent_remote_id = sub_opt$value;
else if ( sub_opt$code == 6 )
DHCP::log_info$subscriber_id = sub_opt$value;
}
}
}