mirror of
https://github.com/zeek/zeek.git
synced 2025-10-07 17:18:20 +00:00
Updates to NTLM script handling.
- This separates NTLM handling away from SMB. - It logs more accurately when logins are succeed or fail or even if the resulting status of an authentication is unknown. - Adds some new fields where the server is indicating information about itself (server_nb_computer_name, server_dns_computer_name, and server_tree_name)
This commit is contained in:
parent
f6e5f0b1a5
commit
be9f97d8b4
1 changed files with 33 additions and 50 deletions
|
@ -1,4 +1,3 @@
|
||||||
@load base/protocols/smb
|
|
||||||
@load base/frameworks/dpd
|
@load base/frameworks/dpd
|
||||||
|
|
||||||
module NTLM;
|
module NTLM;
|
||||||
|
@ -21,32 +20,20 @@ export {
|
||||||
## Domainname given by the client.
|
## Domainname given by the client.
|
||||||
domainname : string &log &optional;
|
domainname : string &log &optional;
|
||||||
|
|
||||||
|
## NetBIOS name given by the server in a CHALLENGE.
|
||||||
|
server_nb_computer_name: string &log &optional;
|
||||||
|
## DNS name given by the server in a CHALLENGE.
|
||||||
|
server_dns_computer_name: string &log &optional;
|
||||||
|
## Tree name given by the server in a CHALLENGE.
|
||||||
|
server_tree_name: string &log &optional;
|
||||||
|
|
||||||
## Indicate whether or not the authentication was successful.
|
## Indicate whether or not the authentication was successful.
|
||||||
success : bool &log &optional;
|
success : bool &log &optional;
|
||||||
## A string representation of the status code that was
|
|
||||||
## returned in response to the authentication attempt.
|
|
||||||
status : string &log &optional;
|
|
||||||
|
|
||||||
## Internally used field to indicate if the login attempt
|
## Internally used field to indicate if the login attempt
|
||||||
## has already been logged.
|
## has already been logged.
|
||||||
done: bool &default=F;
|
done: bool &default=F;
|
||||||
};
|
};
|
||||||
|
|
||||||
## DOS and NT status codes that indicate authentication failure.
|
|
||||||
const auth_failure_statuses: set[count] = {
|
|
||||||
0x052e0001, # logonfailure
|
|
||||||
0x08c00002, # badClient
|
|
||||||
0x08c10002, # badLogonTime
|
|
||||||
0x08c20002, # passwordExpired
|
|
||||||
0xC0000022, # ACCESS_DENIED
|
|
||||||
0xC0000061, # PRIVILEGE_NOT_HELD
|
|
||||||
0xC000006A, # WRONG_PASSWORD
|
|
||||||
0xC000006D, # LOGON_FAILURE
|
|
||||||
0xC000006F, # INVALID_LOGON_HOURS
|
|
||||||
0xC0000070, # INVALID_WORKSTATION
|
|
||||||
0xC0000071, # PASSWORD_EXPIRED
|
|
||||||
0xC0000072, # ACCOUNT_DISABLED
|
|
||||||
} &redef;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
redef DPD::ignore_violations += { Analyzer::ANALYZER_NTLM };
|
redef DPD::ignore_violations += { Analyzer::ANALYZER_NTLM };
|
||||||
|
@ -60,17 +47,37 @@ event bro_init() &priority=5
|
||||||
Log::create_stream(NTLM::LOG, [$columns=Info, $path="ntlm"]);
|
Log::create_stream(NTLM::LOG, [$columns=Info, $path="ntlm"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function set_session(c: connection)
|
||||||
|
{
|
||||||
|
if ( ! c?$ntlm )
|
||||||
|
c$ntlm = NTLM::Info($ts=network_time(), $uid=c$uid, $id=c$id);
|
||||||
|
}
|
||||||
|
|
||||||
event ntlm_negotiate(c: connection, request: NTLM::Negotiate) &priority=5
|
event ntlm_negotiate(c: connection, request: NTLM::Negotiate) &priority=5
|
||||||
{
|
{
|
||||||
|
set_session(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
event ntlm_challenge(c: connection, challenge: NTLM::Challenge) &priority=5
|
event ntlm_challenge(c: connection, challenge: NTLM::Challenge) &priority=5
|
||||||
{
|
{
|
||||||
|
set_session(c);
|
||||||
|
|
||||||
|
if ( challenge?$target_info )
|
||||||
|
{
|
||||||
|
local ti = challenge$target_info;
|
||||||
|
if ( ti?$nb_domain_name )
|
||||||
|
c$ntlm$server_nb_computer_name = ti$nb_computer_name;
|
||||||
|
if ( ti?$dns_domain_name )
|
||||||
|
c$ntlm$server_dns_computer_name = ti$dns_computer_name;
|
||||||
|
if ( ti?$dns_tree_name )
|
||||||
|
c$ntlm$server_tree_name = ti$dns_tree_name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event ntlm_authenticate(c: connection, request: NTLM::Authenticate) &priority=5
|
event ntlm_authenticate(c: connection, request: NTLM::Authenticate) &priority=5
|
||||||
{
|
{
|
||||||
c$ntlm = NTLM::Info($ts=network_time(), $uid=c$uid, $id=c$id);
|
set_session(c);
|
||||||
|
|
||||||
if ( request?$domain_name )
|
if ( request?$domain_name )
|
||||||
c$ntlm$domainname = request$domain_name;
|
c$ntlm$domainname = request$domain_name;
|
||||||
if ( request?$workstation )
|
if ( request?$workstation )
|
||||||
|
@ -81,7 +88,8 @@ event ntlm_authenticate(c: connection, request: NTLM::Authenticate) &priority=5
|
||||||
|
|
||||||
event gssapi_neg_result(c: connection, state: count) &priority=3
|
event gssapi_neg_result(c: connection, state: count) &priority=3
|
||||||
{
|
{
|
||||||
if ( c?$ntlm )
|
# Ignore "incomplete" replies (state==1)
|
||||||
|
if ( c?$ntlm && state != 1 )
|
||||||
c$ntlm$success = (state == 0);
|
c$ntlm$success = (state == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +97,8 @@ event gssapi_neg_result(c: connection, state: count) &priority=-3
|
||||||
{
|
{
|
||||||
if ( c?$ntlm && ! c$ntlm$done )
|
if ( c?$ntlm && ! c$ntlm$done )
|
||||||
{
|
{
|
||||||
if ( c$ntlm?$username || c$ntlm?$hostname )
|
# Only write if success is actually set to something...
|
||||||
|
if ( c$ntlm?$success )
|
||||||
{
|
{
|
||||||
Log::write(NTLM::LOG, c$ntlm);
|
Log::write(NTLM::LOG, c$ntlm);
|
||||||
c$ntlm$done = T;
|
c$ntlm$done = T;
|
||||||
|
@ -97,32 +106,6 @@ event gssapi_neg_result(c: connection, state: count) &priority=-3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event smb1_message(c: connection, hdr: SMB1::Header, is_orig: bool) &priority=3
|
|
||||||
{
|
|
||||||
if ( c?$ntlm && ! c$ntlm$done &&
|
|
||||||
( c$ntlm?$username || c$ntlm?$hostname ) )
|
|
||||||
{
|
|
||||||
c$ntlm$success = (hdr$status !in auth_failure_statuses);
|
|
||||||
c$ntlm$status = SMB::statuses[hdr$status]$id;
|
|
||||||
|
|
||||||
Log::write(NTLM::LOG, c$ntlm);
|
|
||||||
c$ntlm$done = T;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
event smb2_message(c: connection, hdr: SMB2::Header, is_orig: bool) &priority=3
|
|
||||||
{
|
|
||||||
if ( c?$ntlm && ! c$ntlm$done &&
|
|
||||||
( c$ntlm?$username || c$ntlm?$hostname ) )
|
|
||||||
{
|
|
||||||
c$ntlm$success = (hdr$status !in auth_failure_statuses);
|
|
||||||
c$ntlm$status = SMB::statuses[hdr$status]$id;
|
|
||||||
|
|
||||||
Log::write(NTLM::LOG, c$ntlm);
|
|
||||||
c$ntlm$done = T;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
event connection_state_remove(c: connection) &priority=-5
|
event connection_state_remove(c: connection) &priority=-5
|
||||||
{
|
{
|
||||||
if ( c?$ntlm && ! c$ntlm$done )
|
if ( c?$ntlm && ! c$ntlm$done )
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue