/******************************************************************** * 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; }
/******************************************************************** * 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; }
/******************************************************************** * 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); }
/********************************************************************* * 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; }