next up previous contents index
Next: The http Analyzer Up: Analyzers and Events Previous: The hot-ids Module   Contents   Index

Subsections


The ftp Analyzer

The ftp analyzer processes traffic associated with the FTP file transfer service [RFC959]. Bro instantiates an ftp analyzer for any connection with service port 21/tcp, providing you have loaded the ftp analyzer, or defined a handler for ftp_request or ftp_reply.

The analyzer uses a capture filter of ``port ftp'' (§ ). It generates summaries of FTP sessions; looks for sensitive usernames, access to sensitive files, and possible FTP ``bounce'' attacks, in which the host specified in a ``PORT'' or ``PASV'' directive does not correspond to the host sending the directive; or in which a different host than the server (client) connects to the endpoint specified in a PORT (PASV) directive.


The ftp_session_info record

Figure 7.6: Definition of the ftp_session_info record.
\begin{figure}\begin{verbatim}type ftp_session_info: record {
id: count;  ...

The main data structure managed by the ftp analyzer is a collection of ftp_session_info records, where the record type is shown in Figure 7.16.1. The corresponding fields are:

[id] The unique session identifier assigned to this session. Sessions are numbered starting at 1 and incrementing with each new session.

[user] The username associated with this session (from the initial FTP authentication dialog), or an empty string if not yet determined.

[request] The pending request, if the client has issued any. Ordinarily there would be at most one pending request, but a client can in fact send multiple requests to the server all at once, and an attacker could do so attempting to confuse the analyzer into mismatching responses with requests, or simply forgetting about previous requests.

[num_requests] A count of how many requests are currently pending.

[request_t] The time at which the pending request was issued.

[log_if_not_denied] If true, then when the reply to the current request comes in, Bro should log it, unless the reply code is 530 (``denied'').

[log_if_not_unavail] If true, then when the reply to the current request comes in, Bro should log it, unless the reply code is 550 (``unavail'').

[log_it] If true, then when the reply to the current request comes in, Bro should log it.


ftp variables

The standard script defines the following redefinable variables:

[ftp_guest_ids : set[string]] A set of usernames associated with publicly accessible ``guest'' services. Bro interprets guest usernames as indicating Bro should use the authentication password as the effective username.

Default: { "anonymous", "ftp", "guest", }.

[ftp_skip_hot : set[addr, addr, string]] Entries indicate that a connection from the first given address to the second given address, using the given string username, should not be treated as hot even if the username is sensitive.

Default: empty.

Example: redefining ftp_skip_hot using

redef ftp_skip_hot: set[addr, addr, string] += {
    [[bob1.dsl.home.net, bob2.dsl.home.net], bob.work.com, "root"],
};
would result in Bro not alerting on FTP connections as user "root" from either bob1.dsl.home.net or bob2.dsl.home.net to the server running on bob.work.com.

[ftp_hot_files : pattern] Bro matches the argument given in each FTP file manipulation request (RETR, STOR, etc.) against this pattern to see if the file is sensitive. If so, and if the request succeeds, then the access is logged.

eggdrop Default: a pattern that matches various flavors of password files, plus any string with eggdrop in it. Note: Eggdrop is an IRC management tool often installed by certain attackers upon a successful break-in.

[ftp_not_actually_hot_files : pattern] A pattern giving exceptions to ftp_hot_files. It turns out that a pattern like /passwd/ generates a lot of false hits, such as from passwd.c (source for the passwd utility; this can turn up in FTP sessions that fetch entire sets of utility sources using MGET) or passwd.html (a Web page explaining how to enter a password for accessing a particular page).

Default: /(passwd|shadow).*\.(c|gif|htm|pl|rpm|tar|zip)/ .

[ftp_hot_guest_files : pattern] Files that guests should not attempt to access.

Default: .rhosts and .forward .

[skip_unexpected : set[addr]] If a new host (address) unexpectedly connects to the endpoint specified in a PORT or PASV directive, then if either the original host or the new host is in this set, no message is generated. The idea is that you can specify multi-homed hosts that frequently show up in your FTP traffic, as these can generate innocuous warnings about connections from unexpected hosts.

Default: some hp.com hosts, as an example. Most are specified as raw IP addresses rather than hostnames, since the hostnames don't always consistently resolve.

[skip_unexpected_net : set[addr]] The same as skip_unexpected, except addresses are masked to /24 and /16 before looked up in this set.

Default: empty.

Figure 7.7: Example of FTP log file entries for a single FTP session.
\begin{figure}\begin{verbatim}972499885.784104  ...

In addition, ftp_log holds the name of the FTP log file to which Bro writes FTP session summaries. It defaults to open_log_file("ftp").

Figure 7.16.2 shows an example of what entries in this file look like. Here we see a transcript of the 26th FTP session seen since Bro started running. The first line gives its start time and the participating hosts and ports. The next line (split across two lines above for clarity) gives the server's welcome banner. The client then logged in as user ``anonymous'', and because this is one of the guest usernames, Bro recorded their password too, which in this case was ``IEUser@'' (a useless string supplied by their Web browser). The server accepted this authentication, so the status on the line is ``(logged in)''.

The client then issues a request for the Image file type, to which the server agreed. Next they issued a PASV directive, and received a response instructing them to connect to the server on port 2427/tcp for the next transfer. At this point, after issuing a SIZE directive (to which the server returned 1,675,597 bytes), they send RETR to fetch the file /pub/OB/4.0/JOB-4.0.3.zip. However, before the transfer completed, they issued ABOR, but the transfer finished before the server processed the abort, so the log shows a status of (completed). Furthermore, because the client issued two commands without waiting for an intervening response, these are shown together in the log file, and the line marked with a ``*'' so it draws the eye. Finally, because Bro paired up the (completed) with the multi-request line, it then treats the response to the ABOR command as a reply by itself, showing in the last line that the server reported it successfully carried out the abort.

The corresponding lines in the red file look like:

    972499885.784104 565.836 ftp 118 427 131.243.70.68 64.55.26.206
        RSTO L #26 anonymous/IEUser@
    972499888.984116 165.098 ftp-data ? 1675597 131.243.70.68 64.55.26.206
        RSTO L
The first line summarizes the FTP control session (over which the client sends its requests and receives the server's responses). It includes an addl annotation of ``#26 anonymous/IEUser@'', summarizing the session number (so you can find the corresponding records in the ftp log file) and the authentication information.

The second line summarizes the single FTP data transfer, of 1,675,597 bytes. The amount of data sent by the client for this connection is shown as unknown because the client aborted the connection with a RST (hence the state RSTO). For connections that Bro does not look inside (such as FTP data transfers), it learns the amount of data transferred from the sequence numbers of the SYN and FIN connection control packets, and can't (reliably) learn them for the sender of a RST. (It can for the receiver of the RST.)

They also aborted the control session (again, state RSTO), but in this case, Bro captured all of the packets of the session, so it could still assign sizes to both directions.


ftp functions

The standard ftp script provides one function for external use:

[is_ftp_data_conn(c: connection): bool ] Returns true if the given connection matches one we're expecting as the data connection half of an FTP session. Note: This function is not idempotent: if the connection matches an expected one, then Bro updates its state such that that connection is no longer expected. It also logs a discrepancy if the connection appears to be usurping another one that generated either a ``PORT'' or a ``PASV'' directive.

Also returns true if the source port is 20/tcp and there's currently an FTP session active between the originator and responder, in case for some reason Bro's bookkeeping is inconsistent.


ftp event handlers

The standard script handles the following events:

[ftp_request (c: connection, command: string, arg: string)] Invoked upon the client side of connection c having made the request command with the argument arg.

The processing depends on the particular command:

USER
 
Specifies the username that the client wishes to use for authentication. If it is sensitive--in hot_ids (which the ftp analyzer accesses via a @load of hot-ids)--then the analyzer flags the FTP session as log-worthy. In addition, if the username is in forbidden_ids, then the analyzer terminates the session.

The analyzer also updates the connection's addl field with the username.

PASS
 
Specifies the password to use for authentication.

If the password is empty and the username appears in forbidden_ids_if_no_password (also from the hot-ids analyzer), then the analyzer terminates the connection.

If the username corresponds to a guest account (ftp_guest_ids), then the analyzer updates the connection's addl field with the password as additional account information. Otherwise, it generates an account_tried event to facilitate detection of password guessing.

PORT
 
Instructs the FTP server to connect to the given IP address and port for delivery of the next FTP data item. The analyzer first checks the address/port specifier for validity. If valid, it will generate an alert if either the address specified in the directive does not match that of the client, or if the port corresponds to a ``privileged'' port, i.e., one in the range 0-1023. Finally, it establishes state so that is_ftp_data_conn can identify a subsequent connection corresponding to this directive as belonging to this FTP session.

ACCT
 
Specifies additional accounting information associated with a session, which the analyzer simply adds to the connection's addl field.

APPE, CWD, DELE, MKD, RETR, RMD, RNFR, RNTO, STOR, STOU
 
All of these manipulate files (and directories). The analyzer checks the filename against the policies to see if it is sensitive in the context of the given username (i.e., guest or non-guest), and, if so, marks the connection to generate an alert unless the operation fails. The analyzer also checks for an excessively long filename, currently by checking its length against a Deficiency: hardwired maximum of 250 bytes.

[ftp_reply (c: connection, code: count, msg: string, cont_resp: bool)] Invoked upon the server side of connection c having replied to a request using the given status code and text message. cont_resp is true if the reply line is tagged as being continued to the next line. The analyzer only processes requests when the last line of a continued reply is received.

The analyzer checks the reply against any expected for the connection (for example, ``log_if_not_denied'') and generates alerts accordingly. If the reply corresponds to a PASV directive, then it parses the address/port specification in the reply and generates alerts in an analogous fashion as done by the ftp_request handler for PORT directives.

Finally, if the reply is not one that the analyzer is hardwired to skip (code 150, used at the beginning of a data transfer, and code 331, used to prompt for a password), then it writes a summary of the request and reply to the FTP log file (§ ). Also, if the reply is an ``orphan'' (there was no corresponding request, perhaps because Bro started up after the request was made), then the reply is summarized in the log file by itself.

The standard ftp script defines one other handler, an instance of connection_finished used to flush FTP session information in case the session terminates abnormally and no reply is seen to the pending request(s).


next up previous contents index
Next: The http Analyzer Up: Analyzers and Events Previous: The hot-ids Module   Contents   Index
Vern Paxson 2002-11-17