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

📄 dce2_co.c

📁 snort2.8.4版本
💻 C
📖 第 1 页 / 共 5 页
字号:
/**************************************************************************** * Copyright (C) 2008-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. * **************************************************************************** * Module for handling connection-oriented DCE/RPC processing.  Provides * context id, interface UUID correlation and tracking for use with the * preprocessor rule options.  Provides desegmentation and defragmentation. * Sets appropriate data for use with the preprocessor rule options. * * 8/17/2008 - Initial implementation ... Todd Wease <twease@sourcefire.com> *  ****************************************************************************/#include "dce2_co.h"#include "dce2_tcp.h"#include "dce2_smb.h"#include "snort_dce2.h"#include "dce2_memory.h"#include "dce2_utils.h"#include "dce2_stats.h"#include "dce2_event.h"#include "dce2_debug.h"#include "dcerpc.h"#include "sf_snort_packet.h"#include "sf_dynamic_preprocessor.h"/******************************************************************** * Macros ********************************************************************/#define DCE2_FRAG__MIN_ALLOC_SIZE  50/******************************************************************** * Extern variables ********************************************************************/extern DynamicPreprocessorData _dpd;extern DCE2_Stats dce2_stats;extern char *dce2_pdu_types[DCERPC_PDU_TYPE__MAX];/******************************************************************** * Enumerations ********************************************************************/typedef enum _DCE2_CoRpktType{    DCE2_CO_RPKT_TYPE__SEG,    DCE2_CO_RPKT_TYPE__FRAG,    DCE2_CO_RPKT_TYPE__ALL} DCE2_CoRpktType;typedef enum _DCE2_CoCtxState{    DCE2_CO_CTX_STATE__ACCEPTED,    DCE2_CO_CTX_STATE__REJECTED,    DCE2_CO_CTX_STATE__PENDING} DCE2_CoCtxState;/******************************************************************** * Structures ********************************************************************/typedef struct _DCE2_CoCtxIdNode{    uint16_t ctx_id;           /* The context id */    Uuid iface;                /* The presentation syntax uuid for the interface */    uint16_t iface_vers_maj;   /* The major version of the interface */    uint16_t iface_vers_min;   /* The minor version of the interface */    /* Whether or not the server accepted or rejected the client bind/alter context     * request.  Initially set to pending until server response */    DCE2_CoCtxState state;} DCE2_CoCtxIdNode;/******************************************************************** * Private function prototypes ********************************************************************/static DCE2_Ret DCE2_CoHdrChecks(DCE2_SsnData *, DCE2_CoTracker *, const DceRpcCoHdr *);static void DCE2_CoDecode(DCE2_SsnData *, DCE2_CoTracker *,                          const uint8_t *, uint16_t);static void DCE2_CoSegDecode(DCE2_SsnData *, DCE2_CoTracker *, DCE2_CoSeg *);static void DCE2_CoBind(DCE2_SsnData *, DCE2_CoTracker *,                        const DceRpcCoHdr *, const uint8_t *, uint16_t);static void DCE2_CoAlterCtx(DCE2_SsnData *, DCE2_CoTracker *,                            const DceRpcCoHdr *, const uint8_t *, uint16_t);static void DCE2_CoCtxReq(DCE2_SsnData *, DCE2_CoTracker *, const DceRpcCoHdr *,                          const uint8_t, const uint8_t *, uint16_t);static void DCE2_CoBindAck(DCE2_SsnData *, DCE2_CoTracker *,                           const DceRpcCoHdr *, const uint8_t *, uint16_t);static void DCE2_CoRequest(DCE2_SsnData *, DCE2_CoTracker *,                           const DceRpcCoHdr *, const uint8_t *, uint16_t);static void DCE2_CoResponse(DCE2_SsnData *, DCE2_CoTracker *,                            const DceRpcCoHdr *, const uint8_t *, uint16_t);static void DCE2_CoHandleFrag(DCE2_SsnData *, DCE2_CoTracker *,                              const DceRpcCoHdr *, const uint8_t *, uint16_t);static INLINE DCE2_Ret DCE2_CoHandleSegmentation(DCE2_CoSeg *, const uint8_t *,                                                 uint16_t, uint16_t, uint16_t *);static void DCE2_CoReassemble(DCE2_SsnData *, DCE2_CoTracker *, DCE2_CoRpktType);static INLINE void DCE2_CoFragReassemble(DCE2_SsnData *, DCE2_CoTracker *);static INLINE void DCE2_CoSegReassemble(DCE2_SsnData *, DCE2_CoTracker *);static DCE2_Ret DCE2_CoSetIface(DCE2_SsnData *, DCE2_CoTracker *, uint16_t);static int DCE2_CoCtxCompare(const void *, const void *);static void DCE2_CoCtxFree(void *);static INLINE void DCE2_CoSetRopts(DCE2_SsnData *, DCE2_CoTracker *, const DceRpcCoHdr *);static INLINE void DCE2_CoSetRdata(DCE2_CoTracker *, uint8_t *, uint16_t);static INLINE void DCE2_CoResetTracker(DCE2_CoTracker *);static INLINE void DCE2_CoResetForMissedPkts(DCE2_CoTracker *, const SFSnortPacket *);static INLINE DCE2_Ret DCE2_CoInitCtxStorage(DCE2_CoTracker *);static INLINE int DCE2_CoAutodetect(const uint8_t *, uint16_t);static INLINE void DCE2_CoEraseCtxIds(DCE2_CoTracker *);static INLINE int DCE2_CoMissedPkts(DCE2_CoTracker *, const SFSnortPacket *);static INLINE void DCE2_CoSegAlert(DCE2_SsnData *, DCE2_CoTracker *, DCE2_Event);static INLINE SFSnortPacket * DCE2_CoGetSegRpkt(DCE2_SsnData *, const uint8_t *, uint32_t);static INLINE DCE2_RpktType DCE2_CoGetRpktType(DCE2_SsnData *, DCE2_BufType);static SFSnortPacket * DCE2_CoGetRpkt(DCE2_SsnData *, DCE2_CoTracker *, DCE2_CoRpktType, DCE2_RpktType *);static INLINE int DCE2_CoIsSegBuf(DCE2_SsnData *, DCE2_CoTracker *, const uint8_t *);static void DCE2_CoEarlyReassemble(DCE2_SsnData *, DCE2_CoTracker *);static DCE2_Ret DCE2_CoSegEarlyRequest(DCE2_CoTracker *, const uint8_t *, uint32_t);/******************************************************************** * Function: DCE2_CoInitRdata() * * Initializes header of defragmentation reassembly packet. * Sets relevant fields in header that will not have to change * from reassembly to reassembly.  The reassembly buffer used is * big enough for the header. * * Arguments: *  uint8_t * *      Pointer to the place in the reassembly packet to set *      the header data. * * Returns: None * ********************************************************************/void DCE2_CoInitRdata(uint8_t *co_ptr){    DceRpcCoHdr *co_hdr = (DceRpcCoHdr *)co_ptr;    /* Set some relevant fields.  These should never get reset */    co_hdr->pversion.major = DCERPC_PROTO_MAJOR_VERS__5;    co_hdr->ptype = DCERPC_PDU_TYPE__REQUEST;    co_hdr->pfc_flags = (DCERPC_CO_PFC_FLAGS__FIRST_FRAG | DCERPC_CO_PFC_FLAGS__LAST_FRAG);    co_hdr->packed_drep[0] = 0x10;   /* Little endian */}/******************************************************************** * Function: DCE2_CoSetRdata() * * Sets relevant fields in the defragmentation reassembly packet * based on data gathered from the session and reassembly phase. * The reassembly buffer used is big enough for the headers. * * Arguments: *  DCE2_CoTracker * *      Pointer to the relevant connection-oriented tracker. *  uint8_t *  *      Pointer to the place in the reassembly packet where the *      header starts. *  uint16_t  *      The length of the stub data. * * Returns: None * ********************************************************************/static INLINE void DCE2_CoSetRdata(DCE2_CoTracker *cot, uint8_t *co_ptr, uint16_t stub_len){    DceRpcCoHdr *co_hdr = (DceRpcCoHdr *)co_ptr;    DceRpcCoRequest *co_req = (DceRpcCoRequest *)((uint8_t *)co_hdr + sizeof(DceRpcCoHdr));    /* If we've set the fragment tracker context id or opnum, use them.     * Won't get to this point if cot ctx_id or opnum are not set */    uint16_t ctx_id = (cot->frag_tracker.ctx_id != DCE2_SENTINEL) ? (uint16_t)cot->frag_tracker.ctx_id : (uint16_t)cot->ctx_id;    uint16_t opnum = (cot->frag_tracker.opnum != DCE2_SENTINEL) ? (uint16_t)cot->frag_tracker.opnum : (uint16_t)cot->opnum;    uint32_t flen = sizeof(DceRpcCoHdr) + sizeof(DceRpcCoRequest) + stub_len;    if (flen > UINT16_MAX)        flen = UINT16_MAX;    co_hdr->frag_length = DceRpcHtons((uint16_t)flen, DCERPC_BO_FLAG__LITTLE_ENDIAN);    co_req->context_id = DceRpcHtons(ctx_id, DCERPC_BO_FLAG__LITTLE_ENDIAN);    co_req->opnum = DceRpcHtons(opnum, DCERPC_BO_FLAG__LITTLE_ENDIAN);}/******************************************************************** * Function: DCE2_CoProcess() * * Main entry point for connection-oriented DCE/RPC processing. * It attempts to handle missed packets and overlapped bytes, * i.e. bytes we've already seen and processed.  Since there can * be more than one DCE/RPC pdu in the packet, it loops through * the packet data until none is left.  It handles transport layer * segmentation and buffers data until it gets the full pdu, then * hands off to pdu processing. * * Arguments: *  DCE2_SsnData * *      Pointer to the session data structure. *  DCE2_CoTracker * *      Pointer to the relevant connection-oriented tracker. *  const uint8_t * *      Pointer to packet data *  uint16_t *      Packet data length * * Returns: None * ********************************************************************/void DCE2_CoProcess(DCE2_SsnData *sd, DCE2_CoTracker *cot,                    const uint8_t *data_ptr, uint16_t data_len){    DCE2_CoSeg *seg;    DCE2_Ret status;    uint32_t num_frags = 0;    dce2_stats.co_pkts++;    /* Set the appropriate segmentation buffer */    if (DCE2_SsnFromServer(sd->wire_pkt))        seg = &cot->srv_seg;    else        seg = &cot->cli_seg;    /* Check to see if we've missed packets */    if (DCE2_SsnMissedPkts(sd) || DCE2_CoMissedPkts(cot, sd->wire_pkt))    {        DCE2_DEBUG_MSG(DCE2_DEBUG__CO, "CO missed pkts ...\n");        DCE2_CoResetForMissedPkts(cot, sd->wire_pkt);        /* If we don't autodetect, consider this another missed packet */        if (!DCE2_CoAutodetect(data_ptr, data_len))            return;        /* Reset tracker missed packets, since we've just         * dealt with it */        if (cot->cli_missed_pkts)            cot->cli_missed_pkts = 0;        else if (cot->srv_missed_pkts)            cot->srv_missed_pkts = 0;    }    while (data_len > 0)    {        num_frags++;        DCE2_DEBUG_MSG(DCE2_DEBUG__CO, "DCE/RPC message number: %u\n", num_frags);        /* Fast track full fragments */        if (DCE2_BufferIsEmpty(seg->buf))        {            const uint8_t *frag_ptr = data_ptr;            uint16_t frag_len;            uint16_t data_used;            /* Not enough data left for a header.  Buffer it and return */            if (data_len < sizeof(DceRpcCoHdr))            {                DCE2_DEBUG_MSG(DCE2_DEBUG__CO, "Not enough data in packet for CO header.\n");                DCE2_CoHandleSegmentation(seg, data_ptr, data_len, sizeof(DceRpcCoHdr), &data_used);                /* Just break out of loop in case early detect is enabled */                break;            }            if (DCE2_CoHdrChecks(sd, cot, (DceRpcCoHdr *)data_ptr) != DCE2_RET__SUCCESS)                return;            frag_len = DceRpcCoFragLen((DceRpcCoHdr *)data_ptr);            /* Not enough data left for the pdu. */            if (data_len < frag_len)            {                DCE2_DEBUG_MSG(DCE2_DEBUG__CO, "Not enough data in packet for fragment length.\n");                /* Set frag length so we don't have to check it again in seg code */                seg->frag_len = frag_len;                DCE2_CoHandleSegmentation(seg, data_ptr, data_len, frag_len, &data_used);                break;            }            DCE2_MOVE(data_ptr, data_len, frag_len);            /* Got a full DCE/RPC pdu */            DCE2_CoDecode(sd, cot, frag_ptr, frag_len);            /* If we're configured to do defragmentation only detect on first frag             * since we'll detect on reassembled */            if (!DCE2_GcDceDefrag() || (num_frags == 1))                DCE2_Detect(sd);        }        else  /* We've already buffered data */        {            uint16_t data_used;            DCE2_DEBUG_MSG(DCE2_DEBUG__CO, "Segmentation buffer has %u bytes\n",                           DCE2_BufferLength(seg->buf));            /* Need more data to get header */            if (DCE2_BufferLength(seg->buf) < sizeof(DceRpcCoHdr))            {                status = DCE2_CoHandleSegmentation(seg, data_ptr, data_len, sizeof(DceRpcCoHdr), &data_used);                /* Still not enough for header */                if (status != DCE2_RET__SUCCESS)                    break;                /* Move the length of the amount of data we used to get header */                DCE2_MOVE(data_ptr, data_len, data_used);                if (DCE2_CoHdrChecks(sd, cot, (DceRpcCoHdr *)DCE2_BufferData(seg->buf)) != DCE2_RET__SUCCESS)                {                    DCE2_BufferEmpty(seg->buf);                    return;                }                seg->frag_len = DceRpcCoFragLen((DceRpcCoHdr *)DCE2_BufferData(seg->buf));            }            /* Need more data for full pdu */            if (DCE2_BufferLength(seg->buf) < seg->frag_len)            {                status = DCE2_CoHandleSegmentation(seg, data_ptr, data_len, seg->frag_len, &data_used);                /* Still not enough */                if (status != DCE2_RET__SUCCESS)                    break;                DCE2_MOVE(data_ptr, data_len, data_used);            }            /* Got the full DCE/RPC pdu. Need to create new packet before decoding */            DCE2_CoSegDecode(sd, cot, seg);        }    }    if (DCE2_GcReassembleEarly())        DCE2_CoEarlyReassemble(sd, cot);}/******************************************************************** * Function: DCE2_CoHandleSegmentation() * * Wrapper around DCE2_HandleSegmentation() to allocate a new * buffer object if necessary.  * * Arguments: *  DCE2_CoSeg * *      Pointer to a connection-oriented segmentation structure. *  uint8_t * *      Pointer to the current data cursor in packet. *  uint16_t

⌨️ 快捷键说明

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