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

📄 smtp_xlink2state.c

📁 Snort为国际上著名的轻量型入侵防御系统,为国内多家著名“自主知识产权”网络安全公司所使用。
💻 C
字号:
/* * smtp_xlink2state.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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. * * Copyright (C) 2005 Sourcefire Inc. * * Author: Andy  Mullican * * Description: * * This file handles the X-Link2State vulnerability. * * Entry point function: * *    ParseXLink2State() * * */#ifndef WIN32#include <strings.h>#endif#include <ctype.h>#include "snort_packet_header.h"#include "snort_smtp.h"#include "smtp_util.h"extern SMTP         *_smtp;extern SMTP_CONFIG   _smtp_config;#define XLINK_OTHER     1#define XLINK_FIRST     2#define XLINK_CHUNK     3#define XLINK_LEN      12   /* strlen("X-LINK2STATE") *//* * Check for X-LINK2STATE keywords FIRST or CHUNK *    * * @param   x           pointer to "X-LINK2STATE" in buffer * @param   x_len       length of buffer after x * * @retval  int         identifies which keyword found, if any */static u_int CheckKeyword(u_int8_t *x, u_int x_len){    x += XLINK_LEN;      x_len -= XLINK_LEN;    /* Skip over spaces */    while ( isspace(*x) && x_len != 0 )    {        x++;        x_len--;    }    if ( x_len > 5 && !strncasecmp(x, "FIRST", 5) )        return XLINK_FIRST;    if ( x_len > 5 && !strncasecmp(x, "CHUNK", 5) )        return XLINK_CHUNK;    return XLINK_OTHER;}/* * Handle X-Link2State vulnerability *    *  From Lurene Grenier:     The X-LINK2STATE command always takes the following form:    X-LINK2STATE [FIRST|NEXT|LAST] CHUNK=<SOME DATA>    The overwrite occurs when three criteria are met:    No chunk identifier exists - ie neither FIRST, NEXT, or LAST are specified    No previous FIRST chunk was sent    <SOME DATA> has a length greater than 520 bytes    Normally you send a FIRST chunk, then some intermediary chunks marked with    either NEXT or not marked, then finally a LAST chunk.  If no first chunk is    sent, and a chunk with no specifier is sent, it assumes it must append to    something, but it has nothing to append to, so an overwrite occurs. Sending out    of order chunks WITH specifiers results in an exception.    So simply:    if (gotFirstChunk)        next; # chunks came with proper first chunk specified    if (/X-LINK2STATE [FIRST|NEXT|LAST] CHUNK/) {        if (/X-LINK2STATE FIRST CHUNK/) gotFirstChunk = TRUE;        next; # some specifier is marked     }    if (chunkLen > 520)       attempt = TRUE; # Gotcha!    Usually it takes more than one unspecified packet in a row, but I think this is    just a symptom of the fact that we're triggering a heap overwrite, and not a    condition of the bug. However, if we're still getting FPs this might be an    avenue to try. * * @param   p           standard Packet structure * @param   x           pointer to "X-LINK2STATE" in buffer * * @retval  1           if alert raised * @retval  0           if no alert raised */int ParseXLink2State(SFSnortPacket *p, u_int8_t *x){    u_int8_t *eq;    u_int8_t *start;    u_int8_t *lf;    u_int32_t len = 0;    u_int     x_len;    u_int     x_keyword;    /* If we got a FIRST chunk on this stream, this is not an exploit */    if ( _smtp->xlink2state_gotfirstchunk )        return 0;    /* Calculate length from pointer to end of packet data */    x_len = p->payload_size - (x - p->payload);    /* Check for "FIRST" or "CHUNK" after X-LINK2STATE */    x_keyword = CheckKeyword(x, x_len);    if ( x_keyword == XLINK_OTHER )        return 0;    if ( x_keyword == XLINK_FIRST )    {        _smtp->xlink2state_gotfirstchunk = 1;        return 0;    }    /* Must be XLINK_CHUNK */    eq = safe_strchr(x, '=', x_len);    if ( !eq )        return 0;    /*  Look for one of two patterns:        ... CHUNK={0000006d} MULTI (5) ({00000000051} ...        ... CHUNK=AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n     */    if ( *(eq+1) == '{' )    {        /* Parse length - can we always trust it? */        start = eq + 2;        /* The number is hex, so pass in base 16.  16^8 - 1 is the max size of an unsigned long. */         len = safe_sscanf(start, 8, 16);    }    else    {        start = eq + 1;    }    if ( len == 0 )    {        lf = safe_strchr(x, '\n', x_len);        if ( !lf )            return 0;        len = lf - start;    }    if ( len > XLINK2STATE_MAX_LEN )    {        /* Need to drop the packet if we're told to         * and we're inline mode (outside of whether its         * thresholded). */        if (_smtp_config.drop_xlink2state && _dpd.inlineMode())        {            _dpd.inlineDrop(p);        }        _dpd.alertAdd(GENERATOR_SMTP, 1, 1, 0, 3, "X-Link2State command: attempted buffer overflow", 0);        _smtp->xlink2state_alerted = 1;        return 1;    }    /* Check for more than one command in packet */    lf = safe_strchr(x, '\n', x_len);    if ( !lf )        return 0;    if ( (u_int) (lf - x + 1) < x_len )    {        x = lf + 1;        ParseXLink2State(p, x);    }    return 0;}

⌨️ 快捷键说明

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