Exemplo n.º 1
0
/*********************************************************************
 * Function: DCE2_PafAbort()
 *
 * Purpose: Queries the dcerpc2 session data to see if paf abort
 *          flag is set.
 *
 * Arguments:
 *  void *   - stream session pointer
 *  uint32_t - flags passed in to callback.
 *             Should have PKT_FROM_CLIENT or PKT_FROM_SERVER set.
 *
 * Returns:
 *  bool - true if we should abort PAF, false if not.
 *
 *********************************************************************/
static inline bool DCE2_PafAbort(void *ssn, uint32_t flags)
{
    DCE2_SsnData *sd;

    if (_dpd.sessionAPI->get_session_flags(ssn) & SSNFLAG_MIDSTREAM)
    {
        DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__PAF,
                    "Aborting PAF because of midstream pickup.\n"));
        return true;
    }
    else if (!(_dpd.sessionAPI->get_session_flags(ssn) & SSNFLAG_ESTABLISHED))
    {
        DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__PAF,
                    "Aborting PAF because of unestablished session.\n"));
        return true;
    }

    sd = (DCE2_SsnData *)_dpd.sessionAPI->get_application_data(ssn, PP_DCE2);
    if ((sd != NULL) && DCE2_SsnNoInspect(sd))
    {
        DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__PAF, "Aborting PAF because of session data check.\n"));
        return true;
    }

    return false;
}
Exemplo n.º 2
0
/*********************************************************************
 * Function:
 *
 * Purpose:
 *
 * Arguments:
 *
 * Returns:
 *
 *********************************************************************/
void DCE2_Detect(DCE2_SsnData *sd)
{
    SFSnortPacket *top_pkt = (SFSnortPacket *)DCE2_CStackTop(dce2_pkt_stack);
    PROFILE_VARS;

    if (top_pkt == NULL)
    {
        DCE2_Log(DCE2_LOG_TYPE__ERROR,
                 "%s(%d) No packet on top of stack.",
                 __FILE__, __LINE__);
        return;
    }

    DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Detecting ------------------------------------------------\n"));
    DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ROPTIONS, " Rule options:\n"));
    DCE2_DEBUG_CODE(DCE2_DEBUG__ROPTIONS, DCE2_PrintRoptions(&sd->ropts););
Exemplo n.º 3
0
/******************************************************************
 * Function: DCE2_Alert()
 *
 * Potentially generates an alert if an event is triggered.
 *
 * Arguments:
 *  DCE2_SsnData *
 *      This is the current session data structure being used
 *      when the event was triggered.  It is not a necessary
 *      argument if no session data is currently available, for
 *      example if the event is a memcap event - pass in NULL in
 *      this case.
 *  DCE2_Event
 *      The event type that was triggered.
 *  ...
 *      The arguments to the format for the event.
 *
 * Returns: None
 *
 ******************************************************************/
void DCE2_Alert(DCE2_SsnData *sd, DCE2_Event e, ...)
{
    va_list ap;

#ifdef DEBUG_MSGS
    // When debugging want to see all of the alerts generated
    va_start(ap, e);
    vsnprintf(dce2_event_bufs[e], sizeof(dce2_event_bufs[e]) - 1, dce2_events[e].format, ap);
    va_end(ap);

    dce2_event_bufs[e][sizeof(dce2_event_bufs[e]) - 1] = '\0';
    DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "DCE2 Alert => %s\n", dce2_event_bufs[e]));
#endif

    if (sd != NULL)
    {
        // NOTE This check needs to change if the number of preprocessor events
        // should exceed 63

        /* Only log a specific alert once per session */
        if (sd->alert_mask & ((uint64_t)1 << e))
            return;

        /* set bit for this alert so we don't alert on again
         * in this session */
        sd->alert_mask |= ((uint64_t)1 << e);
    }

    if (!DCE2_GcAlertOnEvent(dce2_events[e].eflag))
        return;

    dce2_stats.events++;

