From: Russ Combs (rucombs) Date: Fri, 15 Jul 2016 21:03:21 +0000 (-0400) Subject: Merge pull request #560 in SNORT/snort3 from smb_dialect to master X-Git-Tag: 3.0.0-233~331 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fe9be7c76c181c73b0749156b06fe17de2a4ec27;p=thirdparty%2Fsnort3.git Merge pull request #560 in SNORT/snort3 from smb_dialect to master Squashed commit of the following: commit de5ae8e8737762b7cf24930409dfa6a32693662f Author: mdagon Date: Fri Jul 15 15:10:06 2016 -0400 Code reivew: dialect_index should be const commit 05bd0f3a241e58fd5aae1a6d05c770b927895986 Author: mdagon Date: Fri Jul 15 12:16:22 2016 -0400 Code review: remove unsed defines for various smb dialects commit 3fd9da22b3958bc327987c64abab060aa70ee1ab Author: mdagon Date: Thu Jul 14 11:44:54 2016 -0400 Smb deprecated dialect check --- diff --git a/src/service_inspectors/dce_rpc/dce_smb.h b/src/service_inspectors/dce_rpc/dce_smb.h index bfab7fa71..98d6dc8f9 100644 --- a/src/service_inspectors/dce_rpc/dce_smb.h +++ b/src/service_inspectors/dce_rpc/dce_smb.h @@ -1562,6 +1562,19 @@ inline uint16_t SmbNt_NegotiateRespMaxMultiplex(const SmbNt_NegotiateProtocolRes return alignedNtohs(&resp->smb_maxmux); } +/* This is the Core Protocol response */ +struct SmbCore_NegotiateProtocolResp /* smb_wct = 1 */ +{ + uint8_t smb_wct; /* count of 16-bit words that follow */ + uint16_t smb_index; /* index */ + uint16_t smb_bcc; /* must be 0 */ +}; + +inline uint16_t SmbNegotiateRespDialectIndex(const SmbCore_NegotiateProtocolResp* resp) +{ + return alignedNtohs(&resp->smb_index); +} + /********************************************************************* * SMB_COM_TREE_CONNECT_ANDX *********************************************************************/ diff --git a/src/service_inspectors/dce_rpc/dce_smb_commands.cc b/src/service_inspectors/dce_rpc/dce_smb_commands.cc index 011cbf6de..e9f95325d 100644 --- a/src/service_inspectors/dce_rpc/dce_smb_commands.cc +++ b/src/service_inspectors/dce_rpc/dce_smb_commands.cc @@ -29,6 +29,8 @@ #include "utils/util.h" #include "detection/detect.h" +#define SMB_DIALECT_NT_LM_012 "NT LM 0.12" // NT LAN Manager + #define SERVICE_0 (0) // IPC start #define SERVICE_1 (SERVICE_0+4) // DISK start #define SERVICE_FS (SERVICE_1+3) // Failure @@ -1644,7 +1646,7 @@ DCE2_Ret DCE2_SmbSessionSetupAndX(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr, // SMB_COM_NEGOTIATE DCE2_Ret DCE2_SmbNegotiate(DCE2_SmbSsnData* ssd, const SmbNtHdr*, - const DCE2_SmbComInfo* com_info, const uint8_t* nb_ptr, uint32_t) + const DCE2_SmbComInfo* com_info, const uint8_t* nb_ptr, uint32_t nb_len) { if (!DCE2_ComInfoCanProcessCommand(com_info)) return DCE2_RET__ERROR; @@ -1653,11 +1655,65 @@ DCE2_Ret DCE2_SmbNegotiate(DCE2_SmbSsnData* ssd, const SmbNtHdr*, if (DCE2_ComInfoIsRequest(com_info)) { - // FIXIT-M add dialect related code + // Have at least 2 bytes based on byte count check done earlier + uint8_t* term_ptr; + int ntlm_index = 0; + uint16_t com_size = DCE2_ComInfoCommandSize(com_info); + + DCE2_MOVE(nb_ptr, nb_len, com_size); + + while ((term_ptr = (uint8_t*)memchr(nb_ptr, '\0', nb_len)) != nullptr) + { + if (!SmbFmtDialect(*nb_ptr)) + { + dce_alert(GID_DCE2, DCE2_SMB_BAD_FORM, (dce2CommonStats*)&dce2_smb_stats); + + // Windows errors if bad format + if (DCE2_SsnIsWindowsPolicy(&ssd->sd)) + { + return DCE2_RET__ERROR; + } + } + + // Move past format + DCE2_MOVE(nb_ptr, nb_len, 1); + + if (nb_len == 0) + break; + + // Just a NULL byte - acceptable by Samba and Windows + if (term_ptr == nb_ptr) + continue; + + if ((*nb_ptr == 'N') + && (strncmp((const char*)nb_ptr, SMB_DIALECT_NT_LM_012, term_ptr - nb_ptr) == 0)) + break; + + // Move past string and NULL byte + DCE2_MOVE(nb_ptr, nb_len, (term_ptr - nb_ptr) + 1); + + ntlm_index++; + } + + if (term_ptr != nullptr) + { + ssd->dialect_index = ntlm_index; + } + else + { + ssd->dialect_index = DCE2_SENTINEL; + dce_alert(GID_DCE2, DCE2_SMB_DEPR_DIALECT_NEGOTIATED, + (dce2CommonStats*)&dce2_smb_stats); + } } else { - // FIXIT-M add dialect related code + const uint16_t dialect_index = + SmbNegotiateRespDialectIndex((SmbCore_NegotiateProtocolResp*)nb_ptr); + + if ((ssd->dialect_index != DCE2_SENTINEL) && (dialect_index != ssd->dialect_index)) + dce_alert(GID_DCE2, DCE2_SMB_DEPR_DIALECT_NEGOTIATED, + (dce2CommonStats*)&dce2_smb_stats); ssd->ssn_state_flags |= DCE2_SMB_SSN_STATE__NEGOTIATED;