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

📄 spp_rpc_decode.c

📁 著名的入侵检测系统snort的最新版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    }    /* check the port list */    if(!(RpcDecodePorts[(p->dp/8)] & (1<<(p->dp%8))))    {        return;    }    PREPROC_PROFILE_START(rpcdecodePerfStats);    ret = ConvertRPC(p);    DEBUG_WRAP(DebugMessage(DEBUG_RPC,"Got ret: %d from ConvertRPC\n", ret););        if(ret != 0)    {        switch(ret)        {        case RPC_FRAG_TRAFFIC:            if(rpcpreprocdata.alert_fragments)            {                SnortEventqAdd(GENERATOR_SPP_RPC_DECODE, RPC_FRAG_TRAFFIC,                         1, RPC_CLASS, 3, RPC_FRAG_TRAFFIC_STR, 0);            }            break;        case RPC_MULTIPLE_RECORD:            if(rpcpreprocdata.alert_multi)            {                SnortEventqAdd(GENERATOR_SPP_RPC_DECODE, RPC_MULTIPLE_RECORD,                         1, RPC_CLASS, 3, RPC_MULTIPLE_RECORD_STR, 0);            }            break;        case RPC_LARGE_FRAGSIZE:            if(rpcpreprocdata.alert_large)            {                SnortEventqAdd(GENERATOR_SPP_RPC_DECODE, RPC_LARGE_FRAGSIZE,                         1, RPC_CLASS, 3, RPC_LARGE_FRAGSIZE_STR, 0);            }            break;        case RPC_INCOMPLETE_SEGMENT:            if(rpcpreprocdata.alert_incomplete)            {                SnortEventqAdd(GENERATOR_SPP_RPC_DECODE, RPC_INCOMPLETE_SEGMENT,                         1, RPC_CLASS, 3, RPC_INCOMPLETE_SEGMENT_STR, 0);            }            break;        case RPC_ZERO_LENGTH_FRAGMENT:            if(rpcpreprocdata.alert_multi)            {                SnortEventqAdd(GENERATOR_SPP_RPC_DECODE, RPC_ZERO_LENGTH_FRAGMENT,                         1, RPC_CLASS, 3, RPC_ZERO_LENGTH_FRAGMENT_STR, 0);            }            break;        }    }        PREPROC_PROFILE_END(rpcdecodePerfStats);    return;    }/* most significant bit */#define MSB 0x80000000/* * For proto ref, see rfc1831 section 10 and page 445 UNP vol2 *   * check to make sure we've got enough data to process a record * * Where did the original 16 come from?  It seems that it could be * a last frag of 0 length according to spec. * * The minimum "valid" packet for us is 8 fields * 4 bytes * * This decoder is ignorant of TCP state so we'll have to assume * that reassembled TCP stuff is reinjected to the preprocessor * chain * * This decoder is also ignorant of multiple RPC requests in a * single stream.  To compensate, we can configure alerts * * Additionally, we don't do anything to verify that this is * really an RPC service port so we don't decode anything that * happens as a result * * From rfc1831: * *  Fragment Header ( 1 flag bit, 31 bit uint ) *     RPC Body *   *        unsigned int xid  *        struct call_body { *             unsigned int rpcvers;  // must be equal to two (2)  *             unsigned int prog; *             unsigned int vers; *             unsigned int proc; *             opaque_auth  cred; *             opaque_auth  verf; *        } */int ConvertRPC(Packet *p){    const u_int8_t *data = p->data;   /* packet data */    u_int8_t *norm_index;    u_int8_t *data_index;     /* this is the index pointer to walk thru the data */    u_int8_t *data_end;       /* points to the end of the payload for loop control */    u_int16_t psize = p->dsize;     /* payload size */    int length;          /* length of current fragment */    int last_fragment = 0; /* have we seen the last fragment sign? */    int decoded_len; /* our decoded length is always atleast a 0 byte header */    u_int32_t fraghdr;   /* Used to store the RPC fragment header data */    int fragcount = 0;   /* How many fragment counters have we seen? */    int ret;    u_int8_t *decode_buf_start = &DecodeBuffer[0];    u_int8_t *decode_buf_end = decode_buf_start + DECODE_BLEN;        if(psize < 32)    {        DEBUG_WRAP(DebugMessage(DEBUG_RPC, "Returning due to"                                " small packet size: %d\n ", psize););        return 0;    }    /* on match, normalize the data */    DEBUG_WRAP(DebugMessage(DEBUG_RPC, "Got RPC traffic (%d bytes)!\n", psize););    /* cheesy alignment safe fraghdr = *(uint32_t *) data*/    *((u_int8_t *)  &fraghdr)      = data[0];    *(((u_int8_t *) &fraghdr) + 1) = data[1];    *(((u_int8_t *) &fraghdr) + 2) = data[2];    *(((u_int8_t *) &fraghdr) + 3) = data[3];        /* The fragment header is 4 bytes in network byte order */    fraghdr = ntohl(fraghdr);    length = fraghdr & 0x7FFFFFFF;        /* Check to see if we are on the last fragment */    if(fraghdr & MSB)    {        /* on match, normalize the data */        DEBUG_WRAP(DebugMessage(DEBUG_RPC, "Found Last Fragment: %u!\n",fraghdr););        if((length + 4 != psize) && !(p->packet_flags & PKT_REBUILT_STREAM))        {            DEBUG_WRAP(DebugMessage(DEBUG_RPC, "It's not the only thing in this buffer!"                                    " length: %d psize: %d!\n", length, psize););                        return RPC_MULTIPLE_RECORD;        }        else if ( length == 0 )        {            DEBUG_WRAP(DebugMessage(DEBUG_RPC, "Zero-length RPC fragment detected."                                    " length: %d psize: %d.\n", length, psize););                        return RPC_ZERO_LENGTH_FRAGMENT;        }        return 0;    }    else if(rpcpreprocdata.alert_fragments)    {        return RPC_FRAG_TRAFFIC;    }    norm_index = &DecodeBuffer[0];     data_index = (u_int8_t *)data;    data_end = (u_int8_t *)data + psize;    /* now we know it's in fragmented records, 4 bytes of      * header(of which the most sig bit fragment (0=yes 1=no).      * The header is followed by the value move pointer up 4      * bytes, we need to stuff header in first 4 bytes.       * But the header has the total length...we don't know      * until the end      */        /* This is where decoded data will be written */    norm_index += 4;    decoded_len = 4;    /* always make sure that we have enough data to process atleast     * the header and that we only process at most, one fragment     */        while(((data_end - data_index) >= 4) && (last_fragment == 0))    {        /* get the fragment length (31 bits) and move the pointer to           the start of the actual data */        *((u_int8_t *) &fraghdr)       = data_index[0];        *(((u_int8_t *) &fraghdr) + 1) = data_index[1];        *(((u_int8_t *) &fraghdr) + 2) = data_index[2];        *(((u_int8_t *) &fraghdr) + 3) = data_index[3];        fraghdr = ntohl(fraghdr);        length = fraghdr & 0x7FFFFFFF;                /* move the current index into the packet past the           fragment header */        data_index += 4;                 if(fraghdr & MSB)        {            DEBUG_WRAP(DebugMessage(DEBUG_RPC, "Last Fragment detected\n"););            last_fragment = 1;        }        if((length + decoded_len) < decoded_len)        {            /* don't allow integer overflow to confuse us.  Should be             * caught by length > psize but who knows when weird             * psize's might be allowed */                        DEBUG_WRAP(DebugMessage(DEBUG_RPC, "Integer Overflow"                                    " field(%d) exceeds packet size(%d)\n",                                    length, psize););            return RPC_LARGE_FRAGSIZE;        }        decoded_len += length;        if(length > psize)        {            DEBUG_WRAP(DebugMessage(DEBUG_RPC, "Length of"                                    " field(%d) exceeds packet size(%d)\n",                                    length, psize););            return RPC_INCOMPLETE_SEGMENT;        }        else if(decoded_len > psize)        {            /* The entire request is larger than our current packet             *  size             */            DEBUG_WRAP(DebugMessage(DEBUG_RPC, " Decoded Length (%d)"                                    "exceeds packet size(%d)\n",                                    decoded_len, psize););            return RPC_LARGE_FRAGSIZE;        }        else if((data_index + length) > data_end)        {            DEBUG_WRAP(DebugMessage(DEBUG_RPC,                                    "returning LARGE_FRAGSIZE"                                    "since we'd read past our end\n"););            return RPC_LARGE_FRAGSIZE;        }        else        {            fragcount++;                        DEBUG_WRAP(DebugMessage(DEBUG_RPC,                                    "length: %d size: %d decoded_len: %d\n",                                    length, psize, decoded_len););                                    ret = SafeMemcpy(norm_index, data_index, length, decode_buf_start, decode_buf_end);            if (ret != SAFEMEM_SUCCESS)            {                return 0;            }            norm_index += length;            data_index += length;        }    }    /* rewrite the header on the request packet */    /* move the fragment header back onto the data */        fraghdr = ntohl(decoded_len); /* size */    DecodeBuffer[0] = *((u_int8_t *) &fraghdr);    DecodeBuffer[1] = *(((u_int8_t *) &fraghdr) + 1);    DecodeBuffer[2] = *(((u_int8_t *) &fraghdr) + 2);    DecodeBuffer[3] = *(((u_int8_t *) &fraghdr) + 3);        DecodeBuffer[0] |=  0x80;             /* Mark as unfragmented */    /* is there another request encoded that is trying to evade us by doing     *     * frag last frag [ more data ]?     */    if(decoded_len + ((fragcount - 1) * 4) != psize)    {        DEBUG_WRAP(DebugMessage(DEBUG_RPC, "decoded len does not compute: %d\n",                                decoded_len););        return RPC_MULTIPLE_RECORD;    }    DEBUG_WRAP(DebugMessage(DEBUG_RPC, "New size: %d\n", decoded_len);               DebugMessage(DEBUG_RPC, "converted data:\n");               //PrintNetData(stdout, data, decoded_len);               );    p->alt_dsize = decoded_len;    p->packet_flags |= PKT_ALT_DECODE;    return 0;}

⌨️ 快捷键说明

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