From: Rishabh Duggal (riduggal) Date: Wed, 18 Dec 2024 11:41:51 +0000 (+0000) Subject: Pull request #4476: dns: adding fallback functionality X-Git-Tag: 3.6.1.0~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=05bde84e5ab663b00e140cb07ece70c08bb1ebde;p=thirdparty%2Fsnort3.git Pull request #4476: dns: adding fallback functionality Merge in SNORT/snort3 from ~RIDUGGAL/snort3:dns_fallback to master Squashed commit of the following: commit 9ef5c14e1f1ebc5d2b62e23326bc10c6de931b29 Author: riduggal Date: Tue Oct 8 10:29:36 2024 +0000 dns: adding fallback functionality --- diff --git a/src/service_inspectors/dns/dns.cc b/src/service_inspectors/dns/dns.cc index 5dc827d6e..78951c4a6 100644 --- a/src/service_inspectors/dns/dns.cc +++ b/src/service_inspectors/dns/dns.cc @@ -31,7 +31,6 @@ #include "dns_config.h" #include "log/messages.h" #include "profiler/profiler.h" -#include "protocols/packet.h" #include "stream/stream.h" #include "dns_module.h" @@ -53,6 +52,7 @@ const PegInfo dns_peg_names[] = { CountType::SUM, "responses", "total dns responses" }, { CountType::NOW, "concurrent_sessions", "total concurrent dns sessions" }, { CountType::MAX, "max_concurrent_sessions", "maximum concurrent dns sessions" }, + { CountType::SUM, "aborted_sessions", "total dns sessions aborted" }, { CountType::END, nullptr, nullptr } }; @@ -100,10 +100,31 @@ static DNSData* SetNewDNSData(Packet* p) return &fd->session; } -static DNSData* get_dns_session_data(Packet* p, bool from_server, DNSData& udpSessionData) +bool DNSData::valid_dns(const DNSHdr& dns_header) const { - DnsFlowData* fd; + // Check QR bit (Query/Response) + bool is_query = ((dns_header.flags & 0x8000) == 0); + + // Check Opcode (should be 0 for standard queries) + uint16_t opcode = (dns_header.flags & 0x7800) >> 11; + if (opcode > 2) + return false; + + // Check for reserved bits and RCODE + if (dns_header.flags & 0x7800) + return false; + + // Validate Recursion bits (RA should not be set in a query) + bool ra_bit = (dns_header.flags & 0x0080) != 0; + if (is_query && ra_bit) + return false; + + return true; +} +DNSData* get_dns_session_data(Packet* p, bool from_server, DNSData& udpSessionData) +{ + DnsFlowData* fd; if (p->is_udp()) { if(p->dsize > MAX_UDP_PAYLOAD) @@ -1146,6 +1167,12 @@ static void snort_dns(Packet* p, const DnsConfig* dns_config) bool needNextPacket = false; ParseDNSResponseMessage(p, dnsSessionData, needNextPacket); + if (!dnsSessionData->valid_dns(dnsSessionData->hdr)) + { + dnsSessionData->flags |= DNS_FLAG_NOT_DNS; + return; + } + if (!needNextPacket and dnsSessionData->has_events()) DataBus::publish(Dns::get_pub_id(), DnsEventIds::DNS_RESPONSE_DATA, dnsSessionData->dns_events); diff --git a/src/service_inspectors/dns/dns.h b/src/service_inspectors/dns/dns.h index b60d77468..0c8dcdc5a 100644 --- a/src/service_inspectors/dns/dns.h +++ b/src/service_inspectors/dns/dns.h @@ -24,6 +24,7 @@ #include "flow/flow.h" +#include "protocols/packet.h" #include "pub_sub/dns_events.h" // Implementation header with definitions, datatypes and flowdata class for @@ -204,8 +205,11 @@ struct DNSData bool publish_response() const; bool has_events() const; + bool valid_dns(const DNSHdr&) const; }; +DNSData* get_dns_session_data(snort::Packet* p, bool from_server, DNSData& udpSessionData); + class DnsResponseIp { public: diff --git a/src/service_inspectors/dns/dns_module.h b/src/service_inspectors/dns/dns_module.h index 26d581344..44d57ad20 100644 --- a/src/service_inspectors/dns/dns_module.h +++ b/src/service_inspectors/dns/dns_module.h @@ -48,6 +48,7 @@ struct DnsStats PegCount responses; PegCount concurrent_sessions; PegCount max_concurrent_sessions; + PegCount aborted_sessions; }; extern const PegInfo dns_peg_names[]; diff --git a/src/service_inspectors/dns/dns_splitter.cc b/src/service_inspectors/dns/dns_splitter.cc index 14c893bec..248881415 100644 --- a/src/service_inspectors/dns/dns_splitter.cc +++ b/src/service_inspectors/dns/dns_splitter.cc @@ -25,14 +25,30 @@ #include +#include "log/messages.h" +#include "protocols/packet.h" + +#include "dns.h" +#include "dns_module.h" + using namespace snort; StreamSplitter::Status DnsSplitter::scan( - Packet*, const uint8_t* data, uint32_t len, + Packet* p, const uint8_t* data, uint32_t len, uint32_t, uint32_t* fp) { assert(len > 0); + DNSData udp_session_data; + bool from_server = p->is_from_server(); + DNSData* dnsSessionData = get_dns_session_data(p, from_server, udp_session_data); + + if ( dnsSessionData and ( dnsSessionData->flags & DNS_FLAG_NOT_DNS ) ) + { + dnsstats.aborted_sessions++; + return ABORT; + } + if ( partial ) { *fp = size + *data + 1;