#ifndef DEBUG_MSGS
    va_start(ap, e);
    vsnprintf(dce2_event_bufs[e], sizeof(dce2_event_bufs[e]) - 1, dce2_events[e].format, ap);
    va_end(ap);

    dce2_event_bufs[e][sizeof(dce2_event_bufs[e]) - 1] = '\0';
    DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "DCE2 Alert => %s\n", dce2_event_bufs[e]));
#endif

    _dpd.alertAdd(GENERATOR_DCE2, e, 1, 0, 3, dce2_event_bufs[e], 0);
}
Exemplo n.º 4
0
/********************************************************************
 * Function: DCE2_HttpProcessServer()
 *
 * Wrapper arount main processing point for an RPC over HTTP
 * session.  Checks and sets session setup state for a server.
 *
 * Arguments:
 *  DCE2_HttpSsnData *
 *      Pointer to an RPC over HTTP session data structure.
 *
 * Returns: None
 *
 ********************************************************************/
void DCE2_HttpProcessServer(DCE2_HttpSsnData *hsd)
{
    const SFSnortPacket *p = hsd->sd.wire_pkt;

    DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Processing RPC over HTTP server packet.\n"));
    dce2_stats.http_server_pkts++;

    if (hsd->state == DCE2_HTTP_STATE__NONE)
    {
        if (DCE2_SsnFromServer(p))
            hsd->state = DCE2_HTTP_STATE__INIT_SERVER;
    }

    DCE2_HttpProcess(hsd);
}
Exemplo n.º 5
0
/********************************************************************
 * Function: DCE2_HttpProcessProxy()
 *
 * Wrapper arount main processing point for an RPC over HTTP
 * session.  Checks and sets session setup state for a proxy.
 *
 * Arguments:
 *  DCE2_HttpSsnData *
 *      Pointer to an RPC over HTTP session data structure.
 *
 * Returns: None
 *
 ********************************************************************/
void DCE2_HttpProcessProxy(DCE2_HttpSsnData *hsd)
{
    const SFSnortPacket *p = hsd->sd.wire_pkt;

    DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Processing RPC over HTTP proxy packet.\n"));
    dce2_stats.http_proxy_pkts++;

    if (hsd->state == DCE2_HTTP_STATE__NONE)
    {
        if (DCE2_SsnFromClient(p))
            hsd->state = DCE2_HTTP_STATE__INIT_CLIENT;
    }

    DCE2_HttpProcess(hsd);
}
Exemplo n.º 6
0
/*********************************************************************
 * Function: DCE2_Main()
 *
 * Purpose: Main entry point for DCE/RPC processing.
 *
 * Arguments:
 *  void * - pointer to packet structure
 *  void * - pointer to context
 *
 * Returns: None
 *
 *********************************************************************/
static void DCE2_Main(void *pkt, void *context)
{
    SFSnortPacket *p = (SFSnortPacket *)pkt;
    PROFILE_VARS;

    DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "%s\n", DCE2_DEBUG__START_MSG));

    sfPolicyUserPolicySet (dce2_config, _dpd.getRuntimePolicy());

#ifdef DEBUG_MSGS
    if (DCE2_SsnFromServer(p))
    {
        DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Packet from Server.\n"));
    }
    else
    {
        DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Packet from Client.\n"));
    }
