📄 spp_dns.c
字号:
} else { /* No more data */ return; } } dnsSessionData->state = DNS_RESP_STATE_ANS_RR; dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_NAME_SIZE; dnsSessionData->curr_rec = 0; } /* Handle the RRs */ switch (dnsSessionData->state) { case DNS_RESP_STATE_ANS_RR: /* ANSWERS section */ for (i=dnsSessionData->curr_rec; i<dnsSessionData->hdr.answers; i++) { bytes_unused = ParseDNSAnswer(data, p->payload_size, bytes_unused, dnsSessionData); if (bytes_unused == 0) { /* No more data */ return; } switch (dnsSessionData->curr_rec_state) { case DNS_RESP_STATE_RR_RDATA_START: DEBUG_WRAP( DebugMessage(DEBUG_DNS, "DNS ANSWER RR %d: type %d, class %d, " "ttl %d rdlength %d\n", i, dnsSessionData->curr_rr.type, dnsSessionData->curr_rr.dns_class, dnsSessionData->curr_rr.ttl, dnsSessionData->curr_rr.length); ); dnsSessionData->bytes_seen_curr_rec = 0; dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_RDATA_MID; /* Fall through */ case DNS_RESP_STATE_RR_RDATA_MID: /* Data now points to the beginning of the RDATA */ data = p->payload + (p->payload_size - bytes_unused); bytes_unused = ParseDNSRData(p, data, bytes_unused, dnsSessionData); if (dnsSessionData->curr_rec_state != DNS_RESP_STATE_RR_COMPLETE) { /* Out of data, pick up on the next packet */ return; } else { /* Go to the next record */ dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_NAME_SIZE; dnsSessionData->curr_rec++; if (dnsSessionData->curr_rr.type == DNS_RR_TYPE_TXT) { /* Reset the state tracking for this record */ bzero(&dnsSessionData->curr_txt, sizeof(DNSNameState)); } data = p->payload + (p->payload_size - bytes_unused); } } } dnsSessionData->state = DNS_RESP_STATE_AUTH_RR; dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_NAME_SIZE; dnsSessionData->curr_rec = 0; /* Fall through */ case DNS_RESP_STATE_AUTH_RR: /* AUTHORITIES section */ for (i=dnsSessionData->curr_rec; i<dnsSessionData->hdr.authorities; i++) { bytes_unused = ParseDNSAnswer(data, p->payload_size, bytes_unused, dnsSessionData); if (bytes_unused == 0) { /* No more data */ return; } switch (dnsSessionData->curr_rec_state) { case DNS_RESP_STATE_RR_RDATA_START: DEBUG_WRAP( DebugMessage(DEBUG_DNS, "DNS AUTH RR %d: type %d, class %d, " "ttl %d rdlength %d\n", i, dnsSessionData->curr_rr.type, dnsSessionData->curr_rr.dns_class, dnsSessionData->curr_rr.ttl, dnsSessionData->curr_rr.length); ); dnsSessionData->bytes_seen_curr_rec = 0; dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_RDATA_MID; /* Fall through */ case DNS_RESP_STATE_RR_RDATA_MID: /* Data now points to the beginning of the RDATA */ data = p->payload + (p->payload_size - bytes_unused); bytes_unused = ParseDNSRData(p, data, bytes_unused, dnsSessionData); if (dnsSessionData->curr_rec_state != DNS_RESP_STATE_RR_COMPLETE) { /* Out of data, pick up on the next packet */ return; } else { /* Go to the next record */ dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_NAME_SIZE; dnsSessionData->curr_rec++; if (dnsSessionData->curr_rr.type == DNS_RR_TYPE_TXT) { /* Reset the state tracking for this record */ bzero(&dnsSessionData->curr_txt, sizeof(DNSNameState)); } data = p->payload + (p->payload_size - bytes_unused); } } } dnsSessionData->state = DNS_RESP_STATE_ADD_RR; dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_NAME_SIZE; dnsSessionData->curr_rec = 0; /* Fall through */ case DNS_RESP_STATE_ADD_RR: /* ADDITIONALS section */ for (i=dnsSessionData->curr_rec; i<dnsSessionData->hdr.authorities; i++) { bytes_unused = ParseDNSAnswer(data, p->payload_size, bytes_unused, dnsSessionData); if (bytes_unused == 0) { /* No more data */ return; } switch (dnsSessionData->curr_rec_state) { case DNS_RESP_STATE_RR_RDATA_START: DEBUG_WRAP( DebugMessage(DEBUG_DNS, "DNS ADDITONAL RR %d: type %d, class %d, " "ttl %d rdlength %d\n", i, dnsSessionData->curr_rr.type, dnsSessionData->curr_rr.dns_class, dnsSessionData->curr_rr.ttl, dnsSessionData->curr_rr.length); ); dnsSessionData->bytes_seen_curr_rec = 0; dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_RDATA_MID; /* Fall through */ case DNS_RESP_STATE_RR_RDATA_MID: /* Data now points to the beginning of the RDATA */ data = p->payload + (p->payload_size - bytes_unused); bytes_unused = ParseDNSRData(p, data, bytes_unused, dnsSessionData); if (dnsSessionData->curr_rec_state != DNS_RESP_STATE_RR_COMPLETE) { /* Out of data, pick up on the next packet */ return; } else { /* Go to the next record */ dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_NAME_SIZE; dnsSessionData->curr_rec++; if (dnsSessionData->curr_rr.type == DNS_RR_TYPE_TXT) { /* Reset the state tracking for this record */ bzero(&dnsSessionData->curr_txt, sizeof(DNSNameState)); } data = p->payload + (p->payload_size - bytes_unused); } } } /* Done with this one, onto the next -- may also be in this packet */ dnsSessionData->state = DNS_RESP_STATE_LENGTH; dnsSessionData->curr_rec_state = 0; dnsSessionData->curr_rec = 0; } } return;}/* Main runtime entry point for DNS preprocessor. * Analyzes DNS packets for anomalies/exploits. * * PARAMETERS: * * p: Pointer to current packet to process. * context: Pointer to context block, not used. * * RETURNS: Nothing. */static void ProcessDNS( void* packetPtr, void* context ){ DNSSessionData* dnsSessionData = NULL; u_int8_t src = 0; u_int8_t dst = 0; u_int8_t known_port = 0; u_int8_t direction = 0; SFSnortPacket* p;#ifdef TARGET_BASED int16_t app_id = SFTARGET_UNKNOWN_PROTOCOL;#endif PROFILE_VARS; p = (SFSnortPacket*) packetPtr; /* Do we have a IP packet? */ if (( !p )#ifndef SUP_IP6 || ( !p->ip4_header )#endif ) { return; } /* DNS only goes over TCP or UDP */ if (!p->tcp_header && !p->udp_header) { return; } /* Check the ports to make sure this is a DNS port.#if 0 * Otherwise no need to examine the traffic.#endif */#ifdef TARGET_BASED app_id = _dpd.streamAPI->get_application_protocol_id(p->stream_session_ptr); if (app_id == SFTARGET_UNKNOWN_PROTOCOL) { return; } if (app_id && app_id != dns_app_id) { return; } if (!app_id) {#endif src = CheckDNSPort( p->src_port ); dst = CheckDNSPort( p->dst_port );#ifdef TARGET_BASED }#endif /* See if a known server port is involved. */ known_port = ( src || dst ? 1 : 0 ); #if 0 if ( !dns_config.autodetect && !src && !dst ) { /* Not one of the ports we care about. */ return; }#endif#ifdef TARGET_BASED if (!app_id && !known_port)#else if (!known_port)#endif { /* Not one of the ports we care about. */ return; } /* For TCP, do a few extra checks... */ if (p->tcp_header) { /* If session picked up mid-stream, do not process further. * Would be almost impossible to tell where we are in the * data stream. */ if ( _dpd.streamAPI->get_session_flags( p->stream_session_ptr) & SSNFLAG_MIDSTREAM ) { return; } if ( !_dpd.streamAPI->is_stream_sequenced(p->stream_session_ptr, SSN_DIR_SERVER)) { return; } if (!(_dpd.streamAPI->get_reassembly_direction(p->stream_session_ptr) & SSN_DIR_SERVER)) { /* This should only happen for the first packet (SYN or SYN-ACK) * in the TCP session */ _dpd.streamAPI->set_reassembly(p->stream_session_ptr, STREAM_FLPOLICY_FOOTPRINT, SSN_DIR_SERVER, STREAM_FLPOLICY_SET_APPEND); return; } /* If we're waiting on stream reassembly, don't process this packet. */ if ( p->flags & FLAG_STREAM_INSERT) { return; } /* Get the direction of the packet. */ direction = ( (p->flags & FLAG_FROM_SERVER ) ? DNS_DIR_FROM_SERVER : DNS_DIR_FROM_CLIENT ); } else if (p->udp_header) {#ifdef TARGET_BASED if (app_id == dns_app_id) { direction = ( (p->flags & FLAG_FROM_SERVER ) ? DNS_DIR_FROM_SERVER : DNS_DIR_FROM_CLIENT ); } else {#endif if (src) direction = DNS_DIR_FROM_SERVER; else if (dst) direction = DNS_DIR_FROM_CLIENT;#ifdef TARGET_BASED }#endif } /* check if we have data to work with */ if (( !p->payload ) || ( !p->payload_size )) { return; } PREPROC_PROFILE_START(dnsPerfStats); /* Check the stream session. If it does not currently * have our DNS data-block attached, create one. */ dnsSessionData = GetDNSSessionData( p ); if ( !dnsSessionData ) { /* Could not get/create the session data for this packet. */ PREPROC_PROFILE_END(dnsPerfStats); return; } if (dnsSessionData->flags & DNS_FLAG_NOT_DNS) { /* determined that this session wasn't DNS, we're done */ PREPROC_PROFILE_END(dnsPerfStats); return; } if (direction == DNS_DIR_FROM_SERVER) { ParseDNSResponseMessage(p, dnsSessionData); } PREPROC_PROFILE_END(dnsPerfStats);}static void DNSReset(int signal, void *data){ return;}static void DNSResetStats(int signal, void *data){ return;}static void _addPortsToStream5Filter(){ int portNum; for (portNum = 0; portNum < MAXPORTS; portNum++) { if(dns_config.ports[(portNum/8)] & (1<<(portNum%8))) { //Add port the port _dpd.streamAPI->set_port_filter_status(IPPROTO_TCP, portNum, PORT_MONITOR_SESSION); _dpd.streamAPI->set_port_filter_status(IPPROTO_UDP, portNum, PORT_MONITOR_SESSION); } }}#ifdef TARGET_BASEDstatic void _addServicesToStream5Filter(){ _dpd.streamAPI->set_service_filter_status(dns_app_id, PORT_MONITOR_SESSION);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -