zeek/scripts/base/protocols/ftp/gridftp.bro
Robin Sommer 1e010fbb76 Merge remote-tracking branch 'origin/topic/johanna/conn-threshold'
* origin/topic/johanna/conn-threshold:
  Wrap threshold stuff up - fix two small bugs and update baselines.
  update GridFTP analyzer to use connection thresholding instead of polling
  Add high level api for thresholding that holds lists of thresholds and raises an event for each threshold exactly once.
  Allow setting packet and byte thresholds for connections.

BIT-1377 #merged
2015-04-17 13:02:31 -07:00

121 lines
4.4 KiB
Text

##! A detection script for GridFTP data and control channels.
##!
##! GridFTP control channels are identified by FTP control channels
##! that successfully negotiate the GSSAPI method of an AUTH request
##! and for which the exchange involved an encoded TLS/SSL handshake,
##! indicating the GSI mechanism for GSSAPI was used. This analysis
##! is all supported internally, this script simply adds the "gridftp"
##! label to the *service* field of the control channel's
##! :bro:type:`connection` record.
##!
##! GridFTP data channels are identified by a heuristic that relies on
##! the fact that default settings for GridFTP clients typically
##! mutually authenticate the data channel with TLS/SSL and negotiate a
##! NULL bulk cipher (no encryption). Connections with those attributes
##! are marked as GridFTP if the data transfer within the first two minutes
##! is big enough to indicate a GripFTP data channel that would be
##! undesirable to analyze further (e.g. stop TCP reassembly). A side
##! effect is that true connection sizes are not logged, but at the benefit
##! of saving CPU cycles that would otherwise go to analyzing the large
##! (and likely benign) connections.
@load ./info
@load ./main
@load base/protocols/conn
@load base/protocols/ssl
@load base/frameworks/notice
module GridFTP;
export {
## Number of bytes transferred before guessing a connection is a
## GridFTP data channel.
const size_threshold = 1073741824 &redef;
## Time during which we check whether a connection's size exceeds the
## :bro:see:`GridFTP::size_threshold`.
const max_time = 2 min &redef;
## Whether to skip further processing of the GridFTP data channel once
## detected, which may help performance.
const skip_data = T &redef;
## Raised when a GridFTP data channel is detected.
##
## c: The connection pertaining to the GridFTP data channel.
global data_channel_detected: event(c: connection);
## The initial criteria used to determine whether to start polling
## the connection for the :bro:see:`GridFTP::size_threshold` to have
## been exceeded. This is called in a :bro:see:`ssl_established` event
## handler and by default looks for both a client and server certificate
## and for a NULL bulk cipher. One way in which this function could be
## redefined is to make it also consider client/server certificate
## issuer subjects.
##
## c: The connection which may possibly be a GridFTP data channel.
##
## Returns: true if the connection should be further polled for an
## exceeded :bro:see:`GridFTP::size_threshold`, else false.
const data_channel_initial_criteria: function(c: connection): bool &redef;
}
redef record FTP::Info += {
last_auth_requested: string &optional;
};
event ftp_request(c: connection, command: string, arg: string) &priority=4
{
if ( command == "AUTH" && c?$ftp )
c$ftp$last_auth_requested = arg;
}
event ConnThreshold::bytes_threshold_crossed(c: connection, threshold: count, is_orig: bool)
{
if ( threshold < size_threshold || "gridftp-data" in c$service || c$duration > max_time )
return;
add c$service["gridftp-data"];
event GridFTP::data_channel_detected(c);
if ( skip_data )
skip_further_processing(c$id);
}
event gridftp_possibility_timeout(c: connection)
{
# only remove if we did not already detect it and the connection
# is not yet at its end.
if ( "gridftp-data" !in c$service && ! c$conn?$service )
{
ConnThreshold::delete_bytes_threshold(c, size_threshold, T);
ConnThreshold::delete_bytes_threshold(c, size_threshold, F);
}
}
event ssl_established(c: connection) &priority=5
{
# If an FTP client requests AUTH GSSAPI and later an SSL handshake
# finishes, it's likely a GridFTP control channel, so add service label.
if ( c?$ftp && c$ftp?$last_auth_requested &&
/GSSAPI/ in c$ftp$last_auth_requested )
add c$service["gridftp"];
}
function data_channel_initial_criteria(c: connection): bool
{
return ( c?$ssl && c$ssl?$client_subject && c$ssl?$subject &&
c$ssl?$cipher && /WITH_NULL/ in c$ssl$cipher );
}
event ssl_established(c: connection) &priority=-3
{
# By default GridFTP data channels do mutual authentication and
# negotiate a cipher suite with a NULL bulk cipher.
if ( data_channel_initial_criteria(c) )
{
ConnThreshold::set_bytes_threshold(c, size_threshold, T);
ConnThreshold::set_bytes_threshold(c, size_threshold, F);
schedule max_time { gridftp_possibility_timeout(c) };
}
}