mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
155 lines
3.9 KiB
Text
155 lines
3.9 KiB
Text
# $Id: pop3.bro 4758 2007-08-10 06:49:23Z vern $
|
|
#
|
|
# Analyzer for Post Office Protocol, version 3.
|
|
#
|
|
# If you want to decode the mail itself, also load mime-pop.bro.
|
|
|
|
@load login
|
|
|
|
module POP3;
|
|
|
|
export {
|
|
# Report if source triggers more ERR messages.
|
|
const error_threshold: count = 3 &redef;
|
|
# Don't log these commands.
|
|
const ignore_commands: set[string] = { "STAT" } &redef;
|
|
}
|
|
|
|
redef capture_filters += { ["pop3"] = "port 110" };
|
|
|
|
global pop3_ports = { 110/tcp } &redef;
|
|
redef dpd_config += { [ANALYZER_POP3] = [$ports = pop3_ports] };
|
|
|
|
const log_file = open_log_file("pop3") &redef;
|
|
|
|
type pop3_session_info: record {
|
|
id: count; # Unique session ID.
|
|
quit_sent: bool; # Client issued a QUIT.
|
|
last_command: string; # Last command of client.
|
|
};
|
|
|
|
|
|
global pop_log: function(conn: pop3_session_info,
|
|
command: string, message: string);
|
|
global get_connection: function(id: conn_id): pop3_session_info;
|
|
|
|
|
|
global pop_connections:
|
|
table[conn_id] of pop3_session_info &read_expire = 60 mins;
|
|
global pop_connection_weirds:
|
|
table[addr] of count &default=0 &read_expire = 60 mins;
|
|
global pop_session_id = 0;
|
|
|
|
|
|
event pop3_request(c: connection, is_orig: bool, command: string, arg: string)
|
|
{
|
|
local conn = get_connection(c$id);
|
|
|
|
pop_log(conn, command, fmt("%.6f #%s > %s %s",
|
|
network_time(), prefixed_id(conn$id), command, arg));
|
|
|
|
conn$last_command = command;
|
|
|
|
if ( command == "QUIT" )
|
|
conn$quit_sent = T;
|
|
}
|
|
|
|
event pop3_reply(c: connection, is_orig: bool, cmd: string, msg: string)
|
|
{
|
|
local conn = get_connection(c$id);
|
|
|
|
pop_log(conn, cmd,
|
|
fmt("%.6f #%s < %s %s", network_time(), prefixed_id(conn$id), cmd, msg));
|
|
|
|
if ( cmd == "OK" )
|
|
{
|
|
if ( conn$quit_sent )
|
|
delete pop_connections[c$id];
|
|
}
|
|
|
|
else if ( cmd == "ERR" )
|
|
{
|
|
++pop_connection_weirds[c$id$orig_h];
|
|
if ( pop_connection_weirds[c$id$orig_h] > error_threshold )
|
|
print log_file, fmt("%.6f #%s %s/%d > %s/%d WARNING: error count exceeds threshold",
|
|
network_time(), prefixed_id(conn$id),
|
|
c$id$orig_h, c$id$orig_p,
|
|
c$id$resp_h, c$id$resp_p);
|
|
}
|
|
}
|
|
|
|
event pop3_login_success(c: connection, is_orig: bool,
|
|
user: string, password: string)
|
|
{
|
|
local conn = get_connection(c$id);
|
|
|
|
local pw = byte_len(password) != 0 ? password : "<not seen>";
|
|
|
|
print log_file, fmt("%.6f #%s > login successful: user %s password: %s",
|
|
network_time(), prefixed_id(conn$id), user, pw);
|
|
|
|
event login_success(c, user, "", password, "");
|
|
}
|
|
|
|
event pop3_login_failure(c: connection, is_orig: bool,
|
|
user: string, password: string)
|
|
{
|
|
local conn = get_connection(c$id);
|
|
|
|
print log_file, fmt("%.6f #%s > login failed: user %s password: %s",
|
|
network_time(), prefixed_id(conn$id), user, password);
|
|
|
|
event login_failure(c, user, "", password, "");
|
|
}
|
|
|
|
# event pop3_data(c: connection, is_orig: bool, data: string)
|
|
# {
|
|
# # We could instantiate partial connections here if we wished,
|
|
# # but at considerable cost in terms of event counts.
|
|
# local conn = get_connection(c$id);
|
|
# }
|
|
|
|
event pop3_unexpected(c: connection, is_orig: bool, msg: string, detail: string)
|
|
{
|
|
local conn = get_connection(c$id);
|
|
print log_file, fmt("%.6f #%s unexpected cmd: %s detail: %s",
|
|
network_time(), prefixed_id(conn$id),
|
|
msg, detail);
|
|
}
|
|
|
|
event pop3_terminate(c: connection, is_orig: bool, msg: string)
|
|
{
|
|
delete pop_connections[c$id];
|
|
}
|
|
|
|
|
|
function pop_log(conn: pop3_session_info, command: string, message: string)
|
|
{
|
|
if ( command !in ignore_commands )
|
|
{
|
|
if ( (command == "OK" || command == "ERR") &&
|
|
conn$last_command in ignore_commands )
|
|
;
|
|
else
|
|
print log_file, message;
|
|
}
|
|
}
|
|
|
|
function get_connection(id: conn_id): pop3_session_info
|
|
{
|
|
if ( id in pop_connections )
|
|
return pop_connections[id];
|
|
|
|
local conn: pop3_session_info;
|
|
|
|
conn$id = ++pop_session_id;
|
|
conn$quit_sent = F;
|
|
conn$last_command = "INIT";
|
|
pop_connections[id] = conn;
|
|
|
|
print log_file, fmt("%.6f #%s %s/%d > %s/%d: new connection",
|
|
network_time(), prefixed_id(conn$id),
|
|
id$orig_h, id$orig_p, id$resp_h, id$resp_p);
|
|
|
|
return conn;
|
|
}
|