login
event handlers
The standard login
script handles the following events:
login_failure (c: connection, user: string, client_user: string, password: string, line: string)
user
with password
on the given connection c
.
client_user
is the user's username on the client side of the
connection. For Telnet connections, this is an empty string, but
for Rlogin connections, it is the client name passed in the initial
authentication information (to check against
.rhosts
). line
is the
line of text that led the analyzer to conclude that the authentication
had failed.
The analyzer first generates an account_tried
event to facilitate detection of password guessing, and then checks for
a sensitive username or password. If the username was not sensitive
and the password is empty, then no further analysis is applied, since
clearly the attempt was half-hearted and aborted. Otherwise, the
analyzer annotates the connection's addl
field with fail/<
username>
to mark the
authentication failure, and also checks the client_user
to
see if it is sensitive. If we then find that the connection is
hot, the analyzer logs a message to that effect.
login_success (c: connection, user: string, client_user: string, password: string, line: string)
login_failure
.
The analyzer invokes check_hot
with mode APPL_ESTABLISHED
since the application session has now been established. It generates
an account_tried
event to facilitate detection of password guessing, and then checks for
a sensitive username or password. The event engine uses the special
password "<none>"
to indicate that no password
was exposed, and this mitigates the sensitivity of logins using particular
usernames per rlogin_id_okay_if_no_password_exposed
.
The analyzer annotates the connection's addl
field with "<
username>"
to mark the
successful authentication. Finally, if we then find that the connection
is hot, the analyzer logs a message to that effect.
login_input_line (c: connection, line: string)
input_trouble
and edited_input_trouble
and invokes
hot_login
with a tag of "trb"
if it sees a match,
which will log an alert concerning the connection. However, this
invocation is only done while the connection's hot
field count is <= 2, to avoid cascaded alerts when an attacker gets
really busy and steps on a lot of sensitive patterns.
login_output_line (c: connection, line: string)
backdoor_prompts
and any pending input alerts that
were waiting on the server output, per edited_input_trouble
.
These last are then logged unless the output matched the pattern:
/No such file or directory/
Deficiency: Clearly, this pattern should not be hardwired but instead specified by a redefinable variable.
Finally, if the line is not too long and the text matches output_trouble
and the connection's hot
field count is <= 2 (to avoid cascaded alerts), the analyzer
invokes hot_login
with a tag of "trb"
.
Deficiency: “Too long” is hardwired to be a length $\ge 256$ bytes. It, too, should be specifiable via a redefinable variable.
Note: We might
wonder if not checking overly long lines presents an evasion threat: the
attacker can bury their access to a sensitive string in an excessive line
and thus avoid detection. While this is true, it doesn't appear to cost
much. First, some of the sensitive patterns are generated in server output
that will be hard to manipulate into being overly long. Second, if the
attacker is trying to avoid detection, there are easier ways, such as
passing their output through a filter that alters it a good deal.
login_confused (c: connection, msg: string, line: string)
msg
gives the particular problem the heuristics detected
(for example, multiple_login_prompts
means that the engine saw
several login prompts in a row, without the type-ahead from the client side
presumed necessary to cause them) and line
the line of text that
caused the heuristics to conclude they were confused.
Once declaring that it's confused, the event engine will no longer attempt
to follow the authentication dialog. In particular, it will not
generate subsequent login_failure
or login_success
events.
Upon this event, the standard
login
script invokes check_hot
with
mode APPL_ESTABLISHED
since it could well be that the application
session is now established (it can't know for sure, of course, because
the event engine has given up). It annotates the connection's
addl
field with
confused
<
line>
to mark the confused state,
and then logs to the wierd file the particulars of the
connection and the type of confusion (msg
). Deficiency: This should be done by generating a weird-related event instead.
Finally, the analyzer invokes set_record_packets
to specify
that all of the packets associated with this connection should be recorded
to the trace file.
Note: For the current login
analyzer, this call is not needed—it
records every packet of every login session anyway, because the generally
philosophy is that Bro should record whatever it analyzes, so that the
analysis may be repeated or examined in detail. Since the current analyzer
looks at every input and output line via login_input
and login_output
, it records all of the packets of every such analyzed session.
There is commented-out text in login_success
to be used if
login_input
and login_output
are not being used; it turns
off recording of a session's packets after the user has successfully logged
in (assuming the connection is not considered hot).
login_confused_text (c: connection, line: string)
edit_and_check_line
, and, if
present, annotates the connection's addl
field
with
confused
<
line>
, logs that the connection
has become hot, and invokes set_record_packets
to record
to the trace file all of the packets associated with the connection.
login_terminal (c: connection, terminal: string)
The handler checks the terminal type against hot_terminal_types
and if it finds a match invokes hot_login
with a tag of
"trb"
.
excessive_line (c: connection)
login
analyzer; or, possibly, as
a Login session carrying an unusual application. Note: One example
we have observed occurs when a high-bandwidth binary payload protocol such
as Napster is sent over the Telnet or Rlogin well-known port in an
attempt to either evade detection or tunnel through a firewall.
This event is actually generic to any TCP connection carrying
an application that uses the “Network Virtual Terminal” (NVT) abstraction,
which presently comprises Telnet and FTP. But the only handler defined
in the demonstration Bro policy is for Telnet, hence we discuss it here.
For this reason, the handler first invokes is_login_conn
to check whether the connection is in fact a login session. If so, then
if the connection is not hot, and if the analyzer finds the server
listed in non_ACSII_HOSTS
, then it presumes the long line
is due to use of a non-ASCII character set; the analyzer invokes
set_login_state
and set_record_packets
to avoid
further analysis or recording of the connection.
Otherwise, if the connection is still in the authentication dialog, then
the handler generates a event with a
confusion-type of "excessive_line"
, and changes the connection's
state to confused.
Deficiency: The event engine is currently hardwired to consider a line of >= 1024 bytes as “excessive”; clearly this should be user-redefinable.
inconsistent_option (c: connection)
inconsistent_option
event.
The handler for this event simply records an entry about it to the file. Deficiency: The event handler invocation does not include enough information to determine what option was inconsistently specified; in addition, it would be convenient to integrate the handling of problems like this within the general “weird” framework.
Note: As for excessive_line
above, this event is actually a
generic one applicable to any NVT-based protocol. It is handled here
because the problem most often crops up for Telnet sessions.
Note: Also, the handler does not check to see whether the connection
is a login session (as it does for excessive_line
); it serves
as the handler for any NVT session with an excessive line.
Note: Finally, note that this event can be generated if the session
contains a stream of binary data. One way this can occur is when
the session is encrypted but Bro fails to recognize this fact.
bad_option (c: connection)
The processing of this event (recording information to the
file) and the various notes and deficiencies associated with it are
the same as those for inconsistent_option
above.
bad_option_termination (c: connection)
The processing of this event (recording information to the
file) and the various notes and deficiencies associated with it are
the same as those for inconsistent_option
above.
authentication_accepted (name: string, c: connection)
The handler annotates the connection's addl
field
with
auth
<
name>
,
unless that annotation is already present.
authentication_rejected (name: string, c: connection)
authentication_accepted
, except invoked when the
server replies that it rejects the attempted authentication.
The handler annotates the connection's addl
field
with auth-failed
<
name>
.
authentication_skipped (c: connection)
The handler annotates the connection's addl
field
with “ skipped
”
to mark that authentication was skipped,
and then invokes skip_further_processing
and (unless the
connection is hot) set_record_packets
to skip any further
analysis of the connection, and to stop recording its packets to
the trace file.
connection_established (c: connection)
connection_established
is a generic
event generated for all TCP connections; however, the login
analyzer
defines an additional handler for it.
The handler first checks (via is_login_conn
) whether this is a Telnet
or Rlogin connection. If so, it generates an authentication_skipped
event if the server's address occurs
in skip_logins_to
, and also (for Telnet) checks whether the
client's port occurs in hot_telnet_orig_ports
, invoking hot_login
with the tag "orig"
if it does.
For SSH connections, it likewise checks the client's port, but
in hot_ssh_orig_ports
, marking the connection as hot and
logging a real-time alert if it is.
partial_connection (c: connection)
partial_connection
is a generic
event generated for all TCP connections. The login
analyzer
also defines a handler for it, one which (if it's a Telnet/Rlogin
connection) sets the connection's state to confused and
checks for hot_telnet_orig_ports
.
activating_encryption (c: connection)
The handler annotates the connection's addl
field
with “(encrypted)
” to mark that authentication was encrypted.
Note: The event engine itself marks the connection as requiring no further processing. This is done by the event engine rather than the handler because the event engine cannot do its job (regardless of the policy the handler might desire) in the face of encryption.