Check for netbios to avoid reporting extra bad DNS opcodes

This commit is contained in:
Tim Wojtulewicz 2024-08-27 13:02:45 -07:00
parent 269ca3189c
commit 6394f9893e
3 changed files with 13 additions and 5 deletions

View file

@ -21,9 +21,15 @@ namespace zeek::analyzer::dns {
namespace detail { namespace detail {
// Used for checking whether the connection being parsed comes from NetBIOS,
// since it's similar to DNS but does some things differently.
constexpr int NETBIOS_PORT = 137;
DNS_Interpreter::DNS_Interpreter(analyzer::Analyzer* arg_analyzer) { DNS_Interpreter::DNS_Interpreter(analyzer::Analyzer* arg_analyzer) {
analyzer = arg_analyzer; analyzer = arg_analyzer;
first_message = true; first_message = true;
is_netbios =
ntohs(analyzer->Conn()->OrigPort()) == NETBIOS_PORT || ntohs(analyzer->Conn()->RespPort()) == NETBIOS_PORT;
} }
void DNS_Interpreter::ParseMessage(const u_char* data, int len, int is_query) { void DNS_Interpreter::ParseMessage(const u_char* data, int len, int is_query) {
@ -42,7 +48,8 @@ void DNS_Interpreter::ParseMessage(const u_char* data, int len, int is_query) {
unsigned short flags = ntohs(hdr->flags); unsigned short flags = ntohs(hdr->flags);
int opcode = (flags & 0x7800) >> 11; int opcode = (flags & 0x7800) >> 11;
if ( opcode != DNS_OP_QUERY ) { // NetBIOS registration and release messages look like regular DNS requests, so parse them as such
if ( opcode != DNS_OP_QUERY && ! is_netbios ) {
analyzer->Weird("DNS_unknown_opcode", util::fmt("%d", opcode)); analyzer->Weird("DNS_unknown_opcode", util::fmt("%d", opcode));
analyzer->Conn()->CheckHistory(zeek::session::detail::HIST_UNKNOWN_PKT, 'X'); analyzer->Conn()->CheckHistory(zeek::session::detail::HIST_UNKNOWN_PKT, 'X');
return; return;
@ -256,7 +263,7 @@ bool DNS_Interpreter::ParseAnswer(detail::DNS_MsgInfo* msg, const u_char*& data,
case detail::TYPE_NBS: status = ParseRR_NBS(msg, data, len, rdlength, msg_start); break; case detail::TYPE_NBS: status = ParseRR_NBS(msg, data, len, rdlength, msg_start); break;
case detail::TYPE_SRV: case detail::TYPE_SRV:
if ( ntohs(analyzer->Conn()->RespPort()) == 137 ) { if ( ntohs(analyzer->Conn()->RespPort()) == NETBIOS_PORT ) {
// This is an NBSTAT (NetBIOS NODE STATUS) record. // This is an NBSTAT (NetBIOS NODE STATUS) record.
// The SRV RFC reused the value that was already being // The SRV RFC reused the value that was already being
// used for this. // used for this.
@ -399,7 +406,7 @@ bool DNS_Interpreter::ExtractLabel(const u_char*& data, int& len, u_char*& name,
if ( label_len > 63 && if ( label_len > 63 &&
// NetBIOS name service look ups can use longer labels. // NetBIOS name service look ups can use longer labels.
ntohs(analyzer->Conn()->RespPort()) != 137 ) { ntohs(analyzer->Conn()->RespPort()) != NETBIOS_PORT ) {
analyzer->Weird("DNS_label_too_long"); analyzer->Weird("DNS_label_too_long");
return false; return false;
} }

View file

@ -328,7 +328,7 @@ public:
///< for forward lookups ///< for forward lookups
}; };
class DNS_Interpreter { class DNS_Interpreter final {
public: public:
explicit DNS_Interpreter(analyzer::Analyzer* analyzer); explicit DNS_Interpreter(analyzer::Analyzer* analyzer);
@ -390,6 +390,7 @@ protected:
analyzer::Analyzer* analyzer; analyzer::Analyzer* analyzer;
bool first_message; bool first_message;
bool is_netbios;
}; };
enum TCP_DNS_state { enum TCP_DNS_state {

View file

@ -1 +1 @@
4a2735a9768b124d290a1692d47a25fd8d365320 e051f29d1f03f2264b8cf1ff5ed9bfba9d326c45