mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 22:58:20 +00:00
124 lines
4.4 KiB
Text
124 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.
|
|
option size_threshold = 1073741824;
|
|
|
|
## Time during which we check whether a connection's size exceeds the
|
|
## :bro:see:`GridFTP::size_threshold`.
|
|
option max_time = 2 min;
|
|
|
|
## Whether to skip further processing of the GridFTP data channel once
|
|
## detected, which may help performance.
|
|
option skip_data = T;
|
|
|
|
## 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;
|
|
|
|
if ( ! data_channel_initial_criteria(c) )
|
|
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 && 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) };
|
|
}
|
|
}
|