mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
276 lines
7.1 KiB
Text
276 lines
7.1 KiB
Text
# $Id: sensor-sshd.bro 4758 2007-08-10 06:49:23Z vern $
|
|
#
|
|
# sshd sensor input, i.e., events received from instrumented SSH servers
|
|
# that communicate with Bro via the Broccoli library.
|
|
|
|
# We leverage the login analyzer:
|
|
@load login
|
|
@load remote
|
|
|
|
# To prevent requesting sshd events from any peering Bro that connects,
|
|
# here is a list of our sshds. List the IP addresses of the hosts your
|
|
# sshds are running on here:
|
|
#
|
|
redef Remote::destinations += {
|
|
["sshd1"] = [$host = 127.0.0.1, $events = /sensor_sshd.*/, $connect=F, $ssl=F]
|
|
};
|
|
|
|
# A big log file for all kinds of notes:
|
|
#
|
|
global sshd_log: file = open_log_file("sshd");
|
|
|
|
# A record gathering everything we need to know per connection
|
|
# from an ssh client to the sshd:
|
|
#
|
|
type sshd_conn: record {
|
|
|
|
# Connection record we create for connections to sshd
|
|
conn: connection;
|
|
|
|
# A table indexed by channel numbers, yielding files.
|
|
# For each channel that contains a shell session this
|
|
# table contains a file to which the session content is
|
|
# logged.
|
|
sessions: table[count] of file;
|
|
};
|
|
|
|
# To avoid reporting IP/port quadruples repeatedly, connections in
|
|
# sshd are identified through a globally unique identifier for the
|
|
# sshd server (a string) plus an numerical identifier for each
|
|
# connection to that sshd.
|
|
#
|
|
global sshd_conns: table[string, count] of sshd_conn;
|
|
|
|
|
|
function sshd_conn_new(src_ip: addr, src_p: port,
|
|
dst_ip: addr, dst_p: port,
|
|
ts: time): sshd_conn
|
|
{
|
|
local id: conn_id;
|
|
id$orig_h = src_ip;
|
|
id$orig_p = src_p;
|
|
id$resp_h = dst_ip;
|
|
id$resp_p = dst_p;
|
|
|
|
local orig: endpoint;
|
|
local resp: endpoint;
|
|
orig$size = resp$size = 0;
|
|
orig$state = resp$state = 0;
|
|
|
|
local c: connection;
|
|
c$id = id;
|
|
c$orig = orig;
|
|
c$resp = resp;
|
|
c$start_time = ts;
|
|
c$duration = 0 sec;
|
|
|
|
# We mark this connection so the login analyzer can
|
|
# understand that it is a login session.
|
|
add c$service["ssh-login"];
|
|
|
|
c$addl = "";
|
|
c$hot = 0;
|
|
|
|
local sc: sshd_conn;
|
|
sc$conn = c;
|
|
|
|
return sc;
|
|
}
|
|
|
|
|
|
event sensor_sshd_listen(ts: time, sid: string,
|
|
server_ip: addr, server_p: port)
|
|
{
|
|
print sshd_log, fmt("[%D][%s:%s] sshd listening at %s:%d",
|
|
ts, get_event_peer()$host, sid, server_ip, server_p);
|
|
}
|
|
|
|
|
|
event sensor_sshd_restart(ts: time, sid: string)
|
|
{
|
|
print sshd_log, fmt("[%D][%s:%s] sshd %s restarted",
|
|
ts, get_event_peer()$host, sid, sid);
|
|
}
|
|
|
|
|
|
event sensor_sshd_exit(ts: time, sid: string)
|
|
{
|
|
print sshd_log, fmt("[%D][%s:%s] sshd %s exiting",
|
|
ts, get_event_peer()$host, sid, sid);
|
|
}
|
|
|
|
|
|
event sensor_sshd_conn_new(ts: time, sid: string, cid: count,
|
|
src_ip: addr, src_p: port,
|
|
dst_ip: addr, dst_p: port)
|
|
{
|
|
local sc = sshd_conn_new(src_ip, src_p, dst_ip, dst_p, ts);
|
|
sshd_conns[sid, cid] = sc;
|
|
print sshd_log, fmt("[%D][%s:%s:%d] conn attempt from %s:%d to %s:%d",
|
|
ts, get_event_peer()$host, sid, cid, src_ip, sc$conn$id$orig_p,
|
|
dst_ip, sc$conn$id$resp_p);
|
|
|
|
Login::new_login_session(sc$conn, get_event_peer()$id, 0);
|
|
}
|
|
|
|
|
|
event sensor_sshd_conn_end(ts: time, sid: string, cid: count)
|
|
{
|
|
local pid = get_event_peer()$id;
|
|
local sc = sshd_conns[sid, cid];
|
|
|
|
print sshd_log, fmt("[%D][%s:%s:%d] conn terminated",
|
|
ts, get_event_peer()$host, sid, cid);
|
|
|
|
Login::remove_login_session(sc$conn, pid);
|
|
delete sshd_conns[sid, cid];
|
|
}
|
|
|
|
|
|
event sensor_sshd_auth_ok(ts: time, sid: string, cid: count,
|
|
user: string, uid: int, gid: int)
|
|
{
|
|
local pid = get_event_peer()$id;
|
|
local sc = sshd_conns[sid, cid];
|
|
print sshd_log, fmt("[%D][%s:%s:%d] auth ok: %s (%d/%d)",
|
|
ts, get_event_peer()$host, sid, cid, user, uid, gid);
|
|
|
|
Login::ext_set_login_state(sc$conn$id, pid, LOGIN_STATE_LOGGED_IN);
|
|
event authentication_accepted(user, sc$conn);
|
|
}
|
|
|
|
|
|
event sensor_sshd_auth_failed(ts: time, sid: string, cid: count, user: string)
|
|
{
|
|
local sc = sshd_conns[sid, cid];
|
|
print sshd_log, fmt("[%D][%s:%s:%d] auth reject: user %s from %s:%d",
|
|
ts, get_event_peer()$host, sid, cid, user,
|
|
sc$conn$id$orig_h, sc$conn$id$orig_p);
|
|
|
|
event authentication_rejected(user, sc$conn);
|
|
}
|
|
|
|
|
|
event sensor_sshd_auth_timeout(ts: time, sid: string, cid: count)
|
|
{
|
|
local sc = sshd_conns[sid, cid];
|
|
print sshd_log, fmt("[%D][%s:%s:%d] auth timeout", ts,
|
|
sid, get_event_peer()$host, cid);
|
|
}
|
|
|
|
|
|
event sensor_sshd_auth_password_attempt(ts: time, sid: string, cid: count,
|
|
user: string, password: string,
|
|
valid: bool)
|
|
{
|
|
local sc = sshd_conns[sid, cid];
|
|
|
|
if ( ! valid )
|
|
{
|
|
print sshd_log, fmt("[%D][%s:%s:%d] password bad: user %s, password '%s'",
|
|
ts, get_event_peer()$host, sid, cid, user, password);
|
|
event login_failure(sc$conn, user, "", password, "");
|
|
}
|
|
else
|
|
{
|
|
print sshd_log, fmt("[%D][%s:%s:%d] password ok: user %s, password '%s'",
|
|
ts, get_event_peer()$host, sid, cid, user, password);
|
|
event login_success(sc$conn, user, "", password, "");
|
|
}
|
|
}
|
|
|
|
|
|
event sensor_sshd_channel_new_session(ts: time, sid: string, cid: count,
|
|
chan_id: count, stype: string)
|
|
{
|
|
local sc = sshd_conns[sid, cid];
|
|
|
|
print sshd_log, fmt("[%D][%s:%s:%d:%d] new session: type %s",
|
|
ts, get_event_peer()$host, sid, cid, chan_id, stype);
|
|
|
|
if ( stype == "shell" )
|
|
{
|
|
local filename =
|
|
fmt("sshd-%s-%s-%d-%d.log",
|
|
get_event_peer()$host, sid, cid, chan_id);
|
|
sc$sessions[chan_id] = open(filename);
|
|
}
|
|
}
|
|
|
|
|
|
event sensor_sshd_channel_new_forward(ts: time, sid: string,
|
|
cid: count, chan_id: count,
|
|
src_ip: addr, src_p: port,
|
|
dst_ip: addr, dst_p: port,
|
|
s2h: bool)
|
|
{
|
|
if ( s2h )
|
|
print sshd_log, fmt("[%D][%s:%s:%d:%d] new port channel: %s:%d -> c -> s -> %s:%d",
|
|
ts, get_event_peer()$host, sid, cid,
|
|
chan_id, src_ip, src_p, dst_ip, dst_p);
|
|
else
|
|
print sshd_log, fmt("[%D][%s:%s:%d:%d] new port channel: %s:%d <- c <- s <- %s:%d",
|
|
ts, get_event_peer()$host, sid, cid,
|
|
chan_id, dst_ip, dst_p, src_ip, src_p);
|
|
}
|
|
|
|
|
|
event sensor_sshd_data_rx(ts: time, sid: string, cid: count, chan_id: count,
|
|
line: string)
|
|
{
|
|
local sc = sshd_conns[sid, cid];
|
|
|
|
if ( chan_id in sc$sessions )
|
|
{
|
|
print sc$sessions[chan_id],
|
|
fmt("[%D][%s:%s:%d:%d] rx: %s", ts,
|
|
get_event_peer()$host, sid, cid, chan_id, line);
|
|
event login_output_line(sc$conn, line);
|
|
}
|
|
}
|
|
|
|
|
|
event sensor_sshd_data_tx(ts: time, sid: string, cid: count,
|
|
chan_id: count, line: string)
|
|
{
|
|
local sc: sshd_conn = sshd_conns[sid, cid];
|
|
|
|
if ( chan_id in sc$sessions )
|
|
{
|
|
print sc$sessions[chan_id],
|
|
fmt("[%D][%s:%s:%d:%d] tx: %s", ts,
|
|
get_event_peer()$host, sid, cid, chan_id, line);
|
|
event login_input_line(sc$conn, line);
|
|
}
|
|
}
|
|
|
|
|
|
event sensor_sshd_exec(ts: time, sid: string, cid: count,
|
|
chan_id: count, command: string)
|
|
{
|
|
print sshd_log,
|
|
fmt("[%D][%s:%s:%d:%d] exec: '%s'", ts, get_event_peer()$host,
|
|
sid, cid, chan_id, command);
|
|
}
|
|
|
|
|
|
event sensor_sshd_channel_exit(ts: time, sid: string, cid: count,
|
|
chan_id: count, status: int)
|
|
{
|
|
print sshd_log,
|
|
fmt("[%D][%s:%s:%d:%d] channel exit, code %d", ts,
|
|
get_event_peer()$host, sid, cid, chan_id, status);
|
|
}
|
|
|
|
|
|
event sensor_sshd_channel_cleanup(ts: time, sid: string, cid: count,
|
|
chan_id: count)
|
|
{
|
|
local sc: sshd_conn = sshd_conns[sid, cid];
|
|
|
|
print sshd_log, fmt("[%D][%s:%s:%d:%d] channel cleanup",
|
|
ts, get_event_peer()$host, sid, cid, chan_id);
|
|
|
|
if ( chan_id in sc$sessions )
|
|
delete sc$sessions[chan_id];
|
|
}
|