zeek/scripts/base/protocols/dce-rpc/main.bro
Seth Hall 5721db4be7 Lots of cleanup and improvement to DCE/RPC analyzer.
- It works with DCE/RPC over SMB1+2 now.
   - Using named pipes in 1+2 and the transaction cmd in SMB1.
 - Base scripts based on work by Josh Liburdi.
 - New dce_rpc.log.  Feedback on how to make this log more compact
   and useful would be appreciated.
2016-04-01 09:38:52 -04:00

109 lines
No EOL
2.4 KiB
Text

@load ./consts
module DCE_RPC;
export {
redef enum Log::ID += { LOG };
type Info: record {
## Timestamp for when the event happened.
ts : time &log;
## Unique ID for the connection.
uid : string &log;
## The connection's 4-tuple of endpoint addresses/ports.
id : conn_id &log;
## Round trip time from the request to the response.
## If either the request or response wasn't seen,
## this will be null.
rtt : interval &log &optional;
## Remote pipe name.
named_pipe : string &log &optional;
## Endpoint name looked up from the uuid.
endpoint : string &log &optional;
## Operation seen in the call.
operation : string &log &optional;
};
## Set of interface UUID values to ignore.
const ignored_uuids = set("e1af8308-5d1f-11c9-91a4-08002b14a0fa") &redef;
}
redef record Info += {
uuid: string &optional;
};
redef record connection += {
dce_rpc: Info &optional;
};
const ports = { 135/tcp };
redef likely_server_ports += { ports };
event bro_init() &priority=5
{
Log::create_stream(DCE_RPC::LOG, [$columns=Info, $path="dce_rpc"]);
Analyzer::register_for_ports(Analyzer::ANALYZER_DCE_RPC, ports);
}
function set_session(c: connection)
{
if ( ! c?$dce_rpc )
{
c$dce_rpc = [$ts=network_time(),
$id=c$id,
$uid=c$uid];
}
}
event dce_rpc_bind(c: connection, uuid: string, version: string) &priority=5
{
set_session(c);
local uuid_str = uuid_to_string(uuid);
if ( uuid_str in ignored_uuids )
return;
c$dce_rpc$uuid = uuid_str;
c$dce_rpc$endpoint = uuid_endpoint_map[uuid_str];
}
event dce_rpc_bind_ack(c: connection, sec_addr: string) &priority=5
{
set_session(c);
if ( sec_addr != "" )
c$dce_rpc$named_pipe = sec_addr;
}
event dce_rpc_request(c: connection, opnum: count, stub: string) &priority=5
{
set_session(c);
if ( c?$dce_rpc && c$dce_rpc?$endpoint )
{
}
}
event dce_rpc_response(c: connection, opnum: count, stub: string) &priority=5
{
set_session(c);
if ( c?$dce_rpc && c$dce_rpc?$endpoint )
{
c$dce_rpc$operation = operations[c$dce_rpc$uuid, opnum];
if ( c$dce_rpc$ts != network_time() )
c$dce_rpc$rtt = network_time() - c$dce_rpc$ts;
Log::write(LOG, c$dce_rpc);
}
}
event connection_state_remove(c: connection)
{
if ( ! c?$dce_rpc )
return;
# TODO: Go through any remaining dce_rpc requests that haven't been processed with replies.
}