예제 #1
0
파일: dce2_cl.c 프로젝트: jasonish/snort
/********************************************************************
 * Function: DCE2_ClHdrChecks()
 *
 * Checks to make sure header fields are sane.  If they aren't,
 * alert on the header anomaly.  If we've autodetected the session,
 * however, don't alert, but set a header anomaly flag, so we can
 * re-autodetect on the next go around.
 *
 * Arguments:
 *  DCE2_SsnData *
 *      Pointer to the session data structure.
 *  DceRpcClHdr *
 *      Pointer to the connectionless header in the packet.
 *
 * Returns:
 *  DCE2_Ret
 *      DCE2_RET__ERROR
 *          We should not continue to inspect.
 *      DCE2_RET__SUCCESS
 *          Continue inspection.
 *
 ********************************************************************/
static DCE2_Ret DCE2_ClHdrChecks(DCE2_SsnData *sd, const DceRpcClHdr *cl_hdr)
{
    if (DceRpcClRpcVers(cl_hdr) != DCERPC_PROTO_MAJOR_VERS__4)
    {
        /* If we autodetected the session, we probably guessed wrong */
        if (!DCE2_SsnAutodetected(sd))
            DCE2_Alert(sd, DCE2_EVENT__CL_BAD_MAJ_VERSION, DceRpcClRpcVers(cl_hdr));

        return DCE2_RET__ERROR;
    }

    if (DceRpcClPduType(cl_hdr) >= DCERPC_PDU_TYPE__MAX)
    {
        if (!DCE2_SsnAutodetected(sd))
            DCE2_Alert(sd, DCE2_EVENT__CL_BAD_PDU_TYPE, DceRpcClPduType(cl_hdr));

        return DCE2_RET__ERROR;
    }

    return DCE2_RET__SUCCESS;
}
예제 #2
0
파일: dce2_cl.c 프로젝트: jasonish/snort
/********************************************************************
 * Function: DCE2_ClProcess()
 *
 * Main entry point for connectionless DCE/RPC processing.  Gets
 * the activity tracker associated with this session and passes
 * along to client or server handling.
 *
 * Arguments:
 *  DCE2_SsnData *
 *      Pointer to the session data structure.
 *  DCE2_ClTracker *
 *      Pointer to the connectionless tracker structure.
 *
 * Returns: None
 *
 ********************************************************************/
void DCE2_ClProcess(DCE2_SsnData *sd, DCE2_ClTracker *clt)
{
    DceRpcClHdr *cl_hdr;
    DCE2_ClActTracker *at;
    const uint8_t *data_ptr = sd->wire_pkt->payload;
    uint16_t data_len = sd->wire_pkt->payload_size;
    PROFILE_VARS;

    DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Cl processing ...\n"));

    dce2_stats.cl_pkts++;

    if (data_len < sizeof(DceRpcClHdr))
    {
        if (!DCE2_SsnAutodetected(sd))
            DCE2_Alert(sd, DCE2_EVENT__CL_DATA_LT_HDR, data_len, sizeof(DceRpcClHdr));

        return;
    }

    cl_hdr = (DceRpcClHdr *)data_ptr;

    DCE2_MOVE(data_ptr, data_len, sizeof(DceRpcClHdr));

    if (DCE2_ClHdrChecks(sd, cl_hdr) != DCE2_RET__SUCCESS)
        return;

    PREPROC_PROFILE_START(dce2_pstat_cl_acts);
    at = DCE2_ClGetActTracker(clt, cl_hdr);
    PREPROC_PROFILE_END(dce2_pstat_cl_acts);
    if (at == NULL)
        return;

    if (DCE2_SsnFromClient(sd->wire_pkt))
    {
        switch (DceRpcClPduType(cl_hdr))
        {
            case DCERPC_PDU_TYPE__REQUEST:
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Request\n"));
                dce2_stats.cl_request++;
                DCE2_ClRequest(sd, at, cl_hdr, data_ptr, data_len);
                break;

            case DCERPC_PDU_TYPE__ACK:
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Ack\n"));
                dce2_stats.cl_ack++;
                break;

            case DCERPC_PDU_TYPE__CL_CANCEL:
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Cancel\n"));
                dce2_stats.cl_cancel++;
                break;

            case DCERPC_PDU_TYPE__FACK:
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Fack\n"));
                dce2_stats.cl_cli_fack++;
                break;

            case DCERPC_PDU_TYPE__PING:
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Ping\n"));
                dce2_stats.cl_ping++;
                break;

            case DCERPC_PDU_TYPE__RESPONSE:
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Response from client.  Changing stream direction."));
                _dpd.streamAPI->update_direction(sd->wire_pkt->stream_session, SSN_DIR_FROM_RESPONDER,
                                                 GET_SRC_IP(((SFSnortPacket *)sd->wire_pkt)),
                                                 sd->wire_pkt->src_port);
                break;

            default:
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Other pdu type\n"));
                dce2_stats.cl_other_req++;
                break;
        }
    }
    else
    {
        switch (DceRpcClPduType(cl_hdr))
        {
            case DCERPC_PDU_TYPE__RESPONSE:
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Response\n"));
                dce2_stats.cl_response++;
                break;

            case DCERPC_PDU_TYPE__REJECT:
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Reject\n"));
                dce2_stats.cl_reject++;

                if (DceRpcClSeqNum(cl_hdr) == at->seq_num)
                {
                    DCE2_ClResetFragTracker(&at->frag_tracker);
                    at->seq_num_invalid = 1;
                }

                break;

            case DCERPC_PDU_TYPE__CANCEL_ACK:
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Cancel Ack\n"));
                dce2_stats.cl_cancel_ack++;
                break;

            case DCERPC_PDU_TYPE__FACK:
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Fack\n"));
                dce2_stats.cl_srv_fack++;
                break;

            case DCERPC_PDU_TYPE__FAULT:
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Fault\n"));
                dce2_stats.cl_fault++;
                break;

            case DCERPC_PDU_TYPE__NOCALL:
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "No call\n"));
                dce2_stats.cl_nocall++;
                break;

            case DCERPC_PDU_TYPE__WORKING:
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Working\n"));
                dce2_stats.cl_working++;
                break;

            default:
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Other pdu type\n"));
                dce2_stats.cl_other_resp++;
                break;
        }
    }
}
예제 #3
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;
}