Example #1
0
/********************************************************************
 * Function:
 *
 * Purpose:
 *
 * Arguments:
 *
 * Returns:
 *
 ********************************************************************/
DCE2_UdpSsnData * DCE2_UdpSsnInit(void)
{
    DCE2_UdpSsnData *usd = DCE2_Alloc(sizeof(DCE2_UdpSsnData), DCE2_MEM_TYPE__UDP_SSN);

    if (usd == NULL)
        return NULL;

    DCE2_ResetRopts(&usd->sd.ropts);

    dce2_stats.udp_sessions++;

    return usd;
}
Example #2
0
/********************************************************************
 * Function: DCE2_HttpSsnInit()
 *
 * Creates and initializes an rpc over http session data structure.
 *
 * Arguments: None
 *
 * Returns:
 *  DCE2_HttpSsnData *
 *      Valid pointer to an rpc over http session data structure.
 *      NULL if unable to allocate memory.
 *
 ********************************************************************/
static DCE2_HttpSsnData * DCE2_HttpSsnInit(void)
{
    DCE2_HttpSsnData *hsd = DCE2_Alloc(sizeof(DCE2_HttpSsnData), DCE2_MEM_TYPE__HTTP_SSN);

    if (hsd == NULL)
        return NULL;

    hsd->state = DCE2_HTTP_STATE__NONE;
    DCE2_CoInitTracker(&hsd->co_tracker);

    DCE2_ResetRopts(&hsd->sd.ropts);

    return hsd;
}
Example #3
0
/********************************************************************
 * Function: DCE2_ClRequest()
 *
 * Handles a client request.
 *
 * Arguments:
 *  DCE2_SsnData *
 *      Pointer to the session data structure.
 *  DCE2_ClActTracker *
 *      Pointer to the connectionless activity tracker.
 *  DceRpcClHdr *
 *      Pointer to the connectionless header in the packet.
 *  const uint8_t *
 *      Pointer to current position in the packet payload.
 *  uint16_t
 *      Length of packet payload left from current pointer
 *      position.
 *
 * Returns: None
 *
 ********************************************************************/
static void DCE2_ClRequest(DCE2_SsnData *sd, DCE2_ClActTracker *at, DceRpcClHdr *cl_hdr,
                           const uint8_t *data_ptr, uint16_t data_len)
{
    uint32_t seq_num = DceRpcClSeqNum(cl_hdr);

    DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Processing Request ...\n"));

    if (seq_num > at->seq_num)
    {
        /* This is the normal case where the sequence number is incremented
         * for each request.  Set the new sequence number and mark it valid. */
        at->seq_num = seq_num;
        at->seq_num_invalid = 0;

        /* If there are any fragments, the new sequence number invalidates
         * all of the frags that might be currently stored. */
        DCE2_ClResetFragTracker(&at->frag_tracker);
    }
    else if ((seq_num < at->seq_num) || at->seq_num_invalid)
    {
#if 0
        /* If we get a seqence number less than what we're at, the
         * server won't look at it.  If we get the same sequence number,
         * but we've already processed a previous request, it's bad.
         * Fragments will have the same sequence number, but we won't
         * mark the seq number invalid until we've gotten all of them. */
        /* Comment for now since we're not able to detect retransmits */
        DCE2_Alert(sd, DCE2_EVENT__CL_BAD_SEQ_NUM, dce2_pdu_types[DceRpcClPduType(cl_hdr)]);
#endif
        return;
    }

    DCE2_ResetRopts(&sd->ropts);

    if (DceRpcClFrag(cl_hdr))  /* It's a frag */
    {
        dce2_stats.cl_fragments++;
        if (DCE2_GcDceDefrag())
        {
            DCE2_ClHandleFrag(sd, at, cl_hdr, data_ptr, data_len);
            return;
        }
    }
    else   /* It's a full request */
    {
        if ((at->frag_tracker.frags != NULL) &&
            !DCE2_ListIsEmpty(at->frag_tracker.frags))
        {
            /* If we get a full request, i.e. not a frag, any frags
             * we have collected are invalidated */
            DCE2_ClResetFragTracker(&at->frag_tracker);
        }
        else if (seq_num != DCE2_CL__MAX_SEQ_NUM)
        {
            /* This sequence number is now invalid. 0xffffffff is the end of
             * the sequence number space and can be reused */
            at->seq_num_invalid = 1;
        }
        else
        {
            /* Got the last sequence number in the sequence number space */
            dce2_stats.cl_max_seqnum++;
        }
    }

    /* Cache relevant values for rule option processing */
    sd->ropts.first_frag = DceRpcClFirstFrag(cl_hdr);
    DCE2_CopyUuid(&sd->ropts.iface, DceRpcClIface(cl_hdr), DceRpcClByteOrder(cl_hdr));
    sd->ropts.iface_vers = DceRpcClIfaceVers(cl_hdr);
    sd->ropts.hdr_byte_order = DceRpcClByteOrder(cl_hdr);
    sd->ropts.data_byte_order = DceRpcClByteOrder(cl_hdr);
    sd->ropts.opnum = DceRpcClOpnum(cl_hdr);
    sd->ropts.stub_data = (uint8_t *)cl_hdr + sizeof(DceRpcClHdr);

    DCE2_Detect(sd);
}
Example #4
0
/*********************************************************************
 * Function: DCE2_Process()
 *
 * Purpose: Main entry point for DCE/RPC processing.
 *
 * Arguments:
 *  SFSnortPacket * - pointer to packet structure
 *
 * Returns:
 *  DCE2_Ret - status
 *
 *********************************************************************/
