ftp: add events for command too long

Issue: 5235
pull/8467/head
Jason Ish 2 years ago committed by Victor Julien
parent 48920bd784
commit 3f4dad8676

@ -7,6 +7,7 @@ dhcp-events.rules \
dnp3-events.rules \
dns-events.rules \
files.rules \
ftp-events.rules \
http-events.rules \
http2-events.rules \
ipsec-events.rules \

@ -0,0 +1,6 @@
# FTP app-layer event rules
#
# SID range start: 2232000
alert ftp any any -> any any (msg:"SURICATA FTP Request command too long"; flow:to_server; app-layer-event:ftp.request_command_too_long; classtype:protocol-command-decode; sid:2232000; rev:1;)
alert ftp any any -> any any (msg:"SURICATA FTP Response command too long"; flow:to_client; app-layer-event:ftp.response_command_too_long; classtype:protocol-command-decode; sid:2232001; rev:1;)

@ -80,7 +80,8 @@ include = [
"ModbusState",
"CMark",
"QuicState",
"QuicTransaction"
"QuicTransaction",
"FtpEvent",
]
# A list of items to not include in the generated bindings

@ -0,0 +1,50 @@
/* Copyright (C) 2023 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use crate::core::AppLayerEventType;
use std::os::raw::{c_char, c_int};
#[derive(Debug, PartialEq, Eq, AppLayerEvent)]
#[repr(C)]
pub enum FtpEvent {
#[name("request_command_too_long")]
FtpEventRequestCommandTooLong,
#[name("response_command_too_long")]
FtpEventResponseCommandTooLong,
}
/// Wrapper around the Rust generic function for get_event_info.
///
/// # Safety
/// Unsafe as called from C.
#[no_mangle]
pub unsafe extern "C" fn ftp_get_event_info(
event_name: *const c_char, event_id: *mut c_int, event_type: *mut AppLayerEventType,
) -> c_int {
crate::applayer::get_event_info::<FtpEvent>(event_name, event_id, event_type)
}
/// Wrapper around the Rust generic function for get_event_info_by_id.
///
/// # Safety
/// Unsafe as called from C.
#[no_mangle]
pub unsafe extern "C" fn ftp_get_event_info_by_id(
event_id: c_int, event_name: *mut *const c_char, event_type: *mut AppLayerEventType,
) -> c_int {
crate::applayer::get_event_info_by_id::<FtpEvent>(event_id, event_name, event_type) as c_int
}

@ -24,6 +24,8 @@ use std;
use std::str;
use std::str::FromStr;
pub mod event;
// We transform an integer string into a i64, ignoring surrounding whitespaces
// We look for a digit suite, and try to convert it.
// If either str::from_utf8 or FromStr::from_str fail,

@ -323,6 +323,10 @@ static void FTPTransactionFree(FTPTransaction *tx)
FTPStringFree(str);
}
if (tx->tx_data.events) {
AppLayerDecoderEventsFreeEvents(&tx->tx_data.events);
}
FTPFree(tx, sizeof(*tx));
}
@ -526,6 +530,10 @@ static AppLayerResult FTPParseRequest(Flow *f, void *ftp_state, AppLayerParserSt
tx->request_length = CopyCommandLine(&tx->request, &line);
tx->request_truncated = state->current_line_truncated;
if (tx->request_truncated) {
AppLayerDecoderEventsSetEventRaw(&tx->tx_data.events, FtpEventRequestCommandTooLong);
}
/* change direction (default to server) so expectation will handle
* the correct message when expectation will match.
* For ftp active mode, data connection direction is opposite to
@ -761,6 +769,10 @@ static AppLayerResult FTPParseResponse(Flow *f, void *ftp_state, AppLayerParserS
if (likely(response)) {
response->len = CopyCommandLine(&response->str, &line);
response->truncated = state->current_line_truncated;
if (response->truncated) {
AppLayerDecoderEventsSetEventRaw(
&tx->tx_data.events, FtpEventResponseCommandTooLong);
}
TAILQ_INSERT_TAIL(&tx->response_list, response, next);
}
}
@ -1334,6 +1346,9 @@ void RegisterFTPParsers(void)
AppLayerParserRegisterStateProgressCompletionStatus(
ALPROTO_FTPDATA, FTPDATA_STATE_FINISHED, FTPDATA_STATE_FINISHED);
AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_FTP, ftp_get_event_info);
AppLayerParserRegisterGetEventInfoById(IPPROTO_TCP, ALPROTO_FTP, ftp_get_event_info_by_id);
sbcfg.buf_size = 4096;
sbcfg.Calloc = FTPCalloc;
sbcfg.Realloc = FTPRealloc;

Loading…
Cancel
Save