#endif

    /* No inspection to do */
    if ((p->payload_size == 0) || (p->payload == NULL))
    {
        DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "No payload - not inspecting.\n"));
        DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "%s\n", DCE2_DEBUG__END_MSG));
        return;
    }
    else if (p->stream_session_ptr == NULL)
    {
        DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "No session pointer - not inspecting.\n"));
        DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "%s\n", DCE2_DEBUG__END_MSG));
        return;
    }
    else if (!IsTCP(p) && !IsUDP(p))
    {
        DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Not UDP or TCP - not inspecting.\n"));
        DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "%s\n", DCE2_DEBUG__END_MSG));
        return;
    }

    if (IsTCP(p))
    {
        if (DCE2_SsnIsMidstream(p))
        {
            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Midstream - not inspecting.\n"));
            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "%s\n", DCE2_DEBUG__END_MSG));
            return;
        }
        else if (!DCE2_SsnIsEstablished(p))
        {
            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Not established - not inspecting.\n"));
            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "%s\n", DCE2_DEBUG__END_MSG));
            return;
        }
    }

    PREPROC_PROFILE_START(dce2_pstat_main);

    if (DCE2_Process(p) == DCE2_RET__INSPECTED)
        DCE2_DisableDetect(p);

    PREPROC_PROFILE_END(dce2_pstat_main);

    DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "%s\n", DCE2_DEBUG__END_MSG));
}
Exemplo n.º 7
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);
}
Exemplo n.º 8
0
/********************************************************************
 * 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;
        }
    }
}
Exemplo n.º 9
0
/*********************************************************************
 * Function:
 *
 * Purpose:
 *
 * Arguments:
 *
 * Returns:
 *
 *********************************************************************/
static DCE2_SsnData * DCE2_NewSession(SFSnortPacket *p, tSfPolicyId policy_id)
{
    DCE2_SsnData *sd = NULL;
    DCE2_TransType trans;
    const DCE2_ServerConfig *sc = DCE2_ScGetConfig(p);
    int autodetected = 0;
    PROFILE_VARS;

    PREPROC_PROFILE_START(dce2_pstat_new_session);

    DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Creating new session: "));
    trans = DCE2_GetTransport(p, sc, &autodetected);
    switch (trans)
    {
        case DCE2_TRANS_TYPE__SMB:
            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "SMB transport ... "));
            sd = (DCE2_SsnData *)DCE2_SmbSsnInit(p);
            break;

        case DCE2_TRANS_TYPE__TCP:
            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "TCP transport ... "));
            sd = (DCE2_SsnData *)DCE2_TcpSsnInit();
            break;

        case DCE2_TRANS_TYPE__UDP:
            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "UDP transport ... "));
            sd = (DCE2_SsnData *)DCE2_UdpSsnInit();
            break;

        case DCE2_TRANS_TYPE__HTTP_PROXY:
            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "RPC over HTTP proxy transport ... "));
            sd = (DCE2_SsnData *)DCE2_HttpProxySsnInit();
            break;

        case DCE2_TRANS_TYPE__HTTP_SERVER:
            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "RPC over HTTP server transport ... "));
            sd = (DCE2_SsnData *)DCE2_HttpServerSsnInit();
            break;

        case DCE2_TRANS_TYPE__NONE:
            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Not configured to "
                        "look at this traffic or unable to autodetect - not inspecting.\n"));
            PREPROC_PROFILE_END(dce2_pstat_new_session);
            return NULL;

        default:
            DCE2_Log(DCE2_LOG_TYPE__ERROR,
                     "%s(%d) Invalid transport type: %d",
                     __FILE__, __LINE__, trans);
            PREPROC_PROFILE_END(dce2_pstat_new_session);
            return NULL;
    }

    if (sd == NULL)
    {
        PREPROC_PROFILE_END(dce2_pstat_new_session);
        return NULL;
    }

    DCE2_SsnSetAppData(p, (void *)sd, DCE2_SsnFree);

    dce2_stats.sessions++;
    DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Created (%p)\n", (void *)sd));

    sd->trans = trans;
    sd->server_policy = DCE2_ScPolicy(sc);
    sd->client_policy = DCE2_POLICY__WINXP;  // Default to Windows XP
    sd->sconfig = sc;
    sd->wire_pkt = p;

    sd->policy_id = policy_id;
    sd->config = dce2_config;
    ((DCE2_Config *)sfPolicyUserDataGet(sd->config, policy_id))->ref_count++;

    if (autodetected)
    {
        dce2_stats.sessions_autodetected++;

#ifdef DEBUG
        if (DCE2_SsnFromServer(p))
            dce2_stats.autoports[p->src_port][trans]++;
        else
            dce2_stats.autoports[p->dst_port][trans]++;
#endif

        DCE2_SsnSetAutodetected(sd, p);
    }

    /* If we've determined a transport, make sure we're doing
     * reassembly on the session */
    if (IsTCP(p))
    {
        int rs_dir = DCE2_SsnGetReassembly(p);

        if (!_dpd.isPafEnabled() && (rs_dir != SSN_DIR_BOTH))
        {
            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN,
                        "Setting client/server reassembly to FOOTPRINT for this session.\n"));
            DCE2_SsnSetReassembly(p);
        }

        if (!DCE2_SsnIsRebuilt(p))
        {
            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Got non-rebuilt packet\n"));

            if (DCE2_SsnIsStreamInsert(p))
            {
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Stream inserted - not inspecting.\n"));
                PREPROC_PROFILE_END(dce2_pstat_new_session);
                return NULL;
            }
            else if ((DCE2_SsnFromClient(p) && (rs_dir == SSN_DIR_FROM_SERVER))
                     || (DCE2_SsnFromServer(p) && (rs_dir == SSN_DIR_FROM_CLIENT))
                     || (rs_dir == SSN_DIR_BOTH))
            {
                /* Reassembly was already set for this session, but stream
                 * decided not to use the packet so it's probably not good */
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Got non-stream inserted packet - not inspecting\n"));
                PREPROC_PROFILE_END(dce2_pstat_new_session);
                return NULL;
            }
        }
    }

    PREPROC_PROFILE_END(dce2_pstat_new_session);
    return sd;
}
Exemplo n.º 10
0
/********************************************************************
 * Function: DCE2_SetSsnState()
 *
 * Purpose:
 *  Checks for missing packets and overlapping data on session
 *
 * Arguments:
 *  DCE2_SsnData *  - session data pointer
 *  SFSnortPacket * - packet structure
 *
 * Returns:
 *  DCE2_RET__SUCCESS
 *  DCE2_RET__ERROR
 *
 ********************************************************************/