DCE2_Ret DCE2_Process(SFSnortPacket *p)
{
    tSfPolicyId policy_id = _dpd.getNapRuntimePolicy();
    DCE2_SsnData *sd = (DCE2_SsnData *)DCE2_SsnGetAppData(p);
    PROFILE_VARS;

    PREPROC_PROFILE_START(dce2_pstat_session);

    if ((sd != NULL) && DCE2_SsnNoInspect(sd))
    {
        DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Session set to "
                    "not inspect.  Returning\n"));
        PREPROC_PROFILE_END(dce2_pstat_session);
        return DCE2_RET__NOT_INSPECTED;
    }

    dce2_eval_config = (DCE2_Config *)sfPolicyUserDataGet(dce2_config, policy_id);
    if (sd != NULL)
        dce2_eval_config = (DCE2_Config *)sfPolicyUserDataGet(sd->config, sd->policy_id);

    if (dce2_eval_config == NULL)
    {
        PREPROC_PROFILE_END(dce2_pstat_session);
        return DCE2_RET__NOT_INSPECTED;
    }

    if (sd == NULL)
    {
        sd = DCE2_NewSession(p, policy_id);
        if (sd == NULL)
        {
            PREPROC_PROFILE_END(dce2_pstat_session);
            return DCE2_RET__NOT_INSPECTED;
        }
    }
    else
    {
        sd->wire_pkt = p;

        if (_dpd.isPafEnabled() && !DCE2_SsnIsPafActive(p))
        {
            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "PAF was aborted on "
                        "one or both sides - aborting session inspection\n"));
            DCE2_SetNoInspect(sd);
            PREPROC_PROFILE_END(dce2_pstat_session);
            return DCE2_RET__NOT_INSPECTED;
        }

        if (IsTCP(p) && !DCE2_SsnIsRebuilt(p))
        {
            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Got non-rebuilt packet "
                        "on session (%p)\n", (void *)sd));

            if (DCE2_SsnIsStreamInsert(p))
            {
                if (!_dpd.isPafEnabled())
                {
                    DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Flushing opposite direction.\n"));
                    DCE2_SsnFlush(p);
                }

                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Stream inserted - not inspecting.\n"));
            }
            else
            {
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Got non-stream inserted packet "
                            "- not inspecting\n"));
            }

            PREPROC_PROFILE_END(dce2_pstat_session);
            return DCE2_RET__NOT_INSPECTED;
        }
        else if (DCE2_SsnAutodetected(sd) && !(p->flags & sd->autodetect_dir))
        {
            /* Try to autodetect in opposite direction */
            if ((sd->trans != DCE2_TRANS_TYPE__HTTP_PROXY) &&
                    (sd->trans != DCE2_TRANS_TYPE__HTTP_SERVER) &&
                    (DCE2_GetAutodetectTransport(p, sd->sconfig) != sd->trans))
            {
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Bad autodetect.\n"));

                DCE2_SetNoInspect(sd);
                dce2_stats.bad_autodetects++;

                PREPROC_PROFILE_END(dce2_pstat_session);
                return DCE2_RET__NOT_INSPECTED;
            }

            DCE2_SsnClearAutodetected(sd);
        }
    }

    DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Session pointer: %p\n", (void *)sd));

    if (IsTCP(p) && (DCE2_SetSsnState(sd, p) != DCE2_RET__SUCCESS))
    {
        PREPROC_PROFILE_END(dce2_pstat_session);
        return DCE2_RET__NOT_INSPECTED;
    }

    if (DCE2_PushPkt((void *)p) != DCE2_RET__SUCCESS)
    {
        DCE2_Log(DCE2_LOG_TYPE__ERROR,
                 "%s(%d) Failed to push packet onto packet stack.",
                 __FILE__, __LINE__);
        PREPROC_PROFILE_END(dce2_pstat_session);
        return DCE2_RET__NOT_INSPECTED;
    }

    p->flags |= FLAG_ALLOW_MULTIPLE_DETECT;
    dce2_detected = 0;

    PREPROC_PROFILE_END(dce2_pstat_session);

    switch (sd->trans)
    {
        case DCE2_TRANS_TYPE__SMB:
            DCE2_SmbProcess((DCE2_SmbSsnData *)sd);
            break;
        case DCE2_TRANS_TYPE__TCP:
            DCE2_TcpProcess((DCE2_TcpSsnData *)sd);
            break;
        case DCE2_TRANS_TYPE__UDP:
            DCE2_UdpProcess((DCE2_UdpSsnData *)sd);
            break;
        case DCE2_TRANS_TYPE__HTTP_PROXY:
            DCE2_HttpProcessProxy((DCE2_HttpSsnData *)sd);
            break;
        case DCE2_TRANS_TYPE__HTTP_SERVER:
            DCE2_HttpProcessServer((DCE2_HttpSsnData *)sd);
            break;
        default:
            DCE2_Log(DCE2_LOG_TYPE__ERROR,
                     "%s(%d) Invalid transport type: %d",
                     __FILE__, __LINE__, sd->trans);
            return DCE2_RET__NOT_INSPECTED;
    }

    if (sd->flags & DCE2_SSN_FLAG__NO_INSPECT)
    {
        DCE2_SetNoInspect(sd);
        DCE2_PopPkt();
        PREPROC_PROFILE_END(dce2_pstat_session);
        return DCE2_RET__NOT_INSPECTED;
    }

    if (!dce2_detected)
        DCE2_Detect(sd);

    DCE2_ResetRopts(&sd->ropts);
    DCE2_PopPkt();

    if (dce2_mem_state == DCE2_MEM_STATE__MEMCAP)
    {
        DCE2_SetNoInspect(sd);
        dce2_mem_state = DCE2_MEM_STATE__OKAY;
        return DCE2_RET__NOT_INSPECTED;
    }

    if (DCE2_SsnAutodetected(sd))
        return DCE2_RET__NOT_INSPECTED;

    return DCE2_RET__INSPECTED;
}