Introduce dedicated LDAP::Info

This commit is contained in:
Benjamin Bannier 2023-10-10 14:25:22 +02:00
parent 301d8722bf
commit 346d2c49a9
2 changed files with 79 additions and 75 deletions

View file

@ -7,8 +7,7 @@
module LDAP; module LDAP;
export { export {
redef enum Log::ID += { LDAP_LOG, redef enum Log::ID += { LDAP_LOG, LDAP_SEARCH_LOG };
LDAP_SEARCH_LOG };
## TCP ports which should be considered for analysis. ## TCP ports which should be considered for analysis.
const ports_tcp = { 389/tcp, 3268/tcp } &redef; const ports_tcp = { 389/tcp, 3268/tcp } &redef;
@ -107,6 +106,13 @@ export {
attributes: vector of string &log &optional; attributes: vector of string &log &optional;
}; };
type State: record {
messages: table[int] of MessageInfo &optional;
searches: table[int] of SearchInfo &optional;
};
redef record connection += { ldap: State &optional; };
# Event that can be handled to access the ldap record as it is sent on # Event that can be handled to access the ldap record as it is sent on
# to the logging framework. # to the logging framework.
global log_ldap: event(rec: LDAP::MessageInfo); global log_ldap: event(rec: LDAP::MessageInfo);
@ -140,12 +146,6 @@ global OPCODES_SEARCH: set[LDAP::ProtocolOpcode] = { LDAP::ProtocolOpcode_SEARCH
LDAP::ProtocolOpcode_SEARCH_RESULT_DONE, LDAP::ProtocolOpcode_SEARCH_RESULT_DONE,
LDAP::ProtocolOpcode_SEARCH_RESULT_REFERENCE }; LDAP::ProtocolOpcode_SEARCH_RESULT_REFERENCE };
#############################################################################
redef record connection += {
ldap_messages: table[int] of MessageInfo &optional;
ldap_searches: table[int] of SearchInfo &optional;
};
############################################################################# #############################################################################
event zeek_init() &priority=5 { event zeek_init() &priority=5 {
Analyzer::register_for_ports(Analyzer::ANALYZER_LDAP_TCP, LDAP::ports_tcp); Analyzer::register_for_ports(Analyzer::ANALYZER_LDAP_TCP, LDAP::ports_tcp);
@ -159,21 +159,24 @@ event zeek_init() &priority=5 {
function set_session(c: connection, message_id: int, opcode: LDAP::ProtocolOpcode) { function set_session(c: connection, message_id: int, opcode: LDAP::ProtocolOpcode) {
Conn::register_removal_hook(c, finalize_ldap); Conn::register_removal_hook(c, finalize_ldap);
if (! c?$ldap_messages ) if (! c?$ldap )
c$ldap_messages = table(); c$ldap = State();
if (! c?$ldap_searches ) if (! c$ldap?$messages )
c$ldap_searches = table(); c$ldap$messages = table();
if ((opcode in OPCODES_SEARCH) && (message_id !in c$ldap_searches)) { if (! c$ldap?$searches )
c$ldap_searches[message_id] = [$ts=network_time(), c$ldap$searches = table();
if ((opcode in OPCODES_SEARCH) && (message_id !in c$ldap$searches)) {
c$ldap$searches[message_id] = [$ts=network_time(),
$uid=c$uid, $uid=c$uid,
$id=c$id, $id=c$id,
$message_id=message_id, $message_id=message_id,
$result_count=0]; $result_count=0];
} else if ((opcode !in OPCODES_SEARCH) && (message_id !in c$ldap_messages)) { } else if ((opcode !in OPCODES_SEARCH) && (message_id !in c$ldap$messages)) {
c$ldap_messages[message_id] = [$ts=network_time(), c$ldap$messages[message_id] = [$ts=network_time(),
$uid=c$uid, $uid=c$uid,
$id=c$id, $id=c$id,
$message_id=message_id]; $message_id=message_id];
@ -193,7 +196,7 @@ event LDAP::message(c: connection,
if (opcode == LDAP::ProtocolOpcode_SEARCH_RESULT_DONE) { if (opcode == LDAP::ProtocolOpcode_SEARCH_RESULT_DONE) {
set_session(c, message_id, opcode); set_session(c, message_id, opcode);
local searches = c$ldap_searches[message_id]; local searches = c$ldap$searches[message_id];
if ( result != LDAP::ResultCode_Undef ) { if ( result != LDAP::ResultCode_Undef ) {
if ( ! searches?$results ) if ( ! searches?$results )
@ -208,12 +211,12 @@ event LDAP::message(c: connection,
} }
Log::write(LDAP::LDAP_SEARCH_LOG, searches); Log::write(LDAP::LDAP_SEARCH_LOG, searches);
delete c$ldap_searches[message_id]; delete c$ldap$searches[message_id];
} else if (opcode !in OPCODES_SEARCH) { } else if (opcode !in OPCODES_SEARCH) {
set_session(c, message_id, opcode); set_session(c, message_id, opcode);
local messages = c$ldap_messages[message_id]; local messages = c$ldap$messages[message_id];
if ( ! messages?$opcodes ) if ( ! messages?$opcodes )
messages$opcodes = set(); messages$opcodes = set();
@ -255,7 +258,7 @@ event LDAP::message(c: connection,
} }
Log::write(LDAP::LDAP_LOG, messages); Log::write(LDAP::LDAP_LOG, messages);
delete c$ldap_messages[message_id]; delete c$ldap$messages[message_id];
} }
} }
@ -276,26 +279,26 @@ event LDAP::searchreq(c: connection,
set_session(c, message_id, LDAP::ProtocolOpcode_SEARCH_REQUEST); set_session(c, message_id, LDAP::ProtocolOpcode_SEARCH_REQUEST);
if ( scope != LDAP::SearchScope_Undef ) { if ( scope != LDAP::SearchScope_Undef ) {
if ( ! c$ldap_searches[message_id]?$scopes ) if ( ! c$ldap$searches[message_id]?$scopes )
c$ldap_searches[message_id]$scopes = set(); c$ldap$searches[message_id]$scopes = set();
add c$ldap_searches[message_id]$scopes[SEARCH_SCOPES[scope]]; add c$ldap$searches[message_id]$scopes[SEARCH_SCOPES[scope]];
} }
if ( deref != LDAP::SearchDerefAlias_Undef ) { if ( deref != LDAP::SearchDerefAlias_Undef ) {
if ( ! c$ldap_searches[message_id]?$derefs ) if ( ! c$ldap$searches[message_id]?$derefs )
c$ldap_searches[message_id]$derefs = set(); c$ldap$searches[message_id]$derefs = set();
add c$ldap_searches[message_id]$derefs[SEARCH_DEREF_ALIASES[deref]]; add c$ldap$searches[message_id]$derefs[SEARCH_DEREF_ALIASES[deref]];
} }
if ( base_object != "" ) { if ( base_object != "" ) {
if ( ! c$ldap_searches[message_id]?$base_objects ) if ( ! c$ldap$searches[message_id]?$base_objects )
c$ldap_searches[message_id]$base_objects = vector(); c$ldap$searches[message_id]$base_objects = vector();
c$ldap_searches[message_id]$base_objects += base_object; c$ldap$searches[message_id]$base_objects += base_object;
} }
c$ldap_searches[message_id]$filter = filter; c$ldap$searches[message_id]$filter = filter;
if ( default_log_search_attributes ) { if ( default_log_search_attributes ) {
c$ldap_searches[message_id]$attributes = attributes; c$ldap$searches[message_id]$attributes = attributes;
} }
} }
@ -306,7 +309,7 @@ event LDAP::searchres(c: connection,
set_session(c, message_id, LDAP::ProtocolOpcode_SEARCH_RESULT_ENTRY); set_session(c, message_id, LDAP::ProtocolOpcode_SEARCH_RESULT_ENTRY);
c$ldap_searches[message_id]$result_count += 1; c$ldap$searches[message_id]$result_count += 1;
} }
############################################################################# #############################################################################
@ -316,29 +319,27 @@ event LDAP::bindreq(c: connection,
name: string, name: string,
authType: LDAP::BindAuthType, authType: LDAP::BindAuthType,
authInfo: string) { authInfo: string) {
set_session(c, message_id, LDAP::ProtocolOpcode_BIND_REQUEST); set_session(c, message_id, LDAP::ProtocolOpcode_BIND_REQUEST);
if ( ! c$ldap_messages[message_id]?$version ) if ( ! c$ldap$messages[message_id]?$version )
c$ldap_messages[message_id]$version = version; c$ldap$messages[message_id]$version = version;
if ( ! c$ldap_messages[message_id]?$opcodes ) if ( ! c$ldap$messages[message_id]?$opcodes )
c$ldap_messages[message_id]$opcodes = set(); c$ldap$messages[message_id]$opcodes = set();
if (authType == LDAP::BindAuthType_BIND_AUTH_SIMPLE) { if (authType == LDAP::BindAuthType_BIND_AUTH_SIMPLE) {
add c$ldap_messages[message_id]$opcodes[BIND_SIMPLE]; add c$ldap$messages[message_id]$opcodes[BIND_SIMPLE];
} else if (authType == LDAP::BindAuthType_BIND_AUTH_SASL) { } else if (authType == LDAP::BindAuthType_BIND_AUTH_SASL) {
add c$ldap_messages[message_id]$opcodes[BIND_SASL]; add c$ldap$messages[message_id]$opcodes[BIND_SASL];
} }
} }
############################################################################# #############################################################################
hook finalize_ldap(c: connection) { hook finalize_ldap(c: connection) {
# log any "pending" unlogged LDAP messages/searches # log any "pending" unlogged LDAP messages/searches
if ( c?$ldap_messages && (|c$ldap_messages| > 0) ) { if ( c$ldap?$messages && (|c$ldap$messages| > 0) ) {
for ( [mid], m in c$ldap_messages ) { for ( [mid], m in c$ldap$messages ) {
if (mid > 0) { if (mid > 0) {
if ((BIND_SIMPLE in m$opcodes) || (BIND_SASL in m$opcodes)) { if ((BIND_SIMPLE in m$opcodes) || (BIND_SASL in m$opcodes)) {
@ -349,16 +350,16 @@ hook finalize_ldap(c: connection) {
Log::write(LDAP::LDAP_LOG, m); Log::write(LDAP::LDAP_LOG, m);
} }
} }
delete c$ldap_messages; delete c$ldap$messages;
} }
if ( c?$ldap_searches && (|c$ldap_searches| > 0) ) { if ( c$ldap?$searches && (|c$ldap$searches| > 0) ) {
for ( [mid], s in c$ldap_searches ) { for ( [mid], s in c$ldap$searches ) {
if (mid > 0) { if (mid > 0) {
Log::write(LDAP::LDAP_SEARCH_LOG, s); Log::write(LDAP::LDAP_SEARCH_LOG, s);
} }
} }
delete c$ldap_searches; delete c$ldap$searches;
} }
} }

View file

@ -360,7 +360,9 @@ connection {
* ts: time, log=T, optional=F * ts: time, log=T, optional=F
* uid: string, log=T, optional=F * uid: string, log=T, optional=F
} }
* ldap_messages: table[int] of record LDAP::MessageInfo, log=F, optional=T * ldap: record LDAP::State, log=F, optional=T
LDAP::State {
* messages: table[int] of record LDAP::MessageInfo, log=F, optional=T
LDAP::MessageInfo { LDAP::MessageInfo {
* arguments: vector of string, log=T, optional=T * arguments: vector of string, log=T, optional=T
* diagnostic_messages: vector of string, log=T, optional=T * diagnostic_messages: vector of string, log=T, optional=T
@ -374,7 +376,7 @@ connection {
* uid: string, log=T, optional=F * uid: string, log=T, optional=F
* version: int, log=T, optional=T * version: int, log=T, optional=T
} }
* ldap_searches: table[int] of record LDAP::SearchInfo, log=F, optional=T * searches: table[int] of record LDAP::SearchInfo, log=F, optional=T
LDAP::SearchInfo { LDAP::SearchInfo {
* attributes: vector of string, log=T, optional=T * attributes: vector of string, log=T, optional=T
* base_objects: vector of string, log=T, optional=T * base_objects: vector of string, log=T, optional=T
@ -390,6 +392,7 @@ connection {
* ts: time, log=T, optional=F * ts: time, log=T, optional=F
* uid: string, log=T, optional=F * uid: string, log=T, optional=F
} }
}
* modbus: record Modbus::Info, log=F, optional=T * modbus: record Modbus::Info, log=F, optional=T
Modbus::Info { Modbus::Info {
* exception: string, log=T, optional=T * exception: string, log=T, optional=T