From: Shravan Rangarajuvenkata (shrarang) Date: Mon, 22 Mar 2021 18:35:40 +0000 (+0000) Subject: Merge pull request #2752 in SNORT/snort3 from ~CLJUDGE/snort3:snort3_add_netbios_doma... X-Git-Tag: 3.1.3.0~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c8bd7ea0acde353d02628b9ad51cdbb7d7bf4c96;p=thirdparty%2Fsnort3.git Merge pull request #2752 in SNORT/snort3 from ~CLJUDGE/snort3:snort3_add_netbios_domain_to_logs to master Squashed commit of the following: commit 482176a1c83f2a63941308ec6dbef5f7f2109712 Author: cljudge Date: Wed Feb 17 04:55:19 2021 -0500 appid: Make netbios domain available through appid api. --- diff --git a/src/network_inspectors/appid/appid_session.cc b/src/network_inspectors/appid/appid_session.cc index e946f0eaa..20837ce81 100644 --- a/src/network_inspectors/appid/appid_session.cc +++ b/src/network_inspectors/appid/appid_session.cc @@ -646,8 +646,6 @@ void AppIdSession::delete_session_data(bool free_api) api.client.reset(); api.payload.reset(); - snort_free(netbios_domain); - if (tsession) delete tsession; @@ -908,7 +906,6 @@ void AppIdSession::set_application_ids_service(AppId service_id, AppidChangeBits void AppIdSession::reset_session_data(AppidChangeBits& change_bits) { delete_session_data(); - netbios_domain = nullptr; api.hsessions.clear(); tp_payload_app_id = APP_ID_UNKNOWN; diff --git a/src/network_inspectors/appid/appid_session.h b/src/network_inspectors/appid/appid_session.h index b9ac1cee4..b62ad024c 100644 --- a/src/network_inspectors/appid/appid_session.h +++ b/src/network_inspectors/appid/appid_session.h @@ -277,8 +277,6 @@ public: std::map client_candidates; bool tried_reverse_service = false; - char* netbios_domain = nullptr; - TlsSession* tsession = nullptr; unsigned scan_flags = 0; ThirdPartyAppIdSession* tpsession = nullptr; @@ -567,6 +565,11 @@ public: api.set_netbios_name(change_bits, name); } + void set_netbios_domain(AppidChangeBits& change_bits, const char *domain) + { + api.set_netbios_domain(change_bits, domain); + } + OdpContext& get_odp_ctxt() const { return odp_ctxt; diff --git a/src/network_inspectors/appid/appid_session_api.cc b/src/network_inspectors/appid/appid_session_api.cc index 0e8d3eed0..4830bfcb7 100644 --- a/src/network_inspectors/appid/appid_session_api.cc +++ b/src/network_inspectors/appid/appid_session_api.cc @@ -313,6 +313,11 @@ const char* AppIdSessionApi::get_netbios_name() const return netbios_name; } +const char* AppIdSessionApi::get_netbios_domain() const +{ + return netbios_domain; +} + void AppIdSessionApi::set_netbios_name(AppidChangeBits& change_bits, const char* name) { if (netbios_name) @@ -325,6 +330,18 @@ void AppIdSessionApi::set_netbios_name(AppidChangeBits& change_bits, const char* change_bits.set(APPID_NETBIOS_NAME_BIT); } +void AppIdSessionApi::set_netbios_domain(AppidChangeBits& change_bits, const char* domain) +{ + if (netbios_domain) + { + if (strcmp(netbios_domain, domain) == 0) + return; + snort_free(netbios_domain); + } + netbios_domain = snort_strdup(domain); + change_bits.set(APPID_NETBIOS_DOMAIN_BIT); +} + void AppIdSessionApi::set_ss_application_ids(AppId service_id, AppId client_id, AppId payload_id, AppId misc_id, AppId referred_id, AppidChangeBits& change_bits, Flow& flow) { diff --git a/src/network_inspectors/appid/appid_session_api.h b/src/network_inspectors/appid/appid_session_api.h index 726e39cf9..f4e50cf74 100644 --- a/src/network_inspectors/appid/appid_session_api.h +++ b/src/network_inspectors/appid/appid_session_api.h @@ -126,6 +126,7 @@ public: const char* get_tls_host() const; bool is_http_inspection_done() const; const char* get_netbios_name() const; + const char* get_netbios_domain() const; // For protocols such as HTTP2 which can have multiple streams within a single flow, // get_first_stream_* methods return the appids in the first stream seen in a packet. @@ -166,6 +167,7 @@ private: ServiceAppDescriptor service; char* tls_host = nullptr; char* netbios_name = nullptr; + char* netbios_domain = nullptr; std::string session_id; bool user_logged_in = false; @@ -182,6 +184,7 @@ private: void set_ss_application_ids(AppId client, AppId payload, AppidChangeBits& change_bits, Flow& flow); void set_application_ids_service(AppId service_id, AppidChangeBits& change_bits, Flow& flow); void set_netbios_name(AppidChangeBits& change_bits, const char* name); + void set_netbios_domain(AppidChangeBits& change_bits, const char* domain); AppIdHttpSession* get_hsession(uint32_t stream_index = 0) const; @@ -190,6 +193,7 @@ private: delete_all_http_sessions(); snort_free(tls_host); snort_free(netbios_name); + snort_free(netbios_domain); delete dsession; } diff --git a/src/network_inspectors/appid/service_plugins/service_netbios.cc b/src/network_inspectors/appid/service_plugins/service_netbios.cc index 65a66440a..1acd06693 100644 --- a/src/network_inspectors/appid/service_plugins/service_netbios.cc +++ b/src/network_inspectors/appid/service_plugins/service_netbios.cc @@ -218,6 +218,7 @@ struct ServiceSMBTransactionHeader /* sc * 2 to get to the transaction name */ #define SERVICE_SMB_STATUS_SUCCESS 0x00000000 +#define SERVICE_SMB_MORE_PROCESSING_REQUIRED 0xc0000016 #define SERVICE_SMB_TRANSACTION_COMMAND 0x25 #define SERVICE_SMB_COMMAND_SESSION_SETUP_ANDX_RESPONSE 0x73 #define SERVICE_SMB_COMMAND_NEGOTIATE_PROTOCOL 0x72 @@ -316,11 +317,11 @@ static int netbios_validate_name_and_decode(const uint8_t** data, for (i=0; i<(NBNS_NAME_LEN/2); i++) { int j = 2 * i; - if (lbl_data->data[j] < 'A' || lbl_data->data[j] > 'Z') + if (lbl_data->data[j] < 'A' or lbl_data->data[j] > 'Z') return -1; name[i] = (uint8_t)(((uint8_t)(lbl_data->data[j] - 'A')) << 4); j++; - if (lbl_data->data[i] < 'A' || lbl_data->data[i] > 'Z') + if (lbl_data->data[i] < 'A' or lbl_data->data[i] > 'Z') return -1; name[i] |= (uint8_t)(lbl_data->data[j] - 'A'); } @@ -370,7 +371,7 @@ static int netbios_validate_name(const uint8_t** data, if (lbl_data->zero) return -1; for (i=0; idata[i] < 'A' || lbl_data->data[i] > 'Z') + if (lbl_data->data[i] < 'A' or lbl_data->data[i] > 'Z') return -1; return 0; } @@ -385,7 +386,7 @@ static int netbios_validate_label(const uint8_t** data, const uint8_t* const end lbl = (const NBNSLabel*)(*data); *data += sizeof(NBNSLabel); tmp = ntohs(lbl->type); - if (tmp != NBNS_NB && tmp != NBNS_NBSTAT) + if (tmp != NBNS_NB and tmp != NBNS_NBSTAT) return -1; return 0; } @@ -467,9 +468,9 @@ int NbnsServiceDetector::validate(AppIdDiscoveryArgs& args) if (size < sizeof(NBNSHeader)) goto fail; hdr = (const NBNSHeader*)data; - if ((hdr->Opcode > NBNS_OPCODE_QUERY && - hdr->Opcode < NBNS_OPCODE_REGISTRATION) || - (hdr->Opcode > NBNS_OPCODE_REFRESHALT && + if ((hdr->Opcode > NBNS_OPCODE_QUERY and + hdr->Opcode < NBNS_OPCODE_REGISTRATION) or + (hdr->Opcode > NBNS_OPCODE_REFRESHALT and hdr->Opcode < NBNS_OPCODE_MHREGISTRATION)) { goto fail; @@ -574,7 +575,7 @@ static inline void smb_domain_skip_string(const uint8_t** data, uint16_t* size, { if (unicode) { - if (*size != 0 && ((*offset) % 2)) + if (*size != 0 and ((*offset) % 2)) { (*offset)++; (*data)++; @@ -614,8 +615,8 @@ static inline void smb_domain_skip_string(const uint8_t** data, uint16_t* size, } } -static inline void smb_find_domain(const uint8_t* data, uint16_t size, const int, - AppIdSession& asd) +static inline void smb_find_domain(const uint8_t* data, uint16_t size, + AppIdSession& asd, AppidChangeBits& change_bits) { const ServiceSMBHeader* smb; const ServiceSMBAndXResponse* resp; @@ -631,7 +632,8 @@ static inline void smb_find_domain(const uint8_t* data, uint16_t size, const int if (size < sizeof(*smb) + sizeof(wc)) return; smb = (const ServiceSMBHeader*)data; - if (smb->status != SERVICE_SMB_STATUS_SUCCESS) + if (smb->status != SERVICE_SMB_STATUS_SUCCESS and + smb->status != SERVICE_SMB_MORE_PROCESSING_REQUIRED) return; if (!(smb->flags[0] & SERVICE_SMB_FLAGS_RESPONSE)) return; @@ -641,7 +643,7 @@ static inline void smb_find_domain(const uint8_t* data, uint16_t size, const int resp = (const ServiceSMBAndXResponse*)data; np = (const ServiceSMBNegotiateProtocolResponse*)data; wc = 2 * (uint16_t)*data; - offset = 1; + offset = 0; data++; size--; if (size < (wc + sizeof(byte_count))) @@ -669,7 +671,7 @@ static inline void smb_find_domain(const uint8_t* data, uint16_t size, const int return; smb_domain_skip_string(&data, &byte_count, &offset, unicode); smb_domain_skip_string(&data, &byte_count, &offset, unicode); - if (byte_count != 0 && (offset % 2)) + if (byte_count != 0 and (offset % 2)) { data++; byte_count--; @@ -682,7 +684,7 @@ static inline void smb_find_domain(const uint8_t* data, uint16_t size, const int capabilities = LETOHL_UNALIGNED(&np->capabilities); if (capabilities & SERVICE_SMB_CAPABILITIES_EXTENDED_SECURITY) return; - unicode = (capabilities & SERVICE_SMB_CAPABILITIES_UNICODE) || unicode; + unicode = (capabilities & SERVICE_SMB_CAPABILITIES_UNICODE) or unicode; } else if (wc != 26) return; @@ -719,11 +721,12 @@ static inline void smb_find_domain(const uint8_t* data, uint16_t size, const int data++; } } - if (!found && byte_count == 1 && *data == 0) + if (!found and byte_count == 1 and *data == 0) { byte_count--; } - if (byte_count && smb->command != SERVICE_SMB_COMMAND_NEGOTIATE_PROTOCOL) + if (byte_count and smb->command != SERVICE_SMB_COMMAND_NEGOTIATE_PROTOCOL and + smb->command != SERVICE_SMB_COMMAND_SESSION_SETUP_ANDX_RESPONSE) return; } else @@ -747,12 +750,12 @@ static inline void smb_find_domain(const uint8_t* data, uint16_t size, const int data++; } } - if (byte_count && smb->command != SERVICE_SMB_COMMAND_NEGOTIATE_PROTOCOL) + if (byte_count and smb->command != SERVICE_SMB_COMMAND_NEGOTIATE_PROTOCOL) return; } - if ( pos && (!asd.netbios_domain) ) - asd.netbios_domain = snort_strdup(domain); + if (pos) + asd.set_netbios_domain(change_bits, (const char *)domain); } NbssServiceDetector::NbssServiceDetector(ServiceDiscovery* sd) @@ -823,16 +826,16 @@ int NbssServiceDetector::validate(AppIdDiscoveryArgs& args) switch (hdr->type) { case NBSS_TYPE_RESP_POSITIVE: - if (hdr->flags || hdr->length) + if (hdr->flags or hdr->length) goto fail; nd->state = NBSS_STATE_FLOW; break; case NBSS_TYPE_RESP_NEGATIVE: - if (hdr->flags || ntohs(hdr->length) != 1) + if (hdr->flags or ntohs(hdr->length) != 1) goto fail; if (data >= end) goto fail; - if (*data < 0x80 || (*data > 0x83 && *data < 0x8F) || *data > 0x8F) + if (*data < 0x80 or (*data > 0x83 and *data < 0x8F) or *data > 0x8F) goto fail; data++; break; @@ -842,8 +845,8 @@ int NbssServiceDetector::validate(AppIdDiscoveryArgs& args) nd->length = ((uint32_t)(hdr->flags & 0x01)) << 16; nd->length |= (uint32_t)ntohs(hdr->length); tmp = end - data; - if (tmp >= sizeof(NB_SMB_BANNER) && - nd->length >= sizeof(NB_SMB_BANNER) && + if (tmp >= sizeof(NB_SMB_BANNER) and + nd->length >= sizeof(NB_SMB_BANNER) and !memcmp(data, NB_SMB_BANNER, sizeof(NB_SMB_BANNER))) { if (nd->serviceAppId != APP_ID_DCE_RPC) @@ -854,11 +857,11 @@ int NbssServiceDetector::validate(AppIdDiscoveryArgs& args) if (nd->length <= tmp) { smb_find_domain(data + sizeof(NB_SMB_BANNER), - nd->length - sizeof(NB_SMB_BANNER), dir, args.asd); + nd->length - sizeof(NB_SMB_BANNER), args.asd, args.change_bits); } } - else if (tmp >= 4 && nd->length >= 4 && - !(*((const uint32_t*)data)) && + else if (tmp >= 4 and nd->length >= 4 and + !(*((const uint32_t*)data)) and dcerpc_validate(data+4, ((int)std::min(tmp, nd->length)) - 4) > 0) { nd->serviceAppId = APP_ID_DCE_RPC; @@ -879,7 +882,7 @@ int NbssServiceDetector::validate(AppIdDiscoveryArgs& args) } break; case NBSS_TYPE_RESP_RETARGET: - if (hdr->flags || ntohs(hdr->length) != 6) + if (hdr->flags or ntohs(hdr->length) != 6) goto fail; if (end - data < 6) goto fail; @@ -897,7 +900,7 @@ int NbssServiceDetector::validate(AppIdDiscoveryArgs& args) switch (hdr->type) { case NBSS_TYPE_KEEP_ALIVE: - if (hdr->flags || hdr->length) + if (hdr->flags or hdr->length) goto fail; break; case NBSS_TYPE_MESSAGE: @@ -906,8 +909,8 @@ int NbssServiceDetector::validate(AppIdDiscoveryArgs& args) nd->length = ((uint32_t)(hdr->flags & 0x01)) << 16; nd->length += (uint32_t)ntohs(hdr->length); tmp = end - data; - if (tmp >= sizeof(NB_SMB_BANNER) && - nd->length >= sizeof(NB_SMB_BANNER) && + if (tmp >= sizeof(NB_SMB_BANNER) and + nd->length >= sizeof(NB_SMB_BANNER) and !memcmp(data, NB_SMB_BANNER, sizeof(NB_SMB_BANNER))) { if (nd->serviceAppId != APP_ID_DCE_RPC) @@ -916,11 +919,12 @@ int NbssServiceDetector::validate(AppIdDiscoveryArgs& args) } if (nd->length <= tmp) { - smb_find_domain(data + sizeof(NB_SMB_BANNER), nd->length, dir, args.asd); + smb_find_domain(data + sizeof(NB_SMB_BANNER), nd->length, args.asd, + args.change_bits); } } - else if (tmp >= 4 && nd->length >= 4 && - !(*((const uint32_t*)data)) && + else if (tmp >= 4 and nd->length >= 4 and + !(*((const uint32_t*)data)) and !(dcerpc_validate(data+4, ((int)std::min(tmp, nd->length)) - 4) > 0)) { nd->serviceAppId = APP_ID_DCE_RPC; @@ -1045,7 +1049,7 @@ int NbdgmServiceDetector::validate(AppIdDiscoveryArgs& args) data += sizeof(NBDgmHeader); if (hdr->zero) goto fail; - if (!hdr->first || hdr->more) + if (!hdr->first or hdr->more) goto fail; switch (hdr->type) @@ -1072,7 +1076,7 @@ int NbdgmServiceDetector::validate(AppIdDiscoveryArgs& args) goto fail; if (data >= end) goto fail; - if (end-data >= (int)sizeof(NB_SMB_BANNER) && + if (end-data >= (int)sizeof(NB_SMB_BANNER) and !memcmp(data, NB_SMB_BANNER, sizeof(NB_SMB_BANNER))) { if (!args.asd.is_service_detected()) @@ -1103,7 +1107,7 @@ int NbdgmServiceDetector::validate(AppIdDiscoveryArgs& args) goto not_mailslot; data += sizeof(mailslot); browser = (const ServiceSMBBrowserHeader*)data; - if (browser->command != SERVICE_SMB_MAILSLOT_HOST && + if (browser->command != SERVICE_SMB_MAILSLOT_HOST and browser->command != SERVICE_SMB_MAILSLOT_LOCAL_MASTER) { goto not_mailslot; @@ -1123,7 +1127,7 @@ not_mailslot: data += sizeof(NBDgmError); if (end != data) goto fail; - if (err->code < NBDGM_ERROR_CODE_MIN || + if (err->code < NBDGM_ERROR_CODE_MIN or err->code > NBDGM_ERROR_CODE_MAX) { goto fail; diff --git a/src/network_inspectors/appid/service_plugins/test/service_netbios_test.cc b/src/network_inspectors/appid/service_plugins/test/service_netbios_test.cc index 33061e067..6a916c611 100644 --- a/src/network_inspectors/appid/service_plugins/test/service_netbios_test.cc +++ b/src/network_inspectors/appid/service_plugins/test/service_netbios_test.cc @@ -50,6 +50,7 @@ int ServiceDiscovery::fail_service(AppIdSession&, const Packet*, AppidSessionDir int ServiceDiscovery::add_service_port(AppIdDetector*, const ServiceDetectorPort&) { return APPID_EINVALID; } void AppIdSessionApi::set_netbios_name(AppidChangeBits&, const char*) {} +void AppIdSessionApi::set_netbios_domain(AppidChangeBits&, const char*) {} TEST_GROUP(service_netbios_test){}; diff --git a/src/network_inspectors/appid/test/appid_api_test.cc b/src/network_inspectors/appid/test/appid_api_test.cc index 53e5796fd..4ab780b3b 100644 --- a/src/network_inspectors/appid/test/appid_api_test.cc +++ b/src/network_inspectors/appid/test/appid_api_test.cc @@ -253,7 +253,7 @@ TEST(appid_api, ssl_app_group_id_lookup) CHECK_EQUAL(service, APPID_UT_ID); CHECK_EQUAL(client, APPID_UT_ID); CHECK_EQUAL(payload, APPID_UT_ID); - STRCMP_EQUAL("Published change_bits == 000000000000000000", test_log); + STRCMP_EQUAL("Published change_bits == 0000000000000000000", test_log); service = APP_ID_NONE; client = APP_ID_NONE; @@ -266,7 +266,7 @@ TEST(appid_api, ssl_app_group_id_lookup) STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_first_alt_name(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST); - STRCMP_EQUAL("Published change_bits == 000000000100011000", test_log); + STRCMP_EQUAL("Published change_bits == 0000000000100011000", test_log); mock_session->tsession->set_tls_host("www.cisco.com", 13, change_bits); mock_session->tsession->set_tls_cname("www.cisco.com", 13, change_bits); @@ -282,7 +282,7 @@ TEST(appid_api, ssl_app_group_id_lookup) STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_org_unit(), "Cisco"); - STRCMP_EQUAL("Published change_bits == 000000000100011000", test_log); + STRCMP_EQUAL("Published change_bits == 0000000000100011000", test_log); string host = ""; val = appid_api.ssl_app_group_id_lookup(flow, (const char*)(host.c_str()), nullptr, @@ -293,7 +293,7 @@ TEST(appid_api, ssl_app_group_id_lookup) STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_org_unit(), "Google"); - STRCMP_EQUAL("Published change_bits == 000000000100000000", test_log); + STRCMP_EQUAL("Published change_bits == 0000000000100000000", test_log); mock().checkExpectations(); } diff --git a/src/network_inspectors/appid/test/appid_discovery_test.cc b/src/network_inspectors/appid/test/appid_discovery_test.cc index 657362570..e0abc440e 100644 --- a/src/network_inspectors/appid/test/appid_discovery_test.cc +++ b/src/network_inspectors/appid/test/appid_discovery_test.cc @@ -375,7 +375,7 @@ TEST(appid_discovery_tests, event_published_when_ignoring_flow) // Detect changes in service, client, payload, and misc appid mock().checkExpectations(); - STRCMP_EQUAL("Published change_bits == 000000000001111100", test_log); + STRCMP_EQUAL("Published change_bits == 0000000000001111100", test_log); delete &asd->get_api(); delete asd; @@ -407,7 +407,7 @@ TEST(appid_discovery_tests, event_published_when_processing_flow) // Detect changes in service, client, payload, and misc appid mock().checkExpectations(); - STRCMP_EQUAL("Published change_bits == 000000000001111100", test_log); + STRCMP_EQUAL("Published change_bits == 0000000000001111100", test_log); delete &asd->get_api(); delete asd; delete flow; @@ -503,10 +503,10 @@ TEST(appid_discovery_tests, change_bits_to_string) change_bits_to_string(change_bits, str); STRCMP_EQUAL(str.c_str(), "created, reset, service, client, payload, misc, referred, host," " tls-host, url, user-agent, response, referrer, dns-host, service-info, client-info," - " user-info, netbios-name"); + " user-info, netbios-name, netbios-domain"); // Failure of this test is a reminder that enum is changed, hence translator needs update - CHECK_EQUAL(APPID_MAX_BIT, 18); + CHECK_EQUAL(APPID_MAX_BIT, 19); } int main(int argc, char** argv) diff --git a/src/pub_sub/appid_events.h b/src/pub_sub/appid_events.h index c660a6856..c4337950f 100644 --- a/src/pub_sub/appid_events.h +++ b/src/pub_sub/appid_events.h @@ -63,6 +63,7 @@ enum AppidChangeBit APPID_CLIENT_INFO_BIT, APPID_USER_INFO_BIT, APPID_NETBIOS_NAME_BIT, + APPID_NETBIOS_DOMAIN_BIT, APPID_MAX_BIT }; @@ -109,6 +110,8 @@ inline void change_bits_to_string(AppidChangeBits& change_bits, std::string& str --n? str.append("user-info, ") : str.append("user-info"); if (change_bits.test(APPID_NETBIOS_NAME_BIT)) --n? str.append("netbios-name, ") : str.append("netbios-name"); + if (change_bits.test(APPID_NETBIOS_DOMAIN_BIT)) + --n? str.append("netbios-domain, ") : str.append("netbios-domain"); if (n != 0) // make sure all bits from AppidChangeBit enum get translated str.append("change_bits_to_string error!"); }