⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snort_smtp.c

📁 入侵检测SNORT.最近更新的基于网络检测的IDS.希望能给大家带来方便.
💻 C
📖 第 1 页 / 共 5 页
字号:
/**************************************************************************** * * Copyright (C) 2005-2008 Sourcefire Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as * published by the Free Software Foundation.  You may not use, modify or * distribute this program under any other version of the GNU General * Public License. * * 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 * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ****************************************************************************//************************************************************************** * snort_smtp.c * * Author: Andy Mullican * Author: Todd Wease * * Description: * * This file handles SMTP protocol checking and normalization. * * Entry point functions: * *     SnortSMTP() *     SMTP_Init() *     SMTP_Free() * **************************************************************************//* Includes ***************************************************************/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <sys/types.h>#include "sf_types.h"#include <stdlib.h>#include <string.h>#include <ctype.h>#include <pcre.h>#include "snort_smtp.h"#include "smtp_config.h"#include "smtp_normalize.h"#include "smtp_util.h"#include "smtp_log.h"#include "smtp_xlink2state.h"#include "sf_snort_packet.h"#include "stream_api.h"#include "debug.h"#include "profiler.h"#include "bounds.h"#include "sf_dynamic_preprocessor.h"#include "ssl.h"#ifdef DEBUG#include "sf_types.h"#endif/**************************************************************************//* Externs ****************************************************************/#ifdef PERF_PROFILINGextern PreprocStats smtpDetectPerfStats;extern int smtpDetectCalled;#endifextern SMTPConfig _smtp_config;extern SMTPCmdConfig *_smtp_cmd_config;extern DynamicPreprocessorData _dpd;#ifdef DEBUGextern char smtp_print_buffer[];#endif/**************************************************************************//* Globals ****************************************************************/SMTP          *_smtp = NULL;SMTP           _smtp_no_session;SMTPPcre       _mime_boundary_pcre;char           _smtp_pkt_direction;char           _smtp_normalizing;SMTPSearchInfo _smtp_search_info;int            _smtp_check_gaps = 0;int            _smtp_reassembling = 0;#ifdef DEBUGUINT64 _smtp_session_counter = 0;#endifconst SMTPToken _smtp_known_cmds[] ={    {"ATRN",          4, CMD_ATRN},    {"AUTH",          4, CMD_AUTH},    {"BDAT",          4, CMD_BDAT},    {"DATA",          4, CMD_DATA},    {"DEBUG",         5, CMD_DEBUG},    {"EHLO",          4, CMD_EHLO},    {"EMAL",          4, CMD_EMAL},    {"ESAM",          4, CMD_ESAM},    {"ESND",          4, CMD_ESND},    {"ESOM",          4, CMD_ESOM},    {"ETRN",          4, CMD_ETRN},    {"EVFY",          4, CMD_EVFY},    {"EXPN",          4, CMD_EXPN},    {"HELO",          4, CMD_HELO},    {"HELP",          4, CMD_HELP},    {"IDENT",         5, CMD_IDENT},    {"MAIL",          4, CMD_MAIL},    {"NOOP",          4, CMD_NOOP},    {"ONEX",          4, CMD_ONEX},    {"QUEU",          4, CMD_QUEU},    {"QUIT",          4, CMD_QUIT},    {"RCPT",          4, CMD_RCPT},    {"RSET",          4, CMD_RSET},    {"SAML",          4, CMD_SAML},    {"SEND",          4, CMD_SEND},    {"SIZE",          4, CMD_SIZE},    {"STARTTLS",      8, CMD_STARTTLS},    {"SOML",          4, CMD_SOML},    {"TICK",          4, CMD_TICK},    {"TIME",          4, CMD_TIME},    {"TURN",          4, CMD_TURN},    {"TURNME",        6, CMD_TURNME},    {"VERB",          4, CMD_VERB},    {"VRFY",          4, CMD_VRFY},    {"X-EXPS",        6, CMD_X_EXPS},    {"XADR",          4, CMD_XADR},    {"XAUTH",         5, CMD_XAUTH},    {"XCIR",          4, CMD_XCIR},    {"XEXCH50",       7, CMD_XEXCH50},    {"XGEN",          4, CMD_XGEN},    {"XLICENSE",      8, CMD_XLICENSE},    {"X-LINK2STATE", 12, CMD_X_LINK2STATE},    {"XQUE",          4, CMD_XQUE},    {"XSTA",          4, CMD_XSTA},    {"XTRN",          4, CMD_XTRN},    {"XUSR",          4, CMD_XUSR},    {NULL,            0, 0}};/* new commands can be allocated via the smtp configuration */SMTPToken *_smtp_cmds;SMTPSearch *_smtp_cmd_search;const SMTPToken _smtp_resps[] ={	{"220",  3,  RESP_220},  /* Service ready - initial response and STARTTLS response */	{"221",  3,  RESP_221},  /* Goodbye - response to QUIT */	{"250",  3,  RESP_250},  /* Requested mail action okay, completed */	{"354",  3,  RESP_354},  /* Start mail input - data response */	{"421",  3,  RESP_421},  /* Service not availiable - closes connection */	{"450",  3,  RESP_450},  /* Mailbox unavailable */	{"451",  3,  RESP_451},  /* Local error in processing */	{"452",  3,  RESP_452},  /* Insufficient system storage */	{"500",  3,  RESP_500},  /* Command unrecognized */	{"501",  3,  RESP_501},  /* Syntax error in parameters or arguments */	{"502",  3,  RESP_502},  /* Command not implemented */	{"503",  3,  RESP_503},  /* Bad sequence of commands */	{"504",  3,  RESP_504},  /* Command parameter not implemented */	{"550",  3,  RESP_550},  /* Action not taken - mailbox unavailable */	{"551",  3,  RESP_551},  /* User not local; please try <forward-path> */	{"552",  3,  RESP_552},  /* Mail action aborted: exceeded storage allocation */	{"553",  3,  RESP_553},  /* Action not taken: mailbox name not allowed */	{"554",  3,  RESP_554},  /* Transaction failed */	{NULL,   0,  0}};SMTPSearch _smtp_resp_search[RESP_LAST];const SMTPToken _smtp_hdrs[] ={    {"Content-type:", 13, HDR_CONTENT_TYPE},    {NULL,             0, 0}};SMTPSearch _smtp_hdr_search[HDR_LAST];const SMTPToken _smtp_data_end[] ={	{"\r\n.\r\n",  5,  DATA_END_1},	{"\n.\r\n",    4,  DATA_END_2},	{"\r\n.\n",    4,  DATA_END_3},	{"\n.\n",      3,  DATA_END_4},	{NULL,         0,  0}};SMTPSearch _smtp_data_end_search[DATA_END_LAST];SMTPSearch *_smtp_current_search;/**************************************************************************//* Private functions ******************************************************/static void             SMTP_Setup(SFSnortPacket *);static void             SMTP_ResetState(void);static void             SMTP_SessionFree(void *);static void             SMTP_NoSessionFree(void);static int              SMTP_GetPacketDirection(SFSnortPacket *, int);static void             SMTP_ProcessClientPacket(SFSnortPacket *);static int              SMTP_ProcessServerPacket(SFSnortPacket *);static void             SMTP_DisableDetect(SFSnortPacket *);static const u_int8_t * SMTP_HandleCommand(SFSnortPacket *, const u_int8_t *, const u_int8_t *);static const u_int8_t * SMTP_HandleData(SFSnortPacket *, const u_int8_t *, const u_int8_t *);static const u_int8_t * SMTP_HandleHeader(SFSnortPacket *, const u_int8_t *, const u_int8_t *);static const u_int8_t * SMTP_HandleDataBody(SFSnortPacket *, const u_int8_t *, const u_int8_t *);#ifdef DETECTION_OPTION_TREEstatic int              SMTP_SearchStrFound(void *, void *, int, void *);#elsestatic int              SMTP_SearchStrFound(void *, int, void *);#endif#ifdef DETECTION_OPTION_TREEstatic int              SMTP_BoundaryStrFound(void *, void *, int , void *);#elsestatic int              SMTP_BoundaryStrFound(void *, int, void *);#endifstatic int              SMTP_GetBoundary(const char *, int);static int              SMTP_IsTlsClientHello(const u_int8_t *, const u_int8_t *);static int              SMTP_IsTlsServerHello(const u_int8_t *, const u_int8_t *);static int              SMTP_IsSSL(const u_int8_t *, int, int);/**************************************************************************/void SMTP_InitCmds(void){    const SMTPToken *tmp;    /* add one to CMD_LAST for NULL entry */    _smtp_cmds = (SMTPToken *)calloc(CMD_LAST + 1, sizeof(SMTPToken));    if (_smtp_cmds == NULL)    {        DynamicPreprocessorFatalMessage("%s(%d) => failed to allocate memory for smtp "                                        "command structure\n",                                         *(_dpd.config_file), *(_dpd.config_line));    }    for (tmp = &_smtp_known_cmds[0]; tmp->name != NULL; tmp++)    {        _smtp_cmds[tmp->search_id].name_len = tmp->name_len;        _smtp_cmds[tmp->search_id].search_id = tmp->search_id;        _smtp_cmds[tmp->search_id].name = strdup(tmp->name);        if (_smtp_cmds[tmp->search_id].name == NULL)        {            DynamicPreprocessorFatalMessage("%s(%d) => failed to allocate memory for smtp "                                            "command structure\n",                                             *(_dpd.config_file), *(_dpd.config_line));        }    }    /* initialize memory for command searches */    _smtp_cmd_search = (SMTPSearch *)calloc(CMD_LAST, sizeof(SMTPSearch));    if (_smtp_cmd_search == NULL)    {        DynamicPreprocessorFatalMessage("%s(%d) => failed to allocate memory for smtp "                                        "command structure\n",                                         *(_dpd.config_file), *(_dpd.config_line));    }}/* * Initialize SMTP searches * * @param  none * * @return none */void SMTP_SearchInit(void){    const char *error;    int erroffset;    const SMTPToken *tmp;    /* Initialize searches */    _dpd.searchAPI->search_init(NUM_SEARCHES);    /* Command search */    for (tmp = _smtp_cmds; tmp->name != NULL; tmp++)    {        _smtp_cmd_search[tmp->search_id].name = tmp->name;        _smtp_cmd_search[tmp->search_id].name_len = tmp->name_len;                _dpd.searchAPI->search_add(SEARCH_CMD, tmp->name, tmp->name_len, tmp->search_id);    }    _dpd.searchAPI->search_prep(SEARCH_CMD);    /* Response search */    for (tmp = &_smtp_resps[0]; tmp->name != NULL; tmp++)    {        _smtp_resp_search[tmp->search_id].name = tmp->name;        _smtp_resp_search[tmp->search_id].name_len = tmp->name_len;        _dpd.searchAPI->search_add(SEARCH_RESP, tmp->name, tmp->name_len, tmp->search_id);    }    _dpd.searchAPI->search_prep(SEARCH_RESP);    /* Header search */    for (tmp = &_smtp_hdrs[0]; tmp->name != NULL; tmp++)    {        _smtp_hdr_search[tmp->search_id].name = tmp->name;        _smtp_hdr_search[tmp->search_id].name_len = tmp->name_len;        _dpd.searchAPI->search_add(SEARCH_HDR, tmp->name, tmp->name_len, tmp->search_id);    }    _dpd.searchAPI->search_prep(SEARCH_HDR);    /* Data end search */    for (tmp = &_smtp_data_end[0]; tmp->name != NULL; tmp++)    {        _smtp_data_end_search[tmp->search_id].name = tmp->name;        _smtp_data_end_search[tmp->search_id].name_len = tmp->name_len;        _dpd.searchAPI->search_add(SEARCH_DATA_END, tmp->name, tmp->name_len, tmp->search_id);    }    _dpd.searchAPI->search_prep(SEARCH_DATA_END);    /* create regex for finding boundary string - since it can be cut across multiple     * lines, a straight search won't do. Shouldn't be too slow since it will most     * likely only be acting on a small portion of data */    //"^content-type:\\s*multipart.*boundary\\s*=\\s*\"?([^\\s]+)\"?"    //"^\\s*multipart.*boundary\\s*=\\s*\"?([^\\s]+)\"?"    //_mime_boundary_pcre.re = pcre_compile("^.*boundary\\s*=\\s*\"?([^\\s\"]+)\"?",    //_mime_boundary_pcre.re = pcre_compile("boundary(?:\n|\r\n)?=(?:\n|\r\n)?\"?([^\\s\"]+)\"?",    _mime_boundary_pcre.re = pcre_compile("boundary\\s*=\\s*\"?([^\\s\"]+)\"?",                                          PCRE_CASELESS | PCRE_DOTALL,                                          &error, &erroffset, NULL);    if (_mime_boundary_pcre.re == NULL)    {        DynamicPreprocessorFatalMessage("Failed to compile pcre regex for getting boundary "                                        "in a multipart SMTP message: %s\n", error);    }    _mime_boundary_pcre.pe = pcre_study(_mime_boundary_pcre.re, 0, &error);    if (error != NULL)    {        DynamicPreprocessorFatalMessage("Failed to study pcre regex for getting boundary "                                        "in a multipart SMTP message: %s\n", error);    }}/*  * Initialize run-time boundary search */static int SMTP_BoundarySearchInit(void){    if (_smtp->mime_boundary.boundary_search != NULL)        _dpd.searchAPI->search_instance_free(_smtp->mime_boundary.boundary_search);    _smtp->mime_boundary.boundary_search = _dpd.searchAPI->search_instance_new();    if (_smtp->mime_boundary.boundary_search == NULL)        return -1;    _dpd.searchAPI->search_instance_add(_smtp->mime_boundary.boundary_search,                                        _smtp->mime_boundary.boundary,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -