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

📄 spp_rpc_decode.c

📁 Linux snort-2.4.4源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    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;        }    }        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){    u_int8_t *data = p->data;   /* packet data */    u_int16_t *size = &(p->dsize); /* size of packet data */    u_int8_t *rpc;       /* this is where the converted data will be written */    u_int8_t *index;     /* this is the index pointer to walk thru the data */    u_int8_t *end;       /* points to the end of the payload for loop control */    u_int16_t psize = *size;     /* payload size */    int i = 0;           /* loop counter */    int length;          /* length of current fragment */    int last_fragment = 0; /* have we seen the last fragment sign? */    int decoded_len = 4; /* 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? */        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;    }    rpc =   (u_int8_t *) data;    index = (u_int8_t *) 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 */    rpc += 4;    /* always make sure that we have enough data to process atleast     * the header and that we only process at most, one fragment     */        while(((end - 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)       = index[0];        *(((u_int8_t *) &fraghdr) + 1) = index[1];        *(((u_int8_t *) &fraghdr) + 2) = index[2];        *(((u_int8_t *) &fraghdr) + 3) = index[3];        fraghdr = ntohl(fraghdr);        length = fraghdr & 0x7FFFFFFF;                /* move the current index into the packet past the           fragment header */        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((index + length) > 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););                                    if(fragcount == 1)            {                /* adjust the indexes because the records are already                 * in the right spot */                rpc += length;                index += length; /* index is checked against the end above */            }            else            {                                for (i=0; i < length; i++, rpc++, index++)                {                    *rpc = *index;                }            }        }    }    /* rewrite the header on the request packet */    /* move the fragment header back onto the data */        fraghdr = ntohl(decoded_len); /* size */    data[0] = *((u_int8_t *) &fraghdr);    data[1] = *(((u_int8_t *) &fraghdr) + 1);    data[2] = *(((u_int8_t *) &fraghdr) + 2);    data[3] = *(((u_int8_t *) &fraghdr) + 3);        data[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;    }        /* set the payload size to reflect the new size     *     * sizeof(Header) + total payload size of a single message     */    *size = decoded_len; /* this potentially throws away data... */    DEBUG_WRAP(DebugMessage(DEBUG_RPC, "New size: %d\n", decoded_len);               DebugMessage(DEBUG_RPC, "converted data:\n");               //PrintNetData(stdout, data, decoded_len);               );    return 0;}

⌨️ 快捷键说明

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