From: Shravan Rangarajuvenkata (shrarang) Date: Thu, 24 Jun 2021 14:37:55 +0000 (+0000) Subject: Merge pull request #2936 in SNORT/snort3 from ~CLJUDGE/snort3:snort3_smb_payload_apps... X-Git-Tag: 3.1.7.0~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4c5d7ebd85c81604ffa27019366aae12e20f9267;p=thirdparty%2Fsnort3.git Merge pull request #2936 in SNORT/snort3 from ~CLJUDGE/snort3:snort3_smb_payload_apps to master Squashed commit of the following: commit cc9d61b77d6abecef2d2474c3aa66f39e3410d7e Author: cljudge Date: Tue Jun 1 01:41:02 2021 -0400 appid: enhance netbios service detector to identify SMB versions as web app. --- diff --git a/src/network_inspectors/appid/application_ids.h b/src/network_inspectors/appid/application_ids.h index ecc9b235b..48deec361 100644 --- a/src/network_inspectors/appid/application_ids.h +++ b/src/network_inspectors/appid/application_ids.h @@ -1012,6 +1012,9 @@ enum ApplicationIds : AppId APP_ID_FTP_PASSIVE = 4003, APP_ID_QUIC = 4023, APP_ID_PSIPHON = 4075, + APP_ID_SMB_VERSION_1 = 4645, + APP_ID_SMB_VERSION_2 = 4646, + APP_ID_SMB_VERSION_3 = 4647, #ifdef REG_TEST APP_ID_DNS_OVER_TLS = 4615, APP_ID_REGTEST = 10000, diff --git a/src/network_inspectors/appid/service_plugins/service_netbios.cc b/src/network_inspectors/appid/service_plugins/service_netbios.cc index 9e422a2b2..e9a872efc 100644 --- a/src/network_inspectors/appid/service_plugins/service_netbios.cc +++ b/src/network_inspectors/appid/service_plugins/service_netbios.cc @@ -49,7 +49,7 @@ using namespace snort; #define NBNS_OPCODE_REFRESHALT 9 #define NBNS_OPCODE_MHREGISTRATION 15 -#define NBSS_COUNT_THRESHOLD 4 +#define NBSS_COUNT_THRESHOLD 5 #define NBNS_REPLYCODE_MAX 7 @@ -158,6 +158,17 @@ uint8_t NB_SMB_BANNER[] = 0xFF, 'S', 'M', 'B' }; +uint8_t NB_SMB2_BANNER[] = +{ + 0xFE, 'S', 'M', 'B' +}; + +// this header is used in SMB3+ dialects for encryption negotiation +uint8_t NB_SMB2_TRANSFORM_BANNER[] = +{ + 0xFD, 'S', 'M', 'B' +}; + struct ServiceSMBHeader { uint8_t command; @@ -634,7 +645,7 @@ static inline void smb_find_domain(const uint8_t* data, uint16_t size, if (size < sizeof(*smb) + sizeof(wc)) return; smb = (const ServiceSMBHeader*)data; - if (smb->status != SERVICE_SMB_STATUS_SUCCESS and + if (smb->status != SERVICE_SMB_STATUS_SUCCESS and smb->status != SERVICE_SMB_MORE_PROCESSING_REQUIRED) return; if (!(smb->flags[0] & SERVICE_SMB_FLAGS_RESPONSE)) @@ -760,6 +771,69 @@ static inline void smb_find_domain(const uint8_t* data, uint16_t size, asd.set_netbios_domain(change_bits, (const char *)domain); } +void NbssServiceDetector::parse_type_message(AppIdDiscoveryArgs& args, + const uint8_t* data, uint32_t tmp) +{ + ServiceNBSSData* nd = (ServiceNBSSData*)data_get(args.asd); + + 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) + { + nd->serviceAppId = APP_ID_NETBIOS_SSN; + add_payload(args.asd, APP_ID_SMB_VERSION_1); + } + + if (nd->length <= tmp) + { + smb_find_domain(data + sizeof(NB_SMB_BANNER), + nd->length - sizeof(NB_SMB_BANNER), args.asd, args.change_bits); + } + } + else if (tmp >= sizeof(NB_SMB2_BANNER) and + nd->length >= sizeof(NB_SMB2_BANNER) and + !memcmp(data, NB_SMB2_BANNER, sizeof(NB_SMB2_BANNER))) + { + if (nd->serviceAppId != APP_ID_DCE_RPC) + { + nd->serviceAppId = APP_ID_NETBIOS_SSN; + add_payload(args.asd, APP_ID_SMB_VERSION_2); + } + + if (nd->length <= tmp) + { + smb_find_domain(data + sizeof(NB_SMB2_BANNER), + nd->length - sizeof(NB_SMB2_BANNER), args.asd, args.change_bits); + } + } + else if (tmp >= sizeof(NB_SMB2_TRANSFORM_BANNER) and + nd->length >= sizeof(NB_SMB2_TRANSFORM_BANNER) and + !memcmp(data, NB_SMB2_TRANSFORM_BANNER, sizeof(NB_SMB2_TRANSFORM_BANNER))) + { + if (nd->serviceAppId != APP_ID_DCE_RPC) + { + nd->serviceAppId = APP_ID_NETBIOS_SSN; + add_payload(args.asd, APP_ID_SMB_VERSION_3); + } + + if (nd->length <= tmp) + { + smb_find_domain(data + sizeof(NB_SMB2_TRANSFORM_BANNER), + nd->length - sizeof(NB_SMB2_TRANSFORM_BANNER), args.asd, + args.change_bits); + } + } + 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; + nd->miscAppId = APP_ID_NETBIOS_SSN; + } +} + NbssServiceDetector::NbssServiceDetector(ServiceDiscovery* sd) { handler = sd; @@ -769,7 +843,9 @@ NbssServiceDetector::NbssServiceDetector(ServiceDiscovery* sd) tcp_patterns = { - { NB_SMB_BANNER, sizeof(NB_SMB_BANNER), -1, 0, 0 } + { NB_SMB_BANNER, sizeof(NB_SMB_BANNER), -1, 0, 0 }, + { NB_SMB2_BANNER, sizeof(NB_SMB2_BANNER), -1, 0, 0 }, + { NB_SMB2_TRANSFORM_BANNER, sizeof(NB_SMB2_TRANSFORM_BANNER), -1, 0, 0 } }; appid_registry = @@ -845,31 +921,9 @@ int NbssServiceDetector::validate(AppIdDiscoveryArgs& args) if (hdr->flags & 0xFE) goto fail; nd->length = ((uint32_t)(hdr->flags & 0x01)) << 16; - nd->length |= (uint32_t)ntohs(hdr->length); + nd->length += (uint32_t)ntohs(hdr->length); tmp = end - data; - 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) - { - nd->serviceAppId = APP_ID_NETBIOS_SSN; - } - - if (nd->length <= tmp) - { - smb_find_domain(data + sizeof(NB_SMB_BANNER), - nd->length - sizeof(NB_SMB_BANNER), args.asd, args.change_bits); - } - } - 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; - nd->miscAppId = APP_ID_NETBIOS_SSN; - } - + parse_type_message(args, data, tmp); if (tmp < nd->length) { data = end; @@ -911,28 +965,7 @@ 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) and - nd->length >= sizeof(NB_SMB_BANNER) and - !memcmp(data, NB_SMB_BANNER, sizeof(NB_SMB_BANNER))) - { - if (nd->serviceAppId != APP_ID_DCE_RPC) - { - nd->serviceAppId = APP_ID_NETBIOS_SSN; - } - if (nd->length <= tmp) - { - smb_find_domain(data + sizeof(NB_SMB_BANNER), nd->length, args.asd, - args.change_bits); - } - } - 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; - nd->miscAppId = APP_ID_NETBIOS_SSN; - } - + parse_type_message(args, data, tmp); if (tmp < nd->length) { data = end; diff --git a/src/network_inspectors/appid/service_plugins/service_netbios.h b/src/network_inspectors/appid/service_plugins/service_netbios.h index f9c6024fe..7f1054a33 100644 --- a/src/network_inspectors/appid/service_plugins/service_netbios.h +++ b/src/network_inspectors/appid/service_plugins/service_netbios.h @@ -33,6 +33,10 @@ public: NbssServiceDetector(ServiceDiscovery*); int validate(AppIdDiscoveryArgs&) override; + +private: + void parse_type_message(AppIdDiscoveryArgs& args, const uint8_t* data, + uint32_t tmp); }; class NbnsServiceDetector : public ServiceDetector