static DCE2_Ret DCE2_SetSsnState(DCE2_SsnData *sd, SFSnortPacket *p)
{
    uint32_t pkt_seq = ntohl(p->tcp_header->sequence);
    PROFILE_VARS;

    PREPROC_PROFILE_START(dce2_pstat_session_state);

    DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Payload size: %u\n", p->payload_size));

    if (DCE2_SsnFromClient(p) && !DCE2_SsnSeenClient(sd))
    {
        uint32_t pkt_ack = ntohl(p->tcp_header->acknowledgement);

        if (DCE2_SsnSeenServer(sd) && SEQ_LT(sd->cli_seq, pkt_seq)
                && (sd->trans != DCE2_TRANS_TYPE__HTTP_SERVER))
        {
            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN,
                        "Missing packets on session - aborting session inspection\n"));
            DCE2_SetNoInspect(sd);
            PREPROC_PROFILE_END(dce2_pstat_session_state);
            return DCE2_RET__ERROR;
        }

        DCE2_SsnSetSeenClient(sd);
        sd->cli_seq = pkt_seq;
        sd->cli_nseq = pkt_seq + p->payload_size;

        if (!DCE2_SsnSeenServer(sd))
            sd->srv_seq = sd->srv_nseq = pkt_ack;

        DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Initial client => seq: %u, "
                    "next seq: %u\n", sd->cli_seq, sd->cli_nseq));
    }
    else if (DCE2_SsnFromServer(p) && !DCE2_SsnSeenServer(sd))
    {
        uint32_t pkt_ack = ntohl(p->tcp_header->acknowledgement);

        if ((DCE2_SsnSeenClient(sd) && SEQ_LT(sd->srv_seq, pkt_seq))
                || (!DCE2_SsnSeenClient(sd) && (sd->trans != DCE2_TRANS_TYPE__HTTP_SERVER)))
        {
            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN,
                        "Missing packets on session - aborting session inspection\n"));
            PREPROC_PROFILE_END(dce2_pstat_session_state);
            DCE2_SetNoInspect(sd);
            return DCE2_RET__ERROR;
        }

        DCE2_SsnSetSeenServer(sd);
        sd->srv_seq = pkt_seq;
        sd->srv_nseq = pkt_seq + p->payload_size;

        if (!DCE2_SsnSeenClient(sd))
            sd->cli_seq = sd->cli_nseq = pkt_ack;

        DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Initial server => seq: %u, "
                    "next seq: %u\n", sd->srv_seq, sd->srv_nseq));
    }
    else
    {
        uint32_t *ssn_seq;
        uint32_t *ssn_nseq;

        if (DCE2_SsnFromClient(p))
        {
            ssn_seq = &sd->cli_seq;
            ssn_nseq = &sd->cli_nseq;

            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Client last => seq: %u, "
                        "next seq: %u\n", sd->cli_seq, sd->cli_nseq));
            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "This packet => seq: %u, "
                        "next seq: %u\n", pkt_seq, pkt_seq + p->payload_size));
        }
        else
        {
            ssn_seq = &sd->srv_seq;
            ssn_nseq = &sd->srv_nseq;

            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Server last => seq: %u, "
                        "next seq: %u\n", sd->srv_seq, sd->srv_nseq));
            DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "This packet => seq: %u, "
                        "next seq: %u\n", pkt_seq, pkt_seq + p->payload_size));
        }

        if (*ssn_nseq != pkt_seq)
        {
            if (SEQ_LT(*ssn_nseq, pkt_seq))
            {
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Next expected sequence number (%u) is less than "
                               "this sequence number (%u).\n", *ssn_nseq, pkt_seq));
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN,
                            "Missing packets on session - aborting session inspection\n"));

                DCE2_SetNoInspect(sd);
                PREPROC_PROFILE_END(dce2_pstat_session_state);
                return DCE2_RET__ERROR;
            }
            else
            {
                /* Got some kind of overlap.  This shouldn't happen since we're doing
                 * reassembly on both sides and not looking at non-reassembled packets
                 * Actually this can happen if the stream seg list is empty */
                DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Overlap => seq: %u, "
                            "next seq: %u - aborting session inspection\n",
                            pkt_seq, pkt_seq + p->payload_size));

                DCE2_SetNoInspect(sd);
                PREPROC_PROFILE_END(dce2_pstat_session_state);
                return DCE2_RET__ERROR;
            }
        }

        *ssn_seq = pkt_seq;
        *ssn_nseq = pkt_seq + p->payload_size;
    }

    PREPROC_PROFILE_END(dce2_pstat_session_state);
    return DCE2_RET__SUCCESS;
}
Exemplo n.º 11
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;
}
Exemplo n.º 12
0
{
    SFSnortPacket *top_pkt = (SFSnortPacket *)DCE2_CStackTop(dce2_pkt_stack);
    PROFILE_VARS;

    if (top_pkt == NULL)
    {
        DCE2_Log(DCE2_LOG_TYPE__ERROR,
                 "%s(%d) No packet on top of stack.",
                 __FILE__, __LINE__);
        return;
    }

    DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Detecting ------------------------------------------------\n"));
    DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ROPTIONS, " Rule options:\n"));
    DCE2_DEBUG_CODE(DCE2_DEBUG__ROPTIONS, DCE2_PrintRoptions(&sd->ropts););
    DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Payload:\n"));
    DCE2_DEBUG_CODE(DCE2_DEBUG__MAIN, DCE2_PrintPktData(top_pkt->payload, top_pkt->payload_size););
    DCE2_DEBUG_CODE(DCE2_DEBUG__ROPTIONS,
            if (sd->ropts.stub_data != NULL) {
            printf("\nStub data:\n");
            DCE2_PrintPktData(sd->ropts.stub_data,
                top_pkt->payload_size - (sd->ropts.stub_data - top_pkt->payload)); });

    PREPROC_PROFILE_START(dce2_pstat_detect);

    _dpd.pushAlerts();
    _dpd.detect(top_pkt);
    _dpd.popAlerts();

    PREPROC_PROFILE_END(dce2_pstat_detect);