From: Victor Julien Date: Fri, 3 Dec 2021 07:17:37 +0000 (+0100) Subject: ssl: implement frames for SSLv3 and TLS X-Git-Tag: suricata-7.0.0-beta1~1033 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=af797b5926abbf1583189f75201563f99c72990e;p=thirdparty%2Fsuricata.git ssl: implement frames for SSLv3 and TLS --- diff --git a/src/app-layer-ssl.c b/src/app-layer-ssl.c index 9b32b173af..73700f1af6 100644 --- a/src/app-layer-ssl.c +++ b/src/app-layer-ssl.c @@ -37,6 +37,7 @@ #include "app-layer.h" #include "app-layer-protos.h" #include "app-layer-parser.h" +#include "app-layer-frames.h" #include "app-layer-ssl.h" #include "decode-events.h" @@ -53,6 +54,38 @@ #include "flow-private.h" #include "util-validate.h" +SCEnumCharMap tls_frame_table[] = { + { + "pdu", + TLS_FRAME_PDU, + }, + { + "hdr", + TLS_FRAME_HDR, + }, + { + "data", + TLS_FRAME_DATA, + }, + { + "alert", + TLS_FRAME_ALERT_DATA, + }, + { + "heartbeat", + TLS_FRAME_HB_DATA, + }, + { + "ssl2.hdr", + TLS_FRAME_SSLV2_HDR, + }, + { + "ssl2.pdu", + TLS_FRAME_SSLV2_PDU, + }, + { NULL, -1 }, +}; + SCEnumCharMap tls_decoder_event_table[ ] = { /* TLS protocol messages */ { "INVALID_SSLV2_HEADER", TLS_DECODER_EVENT_INVALID_SSLV2_HEADER }, @@ -1980,9 +2013,8 @@ static int SSLv2ParseRecord(uint8_t direction, SSLState *ssl_state, return (input - initial_input); } -static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, - AppLayerParserState *pstate, const uint8_t *input, - uint32_t input_len) +static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, AppLayerParserState *pstate, + const uint8_t *input, uint32_t input_len, const StreamSlice stream_slice) { int retval = 0; const uint8_t *initial_input = input; @@ -1993,18 +2025,37 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, } else { ssl_state->curr_connp->record_lengths_length = 3; } + + SCLogDebug("record start: ssl2.hdr frame"); + AppLayerFrameNewByPointer(ssl_state->f, &stream_slice, input, + ssl_state->curr_connp->record_lengths_length + 1, direction, TLS_FRAME_SSLV2_HDR); } + SCLogDebug("direction %u ssl_state->curr_connp->record_lengths_length + 1 %u, " + "ssl_state->curr_connp->bytes_processed %u", + direction, ssl_state->curr_connp->record_lengths_length + 1, + ssl_state->curr_connp->bytes_processed); /* the +1 is because we read one extra byte inside SSLv2ParseRecord to read the msg_type */ if (ssl_state->curr_connp->bytes_processed < (ssl_state->curr_connp->record_lengths_length + 1)) { retval = SSLv2ParseRecord(direction, ssl_state, input, input_len); + SCLogDebug("retval %d ssl_state->curr_connp->record_length %u", retval, + ssl_state->curr_connp->record_length); if (retval < 0 || retval > (int)input_len) { DEBUG_VALIDATE_BUG_ON(retval > (int)input_len); SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSLV2_HEADER); return -1; } + // TODO review + // BUG_ON(ssl_state->curr_connp->record_lengths_length + 1 != + // ssl_state->curr_connp->bytes_processed); + + AppLayerFrameNewByPointer(ssl_state->f, &stream_slice, input, + ssl_state->curr_connp->record_lengths_length + ssl_state->curr_connp->record_length, + direction, TLS_FRAME_SSLV2_PDU); + SCLogDebug("record start: ssl2.pdu frame"); + input += retval; input_len -= retval; } @@ -2249,9 +2300,8 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, } } -static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, - AppLayerParserState *pstate, const uint8_t *input, - const uint32_t input_len) +static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, AppLayerParserState *pstate, + const uint8_t *input, const uint32_t input_len, const StreamSlice stream_slice) { uint32_t parsed = 0; uint32_t record_len; /* slice of input_len for the current record */ @@ -2264,6 +2314,12 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_TLS_HEADER); return -1; } + SCLogDebug("%s input %p record_length %u", (direction == 0) ? "toserver" : "toclient", + input, ssl_state->curr_connp->record_length); + AppLayerFrameNewByPointer(ssl_state->f, &stream_slice, input, + ssl_state->curr_connp->record_length + retval, direction, TLS_FRAME_PDU); + AppLayerFrameNewByPointer( + ssl_state->f, &stream_slice, input, SSLV3_RECORD_HDR_LEN, direction, TLS_FRAME_HDR); parsed += retval; record_len = MIN(input_len - parsed, ssl_state->curr_connp->record_length); SCLogDebug("record_len %u (input_len %u, parsed %u, ssl_state->curr_connp->record_length %u)", @@ -2287,6 +2343,8 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_TLS_HEADER); return -1; } + AppLayerFrameNewByPointer(ssl_state->f, &stream_slice, input + parsed, + ssl_state->curr_connp->record_length, direction, TLS_FRAME_DATA); switch (ssl_state->curr_connp->content_type) { @@ -2303,6 +2361,8 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, break; case SSLV3_ALERT_PROTOCOL: + AppLayerFrameNewByPointer(ssl_state->f, &stream_slice, input + parsed, + ssl_state->curr_connp->record_length, direction, TLS_FRAME_ALERT_DATA); break; case SSLV3_APPLICATION_PROTOCOL: @@ -2395,6 +2455,8 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, return parsed; } case SSLV3_HEARTBEAT_PROTOCOL: { + AppLayerFrameNewByPointer(ssl_state->f, &stream_slice, input + parsed, + ssl_state->curr_connp->record_length, direction, TLS_FRAME_HB_DATA); int retval = SSLv3ParseHeartbeatProtocol(ssl_state, input + parsed, record_len, direction); if (retval < 0) { @@ -2474,7 +2536,8 @@ static AppLayerResult SSLDecode(Flow *f, uint8_t direction, void *alstate, if (input == NULL && ((direction == 0 && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS)) || - (direction == 1 && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TC)))) { + (direction == 1 && + AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TC)))) { /* flag session as finished if APP_LAYER_PARSER_EOF is set */ ssl_state->flags |= SSL_AL_FLAG_STATE_FINISHED; SCReturnStruct(APP_LAYER_OK); @@ -2526,8 +2589,7 @@ static AppLayerResult SSLDecode(Flow *f, uint8_t direction, void *alstate, } else { SCLogDebug("Continuing parsing SSLv2 record"); } - int retval = SSLv2Decode(direction, ssl_state, pstate, input, - input_len); + int retval = SSLv2Decode(direction, ssl_state, pstate, input, input_len, stream_slice); if (retval < 0 || retval > input_len) { DEBUG_VALIDATE_BUG_ON(retval > input_len); SCLogDebug("Error parsing SSLv2. Reseting parser " @@ -2548,8 +2610,7 @@ static AppLayerResult SSLDecode(Flow *f, uint8_t direction, void *alstate, SCLogDebug("Continuing parsing TLS record: record_length %u, bytes_processed %u", ssl_state->curr_connp->record_length, ssl_state->curr_connp->bytes_processed); } - int retval = SSLv3Decode(direction, ssl_state, pstate, input, - input_len); + int retval = SSLv3Decode(direction, ssl_state, pstate, input, input_len, stream_slice); if (retval < 0 || retval > input_len) { DEBUG_VALIDATE_BUG_ON(retval > input_len); SCLogDebug("Error parsing TLS. Reseting parser " @@ -2704,6 +2765,22 @@ static AppProto SSLProbingParser(Flow *f, uint8_t direction, return ALPROTO_FAILED; } +static int SSLStateGetFrameIdByName(const char *frame_name) +{ + int id = SCMapEnumNameToValue(frame_name, tls_frame_table); + if (id < 0) { + SCLogError(SC_ERR_INVALID_ENUM_MAP, "unknown frame type \"%s\"", frame_name); + return -1; + } + return id; +} + +static const char *SSLStateGetFrameNameById(const uint8_t frame_id) +{ + const char *name = SCMapEnumValueToName(frame_id, tls_frame_table); + return name; +} + static int SSLStateGetEventInfo(const char *event_name, int *event_id, AppLayerEventType *event_type) { @@ -2931,6 +3008,8 @@ void RegisterSSLParsers(void) AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_TLS, STREAM_TOCLIENT, SSLParseServerRecord); + AppLayerParserRegisterGetFrameFuncs( + IPPROTO_TCP, ALPROTO_TLS, SSLStateGetFrameIdByName, SSLStateGetFrameNameById); AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_TLS, SSLStateGetEventInfo); AppLayerParserRegisterGetEventInfoById(IPPROTO_TCP, ALPROTO_TLS, SSLStateGetEventInfoById); diff --git a/src/app-layer-ssl.h b/src/app-layer-ssl.h index becc5c3def..d7e769e5b9 100644 --- a/src/app-layer-ssl.h +++ b/src/app-layer-ssl.h @@ -32,6 +32,16 @@ #include "util-ja3.h" #include "queue.h" +enum TlsFrameTypes { + TLS_FRAME_PDU = 0, /**< whole PDU, so header + data */ + TLS_FRAME_HDR, /**< only header portion */ + TLS_FRAME_DATA, /**< only data portion */ + TLS_FRAME_ALERT_DATA, + TLS_FRAME_HB_DATA, + TLS_FRAME_SSLV2_HDR, + TLS_FRAME_SSLV2_PDU, +}; + enum { /* TLS protocol messages */ TLS_DECODER_EVENT_INVALID_SSLV2_HEADER,