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

📄 dce2_co.c

📁 snort2.8.4版本
💻 C
📖 第 1 页 / 共 5 页
字号:
        }    }}/******************************************************************** * Function: DCE2_CoHandleFrag() * * Handles adding a fragment to the defragmentation buffer. * Does overflow checking.  Maximum length of fragmentation buffer * is based on the maximum packet length Snort can handle. * * Arguments: *  DCE2_SsnData * *      Pointer to the session data structure. *  DCE2_CoTracker * *      Pointer to the relevant connection-oriented tracker. *  DceRpcCoHdr * *      Pointer to the main header in the packet data. *  const uint8_t * *      Pointer to the current processing point of the DCE/RPC *      pdu in the packet data. *  uint16_t *      Fragment length left in the pdu. * * Returns: None * ********************************************************************/static void DCE2_CoHandleFrag(DCE2_SsnData *sd, DCE2_CoTracker *cot,                              const DceRpcCoHdr *co_hdr, const uint8_t *frag_ptr, uint16_t frag_len){    DCE2_CoFragTracker *ft = &cot->frag_tracker;    uint32_t size = (frag_len < DCE2_FRAG__MIN_ALLOC_SIZE) ? DCE2_FRAG__MIN_ALLOC_SIZE : frag_len;    uint16_t max_frag_data;    DCE2_BufferMinAddFlag mflag = DCE2_BUFFER_MIN_ADD_FLAG__USE;    DCE2_Ret status;    if (frag_len > dce2_stats.co_max_frag_size)        dce2_stats.co_max_frag_size = frag_len;    if (ft->frag_buf == NULL)    {        ft->frag_buf = DCE2_BufferNew(size, DCE2_FRAG__MIN_ALLOC_SIZE, DCE2_MEM_TYPE__CO_FRAG);        if (ft->frag_buf == NULL)            return;    }    /* If there's already data in the buffer and this is a first frag     * we probably missed packets */    if (DceRpcCoFirstFrag(co_hdr) && !DCE2_BufferIsEmpty(ft->frag_buf))        DCE2_BufferEmpty(ft->frag_buf);    /* Check for potential overflow */    if (sd->trans == DCE2_TRANS_TYPE__SMB)        max_frag_data = DCE2_GetRpktMaxData(sd, DCE2_RPKT_TYPE__SMB_CO_FRAG);    else        max_frag_data = DCE2_GetRpktMaxData(sd, DCE2_RPKT_TYPE__TCP_CO_FRAG);    if (DCE2_GcMaxFrag() && (frag_len > DCE2_GcMaxFragLen()))        frag_len = DCE2_GcMaxFragLen();    if ((DCE2_BufferLength(ft->frag_buf) + frag_len) > max_frag_data)        frag_len = max_frag_data - (uint16_t)DCE2_BufferLength(ft->frag_buf);    if (frag_len != 0)    {        /* If it's the last fragment we're going to flush so just alloc         * exactly what we need ... or if there is more data than can fit         * in the reassembly buffer */        if (DceRpcCoLastFrag(co_hdr) || (DCE2_BufferLength(ft->frag_buf) == max_frag_data))            mflag = DCE2_BUFFER_MIN_ADD_FLAG__IGNORE;        status = DCE2_BufferAddData(ft->frag_buf, frag_ptr, frag_len, mflag);        if (status != DCE2_RET__SUCCESS)        {            /* Either hit memcap or a memcpy failed - reassemble */            DCE2_CoFragReassemble(sd, cot);            DCE2_BufferEmpty(cot->frag_tracker.frag_buf);            return;        }    }    /* Reassemble if we got a last frag ... */    if (DceRpcCoLastFrag(co_hdr))    {        DCE2_CoFragReassemble(sd, cot);        DCE2_BufferEmpty(cot->frag_tracker.frag_buf);        DCE2_CoResetTracker(cot);        /* Return early - rule opts will be set in reassembly handler */        return;    }    else if (DCE2_BufferLength(ft->frag_buf) == max_frag_data)    {        /* ... or can't fit any more data in the buffer         * Don't reset frag tracker */        DCE2_CoFragReassemble(sd, cot);        DCE2_BufferEmpty(cot->frag_tracker.frag_buf);        return;    }}/******************************************************************** * Function: DCE2_CoFragReassemble() * * Wrapper for the generic reassembly function.  Calls generic * reassembly function specifying that we want to do fragmentation * reassembly. * * Arguments: *  DCE2_SsnData * *      Pointer to the session data structure. *  DCE2_CoTracker * *      Pointer to the relevant connection-oriented tracker. * * Returns: None * ********************************************************************/static INLINE void DCE2_CoFragReassemble(DCE2_SsnData *sd, DCE2_CoTracker *cot){    DCE2_CoReassemble(sd, cot, DCE2_CO_RPKT_TYPE__FRAG);}/******************************************************************** * Function: DCE2_CoSegReassemble() * * Wrapper for the generic reassembly function.  Calls generic * reassembly function specifying that we want to do segmentation * reassembly. * * Arguments: *  DCE2_SsnData * *      Pointer to the session data structure. *  DCE2_CoTracker * *      Pointer to the relevant connection-oriented tracker. * * Returns: None * ********************************************************************/static INLINE void DCE2_CoSegReassemble(DCE2_SsnData *sd, DCE2_CoTracker *cot){    DCE2_CoReassemble(sd, cot, DCE2_CO_RPKT_TYPE__SEG);}/******************************************************************** * Function: DCE2_CoReassemble() * * Gets a reassemly packet based on the transport and the type of * reassembly we want to do.  Sets rule options and calls detect * on the reassembled packet. * * Arguments: *  DCE2_SsnData * *      Pointer to the session data structure. *  DCE2_CoTracker * *      Pointer to the relevant connection-oriented tracker. *  DCE2_CoRpktType *      Specifies whether we want to do segmenation, fragmentation *      or fragmentation and segmentation reassembly. * * Returns: None * ********************************************************************/static void DCE2_CoReassemble(DCE2_SsnData *sd, DCE2_CoTracker *cot, DCE2_CoRpktType co_rtype){    DCE2_RpktType rpkt_type;    DceRpcCoHdr *co_hdr;    SFSnortPacket *rpkt = DCE2_CoGetRpkt(sd, cot, co_rtype, &rpkt_type);    if (rpkt == NULL)        return;    switch (rpkt_type)    {        case DCE2_RPKT_TYPE__SMB_CO_FRAG:        case DCE2_RPKT_TYPE__SMB_CO_SEG:            DCE2_SmbSetRdata((DCE2_SmbSsnData *)sd, (uint8_t *)rpkt->payload,                             (uint16_t)(rpkt->payload_size - DCE2_MOCK_HDR_LEN__SMB));            if (rpkt_type == DCE2_RPKT_TYPE__SMB_CO_FRAG)            {                DCE2_CoSetRdata(cot, (uint8_t *)rpkt->payload + DCE2_MOCK_HDR_LEN__SMB,                                (uint16_t)(rpkt->payload_size - (DCE2_MOCK_HDR_LEN__SMB + DCE2_MOCK_HDR_LEN__CO)));            }            co_hdr = (DceRpcCoHdr *)(rpkt->payload + DCE2_MOCK_HDR_LEN__SMB);            cot->stub_data = rpkt->payload + DCE2_MOCK_HDR_LEN__SMB + DCE2_MOCK_HDR_LEN__CO;            break;        case DCE2_RPKT_TYPE__TCP_CO_FRAG:        case DCE2_RPKT_TYPE__TCP_CO_SEG:            if (rpkt_type == DCE2_RPKT_TYPE__TCP_CO_FRAG)            {                DCE2_CoSetRdata(cot, (uint8_t *)rpkt->payload, (uint16_t)(rpkt->payload_size - DCE2_MOCK_HDR_LEN__CO));            }            co_hdr = (DceRpcCoHdr *)rpkt->payload;            cot->stub_data = rpkt->payload + DCE2_MOCK_HDR_LEN__CO;            break;        default:            DCE2_Log("%s(%d) => Invalid transport type\n", __FILE__, __LINE__);            return;    }    /* Push packet onto stack */    if (DCE2_PushPkt(rpkt) != DCE2_RET__SUCCESS)    {        DCE2_Log("%s(%d) => Failed to push packet onto packet stack\n", __FILE__, __LINE__);        return;    }    DCE2_CoSetRopts(sd, cot, co_hdr);    DCE2_DEBUG_MSG(DCE2_DEBUG__CO, "Reassembled CO fragmented packet:\n");    DCE2_DEBUG_CODE(DCE2_DEBUG__CO, DCE2_PrintPktData(rpkt->payload, rpkt->payload_size););    DCE2_Detect(sd);    DCE2_PopPkt();    dce2_stats.co_reassembled++;}/******************************************************************** * Function: DCE2_CoSetIface() * * Sets the interface UUID for the rules options.  Looks in the  * context id list.  If nothing found there, it looks in the pending * list (in case we never saw the server response because of  * missed packets) to see if something is there. * * Arguments: *  DCE2_SsnData * *      Pointer to the session data structure. *  DCE2_CoTracker * *      Pointer to the relevant connection-oriented tracker. *  uint16_t *      The context id to use for the lookup. * * Returns: *  DCE2_Ret *      DCE2_RET__ERROR if the interface UUID could not be found *          based on the context id passed in. *      DCE2_RET__SUCESS if the interface UUID could be found and *          the appropriate rule options could be set. * ********************************************************************/static DCE2_Ret DCE2_CoSetIface(DCE2_SsnData *sd, DCE2_CoTracker *cot, uint16_t ctx_id){    DCE2_CoCtxIdNode *ctx_id_node;    /* This should be set if we've gotten a Bind */    if (cot->ctx_ids == NULL)        return DCE2_RET__ERROR;    ctx_id_node = (DCE2_CoCtxIdNode *)DCE2_ListFind(cot->ctx_ids, (void *)(uintptr_t)ctx_id);    if (ctx_id_node == NULL)  /* context id not found in list */    {        /* See if it's in the queue.  An easy evasion would be to stagger the writes         * and reads such that we see a request before seeing the server bind ack */        if (cot->pending_ctx_ids != NULL)        {            for (ctx_id_node = (DCE2_CoCtxIdNode *)DCE2_QueueFirst(cot->pending_ctx_ids);                 ctx_id_node != NULL;                 ctx_id_node = (DCE2_CoCtxIdNode *)DCE2_QueueNext(cot->pending_ctx_ids))            {                if (ctx_id_node->ctx_id == ctx_id)                    break;            }        }        if (ctx_id_node == NULL)            return DCE2_RET__ERROR;    }    if (ctx_id_node->state == DCE2_CO_CTX_STATE__REJECTED)        return DCE2_RET__ERROR;    DCE2_CopyUuid(&sd->ropts.iface, &ctx_id_node->iface, DCERPC_BO_FLAG__NONE);    sd->ropts.iface_vers_maj = ctx_id_node->iface_vers_maj;    sd->ropts.iface_vers_min = ctx_id_node->iface_vers_min;    return DCE2_RET__SUCCESS;}/******************************************************************** * Function: DCE2_CoCtxCompare() * * Callback to context id list for finding the right interface * UUID node.  Values passed in are context ids which are used as * the keys for the list. * * Arguments: *  const void * *      First context id to compare. *  const void * *      Second context id to compare. * * Returns: *  int *       0 if first value equals second value *      -1 if first value does not equal the second value * ********************************************************************/static int DCE2_CoCtxCompare(const void *a, const void *b){    int x = (int)(uintptr_t)a;    int y = (int)(uintptr_t)b;    if (x == y)        return 0;    /* Only care about equality for finding */    return -1;}/******************************************************************** * Function: DCE2_CoCtxFree() * * Callback to context id list for freeing context id nodes in * the list. * * Arguments: *  void * *      Context id node to free. * * Returns: None * ********************************************************************/static void DCE2_CoCtxFree(void *data){    if (data == NULL)        return;    DCE2_Free(data, sizeof(DCE2_CoCtxIdNode), DCE2_MEM_TYPE__CO_CTX);}/******************************************************************** * Function: DCE2_CoInitTracker() * * Initializes fields in the connection-oriented tracker to * sentinels.  Many decisions are made based on whether or not * these fields have been set. * * Arguments: *  DCE2_CoTracker * *      Pointer to the relevant connection-oriented tracker. * * Returns: None * ********************************************************************/void DCE2_CoInitTracker(DCE2_CoTracker *cot){    if (cot == NULL)        return;    cot->max_xmit_frag = DCE2_SENTINEL;    cot->data_byte_order = DCE2_SENTINEL;    cot->ctx_id = DCE2_SENTINEL;    cot->opnum = DCE2_SENTINEL;    cot->call_id = DCE2_SENTINEL;    cot->stub_data = NULL;    cot->got_bind = 0;    cot->frag_tracker.opnum = DCE2_SENTINEL;    cot->frag_tracker.ctx_id = DCE2_SENTINEL;    cot->frag_tracker.expected_call_id = DCE2_SENT

⌨️ 快捷键说明

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