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

📄 netbios_writex.c

📁 This is the snapshot of Snot Latest Rules
💻 C
字号:
/* * SMB WriteX overflow - CVE-2006-5276 *  * Copyright (C) 2007 Sourcefire, Inc. All Rights Reserved *  * Writen by Brian Caswell <bmc@sourcefire.com> *  * Structs from SPP_DCERPC, by Andrew Mullican <amullican@sourcefire.com> * * This file may contain proprietary rules that were created, tested and * certified by Sourcefire, Inc. (the "VRT Certified Rules") as well as * rules that were created by Sourcefire and other third parties and * distributed under the GNU General Public License (the "GPL Rules").  The * VRT Certified Rules contained in this file are the property of * Sourcefire, Inc. Copyright 2005 Sourcefire, Inc. All Rights Reserved. * The GPL Rules created by Sourcefire, Inc. are the property of * Sourcefire, Inc. Copyright 2002-2005 Sourcefire, Inc. All Rights * Reserved.  All other GPL Rules are owned and copyrighted by their * respective owners (please see www.snort.org/contributors for a list of * owners and their respective copyrights).  In order to determine what * rules are VRT Certified Rules or GPL Rules, please refer to the VRT * Certified Rules License Agreement. */// #include <syslog.h>#include "sf_snort_plugin_api.h"#include "sf_snort_packet.h"#include <stdio.h>#include <stdint.h>#include <stdlib.h>#ifdef WIN32#pragma pack(push,smb_hdrs,1)#else#pragma pack(1)#endif#if defined(__ia64__) || defined(__x86_64__) || defined(__i386__) || defined (M_I86) || defined (_M_IX86) || defined (WIN32)#define smb_htons(A)  (A)#define smb_htonl(A)  (A)#define smb_ntohs(A)  (A)#define smb_ntohl(A)  (A)#else#define smb_htons(A)  ((((u_int16_t)(A) & 0xff00) >> 8) | (((u_int16_t)(A) & 0x00ff) << 8))#define smb_htonl(A)  ((((u_int32_t)(A) & 0xff000000) >> 24) | (((u_int32_t)(A) & 0x00ff0000) >> 8)  | (((u_int32_t)(A) & 0x0000ff00) << 8)  | (((u_int32_t)(A) & 0x000000ff) << 24))#define smb_ntohs     smb_htons#define smb_ntohl     smb_htonl#endiftypedef struct _andx_header{    u_int8_t wc;     u_int8_t next_command;    u_int8_t reserved;    u_int16_t next_command_offset;} ANDX_HEADER;typedef struct _writex_header{    u_int8_t wc;    u_int8_t next_command;    u_int8_t reserved;    u_int16_t next_command_offset;    u_int16_t fid;    u_int32_t offset;    u_int32_t reserved2;    u_int16_t writeMode;    u_int16_t remaining;    u_int16_t dataLengthHigh;    u_int16_t dataLength;    u_int16_t dataOffset;    u_int32_t highOffset;    u_int16_t byteCount;} WRITEX_HEADER;typedef struct _smb_header{    u_int8_t protocol[4];      /* Should always be 0xff,SMB */    u_int8_t command;          /* Command code */    union    {        /* 32 Bits */        struct {            u_int8_t errClass; /* Error class */            u_int8_t reserved; /* Should be 0 */            u_int16_t err;     /* Error code */        } dosErr;        u_int32_t ntErrCode;    /* 32-bit Error code */    } status;    u_int8_t flags;            /* Flags */    u_int16_t flags2;          /* 8 bits weren't enough */    union    {        u_int16_t pad[6];      /* Make this 12 bytes long */        struct        {            u_int16_t pidHigh; /* Upper 16 bits of PID */            u_int32_t unused;            u_int32_t unusedToo;        } extra;    } extended;    u_int16_t tid;             /* Tree ID */    u_int16_t pid;             /* Process ID */    u_int16_t uid;             /* User ID */    u_int16_t mid;             /* Multiplex ID */} SMB_HEADER;/* declare detection functions */int ruleWriteXeval(void *p);static RuleReference ruleWriteXref1 = {    "cve",     "2006-5276"};static RuleReference *ruleWriteXrefs[] ={    &ruleWriteXref1,    NULL};static ContentInfo ruleWriteXcontent1 ={    (u_int8_t *)"|FF|SMB", /* pattern */    4, /* depth */    4, /* offset */    CONTENT_FAST_PATTERN,    NULL, /* holder for boyer/moore PTR */    NULL, /* more holder info - byteform */    0 /* byteform length */};static RuleOption ruleWriteXoption0 ={    OPTION_TYPE_CONTENT,    {        &ruleWriteXcontent1    }};RuleOption *ruleWriteXoptions[] ={    &ruleWriteXoption0,    NULL};Rule ruleWriteX = {   /* rule header, akin to => tcp any any -> any any               */   {       IPPROTO_TCP, /* proto */       "any", /* SRCIP     */       "any", /* SRCPORT   */       0, /* DIRECTION */       "any", /* DSTIP     */       "any", /* DSTPORT   */   },   /* metadata */   {        3,   /* genid (HARDCODED!!!) */       10161,   /* sigid 854383f6-1272-4126-af13-273c4f4df425 */       5,   /* revision  8c14a28e-2bbd-4c96-8e45-ce42decf3746 */       "attempted-admin", /* classification, generic */       0,   /* hardcoded priority XXX NOT PROVIDED BY GRAMMAR YET! */       "NETBIOS SMB write_andx overflow attempt", /* message */       ruleWriteXrefs /* ptr to references */#ifdef HAS_METADATA        ,NULL#endif   },   ruleWriteXoptions, /* ptr to rule options */   &ruleWriteXeval, /* ptr to rule detection function */   0, /* am I initialized yet? */   0, /* number of options */   0  /* don't alert */};int process_writex (char *data, int size, u_int8_t command, int offset){    WRITEX_HEADER *writex;    u_int32_t writex_len;    u_int16_t data_offset;        if (size < offset + sizeof(WRITEX_HEADER)) {        return -7;    }    writex = (WRITEX_HEADER *) (data + offset);    data_offset = smb_ntohs(writex->dataOffset);        if (offset > data_offset) {        return 3;    }    writex_len = data_offset - offset;    /*      * grr.  1 byte of pad is common.  1 byte of pad causes overwrite.     * 1 byte overwrite can be exploitable.  Can't alert on 1 byte overwrite     * cause that would cause us to alert on normal traffic.     */    if (writex_len > sizeof(WRITEX_HEADER) + 1) {//        syslog(LOG_NOTICE, "writing %d to a buffer of size %d", writex_len, sizeof(WRITEX_HEADER));//        printf("EVIL! %d > %d\n", writex_len, sizeof(WRITEX_HEADER));        return 1;    }    return 0;}int process_command (char *data, int size, u_int8_t command, int offset){    ANDX_HEADER *andx;    int ret = 0;    u_int16_t next_command_offset;        if (offset > size)        return -3;    if (command == 0x2F) {        ret = process_writex(data, size, command, offset);        if (0 != ret)             return ret;    }    if (command == 0x24 || command == 0x2D || command == 0x2E || command == 0x2F ||        command == 0x73 || command == 0x74 || command == 0x75 || command == 0xA2) {        if (size < offset + sizeof(ANDX_HEADER)) {            return -4;        }        andx = (ANDX_HEADER *) (data + offset);        if (andx->next_command == 0xFF) // no more commands        {            return -5;        }        next_command_offset = smb_ntohs(andx->next_command_offset);        if (next_command_offset > size) {            return -6;        }        /* XXX - handle someone looping us around as the overflow */        if (next_command_offset <= offset) {            return 2;        }        return process_command(data, size, andx->next_command, next_command_offset);    }    return 0;}int process_packet(char *data, int size){    SMB_HEADER *smb;        if (size < (sizeof(SMB_HEADER) + 4)) {        return -1;    }    data = data + 4;    size = size - 4;    smb = (SMB_HEADER *) (data);/* rule option magic! *///    if (0 != memcmp(smb->protocol, "\xFFSMB", 4)) {//        return -2;//    }    return process_command(data, size, smb->command, 32);}/* detection functions */int ruleWriteXeval(void *p) {    int ret = 0;    const u_int8_t *cursor = 0;    SFSnortPacket *sp = (SFSnortPacket *) p;    if (NULL == sp)        return RULE_NOMATCH;    if (NULL == sp->payload)         return RULE_NOMATCH;    /* minsize = 4 + sizeof(SMB_HEADER) + sizeof(WRITEX) */    /* minsize = 4 + 32 +                 31 */    if (67 > sp->payload_size) {        return RULE_NOMATCH;    }    /*      * this should use the API, but the API might do something additional, so     * we do just like dcerpc does...     */    if(sp->flags & FLAG_FROM_SERVER)        return RULE_NOMATCH;    if (!(contentMatch(p, ruleWriteXoptions[0]->option_u.content, &cursor) > 0))        return RULE_NOMATCH;    ret = process_packet((char *)sp->payload, (int ) sp->payload_size);    if (ret > 0)        return RULE_MATCH;    return RULE_NOMATCH;}

⌨️ 快捷键说明

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