예제 #1
0
/********************************************************************
 * Function: DCE2_HttpProcess()
 *
 * Main processing point for an RPC over HTTP session.
 *
 * Arguments:
 *  DCE2_HttpSsnData *
 *      Pointer to an RPC over HTTP session data structure.
 *
 * Returns: None
 *
 ********************************************************************/
static void DCE2_HttpProcess(DCE2_HttpSsnData *hsd)
{
    const SFSnortPacket *p = hsd->sd.wire_pkt;
    const uint8_t *data_ptr = p->payload;
    uint16_t data_len = p->payload_size;
    uint16_t overlap_bytes = DCE2_SsnGetOverlap(&hsd->sd);

    switch (hsd->state)
    {
        case DCE2_HTTP_STATE__INIT_CLIENT:
            hsd->state = DCE2_HTTP_STATE__INIT_SERVER;
            break;

        case DCE2_HTTP_STATE__INIT_SERVER:
            /* Don't really need to look at server response, since if the client
             * RPC_CONNECT request was bad, the TCP session is terminated by
             * the server */
            hsd->state = DCE2_HTTP_STATE__RPC_DATA;
            break;

        case DCE2_HTTP_STATE__RPC_DATA:
            if (overlap_bytes != 0)
            {
                if (overlap_bytes >= data_len)
                    return;

                DCE2_MOVE(data_ptr, data_len, overlap_bytes);
            }

            DCE2_CoProcess(&hsd->sd, &hsd->co_tracker, data_ptr, data_len);

            break;

        default:
            break;
    }
}
예제 #2
0
파일: dce2_cl.c 프로젝트: jasonish/snort
/********************************************************************
 * Function: DCE2_ClFragReassemble()
 *
 * Reassembles fragments into reassembly buffer and copies to
 * reassembly packet.
 *
 * 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.
 *
 * Returns: None
 *
 ********************************************************************/
static void DCE2_ClFragReassemble(DCE2_SsnData *sd, DCE2_ClActTracker *at, const DceRpcClHdr *cl_hdr)
{
    DCE2_ClFragTracker *ft = &at->frag_tracker;
    DCE2_ClFragNode *fnode;
    uint8_t *rdata = dce2_cl_rbuf;
    uint16_t rlen = sizeof(dce2_cl_rbuf);
    uint32_t stub_len = 0;
    const uint8_t *stub_data = NULL;
    SFSnortPacket *rpkt = NULL;
    PROFILE_VARS;

    PREPROC_PROFILE_START(dce2_pstat_cl_reass);

    for (fnode = (DCE2_ClFragNode *)DCE2_ListFirst(ft->frags);
         fnode != NULL;
         fnode = (DCE2_ClFragNode *)DCE2_ListNext(ft->frags))
    {
        if (fnode->frag_len > rlen)
        {
            DCE2_Log(DCE2_LOG_TYPE__WARN,
                     "%s(%d) Size of fragments exceeds reassembly buffer size. "
                     "Using as many fragments as will fit.", __FILE__, __LINE__);
            break;
        }

        if (DCE2_Memcpy(rdata, fnode->frag_data, fnode->frag_len, rdata, rdata + rlen) != DCE2_RET__SUCCESS)
        {
            DCE2_Log(DCE2_LOG_TYPE__ERROR,
                     "%s(%d) Failed to copy data into fragment "
                     "reassembly buffer.", __FILE__, __LINE__);
            break;
        }

        DCE2_MOVE(rdata, rlen, fnode->frag_len);
        stub_len += fnode->frag_len;
    }

    switch (sd->trans)
    {
        case DCE2_TRANS_TYPE__UDP:
            rpkt = DCE2_GetRpkt(sd->wire_pkt, DCE2_RPKT_TYPE__UDP_CL_FRAG, dce2_cl_rbuf, stub_len);
            if (rpkt == NULL)
            {
                DCE2_Log(DCE2_LOG_TYPE__ERROR,
                         "%s(%d) Failed to create reassembly packet.",
                         __FILE__, __LINE__);
                PREPROC_PROFILE_END(dce2_pstat_cl_reass);
                return;
            }

            DCE2_ClSetRdata(at, cl_hdr, (uint8_t *)rpkt->payload,
                            (uint16_t)(rpkt->payload_size - DCE2_MOCK_HDR_LEN__CL));

            stub_data = rpkt->payload + DCE2_MOCK_HDR_LEN__CL;

            break;

        default:
            DCE2_Log(DCE2_LOG_TYPE__ERROR,
                     "%s(%d) Invalid transport type: %d",
                     __FILE__, __LINE__, sd->trans);
            return;
    }

    PREPROC_PROFILE_END(dce2_pstat_cl_reass);

    if (DCE2_PushPkt(rpkt) != DCE2_RET__SUCCESS)
    {
        DCE2_Log(DCE2_LOG_TYPE__ERROR,
                 "%s(%d) Failed to push packet onto packet stack.",
                 __FILE__, __LINE__);
        return;
    }

    /* Cache relevant values for rule option processing */
    sd->ropts.first_frag = 1;
    DCE2_CopyUuid(&sd->ropts.iface, &ft->iface, DCERPC_BO_FLAG__NONE);
    sd->ropts.iface_vers = ft->iface_vers;
    sd->ropts.hdr_byte_order = DceRpcClByteOrder(cl_hdr);

    if (ft->data_byte_order != DCE2_SENTINEL)
        sd->ropts.data_byte_order = ft->data_byte_order;
    else
        sd->ropts.data_byte_order = DceRpcClByteOrder(cl_hdr);

    if (ft->opnum != DCE2_SENTINEL)
        sd->ropts.opnum = ft->opnum;
    else
        sd->ropts.opnum = DceRpcClOpnum(cl_hdr);

    sd->ropts.stub_data = stub_data;

    DCE2_Detect(sd);
    DCE2_PopPkt();

    dce2_stats.cl_frag_reassembled++;
}
예제 #3
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;
        }
    }
}