mirror of
https://github.com/zeek/zeek.git
synced 2025-10-17 14:08:20 +00:00
Rework the DHCP analyzer to make it compatible again.
This commit is contained in:
parent
7838113dc2
commit
deeb5ec38e
14 changed files with 623 additions and 275 deletions
|
@ -36,6 +36,7 @@
|
|||
@load base/frameworks/tunnels
|
||||
|
||||
@load base/protocols/conn
|
||||
@load base/protocols/dhcp
|
||||
@load base/protocols/dns
|
||||
@load base/protocols/ftp
|
||||
@load base/protocols/http
|
||||
|
|
2
scripts/base/protocols/dhcp/__load__.bro
Normal file
2
scripts/base/protocols/dhcp/__load__.bro
Normal file
|
@ -0,0 +1,2 @@
|
|||
@load ./consts
|
||||
@load ./main
|
20
scripts/base/protocols/dhcp/consts.bro
Normal file
20
scripts/base/protocols/dhcp/consts.bro
Normal file
|
@ -0,0 +1,20 @@
|
|||
##! Types, errors, and fields for analyzing DHCP data. A helper file
|
||||
##! for DHCP analysis scripts.
|
||||
|
||||
module DHCP;
|
||||
|
||||
export {
|
||||
|
||||
## Types of DHCP messages. See RFC 1533.
|
||||
const message_types = {
|
||||
[1] = "DHCP_DISCOVER",
|
||||
[2] = "DHCP_OFFER",
|
||||
[3] = "DHCP_REQUEST",
|
||||
[4] = "DHCP_DECLINE",
|
||||
[5] = "DHCP_ACK",
|
||||
[6] = "DHCP_NAK",
|
||||
[7] = "DHCP_RELEASE",
|
||||
[8] = "DHCP_INFORM",
|
||||
} &default = function(n: count): string { return fmt("unknown-message-type-%d", n); };
|
||||
|
||||
}
|
74
scripts/base/protocols/dhcp/main.bro
Normal file
74
scripts/base/protocols/dhcp/main.bro
Normal file
|
@ -0,0 +1,74 @@
|
|||
##! Analyzes DHCP traffic in order to log DHCP leases given to clients.
|
||||
##! This script ignores large swaths of the protocol, since it is rather
|
||||
##! noisy on most networks, and focuses on the end-result: assigned leases.
|
||||
##!
|
||||
##! To enable further analysis and log output for DHCP, see the optional
|
||||
##! scripts in the policy/protocols/dhcp directory.
|
||||
|
||||
@load ./utils.bro
|
||||
|
||||
module DHCP;
|
||||
|
||||
export {
|
||||
redef enum Log::ID += { LOG };
|
||||
|
||||
## The record type which contains the column fields of the DHCP log.
|
||||
type Info: record {
|
||||
## The earliest time at which a DHCP message over the
|
||||
## associated connection is observed.
|
||||
ts: time &log;
|
||||
## A unique identifier of the connection over which DHCP is
|
||||
## occuring.
|
||||
uid: string &log;
|
||||
## The connection's 4-tuple of endpoint addresses/ports.
|
||||
id: conn_id &log;
|
||||
## Client's hardware address.
|
||||
mac: string &log &optional;
|
||||
## Client's actual assigned IP address.
|
||||
assigned_ip: addr &log &optional;
|
||||
## IP address lease interval.
|
||||
lease_time: interval &log &optional;
|
||||
## A random number choosen by the client for this transaction.
|
||||
trans_id: count &log;
|
||||
};
|
||||
|
||||
## Event that can be handled to access the DHCP
|
||||
## record as it is sent on to the logging framework.
|
||||
global log_dhcp: event(rec: Info);
|
||||
}
|
||||
|
||||
# Add the dhcp info to the connection record
|
||||
redef record connection += {
|
||||
dhcp: Info &optional;
|
||||
};
|
||||
|
||||
const ports = { 67/udp, 68/udp };
|
||||
redef likely_server_ports += { 67/udp };
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(DHCP::LOG, [$columns=Info, $ev=log_dhcp]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_DHCP, ports);
|
||||
}
|
||||
|
||||
event dhcp_ack(c: connection, msg: dhcp_msg, mask: addr, router: dhcp_router_list, lease: interval, serv_addr: addr, host_name: string) &priority=5
|
||||
{
|
||||
local info: Info;
|
||||
info$ts = network_time();
|
||||
info$id = c$id;
|
||||
info$uid = c$uid;
|
||||
info$assigned_ip = reverse_ip(msg$yiaddr);
|
||||
info$lease_time = lease;
|
||||
info$trans_id = msg$xid;
|
||||
|
||||
if ( msg$h_addr != "" )
|
||||
info$mac = msg$h_addr;
|
||||
|
||||
c$dhcp = info;
|
||||
}
|
||||
|
||||
# We let policy scripts add stuff too, so we run this at a lower priority
|
||||
event dhcp_ack(c: connection, msg: dhcp_msg, mask: addr, router: dhcp_router_list, lease: interval, serv_addr: addr, host_name: string) &priority=1
|
||||
{
|
||||
Log::write(DHCP::LOG, c$dhcp);
|
||||
}
|
21
scripts/base/protocols/dhcp/utils.bro
Normal file
21
scripts/base/protocols/dhcp/utils.bro
Normal file
|
@ -0,0 +1,21 @@
|
|||
##! Utilities specific for DHCP processing.
|
||||
|
||||
@load ./main
|
||||
|
||||
module DHCP;
|
||||
|
||||
export {
|
||||
## Reverse the octets of an IPv4 IP.
|
||||
##
|
||||
## ip: An :bro:type:`addr` IPv4 address.
|
||||
##
|
||||
## Returns: A reversed addr.
|
||||
global reverse_ip: function(ip: addr): addr;
|
||||
}
|
||||
|
||||
function reverse_ip(ip: addr): addr
|
||||
{
|
||||
local octets = split(cat(ip), /\./);
|
||||
return to_addr(cat(octets[4], ".", octets[3], ".", octets[2], ".", octets[1]));
|
||||
}
|
||||
|
256
scripts/policy/protocols/dhcp/handle_extra_msg_types.bro
Normal file
256
scripts/policy/protocols/dhcp/handle_extra_msg_types.bro
Normal file
|
@ -0,0 +1,256 @@
|
|||
##! Handlers for DHCP message types other than DHCPACK, which is handled in base/protocols/dhcp.
|
||||
##! For networks that wish to get more details from their DHCP logs, at the expense
|
||||
##! of a significantly higher log rate.
|
||||
|
||||
@load base/protocols/dhcp
|
||||
|
||||
module DHCP;
|
||||
|
||||
export {
|
||||
redef record Info += {
|
||||
## The value of the host name option, if seen
|
||||
host_name: string &log &optional;
|
||||
## The IP requested by the client, if any
|
||||
requested_ip: addr &log &optional;
|
||||
## The type of the DHCP message (DHCPOFFER, DHCPRELEASE, etc.)
|
||||
msg_type: string &log &optional;
|
||||
};
|
||||
|
||||
#### Enabled by default
|
||||
|
||||
## A boolean value to determine if DHCPREQUEST messages are logged.
|
||||
## Often useful to see client activity, and because host_name is often available.
|
||||
const log_dhcprequest = T &redef;
|
||||
|
||||
## A boolean value to determine if DHCPDECLINE messages are logged.
|
||||
## A client declines a lease if it detects that the IP is already in use (usually via ARP).
|
||||
const log_dhcpdecline = T &redef;
|
||||
|
||||
## A boolean value to determine if DHCPNAK messages are logged.
|
||||
## A server issues a DHCPNAK if a client DHCPREQUEST is invalid.
|
||||
const log_dhcpnak = T &redef;
|
||||
|
||||
## A boolean value to determine if DHCPRELEASE messages are logged.
|
||||
## A client issues a DHCPRELEASE when it no longer needs the lease (e.g. it's shutting down).
|
||||
const log_dhcprelease = T &redef;
|
||||
|
||||
#### Not enabled by default
|
||||
|
||||
## A boolean value to determine if DHCPOFFER messages are logged.
|
||||
## Used to profile server -> client communication.
|
||||
const log_dhcpoffer = F &redef;
|
||||
|
||||
## A boolean value to determine if DHCPDISCOVER messages are logged.
|
||||
## Used to profile broadcast client discovery requests.
|
||||
const log_dhcpdiscover = F &redef;
|
||||
|
||||
## A boolean value to determine if DHCPINFORM messages are logged.
|
||||
## Used to profile clients attempting to request/renew specific IPs.
|
||||
const log_dhcpinform = F &redef;
|
||||
|
||||
}
|
||||
|
||||
event dhcp_offer(c: connection, msg: dhcp_msg, mask: addr, router: dhcp_router_list, lease: interval, serv_addr: addr, host_name: string) &priority=5
|
||||
{
|
||||
if ( ! log_dhcpoffer )
|
||||
return;
|
||||
|
||||
local info: Info;
|
||||
info$ts = network_time();
|
||||
info$id = c$id;
|
||||
info$uid = c$uid;
|
||||
info$assigned_ip = reverse_ip(msg$yiaddr);
|
||||
info$lease_time = lease;
|
||||
info$trans_id = msg$xid;
|
||||
info$msg_type = "DHCPOFFER";
|
||||
|
||||
if ( msg$h_addr != "" )
|
||||
info$mac = msg$h_addr;
|
||||
|
||||
if ( host_name != "" )
|
||||
info$host_name = host_name;
|
||||
|
||||
c$dhcp = info;
|
||||
}
|
||||
|
||||
event dhcp_discover(c: connection, msg: dhcp_msg, req_addr: addr, host_name: string) &priority=5
|
||||
{
|
||||
if ( ! log_dhcpdiscover )
|
||||
return;
|
||||
|
||||
local info: Info;
|
||||
info$ts = network_time();
|
||||
info$id = c$id;
|
||||
info$uid = c$uid;
|
||||
info$requested_ip = req_addr;
|
||||
info$trans_id = msg$xid;
|
||||
info$msg_type = "DHCPDISCOVER";
|
||||
|
||||
if ( msg$h_addr != "" )
|
||||
info$mac = msg$h_addr;
|
||||
|
||||
if ( host_name != "" )
|
||||
info$host_name = host_name;
|
||||
|
||||
c$dhcp = info;
|
||||
}
|
||||
|
||||
event dhcp_request(c: connection, msg: dhcp_msg, req_addr: addr, serv_addr: addr, host_name: string) &priority=5
|
||||
{
|
||||
if ( ! log_dhcprequest )
|
||||
return;
|
||||
|
||||
local info: Info;
|
||||
info$ts = network_time();
|
||||
info$id = c$id;
|
||||
info$uid = c$uid;
|
||||
info$requested_ip = req_addr;
|
||||
info$trans_id = msg$xid;
|
||||
info$msg_type = "DHCPREQUEST";
|
||||
|
||||
if ( msg$h_addr != "" )
|
||||
info$mac = msg$h_addr;
|
||||
|
||||
if ( host_name != "" )
|
||||
info$host_name = host_name;
|
||||
|
||||
c$dhcp = info;
|
||||
}
|
||||
|
||||
event dhcp_decline(c: connection, msg: dhcp_msg, host_name: string) &priority=5
|
||||
{
|
||||
if ( ! log_dhcpdecline )
|
||||
return;
|
||||
|
||||
local info: Info;
|
||||
info$ts = network_time();
|
||||
info$id = c$id;
|
||||
info$uid = c$uid;
|
||||
info$trans_id = msg$xid;
|
||||
info$msg_type = "DHCPDECLINE";
|
||||
|
||||
if ( msg$h_addr != "" )
|
||||
info$mac = msg$h_addr;
|
||||
|
||||
if ( host_name != "" )
|
||||
info$host_name = host_name;
|
||||
|
||||
c$dhcp = info;
|
||||
}
|
||||
|
||||
event dhcp_nak(c: connection, msg: dhcp_msg, host_name: string) &priority=5
|
||||
{
|
||||
if ( ! log_dhcpnak )
|
||||
return;
|
||||
|
||||
local info: Info;
|
||||
info$ts = network_time();
|
||||
info$id = c$id;
|
||||
info$uid = c$uid;
|
||||
info$trans_id = msg$xid;
|
||||
info$msg_type = "DHCPNAK";
|
||||
|
||||
if ( msg$h_addr != "" )
|
||||
info$mac = msg$h_addr;
|
||||
|
||||
if ( host_name != "" )
|
||||
info$host_name = host_name;
|
||||
|
||||
c$dhcp = info;
|
||||
}
|
||||
|
||||
event dhcp_release(c: connection, msg: dhcp_msg, host_name: string) &priority=5
|
||||
{
|
||||
if ( ! log_dhcprelease )
|
||||
return;
|
||||
|
||||
local info: Info;
|
||||
info$ts = network_time();
|
||||
info$id = c$id;
|
||||
info$uid = c$uid;
|
||||
info$trans_id = msg$xid;
|
||||
info$msg_type = "DHCPRELEASE";
|
||||
|
||||
if ( msg$h_addr != "" )
|
||||
info$mac = msg$h_addr;
|
||||
|
||||
if ( host_name != "" )
|
||||
info$host_name = host_name;
|
||||
|
||||
c$dhcp = info;
|
||||
}
|
||||
|
||||
event dhcp_inform(c: connection, msg: dhcp_msg, host_name: string) &priority=5
|
||||
{
|
||||
if ( ! log_dhcpinform )
|
||||
return;
|
||||
|
||||
local info: Info;
|
||||
info$ts = network_time();
|
||||
info$id = c$id;
|
||||
info$uid = c$uid;
|
||||
info$trans_id = msg$xid;
|
||||
info$msg_type = "DHCPINFORM";
|
||||
|
||||
if ( msg$h_addr != "" )
|
||||
info$mac = msg$h_addr;
|
||||
|
||||
if ( host_name != "" )
|
||||
info$host_name = host_name;
|
||||
|
||||
c$dhcp = info;
|
||||
}
|
||||
|
||||
event dhcp_ack(c: connection, msg: dhcp_msg, mask: addr, router: dhcp_router_list, lease: interval, serv_addr: addr, host_name: string) &priority=4
|
||||
{
|
||||
## For the sake of consistency, let's add msg_type to DHCPACK as well.
|
||||
c$dhcp$msg_type = "DHCPACK";
|
||||
## host_name is generally not in ACKs, but let's check anyway.
|
||||
if ( host_name != "" )
|
||||
c$dhcp$host_name = host_name;
|
||||
}
|
||||
|
||||
#### We log stuff at a lower priority, in case any other scripts would like to extend the Info record first.
|
||||
|
||||
event dhcp_offer(c: connection, msg: dhcp_msg, mask: addr, router: dhcp_router_list, lease: interval, serv_addr: addr, host_name: string) &priority=1
|
||||
{
|
||||
if ( log_dhcpoffer )
|
||||
Log::write(DHCP::LOG, c$dhcp);
|
||||
}
|
||||
|
||||
event dhcp_discover(c: connection, msg: dhcp_msg, req_addr: addr, host_name: string) &priority=1
|
||||
{
|
||||
if ( log_dhcpdiscover )
|
||||
Log::write(DHCP::LOG, c$dhcp);
|
||||
}
|
||||
|
||||
event dhcp_request(c: connection, msg: dhcp_msg, req_addr: addr, serv_addr: addr, host_name: string) &priority=1
|
||||
{
|
||||
if ( log_dhcprequest )
|
||||
Log::write(DHCP::LOG, c$dhcp);
|
||||
}
|
||||
|
||||
event dhcp_decline(c: connection, msg: dhcp_msg, host_name: string) &priority=1
|
||||
{
|
||||
if ( log_dhcpdecline )
|
||||
Log::write(DHCP::LOG, c$dhcp);
|
||||
}
|
||||
|
||||
event dhcp_nak(c: connection, msg: dhcp_msg, host_name: string) &priority=1
|
||||
{
|
||||
if ( log_dhcpnak )
|
||||
Log::write(DHCP::LOG, c$dhcp);
|
||||
}
|
||||
|
||||
event dhcp_release(c: connection, msg: dhcp_msg, host_name: string) &priority=1
|
||||
{
|
||||
if ( log_dhcprelease )
|
||||
Log::write(DHCP::LOG, c$dhcp);
|
||||
}
|
||||
|
||||
event dhcp_inform(c: connection, msg: dhcp_msg, host_name: string) &priority=1
|
||||
{
|
||||
if ( log_dhcpinform )
|
||||
Log::write(DHCP::LOG, c$dhcp);
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue