📄 snort_smtp.c
字号:
*/static u_int16_t SMTP_HandleDataBodyState(SFSnortPacket *p, u_int16_t i){ char *searchStr; int cmdFound = 0; u_int16_t next_index = i; if ( !_smtp->data_search ) { /* Nothing to do, so skip packet */ return p->payload_size; } /* Search starting at current character */ searchStr = p->payload + i; /* Check for command verb or data header end */ cmdFound = _dpd.searchAPI->search_instance_find(_smtp->data_search, searchStr, p->payload_size - i, 0, SMTP_DataStrFound); if ( cmdFound ) { /* If found MIME boundary */ if ( _smtp->token_id & DATA_BOUNDARY ) { _smtp->state = MIME_HEADER; } /* If found end of mail, drop back into command state */ else if ( _smtp->token_id & DATA_BODY_END ) { /* Make sure the period is on a line by itself */ if ( _smtp->token_index == 0 || searchStr[_smtp->token_index-1] == '\n' ) { /* Handle multiple mail messages */ _smtp->state = COMMAND; _smtp->message_number++; DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, "Message number: %d", _smtp->message_number);); } } next_index += _smtp->token_index + _smtp->token_length; } else if ( _smtp_config.ignore_data ) { /* Ignore data */ DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, "In DATA_BODY section; ignore data\n");); if ( _smtp->normalizing ) { p->normalized_payload_size = i; } else { p->payload_size = i; } } if ( !cmdFound ) { /* Done looking at this packet */ return p->payload_size; } return next_index;}/* * Handle COMMAND state * * @param packet standard Packet structure * * @param i index into p->payload buffer to start looking at data * * @return i index into p->payload where we stopped looking at data */static u_int16_t SMTP_HandleMimeHeaderState(SFSnortPacket *p, u_int16_t i){ char *searchStr; int cmdFound = 0; if ( !_smtp->data_search ) { /* Nothing to do, so skip packet */ return p->payload_size; } /* Search starting at current character */ searchStr = p->payload + i; /* Check for MIME header end */ cmdFound = _dpd.searchAPI->search_instance_find(_smtp->data_search, searchStr, p->payload_size - i, 0, SMTP_DataStrFound); /* If found LFLF, or CRLFCRLF, or (LF or CRLF) at the beginning of a line */ if ( (i == 0 && ((p->payload_size > 0 && searchStr[0] == '\n') || (p->payload_size > 1 && searchStr[0] == '\r' && searchStr[1] == '\n'))) || (cmdFound && _smtp->token_id & DATA_HEADER_END) ) { /* Drop back to normal body search */ _smtp->state = DATA_BODY; return i + _smtp->token_index + _smtp->token_length; } return p->payload_size;}/* * Handle COMMAND state * * @param packet standard Packet structure * * @param i index into p->payload buffer to start looking at data * * @return i index into p->payload where we stopped looking at data */static u_int16_t SMTP_HandleTlsDataState(SFSnortPacket *p, u_int16_t i){ if ( _smtp_config.ignore_tls_data ) { DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, "In TLS_DATA section; ignore encrypted data\n");); /* Make rules ignore TLS encoded data */ p->payload_size = i; } return p->payload_size; /* Skip over all data */} /* * Process client packet * * @param packet standard Packet structure * * @return none */static void SMTP_ProcessClientPacket(SFSnortPacket *p){ u_int16_t i = 0;#ifdef DEBUG p->payload[p->payload_size - 1] = '\0'; DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, "In SMTP_ProcessClientPacket(), %d: %s\n", p->payload_size, p->payload););#endif if ( p->flags & FLAG_REBUILT_STREAM ) { DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, "FLAG_REBUILT_STREAM: yes\n");); } if ( p->flags & FLAG_STREAM_INSERT ) { DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, "FLAG_STREAM_INSERT: yes\n");); } if ( p->flags & FLAG_STREAM_EST ) { DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, "FLAG_STREAM_EST: yes\n");); } _smtp->token_id = 0; _smtp->normalizing = 0; while ( i < p->payload_size ) { switch ( _smtp->state ) { case COMMAND: i = SMTP_HandleCommandState(p, i); break; case DATA: case DATA_PEND: i = SMTP_HandleDataState(p, i); break; case DATA_BODY: i = SMTP_HandleDataBodyState(p, i); break; case MIME_HEADER: i = SMTP_HandleMimeHeaderState(p, i); break; case TLS_DATA: i = SMTP_HandleTlsDataState(p, i); break; default: DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, "Unknown SMTP state\n");); return; } } return;}/* * Check to see if this is a TLS handshake * * @param p packet we are examining * @param index index into buffer where new line starts * * @retval 1 if TLS server handshake * @retval 0 if not TLS server handshake */static int SMTP_IsTLSServerHandshake(SFSnortPacket *p, u_int16_t index){ if ( (index+2) < p->payload_size && *(p->payload + index) == 0x16 && *(p->payload + index+1) == 0x03 && *(p->payload + index+2) == 0x01 ) { return 1; } return 0;}/* * Process server packet * * @param packet standard Packet structure * * @return do_flush * @retval 1 flush queued packets on client side * @retval 0 do not flush queued packets on client side */static int SMTP_ProcessServerPacket(SFSnortPacket *p){ u_int16_t i, count = 0; u_int8_t c; int numFound; int do_flush = 0; if ( _smtp->state == TLS_DATA && _smtp_config.ignore_tls_data ) { /* Ignore data */ DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, "In TLS_DATA section; ignore encrypted data\n");); p->payload_size = 0; return 0; } _smtp->token_id = 0; /* Loop through packet, counting chars. Notice if one is LF. */ for ( i = 0; i < p->payload_size; i++ ) { /* If at beginning of line */ if ( count == 0 ) { /* Check for response code */ numFound = _dpd.searchAPI->search_find(RESP_SEARCH, p->payload + i, p->payload_size - i, 1, SMTP_RespStrFound); DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, "Number of matches found: %d\n", numFound);); if ( numFound && (_smtp->token_id & RESP_354) ) { DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, "354 flag set, dsize = %d\n", p->payload_size);); /* Got client DATA and server 354, now we know we are in data section */ if ( _smtp->got_data_cmd ) { _smtp->state = DATA; } _smtp->got_data_resp = 1; do_flush = 1; } /* Check for TLS encoding */ if ( SMTP_IsTLSServerHandshake(p, i) ) { _smtp->got_server_tls = 1; if ( _smtp->got_starttls ) _smtp->state = TLS_DATA; } } count++; c = *(p->payload + i); if ( c == '\n' ) { if ( _smtp_config.max_response_line_len != 0 && count > _smtp_config.max_response_line_len ) { SMTP_GenerateAlert(SMTP_EVENT_RESPONSE_OVERFLOW, "%s: %d chars", SMTP_RESPONSE_OVERFLOW_STR, count); } count = 0; } } return do_flush;}/* * Entry point to snort preprocessor for each packet * * @param packet standard Packet structure * * @return none */void SnortSMTP(SFSnortPacket *p){ int detected = 0; int do_flush = 0; PROFILE_VARS; /* Make sure it's traffic we're interested in */ if ( !IsServer(p->src_port) && !IsServer(p->dst_port) ) return; /* Ignore if no data */ if (p->payload_size == 0) return; SMTP_Setup(p); if(_smtp && _smtp_config.inspection_type == SMTP_STATELESS) { SMTP_ResetState(_smtp); } /* Figure out direction of packet */ GetPacketDirection(p); if ( p->payload[p->payload_size-1] == '\n' ) _smtp->last_byte_is_lf = 1; if ( _smtp->pkt_direction == SMTP_PKT_FROM_SERVER ) { DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, " <SMTP packet from server>\n");); /* Process as a server packet */ do_flush = SMTP_ProcessServerPacket(p); if ( do_flush ) { _dpd.streamAPI->response_flush_stream(p); } } else if ( _smtp->pkt_direction == SMTP_PKT_FROM_CLIENT ) { DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, " <SMTP packet from client>\n");); if (p->flags & FLAG_STREAM_INSERT) { /* Packet will be rebuilt, so wait for it */ DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, "Client packet will be reassembled\n")); /* Turn off detection until we get the rebuilt packet. */ SMTP_DisableDetect(p); return; } /* Interesting to see how often packets are rebuilt */ DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, "Client packet: rebuilt %s: %.*s\n", (p->flags & FLAG_REBUILT_STREAM) ? "yes" : "no", p->payload_size, p->payload)); /* Process as a client packet */ SMTP_ProcessClientPacket(p); } else { DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, "SMTP packet NOT from client or server!\n");); /* Attempt to process as if it is a client packet */ SMTP_ProcessClientPacket(p); } PREPROC_PROFILE_START(smtpDetectPerfStats); detected = _dpd.detect(p);#ifdef PERF_PROFILING smtpDetectCalled = 1;#endif PREPROC_PROFILE_END(smtpDetectPerfStats); /* Turn off detection since we've already done it. */ SMTP_DisableDetect(p); if ( detected ) { DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, "SMTP vulnerability detected\n");); }}static void SMTP_DisableDetect(SFSnortPacket *p){ _dpd.disableAllDetect(p); _dpd.setPreprocBit(p, PP_SFPORTSCAN); _dpd.setPreprocBit(p, PP_PERFMONITOR); _dpd.setPreprocBit(p, PP_STREAM4);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -