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

📄 dce2_co.c

📁 snort2.8.4版本
💻 C
📖 第 1 页 / 共 5 页
字号:
        if (ctx_node == NULL)        {            DCE2_Log("%s(%d) => Failed to dequeue a context id node\n", __FILE__, __LINE__);            return;        }        DCE2_DEBUG_MSG(DCE2_DEBUG__CO, "Adding ctx node to context id list.\n"                       "Context id: %u\n"                       "Interface: %s\n"                       "Interface major version: %u\n"                       "Interface minor version: %u\n",                       ctx_node->ctx_id,                       DCE2_UuidToStr(&ctx_node->iface, DCERPC_BO_FLAG__NONE),                       ctx_node->iface_vers_maj, ctx_node->iface_vers_min);        if (result == DCERPC_CO_CONT_DEF_RESULT__ACCEPTANCE)        {            DCE2_DEBUG_MSG(DCE2_DEBUG__CO, "Server accepted context item.\n");            ctx_node->state = DCE2_CO_CTX_STATE__ACCEPTED;            if (DceRpcCoPduType(co_hdr) == DCERPC_PDU_TYPE__BIND_ACK)                cot->got_bind = 1;        }        else        {            DCE2_DEBUG_MSG(DCE2_DEBUG__CO, "Server rejected context item.\n");            ctx_node->state = DCE2_CO_CTX_STATE__REJECTED;            cot->got_bind = 0;        }        existing_ctx_node =            (DCE2_CoCtxIdNode *)DCE2_ListFind(cot->ctx_ids, (void *)(uintptr_t)ctx_node->ctx_id);        if (existing_ctx_node != NULL)        {            switch (policy)            {                case DCE2_POLICY__WIN2000:                case DCE2_POLICY__WIN2003:                case DCE2_POLICY__WINXP:                case DCE2_POLICY__WINVISTA:                    if (ctx_node->state == DCE2_CO_CTX_STATE__REJECTED)                        break;                    if (existing_ctx_node->state == DCE2_CO_CTX_STATE__REJECTED)                    {                        existing_ctx_node->ctx_id = ctx_node->ctx_id;                        DCE2_CopyUuid(&existing_ctx_node->iface, &ctx_node->iface, DCERPC_BO_FLAG__NONE);                        existing_ctx_node->iface_vers_maj = ctx_node->iface_vers_maj;                        existing_ctx_node->iface_vers_min = ctx_node->iface_vers_min;                        existing_ctx_node->state = ctx_node->state;                    }                    break;                case DCE2_POLICY__SAMBA_3_0_20:                case DCE2_POLICY__SAMBA_3_0_22:                case DCE2_POLICY__SAMBA:                    /* Samba actually alters the context.  Windows keeps the old */                    if (ctx_node->state != DCE2_CO_CTX_STATE__REJECTED)                    {                        existing_ctx_node->ctx_id = ctx_node->ctx_id;                        DCE2_CopyUuid(&existing_ctx_node->iface, &ctx_node->iface, DCERPC_BO_FLAG__NONE);                        existing_ctx_node->iface_vers_maj = ctx_node->iface_vers_maj;                        existing_ctx_node->iface_vers_min = ctx_node->iface_vers_min;                        existing_ctx_node->state = ctx_node->state;                    }                    break;                default:                    break;            }            DCE2_Free((void *)ctx_node, sizeof(DCE2_CoCtxIdNode), DCE2_MEM_TYPE__CO_CTX);        }        else        {            status = DCE2_ListInsert(cot->ctx_ids, (void *)(uintptr_t)ctx_node->ctx_id, (void *)ctx_node);            if (status != DCE2_RET__SUCCESS)            {                DCE2_Free((void *)ctx_node, sizeof(DCE2_CoCtxIdNode), DCE2_MEM_TYPE__CO_CTX);                DCE2_Log("%s(%d) => Failed to add context id node to list\n", __FILE__, __LINE__);                return;            }        }    }}/******************************************************************** * Function: DCE2_CoRequest() * * Handles a DCE/RPC request from the client.  This is were the * client actually asks the server to do stuff on it's behalf. * If it's a first/last fragment, set relevant rule option * data and return. If it's a true fragment, do some target * based futzing to set the right opnum and context id for * the to be reassembled packet.   * * 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_CoRequest(DCE2_SsnData *sd, DCE2_CoTracker *cot,                           const DceRpcCoHdr *co_hdr, const uint8_t *frag_ptr, uint16_t frag_len){    DceRpcCoRequest *rhdr = (DceRpcCoRequest *)frag_ptr;    uint16_t req_size = sizeof(DceRpcCoRequest);    DCE2_Policy policy = DCE2_ScPolicy(sd->sconfig);    /* Account for possible object uuid */    if (DceRpcCoObjectFlag(co_hdr))        req_size += sizeof(Uuid);    if (frag_len < req_size)    {        DCE2_Alert(sd, DCE2_EVENT__CO_FLEN_LT_SIZE, dce2_pdu_types[DceRpcCoPduType(co_hdr)],                   frag_len, req_size);        return;    }    switch (policy)    {        case DCE2_POLICY__SAMBA_3_0_20:        case DCE2_POLICY__SAMBA_3_0_22:        case DCE2_POLICY__SAMBA:            cot->data_byte_order = DceRpcCoByteOrder(co_hdr);            break;        default:            break;    }    /* Move past header */    DCE2_MOVE(frag_ptr, frag_len, req_size);    /* If for some reason we had some fragments queued */    if (DceRpcCoFirstFrag(co_hdr) && !DCE2_BufferIsEmpty(cot->frag_tracker.frag_buf))    {        DCE2_CoFragReassemble(sd, cot);        DCE2_BufferEmpty(cot->frag_tracker.frag_buf);        DCE2_CoResetTracker(cot);    }    cot->stub_data = frag_ptr;    cot->opnum = DceRpcCoOpnum(co_hdr, rhdr);    cot->ctx_id = DceRpcCoCtxId(co_hdr, rhdr);    cot->call_id = DceRpcCoCallId(co_hdr);    if (DceRpcCoFirstFrag(co_hdr) && DceRpcCoLastFrag(co_hdr))    {        DCE2_DEBUG_MSG(DCE2_DEBUG__CO, "First and last fragment.\n");        DCE2_CoSetRopts(sd, cot, co_hdr);        DCE2_CoResetTracker(cot);    }    else    {        DCE2_CoFragTracker *ft = &cot->frag_tracker;        uint16_t auth_len = DceRpcCoAuthLen(co_hdr);        dce2_stats.co_fragments++;        DCE2_DEBUG_CODE(DCE2_DEBUG__CO,                        if (DceRpcCoFirstFrag(co_hdr)) DCE2_DEBUG_MSG(DCE2_DEBUG__CO, "First fragment.\n");                        else if (DceRpcCoLastFrag(co_hdr)) DCE2_DEBUG_MSG(DCE2_DEBUG__CO, "Last fragment.\n");                        else DCE2_DEBUG_MSG(DCE2_DEBUG__CO, "Middle fragment.\n");                        DCE2_PrintPktData(frag_ptr, frag_len););        if (DCE2_BufferIsEmpty(ft->frag_buf))        {            ft->expected_opnum = cot->opnum;            ft->expected_ctx_id = cot->ctx_id;            ft->expected_call_id = cot->call_id;        }        else        {            /* Don't return for these, because we can still process and servers             * will still accept and deal with the anomalies in their own way */            if ((ft->expected_opnum != DCE2_SENTINEL) &&                (ft->expected_opnum != cot->opnum))            {                DCE2_Alert(sd, DCE2_EVENT__CO_FRAG_DIFF_OPNUM,                           cot->opnum, ft->expected_opnum);            }            if ((ft->expected_ctx_id != DCE2_SENTINEL) &&                (ft->expected_ctx_id != cot->ctx_id))            {                DCE2_Alert(sd, DCE2_EVENT__CO_FRAG_DIFF_CTX_ID,                           cot->ctx_id, ft->expected_ctx_id);            }            if ((ft->expected_call_id != DCE2_SENTINEL) &&                (ft->expected_call_id != cot->call_id))            {                DCE2_Alert(sd, DCE2_EVENT__CO_FRAG_DIFF_CALL_ID,                           cot->call_id, ft->expected_call_id);            }        }        /* Possibly set opnum in frag tracker */        switch (policy)        {            case DCE2_POLICY__WIN2000:            case DCE2_POLICY__WIN2003:            case DCE2_POLICY__WINXP:            case DCE2_POLICY__SAMBA:            case DCE2_POLICY__SAMBA_3_0_20:            case DCE2_POLICY__SAMBA_3_0_22:                if (DceRpcCoLastFrag(co_hdr))                    ft->opnum = cot->opnum;                break;            case DCE2_POLICY__WINVISTA:                if (DceRpcCoFirstFrag(co_hdr))                    ft->opnum = cot->opnum;                break;            default:                DCE2_Log("%s(%d) => Invalid policy\n", __FILE__, __LINE__);                break;        }        /* Possibly set context id in frag tracker */        switch (DCE2_ScPolicy(sd->sconfig))        {            case DCE2_POLICY__WIN2000:            case DCE2_POLICY__WIN2003:            case DCE2_POLICY__WINXP:            case DCE2_POLICY__WINVISTA:                if (DceRpcCoFirstFrag(co_hdr))                {                    ft->ctx_id = cot->ctx_id;                }                else if ((ft->expected_call_id != DCE2_SENTINEL) &&                         (ft->expected_call_id != cot->call_id))                {                    /* Server won't accept frag */                    return;                }                break;            case DCE2_POLICY__SAMBA:            case DCE2_POLICY__SAMBA_3_0_20:            case DCE2_POLICY__SAMBA_3_0_22:                if (DceRpcCoLastFrag(co_hdr))                {                    ft->ctx_id = cot->ctx_id;                }                break;            default:                DCE2_Log("%s(%d) => Invalid policy\n", __FILE__, __LINE__);                break;        }        /* Don't want to include authentication data in fragment */        if (auth_len != 0)        {            DceRpcCoAuthVerifier *auth_hdr;            auth_len += sizeof(DceRpcCoAuthVerifier);            /* This means the auth len was bogus */            if (auth_len > frag_len)            {                DCE2_Alert(sd, DCE2_EVENT__CO_FLEN_LT_SIZE, dce2_pdu_types[DceRpcCoPduType(co_hdr)],                           frag_len, auth_len);                return;            }            auth_hdr = (DceRpcCoAuthVerifier *)(frag_ptr + (frag_len - auth_len));            auth_len += DceRpcCoAuthPad(auth_hdr);            /* This means the auth pad len was bogus */            if (auth_len > frag_len)            {                DCE2_Alert(sd, DCE2_EVENT__CO_FLEN_LT_SIZE, dce2_pdu_types[DceRpcCoPduType(co_hdr)],                           frag_len, auth_len);                return;            }        }        DCE2_CoSetRopts(sd, cot, co_hdr);        /* If we're configured to do defragmentation */        if (DCE2_GcDceDefrag())            DCE2_CoHandleFrag(sd, cot, co_hdr, frag_ptr, (uint16_t)(frag_len - auth_len));    }}/******************************************************************** * Function: DCE2_CoResponse() * * Handles a DCE/RPC response from the server. * Samba responds to SMB bind write, request write before read with * a response to the request and doesn't send a bind ack.  Get the * context id from the pending context id list and put in stable * list.  Otherwise the bind ack might have been missed.  Might as * well just move items from pending queue to list. * * 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_CoResponse(DCE2_SsnData *sd, DCE2_CoTracker *cot,                            const DceRpcCoHdr *co_hdr, const uint8_t *frag_ptr, uint16_t frag_len){    DceRpcCoResponse *rhdr = (DceRpcCoResponse *)frag_ptr;    uint16_t ctx_id;    if (DCE2_QueueIsEmpty(cot->pending_ctx_ids))        return;    if (frag_len < sizeof(DceRpcCoResponse))    {        DCE2_Alert(sd, DCE2_EVENT__CO_FLEN_LT_SIZE, dce2_pdu_types[DceRpcCoPduType(co_hdr)],                   frag_len, sizeof(DceRpcCoResponse));        return;    }    ctx_id = DceRpcCoCtxIdResp(co_hdr, rhdr);    while (!DCE2_QueueIsEmpty(cot->pending_ctx_ids))    {        DCE2_Ret status;        DCE2_CoCtxIdNode *ctx_node = (DCE2_CoCtxIdNode *)DCE2_QueueDequeue(cot->pending_ctx_ids);        if (ctx_node == NULL)        {            DCE2_Log("%s(%d) => Failed to dequeue a context id node\n", __FILE__, __LINE__);            return;        }        if (ctx_node->ctx_id == ctx_id)            ctx_node->state = DCE2_CO_CTX_STATE__ACCEPTED;        status = DCE2_ListInsert(cot->ctx_ids, (void *)(uintptr_t)ctx_node->ctx_id, (void *)ctx_node);        if (status != DCE2_RET__SUCCESS)        {            /* Might be a duplicate in there already.  If there is we would have used it             * anyway before looking at the pending queue.  Just get rid of it */            DCE2_Free((void *)ctx_node, sizeof(DCE2_CoCtxIdNode), DCE2_MEM_TYPE__CO_CTX);            return;

⌨️ 快捷键说明

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