📄 spp_dns.c
字号:
dnsSessionData->hdr.flags, dnsSessionData->hdr.questions, dnsSessionData->hdr.answers, dnsSessionData->hdr.authorities, dnsSessionData->hdr.additionals); }#endif if (!(dnsSessionData->hdr.flags & DNS_HDR_FLAG_RESPONSE)) { /* Not a response */ return; } /* Handle the DNS Queries */ if (dnsSessionData->state == DNS_RESP_STATE_QUESTION) { /* Skip over the 4 byte question records... */ for (i=dnsSessionData->curr_rec; i< dnsSessionData->hdr.questions; i++) { bytes_unused = ParseDNSQuestion(data, p->payload_size, bytes_unused, dnsSessionData); if (dnsSessionData->curr_rec_state == DNS_RESP_STATE_Q_COMPLETE) { DEBUG_WRAP( DebugMessage(DEBUG_DNS, "DNS Question %d: type %d, class %d\n", i, dnsSessionData->curr_q.type, dnsSessionData->curr_q.dns_class); ); dnsSessionData->curr_rec_state = DNS_RESP_STATE_Q_NAME; dnsSessionData->curr_rec++; } if (bytes_unused > 0) { data = p->payload + (p->payload_size - bytes_unused); } 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; PROFILE_VARS; p = (SFSnortPacket*) packetPtr; /* Do we have a IP packet? */ if (( !p ) || ( !p->ip4_header ) ) { 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 */ src = CheckDNSPort( p->src_port ); dst = CheckDNSPort( p->dst_port ); /* 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 if (!known_port) { /* 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) { if (src) direction = DNS_DIR_FROM_SERVER; else if (dst) direction = DNS_DIR_FROM_CLIENT; } /* 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -