📄 snort_dcerpc.c
字号:
/* * snort_dcerpc.c * * Copyright (C) 2004-2008 Sourcefire,Inc * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as * published by the Free Software Foundation. You may not use, modify or * distribute this program under any other version of the GNU General * Public License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Description: * * This performs the DCERPC decoding. * * Arguments: * * Effect: * * None * * NOTES: * - 08.12.04: Initial Development. SAS * */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdlib.h>#include <string.h>#include <pcap.h>#include "debug.h"#include "snort_dcerpc.h"#include "smb_structs.h"#include "smb_andx_decode.h"#include "smb_file_decode.h"#include "dcerpc.h"#include "dcerpc_util.h"#include "bounds.h"#include "sf_snort_packet.h"#include "sf_types.h"#include "profiler.h"#ifdef PERF_PROFILINGextern PreprocStats dcerpcPerfStats;extern PreprocStats dcerpcDetectPerfStats;extern PreprocStats dcerpcIgnorePerfStats;#endifextern char SMBPorts[MAX_PORT_INDEX];extern char DCERPCPorts[MAX_PORT_INDEX];extern u_int8_t _debug_print;extern u_int8_t _autodetect;extern int _reassemble_increment;extern u_int32_t _memcap;extern u_int8_t _alert_memcap;extern u_int8_t _disable_smb_fragmentation;extern u_int8_t _disable_dcerpc_fragmentation;u_int32_t _total_memory = 0;#ifdef TARGET_BASEDDCERPC_ProtoIds _dce_proto_ids;#endif/* Session structure */DCERPC *_dcerpc;/* Save packet so we don't have to pass it around */SFSnortPacket *_dcerpc_pkt;u_int8_t *dce_reassembly_buf = NULL;const u_int16_t dce_reassembly_buf_size = IP_MAXPKT - (IP_HDR_LEN + TCP_HDR_LEN);/* this is used to store one of the below */SFSnortPacket *real_dce_mock_pkt = NULL;SFSnortPacket *dce_mock_pkt = NULL;const u_int16_t dce_mock_pkt_payload_len = IP_MAXPKT - (IP_HDR_LEN + TCP_HDR_LEN);#ifdef SUP_IP6SFSnortPacket *dce_mock_pkt_6 = NULL;const u_int16_t dce_mock_pkt_6_payload_len = IP_MAXPKT - (IP6_HDR_LEN + TCP_HDR_LEN);#endifstatic DCERPC_TransType DCERPC_AutoDetect(SFSnortPacket *, const u_int8_t *, u_int16_t);static void DCERPC_DataFree(DCERPC *);static int ProcessRawDCERPC(SFSnortPacket *, const u_int8_t *, u_int16_t);static int ProcessRawSMB(SFSnortPacket *, const u_int8_t *, u_int16_t);static DCERPC_TransType DCERPC_GetTransport(SFSnortPacket *, char *);void DCERPC_BufferReassemble(DCERPC_Buffer *sbuf){ u_int16_t len; int status; if (DCERPC_BufferIsEmpty(sbuf)) return; len = sbuf->len; /* Copy data into buffer */ if (len > dce_reassembly_buf_size) len = dce_reassembly_buf_size; status = SafeMemcpy(dce_reassembly_buf, sbuf->data, len, dce_reassembly_buf, dce_reassembly_buf + dce_reassembly_buf_size); if (status != SAFEMEM_SUCCESS) { DEBUG_WRAP(DebugMessage(DEBUG_DCERPC, "Failed to copy DCERPC data, " "skipping DCERPC reassembly.\n");); return; } if (_debug_print) { PrintBuffer("DCE/RPC reassembled fragment", (u_int8_t *)dce_reassembly_buf, (u_int16_t)len); } /* create pseudo packet */ real_dce_mock_pkt = DCERPC_SetPseudoPacket(_dcerpc_pkt, dce_reassembly_buf, len);}void DCERPC_EarlyFragReassemble(DCERPC *dce_ssn_data, const u_int8_t *smb_hdr, u_int16_t smb_hdr_len, u_int16_t opnum){ dce_ssn_data->num_inc_reass++; if (_reassemble_increment == dce_ssn_data->num_inc_reass) { dce_ssn_data->num_inc_reass = 0; if (!DCERPC_BufferIsEmpty(&dce_ssn_data->dce_frag_buf)) { DCERPC_REQ fake_req; memset(&fake_req, 0, sizeof(DCERPC_REQ)); fake_req.dcerpc_hdr.version = 5; fake_req.dcerpc_hdr.flags = 0x03; fake_req.dcerpc_hdr.byte_order = 0x10; fake_req.opnum = opnum; /* Create a reassembly packet but don't free buffers */ ReassembleDCERPCRequest(smb_hdr, smb_hdr_len, (uint8_t *)&fake_req); } }}void * DCERPC_GetReassemblyPkt(void){ if (real_dce_mock_pkt != NULL) return (void *)real_dce_mock_pkt; return NULL;} SFSnortPacket * DCERPC_SetPseudoPacket(SFSnortPacket *p, const u_int8_t *data, u_int16_t data_len){ SFSnortPacket *ret_pkt = dce_mock_pkt; u_int16_t payload_len = dce_mock_pkt_payload_len; u_int16_t ip_len; int result;#ifdef SUP_IP6 if (p->family == AF_INET) { IP_COPY_VALUE(ret_pkt->inner_ip4h.ip_src, (&p->ip4h->ip_src)); IP_COPY_VALUE(ret_pkt->inner_ip4h.ip_dst, (&p->ip4h->ip_dst)); //((IPV4Header *)ret_pkt->ip4h)->source.s_addr = p->ip4h->ip_src.ip32[0]; //((IPV4Header *)ret_pkt->ip4h)->destination.s_addr = p->ip4h->ip_dst.ip32[0]; } else { ret_pkt = dce_mock_pkt_6; IP_COPY_VALUE(ret_pkt->inner_ip6h.ip_src, (&p->ip6h->ip_src)); IP_COPY_VALUE(ret_pkt->inner_ip6h.ip_dst, (&p->ip6h->ip_dst)); payload_len = dce_mock_pkt_6_payload_len; } ret_pkt->family = p->family;#else ((IPV4Header *)ret_pkt->ip4_header)->source.s_addr = p->ip4_header->source.s_addr; ((IPV4Header *)ret_pkt->ip4_header)->destination.s_addr = p->ip4_header->destination.s_addr;#endif ((TCPHeader *)ret_pkt->tcp_header)->source_port = p->tcp_header->source_port; ((TCPHeader *)ret_pkt->tcp_header)->destination_port = p->tcp_header->destination_port; ret_pkt->src_port = p->src_port; ret_pkt->dst_port = p->dst_port; if(p->ether_header != NULL) { result = SafeMemcpy((void *)((EtherHeader *)ret_pkt->ether_header)->ether_source, (void *)p->ether_header->ether_source, (size_t)6, (void *)ret_pkt->ether_header->ether_source, (void *)((u_int8_t *)ret_pkt->ether_header->ether_source + 6)); if (result != SAFEMEM_SUCCESS) return NULL; result = SafeMemcpy((void *)((EtherHeader *)ret_pkt->ether_header)->ether_destination, (void *)p->ether_header->ether_destination, (size_t)6, (void *)ret_pkt->ether_header->ether_destination, (void *)((u_int8_t *)ret_pkt->ether_header->ether_destination + 6)); if (result != SAFEMEM_SUCCESS) return NULL; } if (data_len > payload_len) data_len = payload_len; result = SafeMemcpy((void *)ret_pkt->payload, (void *)data, (size_t)data_len, (void *)ret_pkt->payload, (void *)((u_int8_t *)ret_pkt->payload + payload_len)); if (result != SAFEMEM_SUCCESS) return NULL; ret_pkt->payload_size = data_len; ((struct pcap_pkthdr *)ret_pkt->pcap_header)->caplen = ret_pkt->payload_size + IP_HDR_LEN + TCP_HDR_LEN + ETHER_HDR_LEN; ((struct pcap_pkthdr *)ret_pkt->pcap_header)->len = ret_pkt->pcap_header->caplen; ((struct pcap_pkthdr *)ret_pkt->pcap_header)->ts.tv_sec = p->pcap_header->ts.tv_sec; ((struct pcap_pkthdr *)ret_pkt->pcap_header)->ts.tv_usec = p->pcap_header->ts.tv_usec; ip_len = (u_int16_t)(ret_pkt->payload_size + IP_HDR_LEN + TCP_HDR_LEN);#ifdef SUP_IP6 if (p->family == AF_INET) { ret_pkt->ip4h->ip_len = ((IPV4Header *)ret_pkt->ip4_header)->data_length = htons(ip_len); } else { ip_len = (u_int16_t)(ret_pkt->payload_size + IP6_HDR_LEN + TCP_HDR_LEN); ret_pkt->ip6h->len = htons(ip_len); }#else ((IPV4Header *)ret_pkt->ip4_header)->data_length = htons(ip_len);#endif ret_pkt->flags = FLAG_STREAM_EST; ret_pkt->flags |= FLAG_FROM_CLIENT; ret_pkt->flags |= FLAG_DCE_RPKT; ret_pkt->stream_session_ptr = p->stream_session_ptr; /* Set bit in wire packet to indicate a reassembled packet needs to * be detected upon */ _dpd.setPreprocGetReassemblyPktBit(_dcerpc_pkt, PP_DCERPC); return ret_pkt;}void DCERPC_InitPacket(void){ /* Alloc for global reassembly buffers */ dce_reassembly_buf = (u_int8_t *)calloc(1, dce_reassembly_buf_size); if (dce_reassembly_buf == NULL) { DynamicPreprocessorFatalMessage("Failed to allocate memory for " "reassembly packet\n"); } /* Alloc for mock packets */ dce_mock_pkt = (SFSnortPacket *)calloc(1, sizeof(SFSnortPacket)); if (dce_mock_pkt == NULL) { DynamicPreprocessorFatalMessage("Failed to allocate memory for " "mock packet\n"); } dce_mock_pkt->pcap_header = calloc(1, sizeof(struct pcap_pkthdr) + ETHER_HDR_LEN + SUN_SPARC_TWIDDLE + IP_MAXPKT); if (dce_mock_pkt->pcap_header == NULL) { DynamicPreprocessorFatalMessage("Failed to allocate memory " "for mock pcap header\n"); } dce_mock_pkt->pkt_data = ((u_int8_t *)dce_mock_pkt->pcap_header) + sizeof(struct pcap_pkthdr); dce_mock_pkt->ether_header = (void *)((u_int8_t *)dce_mock_pkt->pkt_data + SUN_SPARC_TWIDDLE); dce_mock_pkt->ip4_header = (IPV4Header *)((u_int8_t *)dce_mock_pkt->ether_header + ETHER_HDR_LEN); dce_mock_pkt->tcp_header = (TCPHeader *)((u_int8_t *)dce_mock_pkt->ip4_header + IP_HDR_LEN); dce_mock_pkt->payload = (u_int8_t *)dce_mock_pkt->tcp_header + TCP_HDR_LEN; ((EtherHeader *)dce_mock_pkt->ether_header)->ethernet_type = htons(0x0800); SET_IP4_VER((IPV4Header *)dce_mock_pkt->ip4_header, 0x4); SET_IP4_HLEN((IPV4Header *)dce_mock_pkt->ip4_header, 0x5); ((IPV4Header *)dce_mock_pkt->ip4_header)->proto = IPPROTO_TCP; ((IPV4Header *)dce_mock_pkt->ip4_header)->time_to_live = 0xF0; ((IPV4Header *)dce_mock_pkt->ip4_header)->type_service = 0x10; SET_TCP_HDR_OFFSET((TCPHeader *)dce_mock_pkt->tcp_header, 0x5);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -