1 //--------------------------------------------------------------------------
2 // Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 // Copyright (C) 2005-2013 Sourcefire, Inc.
4 //
5 // This program is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License Version 2 as published
7 // by the Free Software Foundation.  You may not use, modify or distribute
8 // this program under any other version of the GNU General Public License.
9 //
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License along
16 // with this program; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 //--------------------------------------------------------------------------
19 
20 // service_netbios.cc author Sourcefire Inc.
21 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #include "service_netbios.h"
27 
28 #include "detection/detection_engine.h"
29 #include "protocols/packet.h"
30 #include "pub_sub/smb_events.h"
31 #include "utils/endian.h"
32 #include "utils/util_cstring.h"
33 
34 #include "app_info_table.h"
35 #include "dcerpc.h"
36 
37 using namespace snort;
38 
39 #define NBSS_PORT   139
40 
41 #define NBNS_NB 32
42 #define NBNS_NBSTAT 33
43 #define NBNS_LENGTH_FLAGS 0xC0
44 
45 #define NBNS_OPCODE_QUERY           0
46 #define NBNS_OPCODE_REGISTRATION    5
47 #define NBNS_OPCODE_RELEASE         6
48 #define NBNS_OPCODE_WEACK           7
49 #define NBNS_OPCODE_REFRESH         8
50 #define NBNS_OPCODE_REFRESHALT      9
51 #define NBNS_OPCODE_MHREGISTRATION 15
52 
53 #define NBSS_COUNT_THRESHOLD 5
54 
55 #define NBNS_REPLYCODE_MAX  7
56 
57 #define NBSS_TYPE_MESSAGE       0x00
58 #define NBSS_TYPE_REQUEST       0x81
59 #define NBSS_TYPE_RESP_POSITIVE 0x82
60 #define NBSS_TYPE_RESP_NEGATIVE 0x83
61 #define NBSS_TYPE_RESP_RETARGET 0x84
62 #define NBSS_TYPE_KEEP_ALIVE    0x85
63 
64 enum NBSSState
65 {
66     NBSS_STATE_CONNECTION,
67     NBSS_STATE_FLOW,
68     NBSS_STATE_CONT,
69     NBSS_STATE_ERROR
70 };
71 
72 #define NBDGM_TYPE_DIRECT_UNIQUE        0x10
73 #define NBDGM_TYPE_DIRECT_GROUP         0x11
74 #define NBDGM_TYPE_BROADCAST            0x12
75 #define NBDGM_TYPE_ERROR                0x13
76 #define NBDGM_TYPE_REQUEST              0x14
77 #define NBDGM_TYPE_POSITIVE_REPSONSE    0x15
78 #define NBDGM_TYPE_NEGATIVE_RESPONSE    0x16
79 
80 #define NBDGM_ERROR_CODE_MIN    0x82
81 #define NBDGM_ERROR_CODE_MAX    0x84
82 
83 #define FINGERPRINT_UDP_FLAGS_XENIX 0x00000800
84 #define FINGERPRINT_UDP_FLAGS_NT    0x00001000
85 #define FINGERPRINT_UDP_FLAGS_MASK  (FINGERPRINT_UDP_FLAGS_XENIX | FINGERPRINT_UDP_FLAGS_NT)
86 
87 #pragma pack(1)
88 
89 struct NBNSHeader
90 {
91     uint16_t id;
92 #if defined(WORDS_BIGENDIAN)
93     uint8_t response : 1,
94         Opcode : 4,
95         auth : 1,
96         trunc : 1,
97         RD : 1;
98     uint8_t RA : 1,
99         unused : 2,
100         broadcast : 1,
101         replycode : 4;
102 #else
103     uint8_t RD : 1,
104         trunc : 1,
105         auth : 1,
106         Opcode : 4,
107         response : 1;
108     uint8_t replycode : 4,
109         broadcast : 1,
110         unused : 2,
111         RA : 1;
112 #endif
113     uint16_t QCount;
114     uint16_t ACount;
115     uint16_t NSCount;
116     uint16_t ARCount;
117 };
118 
119 #define NBNS_NAME_LEN 0x20
120 struct NBNSLabelLength
121 {
122     uint8_t len;
123 };
124 
125 struct NBNSLabelData
126 {
127     uint8_t len;
128     uint8_t data[NBNS_NAME_LEN];
129     uint8_t zero;
130 };
131 
132 struct NBNSLabel
133 {
134     uint16_t type;
135     uint16_t class_id;
136 };
137 
138 struct NBNSLabelPtr
139 {
140     uint8_t flag;
141     uint8_t position;
142 };
143 
144 struct NBNSAnswerData
145 {
146     uint32_t ttl;
147     uint16_t data_len;
148 };
149 
150 struct NBSSHeader
151 {
152     uint8_t type;
153     uint8_t flags;
154     uint16_t length;
155 };
156 
157 uint8_t NB_SMB_BANNER[] =
158 {
159     0xFF, 'S', 'M', 'B'
160 };
161 
162 uint8_t NB_SMB2_BANNER[] =
163 {
164     0xFE, 'S', 'M', 'B'
165 };
166 
167 // this header is used in SMB3+ dialects for encryption negotiation
168 uint8_t NB_SMB2_TRANSFORM_BANNER[] =
169 {
170     0xFD, 'S', 'M', 'B'
171 };
172 
173 struct ServiceSMBHeader
174 {
175     uint8_t command;
176     uint32_t status;
177     uint8_t flags[3];
178     uint16_t pid_high;
179     uint8_t signature[8];
180     uint16_t reserved2;
181     uint16_t tid;
182     uint16_t pid;
183     uint16_t uid;
184     uint16_t mid;
185 };
186 
187 struct ServiceSMB2Header
188 {
189     uint16_t length;
190     uint16_t cc;
191     uint32_t status;
192     uint16_t command;
193     uint16_t cr;
194     uint32_t flags;
195     uint32_t nc;
196     uint32_t msg_id[2];
197     uint32_t proc;
198     uint32_t tree_id;
199     uint32_t session_id[2];
200     uint32_t sig[4];
201 };
202 
203 struct ServiceSMB2SetupResponse
204 {
205     uint16_t struct_size;
206     uint16_t flags;
207     uint16_t sec_offset;
208     uint16_t sec_length;
209 };
210 
211 struct ServiceSMB2NtlmChallenge
212 {
213     uint8_t signature[8];
214     uint32_t msg_type;
215     uint16_t target_name_len;
216     uint16_t target_name_max_len;
217     uint32_t target_name_offset;
218     uint32_t negotiate_flags;
219     uint8_t server_challenge[8];
220     uint8_t reserved[8];
221     uint16_t target_info_len;
222     uint16_t target_info_max_len;
223     uint32_t target_info_offset;
224     uint8_t version[8];
225 };
226 
227 struct ServiceSMB2NtlmAttr
228 {
229     uint16_t type;
230     uint16_t length;
231 };
232 
233 struct ServiceSMBAndXResponse
234 {
235     uint8_t wc;
236     uint8_t cmd;
237     uint8_t reserved;
238     uint16_t offset;
239     uint16_t action;
240     uint16_t sec_len;
241 };
242 
243 struct ServiceSMBNegotiateProtocolResponse
244 {
245     uint8_t wc;
246     uint16_t dialect_index;
247     uint8_t security_mode;
248     uint16_t max_mpx_count;
249     uint16_t max_vcs;
250     uint32_t max_buffer_size;
251     uint32_t max_raw_buffer;
252     uint32_t session_key;
253     uint32_t capabilities;
254     uint32_t system_time[2];
255     uint16_t time_zone;
256     uint8_t sec_len;
257 };
258 
259 struct ServiceSMBTransactionHeader
260 {
261     uint8_t wc;
262     uint16_t total_pc;
263     uint16_t total_dc;
264     uint16_t max_pc;
265     uint16_t max_dc;
266     uint8_t max_sc;
267     uint8_t reserved;
268     uint16_t flags;
269     uint32_t timeout;
270     uint16_t reserved2;
271     uint16_t pc;
272     uint16_t po;
273     uint16_t dc;
274     uint16_t offset;
275     uint8_t sc;
276     uint8_t reserved3;
277 };
278 /* sc * 2 to get to the transaction name */
279 
280 #define SERVICE_SMB_STATUS_SUCCESS              0x00000000
281 #define SERVICE_SMB_MORE_PROCESSING_REQUIRED    0xc0000016
282 #define SERVICE_SMB_TRANSACTION_COMMAND         0x25
283 #define SERVICE_SMB_COMMAND_SESSION_SETUP_ANDX_RESPONSE 0x73
284 #define SERVICE_SMB_COMMAND_NEGOTIATE_PROTOCOL          0x72
285 #define SERVICE_SMB_CAPABILITIES_EXTENDED_SECURITY  0x80000000
286 #define SERVICE_SMB_CAPABILITIES_UNICODE            0x00000004
287 #define SERVICE_SMB_FLAGS_RESPONSE              0x80
288 #define SERVICE_SMB_FLAGS_UNICODE               0x80
289 #define SERVICE_SMB_NOT_TRANSACTION_WC          8
290 #define SERVICE_SMB_MAILSLOT_HOST               0x01
291 #define SERVICE_SMB_MAILSLOT_LOCAL_MASTER       0x0f
292 #define SERVICE_SMB_MAILSLOT_SERVER_TYPE_XENIX  0x00000800
293 #define SERVICE_SMB_MAILSLOT_SERVER_TYPE_NT     0x00001000
294 #define SERVICE_SMB2_SESSION_SETUP              0x0001
295 #define NTLM_CHALLENGE                          0x00000002
296 #define NTLM_DOMAIN_FLAG                        0x0002
297 static char mailslot[] = "\\MAILSLOT\\BROWSE";
298 static char ntlmssp[] = "NTLMSSP";
299 
300 struct ServiceSMBBrowserHeader
301 {
302     uint8_t command;
303     uint8_t count;
304     uint32_t period;
305     uint8_t hostname[16];
306     uint8_t major;
307     uint8_t minor;
308     uint32_t server_type;
309 };
310 
311 struct ServiceNBSSData
312 {
313     NBSSState state;
314     unsigned count;
315     uint32_t length;
316     AppId serviceAppId;
317     AppId miscAppId;
318     AppId payloadAppId;
319 };
320 
321 struct NBDgmHeader
322 {
323     uint8_t type;
324 #if defined(WORDS_BIGENDIAN)
325     uint8_t zero : 4,
326         SNT : 2,
327         first : 1,
328         more : 1;
329 #else
330     uint8_t more : 1,
331         first : 1,
332         SNT : 2,
333         zero : 4;
334 #endif
335     uint16_t id;
336     uint32_t src_ip;
337     uint16_t src_port;
338 };
339 
340 struct NBDgmError
341 {
342     uint8_t code;
343 };
344 
345 #pragma pack()
346 
netbios_validate_name_and_decode(const uint8_t ** data,const uint8_t * const begin,const uint8_t * const end,char * name)347 static int netbios_validate_name_and_decode(const uint8_t** data,
348     const uint8_t* const begin,
349     const uint8_t* const end,
350     char* name)
351 {
352     const NBNSLabelLength* lbl_len;
353     const NBNSLabelData* lbl_data;
354     const NBNSLabelPtr* lbl_ptr;
355     int i;
356 
357     if (end - *data < (int)sizeof(NBNSLabelLength))
358         return -1;
359     lbl_len = (const NBNSLabelLength*)(*data);
360     switch (lbl_len->len & NBNS_LENGTH_FLAGS)
361     {
362     case 0x00:
363         lbl_data = (const NBNSLabelData*)(*data);
364         if (end - *data < (int)sizeof(NBNSLabelData))
365             return -1;
366         *data += sizeof(NBNSLabelData);
367         break;
368     case 0xC0:
369         lbl_ptr = (const NBNSLabelPtr*)(*data);
370         *data += sizeof(NBNSLabelPtr);
371         if (begin + lbl_ptr->position + sizeof(NBNSLabelData) > end)
372             return -1;
373         lbl_data = (const NBNSLabelData*)(begin + lbl_ptr->position);
374         break;
375     default:
376         return -1;
377     }
378     if (lbl_data->len != NBNS_NAME_LEN)
379         return -1;
380     if (lbl_data->zero)
381         return -1;
382     for (i=0; i<(NBNS_NAME_LEN/2); i++)
383     {
384         int j = 2 * i;
385         if (lbl_data->data[j] < 'A' or lbl_data->data[j] > 'Z')
386             return -1;
387         name[i] = (uint8_t)(((uint8_t)(lbl_data->data[j] - 'A')) << 4);
388         j++;
389         if (lbl_data->data[i] < 'A' or lbl_data->data[i] > 'Z')
390             return -1;
391         name[i] |= (uint8_t)(lbl_data->data[j] - 'A');
392     }
393     name[(NBNS_NAME_LEN/2)] = 0;
394     for (i=(NBNS_NAME_LEN/2)-1; i >= 0; i--)
395     {
396         if (name[i] == ' ')
397             name[i] = 0;
398         else if (name[i])
399             break;
400     }
401     return 0;
402 }
403 
netbios_validate_name(const uint8_t ** data,const uint8_t * const begin,const uint8_t * const end)404 static int netbios_validate_name(const uint8_t** data,
405     const uint8_t* const begin,
406     const uint8_t* const end)
407 {
408     const NBNSLabelLength* lbl_len;
409     const NBNSLabelData* lbl_data;
410     const NBNSLabelPtr* lbl_ptr;
411     int i;
412 
413     if (end - *data < (int)sizeof(NBNSLabelLength))
414         return -1;
415     lbl_len = (const NBNSLabelLength*)(*data);
416     switch (lbl_len->len & NBNS_LENGTH_FLAGS)
417     {
418     case 0x00:
419         lbl_data = (const NBNSLabelData*)(*data);
420         if (end - *data < (int)sizeof(NBNSLabelData))
421             return -1;
422         *data += sizeof(NBNSLabelData);
423         break;
424     case 0xC0:
425         lbl_ptr = (const NBNSLabelPtr*)(*data);
426         *data += sizeof(NBNSLabelPtr);
427         if (begin + lbl_ptr->position + sizeof(NBNSLabelData) > end)
428             return -1;
429         lbl_data = (const NBNSLabelData*)(begin + lbl_ptr->position);
430         break;
431     default:
432         return -1;
433     }
434     if (lbl_data->len != NBNS_NAME_LEN)
435         return -1;
436     if (lbl_data->zero)
437         return -1;
438     for (i=0; i<NBNS_NAME_LEN; i++)
439         if (lbl_data->data[i] < 'A' or lbl_data->data[i] > 'Z')
440             return -1;
441     return 0;
442 }
443 
netbios_validate_label(const uint8_t ** data,const uint8_t * const end)444 static int netbios_validate_label(const uint8_t** data, const uint8_t* const end)
445 {
446     const NBNSLabel* lbl;
447     uint16_t tmp;
448 
449     if (end - *data < (int)sizeof(NBNSLabel))
450         return -1;
451     lbl = (const NBNSLabel*)(*data);
452     *data += sizeof(NBNSLabel);
453     tmp = ntohs(lbl->type);
454     if (tmp != NBNS_NB and tmp != NBNS_NBSTAT)
455         return -1;
456     return 0;
457 }
458 
nbns_validate_query(const uint8_t ** data,const uint8_t * const begin,const uint8_t * const end)459 static int nbns_validate_query(const uint8_t** data, const uint8_t* const begin,
460     const uint8_t* const end)
461 {
462     int ret;
463 
464     ret = netbios_validate_name(data, begin, end);
465     if (!ret)
466     {
467         return netbios_validate_label(data, end);
468     }
469     return ret;
470 }
471 
nbns_validate_answer(const uint8_t ** data,const uint8_t * const begin,const uint8_t * const end)472 static int nbns_validate_answer(const uint8_t** data, const uint8_t* const begin,
473     const uint8_t* const end)
474 {
475     int ret;
476 
477     ret = netbios_validate_name(data, begin, end);
478     if (ret)
479         return ret;
480     ret = netbios_validate_label(data, end);
481     if (!ret)
482     {
483         const NBNSAnswerData* ad = (const NBNSAnswerData*)(*data);
484         if (end - *data < (int)sizeof(NBNSAnswerData))
485             return -1;
486 
487         *data += sizeof(NBNSAnswerData);
488         uint16_t tmp = ntohs(ad->data_len);
489 
490         if (end - *data < tmp)
491             return -1;
492         *data += tmp;
493     }
494     return ret;
495 }
496 
NbnsServiceDetector(ServiceDiscovery * sd)497 NbnsServiceDetector::NbnsServiceDetector(ServiceDiscovery* sd)
498 {
499     handler = sd;
500     name = "nbns";
501     proto = IpProtocol::TCP;
502     detectorType = DETECTOR_TYPE_DECODER;
503 
504     appid_registry =
505     {
506         { APP_ID_NETBIOS_NS, APPINFO_FLAG_SERVICE_UDP_REVERSED }
507     };
508 
509     service_ports =
510     {
511         { 137, IpProtocol::TCP, false },
512         { 137, IpProtocol::UDP, false },
513         { 137, IpProtocol::UDP, true }
514     };
515 
516     handler->register_detector(name, this, proto);
517 }
518 
519 
validate(AppIdDiscoveryArgs & args)520 int NbnsServiceDetector::validate(AppIdDiscoveryArgs& args)
521 {
522     uint16_t i;
523     uint16_t count;
524     const NBNSHeader* hdr;
525     const uint8_t* begin;
526     const uint8_t* end;
527     const uint8_t* data = args.data;
528     const AppidSessionDirection dir = args.dir;
529     uint16_t size = args.size;
530 
531     if (!size)
532         goto inprocess;
533     if (size < sizeof(NBNSHeader))
534         goto fail;
535     hdr = (const NBNSHeader*)data;
536     if ((hdr->Opcode > NBNS_OPCODE_QUERY and
537         hdr->Opcode < NBNS_OPCODE_REGISTRATION) or
538         (hdr->Opcode > NBNS_OPCODE_REFRESHALT and
539         hdr->Opcode < NBNS_OPCODE_MHREGISTRATION))
540     {
541         goto fail;
542     }
543     if (hdr->trunc)
544         goto not_compatible;
545     if (hdr->broadcast)
546         goto not_compatible;
547 
548     begin = data;
549     end = data + size;
550     data += sizeof(NBNSHeader);
551 
552     if (!hdr->response)
553     {
554         if (dir == APP_ID_FROM_RESPONDER)
555         {
556             if (args.asd.get_session_flags(APPID_SESSION_UDP_REVERSED))
557                 goto success;
558             goto fail;
559         }
560         goto inprocess;
561     }
562 
563     if (hdr->replycode > NBNS_REPLYCODE_MAX)
564         goto fail;
565 
566     if (hdr->QCount)
567     {
568         count = ntohs(hdr->QCount);
569         for (i=0; i<count; i++)
570         {
571             if (nbns_validate_query(&data, begin, end))
572                 goto fail;
573         }
574     }
575 
576     if (hdr->ACount)
577     {
578         count = ntohs(hdr->ACount);
579         for (i=0; i<count; i++)
580         {
581             if (nbns_validate_answer(&data, begin, end))
582                 goto fail;
583         }
584     }
585 
586     if (hdr->NSCount)
587     {
588         count = ntohs(hdr->NSCount);
589         for (i=0; i<count; i++)
590         {
591             if (nbns_validate_answer(&data, begin, end))
592                 goto fail;
593         }
594     }
595 
596     if (hdr->ARCount)
597     {
598         count = ntohs(hdr->ARCount);
599         for (i=0; i<count; i++)
600         {
601             if (nbns_validate_answer(&data, begin, end))
602                 goto fail;
603         }
604     }
605 
606     if (dir == APP_ID_FROM_INITIATOR)
607     {
608         args.asd.set_session_flags(APPID_SESSION_UDP_REVERSED);
609         goto inprocess;
610     }
611 
612 success:
613     return add_service(args.change_bits, args.asd, args.pkt, dir, APP_ID_NETBIOS_NS);
614 
615 inprocess:
616     service_inprocess(args.asd, args.pkt, dir);
617     return APPID_INPROCESS;
618 
619 fail:
620     fail_service(args.asd, args.pkt, dir);
621     return APPID_NOMATCH;
622 
623 not_compatible:
624     incompatible_data(args.asd, args.pkt, dir);
625     return APPID_NOT_COMPATIBLE;
626 }
627 
nbss_free_state(void * data)628 static void nbss_free_state(void* data)
629 {
630     ServiceNBSSData* nd = (ServiceNBSSData*)data;
631 
632     if (nd)
633     {
634         snort_free(nd);
635     }
636 }
637 
smb_domain_skip_string(const uint8_t ** data,uint16_t * size,uint16_t * offset,const uint8_t unicode)638 static inline void smb_domain_skip_string(const uint8_t** data, uint16_t* size, uint16_t* offset,
639     const uint8_t unicode)
640 {
641     if (unicode)
642     {
643         if (*size != 0 and ((*offset) % 2))
644         {
645             (*offset)++;
646             (*data)++;
647             (*size)--;
648         }
649         while (*size > 1)
650         {
651             *size -= 2;
652             *offset += 2;
653             if (**data == 0)
654             {
655                 *data += 2;
656                 break;
657             }
658             else
659             {
660                 *data += 2;
661             }
662         }
663     }
664     else
665     {
666         while (*size)
667         {
668             (*size)--;
669             (*offset)++;
670             if (**data == 0)
671             {
672                 (*data)++;
673                 break;
674             }
675             else
676             {
677                 (*data)++;
678             }
679         }
680     }
681 }
682 
smb2_find_domain(const uint8_t * data,uint16_t size,AppIdSession & asd,AppidChangeBits & change_bits)683 static void smb2_find_domain(const uint8_t* data, uint16_t size,
684     AppIdSession& asd, AppidChangeBits& change_bits)
685 {
686     if (size < sizeof(ServiceSMB2Header))
687         return;
688     const ServiceSMB2Header* smb2 = (const ServiceSMB2Header*)data;
689     if (smb2->command != SERVICE_SMB2_SESSION_SETUP)
690         return;
691     data += sizeof(*smb2);
692     size -= sizeof(*smb2);
693     if (size < sizeof(ServiceSMB2SetupResponse))
694         return;
695     const ServiceSMB2SetupResponse* resp = (const ServiceSMB2SetupResponse*)data;
696     if (resp->struct_size != 9 or resp->sec_length < 1)
697         return;
698     data += sizeof(*resp);
699     size -= sizeof(*resp);
700     if (size < resp->sec_length)
701         return;
702     const uint8_t* ptr = (const uint8_t*)SnortStrnStr((const char*)data, size, ntlmssp);
703     if (!ptr)
704         return;
705     size -= ptr - data;
706     data = ptr;
707     if (size < sizeof(ServiceSMB2NtlmChallenge))
708         return;
709     const ServiceSMB2NtlmChallenge* ntlm = (const ServiceSMB2NtlmChallenge*)data;
710     if (ntlm->msg_type != NTLM_CHALLENGE)
711         return;
712     data += sizeof(*ntlm);
713     size -= sizeof(*ntlm);
714     if (size < ntlm->target_name_len or ntlm->target_name_len < 1 or ntlm->target_info_len < 1)
715         return;
716     data += ntlm->target_name_len;
717     size -= ntlm->target_name_len;
718     const ServiceSMB2NtlmAttr* info;
719     while (true)
720     {
721         if (size < sizeof(ServiceSMB2NtlmAttr))
722             return;
723         info = (const ServiceSMB2NtlmAttr*)data;
724         data += sizeof(*info);
725         size -= sizeof(*info);
726         if (size < info->length or info->length == 0)
727             return;
728         if (info->type == NTLM_DOMAIN_FLAG)
729             break;
730         data += info->length;
731         size -= info->length;
732     }
733     char domain[NBNS_NAME_LEN+1];
734     unsigned pos = 0;
735     while (pos < (info->length)/2 and pos < NBNS_NAME_LEN)
736     {
737         domain[pos] = *data;
738         pos++;
739         domain[pos] = 0;
740         data++;
741         if (*data != 0)
742             return;
743         data++;
744     }
745     asd.set_netbios_domain(change_bits, (const char*)domain);
746 }
747 
smb_find_domain(const uint8_t * data,uint16_t size,AppIdSession & asd,AppidChangeBits & change_bits)748 static void smb_find_domain(const uint8_t* data, uint16_t size,
749     AppIdSession& asd, AppidChangeBits& change_bits)
750 {
751     const ServiceSMBHeader* smb;
752     const ServiceSMBAndXResponse* resp;
753     const ServiceSMBNegotiateProtocolResponse* np;
754     char domain[NBNS_NAME_LEN+1];
755     unsigned pos = 0;
756     uint16_t byte_count;
757     uint16_t wc;
758     uint8_t unicode;
759     uint32_t capabilities;
760     uint16_t offset;
761 
762     if (size < sizeof(*smb) + sizeof(wc))
763         return;
764     smb = (const ServiceSMBHeader*)data;
765     if (smb->status != SERVICE_SMB_STATUS_SUCCESS and
766         smb->status != SERVICE_SMB_MORE_PROCESSING_REQUIRED)
767         return;
768     if (!(smb->flags[0] & SERVICE_SMB_FLAGS_RESPONSE))
769         return;
770     unicode = smb->flags[2] & SERVICE_SMB_FLAGS_UNICODE;
771     data += sizeof(*smb);
772     size -= sizeof(*smb);
773     resp = (const ServiceSMBAndXResponse*)data;
774     np = (const ServiceSMBNegotiateProtocolResponse*)data;
775     wc = 2 * (uint16_t)*data;
776     offset = 0;
777     data++;
778     size--;
779     if (size < (wc + sizeof(byte_count)))
780         return;
781     data += wc;
782     size -= wc;
783     byte_count = LETOHS_UNALIGNED(data);
784     data += sizeof(byte_count);
785     size -= sizeof(byte_count);
786     if (size < byte_count)
787         return;
788     offset += sizeof(byte_count);
789     offset += wc;
790     if (smb->command == SERVICE_SMB_COMMAND_SESSION_SETUP_ANDX_RESPONSE)
791     {
792         if (wc == 8)
793         {
794             uint16_t sec_len = LETOHS_UNALIGNED(&resp->sec_len);
795             if (sec_len >= byte_count)
796                 return;
797             data += sec_len;
798             byte_count -= sec_len;
799         }
800         else if (wc != 6)
801             return;
802         smb_domain_skip_string(&data, &byte_count, &offset, unicode);
803         smb_domain_skip_string(&data, &byte_count, &offset, unicode);
804         if (byte_count != 0 and (offset % 2))
805         {
806             data++;
807             byte_count--;
808         }
809     }
810     else if (smb->command == SERVICE_SMB_COMMAND_NEGOTIATE_PROTOCOL)
811     {
812         if (wc == 34)
813         {
814             capabilities = LETOHL_UNALIGNED(&np->capabilities);
815             if (capabilities & SERVICE_SMB_CAPABILITIES_EXTENDED_SECURITY)
816                 return;
817             unicode = (capabilities & SERVICE_SMB_CAPABILITIES_UNICODE) or unicode;
818         }
819         else if (wc != 26)
820             return;
821         if (np->sec_len >= byte_count)
822             return;
823         data += np->sec_len;
824         byte_count -= np->sec_len;
825     }
826     else
827         return;
828     if (unicode)
829     {
830         int found = 0;
831         while (byte_count > 1)
832         {
833             byte_count -= 2;
834             if (*data == 0)
835             {
836                 data += 2;
837                 found = 1;
838                 break;
839             }
840             else
841             {
842                 if (pos < NBNS_NAME_LEN)
843                 {
844                     domain[pos] = *data;
845                     pos++;
846                     domain[pos] = 0;
847                 }
848                 data++;
849                 if (*data != 0)
850                     return;
851                 data++;
852             }
853         }
854         if (!found and byte_count == 1 and *data == 0)
855         {
856             byte_count--;
857         }
858         if (byte_count and smb->command != SERVICE_SMB_COMMAND_NEGOTIATE_PROTOCOL and
859             smb->command != SERVICE_SMB_COMMAND_SESSION_SETUP_ANDX_RESPONSE)
860             return;
861     }
862     else
863     {
864         while (byte_count)
865         {
866             byte_count--;
867             if (*data == 0)
868             {
869                 data++;
870                 break;
871             }
872             else
873             {
874                 if (pos < NBNS_NAME_LEN)
875                 {
876                     domain[pos] = *data;
877                     pos++;
878                     domain[pos] = 0;
879                 }
880                 data++;
881             }
882         }
883         if (byte_count and smb->command != SERVICE_SMB_COMMAND_NEGOTIATE_PROTOCOL)
884             return;
885     }
886 
887     if (pos)
888         asd.set_netbios_domain(change_bits, (const char*)domain);
889 }
890 
parse_type_message(AppIdDiscoveryArgs & args,const uint8_t * data,uint32_t tmp)891 void NbssServiceDetector::parse_type_message(AppIdDiscoveryArgs& args,
892     const uint8_t* data, uint32_t tmp)
893 {
894     ServiceNBSSData* nd = (ServiceNBSSData*)data_get(args.asd);
895 
896     if (tmp >= sizeof(NB_SMB_BANNER) and
897         nd->length >= sizeof(NB_SMB_BANNER) and
898         !memcmp(data, NB_SMB_BANNER, sizeof(NB_SMB_BANNER)))
899     {
900         if (nd->serviceAppId != APP_ID_DCE_RPC)
901         {
902             nd->serviceAppId = APP_ID_NETBIOS_SSN;
903             nd->payloadAppId = APP_ID_SMB_VERSION_1;
904         }
905 
906         if (nd->length <= tmp)
907         {
908             smb_find_domain(data + sizeof(NB_SMB_BANNER),
909                 tmp - sizeof(NB_SMB_BANNER), args.asd, args.change_bits);
910         }
911     }
912     else if (tmp >= sizeof(NB_SMB2_BANNER) and
913         nd->length >= sizeof(NB_SMB2_BANNER) and
914         !memcmp(data, NB_SMB2_BANNER, sizeof(NB_SMB2_BANNER)))
915     {
916         if (nd->serviceAppId != APP_ID_DCE_RPC)
917         {
918             nd->serviceAppId = APP_ID_NETBIOS_SSN;
919             nd->payloadAppId = APP_ID_SMB_VERSION_2;
920         }
921 
922         if (nd->length <= tmp)
923         {
924             smb2_find_domain(data + sizeof(NB_SMB2_BANNER),
925                 tmp - sizeof(NB_SMB2_BANNER), args.asd, args.change_bits);
926         }
927     }
928     else if (tmp >= sizeof(NB_SMB2_TRANSFORM_BANNER) and
929         nd->length >= sizeof(NB_SMB2_TRANSFORM_BANNER) and
930         !memcmp(data, NB_SMB2_TRANSFORM_BANNER, sizeof(NB_SMB2_TRANSFORM_BANNER)))
931     {
932         if (nd->serviceAppId != APP_ID_DCE_RPC)
933         {
934             nd->serviceAppId = APP_ID_NETBIOS_SSN;
935             nd->payloadAppId = APP_ID_SMB_VERSION_3;
936         }
937     }
938     else if (tmp >= 4 and nd->length >= 4 and
939         !(*((const uint32_t*)data)) and
940         dcerpc_validate(data+4, ((int)std::min(tmp, nd->length)) - 4) > 0)
941     {
942         nd->serviceAppId = APP_ID_DCE_RPC;
943         nd->miscAppId = APP_ID_NETBIOS_SSN;
944     }
945 }
946 
NbssServiceDetector(ServiceDiscovery * sd)947 NbssServiceDetector::NbssServiceDetector(ServiceDiscovery* sd)
948 {
949     handler = sd;
950     name = "nbss";
951     proto = IpProtocol::TCP;
952     detectorType = DETECTOR_TYPE_DECODER;
953 
954     tcp_patterns =
955     {
956         { NB_SMB_BANNER, sizeof(NB_SMB_BANNER), -1, 0, 0 },
957         { NB_SMB2_BANNER, sizeof(NB_SMB2_BANNER), -1, 0, 0 },
958         { NB_SMB2_TRANSFORM_BANNER, sizeof(NB_SMB2_TRANSFORM_BANNER), -1, 0, 0 }
959     };
960 
961     appid_registry =
962     {
963         { APP_ID_NETBIOS_SSN, APPINFO_FLAG_SERVICE_ADDITIONAL },
964         { APP_ID_DCE_RPC, 0 }
965     };
966 
967     service_ports =
968     {
969         { 139, IpProtocol::TCP, false },
970         { 445, IpProtocol::TCP, false }
971     };
972 
973     handler->register_detector(name, this, proto);
974 }
975 
validate(AppIdDiscoveryArgs & args)976 int NbssServiceDetector::validate(AppIdDiscoveryArgs& args)
977 {
978     ServiceNBSSData* nd;
979     const NBSSHeader* hdr;
980     const uint8_t* end;
981     uint32_t tmp;
982     int retval = -1;
983     const uint8_t* data = args.data;
984     const AppidSessionDirection dir = args.dir;
985     uint16_t size = args.size;
986 
987     if (dir != APP_ID_FROM_RESPONDER)
988         goto inprocess;
989     if (!size)
990         goto inprocess;
991 
992     nd = (ServiceNBSSData*)data_get(args.asd);
993     if (!nd)
994     {
995         nd = (ServiceNBSSData*)snort_calloc(sizeof(ServiceNBSSData));
996         data_add(args.asd, nd, &nbss_free_state);
997         nd->state = NBSS_STATE_CONNECTION;
998         nd->serviceAppId = APP_ID_NETBIOS_SSN;
999         nd->miscAppId = APP_ID_NONE;
1000     }
1001 
1002     end = data + size;
1003     while (data < end)
1004     {
1005         switch (nd->state)
1006         {
1007         case NBSS_STATE_CONNECTION:
1008             if (size < sizeof(NBSSHeader))
1009                 goto fail;
1010             hdr = (const NBSSHeader*)data;
1011             data += sizeof(NBSSHeader);
1012             nd->state = NBSS_STATE_ERROR;
1013             switch (hdr->type)
1014             {
1015             case NBSS_TYPE_RESP_POSITIVE:
1016                 if (hdr->flags or hdr->length)
1017                     goto fail;
1018                 nd->state = NBSS_STATE_FLOW;
1019                 break;
1020             case NBSS_TYPE_RESP_NEGATIVE:
1021                 if (hdr->flags or ntohs(hdr->length) != 1)
1022                     goto fail;
1023                 if (data >= end)
1024                     goto fail;
1025                 if (*data < 0x80 or (*data > 0x83 and *data < 0x8F) or *data > 0x8F)
1026                     goto fail;
1027                 data++;
1028                 break;
1029             case NBSS_TYPE_MESSAGE:
1030                 if (hdr->flags & 0xFE)
1031                     goto fail;
1032                 nd->length = ((uint32_t)(hdr->flags & 0x01)) << 16;
1033                 nd->length += (uint32_t)ntohs(hdr->length);
1034                 tmp = end - data;
1035                 parse_type_message(args, data, tmp);
1036                 if (tmp < nd->length)
1037                 {
1038                     data = end;
1039                     nd->length -= tmp;
1040                     nd->state = NBSS_STATE_CONT;
1041                 }
1042                 else
1043                 {
1044                     data += nd->length;
1045                     nd->count++;
1046                     nd->state = NBSS_STATE_FLOW;
1047                 }
1048                 break;
1049             case NBSS_TYPE_RESP_RETARGET:
1050                 if (hdr->flags or ntohs(hdr->length) != 6)
1051                     goto fail;
1052                 if (end - data < 6)
1053                     goto fail;
1054                 data += 6;
1055                 break;
1056             default:
1057                 goto fail;
1058             }
1059             break;
1060         case NBSS_STATE_FLOW:
1061             if (size < sizeof(NBSSHeader))
1062                 goto fail;
1063             hdr = (const NBSSHeader*)data;
1064             data += sizeof(NBSSHeader);
1065             switch (hdr->type)
1066             {
1067             case NBSS_TYPE_KEEP_ALIVE:
1068                 if (hdr->flags or hdr->length)
1069                     goto fail;
1070                 break;
1071             case NBSS_TYPE_MESSAGE:
1072                 if (hdr->flags & 0xFE)
1073                     goto fail;
1074                 nd->length = ((uint32_t)(hdr->flags & 0x01)) << 16;
1075                 nd->length += (uint32_t)ntohs(hdr->length);
1076                 tmp = end - data;
1077                 parse_type_message(args, data, tmp);
1078                 if (tmp < nd->length)
1079                 {
1080                     data = end;
1081                     nd->length -= tmp;
1082                     nd->state = NBSS_STATE_CONT;
1083                 }
1084                 else
1085                 {
1086                     data += nd->length;
1087                     if (nd->count < NBSS_COUNT_THRESHOLD)
1088                     {
1089                         nd->count++;
1090                         if (nd->count >= NBSS_COUNT_THRESHOLD)
1091                         {
1092                             retval = APPID_SUCCESS;
1093                         }
1094                     }
1095                 }
1096                 break;
1097             default:
1098                 goto fail;
1099             }
1100             break;
1101         case NBSS_STATE_CONT:
1102             tmp = end - data;
1103             if (tmp < nd->length)
1104             {
1105                 data = end;
1106                 nd->length -= tmp;
1107             }
1108             else
1109             {
1110                 data += nd->length;
1111                 nd->state = NBSS_STATE_FLOW;
1112                 if (nd->count < NBSS_COUNT_THRESHOLD)
1113                 {
1114                     nd->count++;
1115                     if (nd->count >= NBSS_COUNT_THRESHOLD)
1116                     {
1117                         retval = APPID_SUCCESS;
1118                     }
1119                 }
1120             }
1121             break;
1122         default:
1123             goto fail;
1124         }
1125     }
1126     if (retval == -1)
1127         goto inprocess;
1128 
1129     if (!args.asd.is_service_detected())
1130         if (add_service(args.change_bits, args.asd, args.pkt, dir, nd->serviceAppId) == APPID_SUCCESS)
1131         {
1132             add_miscellaneous_info(args.asd, nd->miscAppId);
1133             add_payload(args.asd, nd->payloadAppId);
1134         }
1135     return APPID_SUCCESS;
1136 
1137 inprocess:
1138     if (!args.asd.is_service_detected())
1139         service_inprocess(args.asd, args.pkt, dir);
1140     return APPID_INPROCESS;
1141 
1142 fail:
1143     if (!args.asd.is_service_detected())
1144         fail_service(args.asd, args.pkt, dir);
1145     return APPID_NOMATCH;
1146 }
1147 
NbdgmServiceDetector(ServiceDiscovery * sd)1148 NbdgmServiceDetector::NbdgmServiceDetector(ServiceDiscovery* sd)
1149 {
1150     handler = sd;
1151     name = "nbdgm";
1152     proto = IpProtocol::UDP;
1153     detectorType = DETECTOR_TYPE_DECODER;
1154 
1155     appid_registry =
1156     {
1157         { APP_ID_NETBIOS_DGM, APPINFO_FLAG_SERVICE_ADDITIONAL }
1158     };
1159 
1160     service_ports =
1161     {
1162         { 138, IpProtocol::UDP, false }
1163     };
1164 
1165     handler->register_detector(name, this, proto);
1166 }
1167 
validate(AppIdDiscoveryArgs & args)1168 int NbdgmServiceDetector::validate(AppIdDiscoveryArgs& args)
1169 {
1170     const NBDgmHeader* hdr;
1171     const NBDgmError* err;
1172     const uint8_t* end;
1173     const ServiceSMBHeader* smb;
1174     const ServiceSMBTransactionHeader* trans;
1175     const ServiceSMBBrowserHeader* browser;
1176     uint16_t len;
1177     char source_name[(NBNS_NAME_LEN/2)+1];
1178     uint32_t server_type;
1179     AppId serviceAppId = APP_ID_NETBIOS_DGM;
1180     AppId miscAppId = APP_ID_NONE;
1181     const uint8_t* data = args.data;
1182     const AppidSessionDirection dir = args.dir;
1183     uint16_t size = args.size;
1184 
1185     if (!size)
1186         goto inprocess;
1187     if (size < sizeof(NBDgmHeader))
1188         goto fail;
1189     if (args.pkt->ptrs.sp != args.pkt->ptrs.dp)
1190         goto fail;
1191 
1192     source_name[0] = 0;
1193     end = data + size;
1194 
1195     hdr = (const NBDgmHeader*)data;
1196     data += sizeof(NBDgmHeader);
1197     if (hdr->zero)
1198         goto fail;
1199     if (!hdr->first or hdr->more)
1200         goto fail;
1201 
1202     switch (hdr->type)
1203     {
1204     case NBDGM_TYPE_POSITIVE_REPSONSE:
1205     case NBDGM_TYPE_NEGATIVE_RESPONSE:
1206     case NBDGM_TYPE_REQUEST:
1207         if (netbios_validate_name(&data, data, end))
1208             goto fail;
1209         if (end != data)
1210             goto fail;
1211         goto success;
1212     case NBDGM_TYPE_DIRECT_UNIQUE:
1213     case NBDGM_TYPE_DIRECT_GROUP:
1214     case NBDGM_TYPE_BROADCAST:
1215         data += sizeof(uint16_t) + sizeof(uint16_t); /* dgm_length and packet_offset */
1216         if (data >= end)
1217             goto fail;
1218         if (netbios_validate_name_and_decode(&data, data, end, source_name))
1219             goto fail;
1220         if (data >= end)
1221             goto fail;
1222         if (netbios_validate_name(&data, data, end))
1223             goto fail;
1224         if (data >= end)
1225             goto fail;
1226         if (end-data >= (int)sizeof(NB_SMB_BANNER) and
1227             !memcmp(data, NB_SMB_BANNER, sizeof(NB_SMB_BANNER)))
1228         {
1229             if (!args.asd.is_service_detected())
1230                 serviceAppId = APP_ID_NETBIOS_DGM;
1231 
1232             data += sizeof(NB_SMB_BANNER);
1233             if (end-data < (int)sizeof(ServiceSMBHeader))
1234                 goto not_mailslot;
1235             smb = (const ServiceSMBHeader*)data;
1236             data += sizeof(ServiceSMBHeader);
1237             if (smb->command != SERVICE_SMB_TRANSACTION_COMMAND)
1238                 goto not_mailslot;
1239             if (end-data < (int)sizeof(ServiceSMBTransactionHeader))
1240                 goto not_mailslot;
1241             trans = (const ServiceSMBTransactionHeader*)data;
1242             data += sizeof(ServiceSMBTransactionHeader);
1243             if (trans->wc == SERVICE_SMB_NOT_TRANSACTION_WC)
1244                 goto not_mailslot;
1245             if ((unsigned)(end-data) < (trans->sc*2)+sizeof(uint16_t)+sizeof(mailslot)+
1246                 sizeof(ServiceSMBBrowserHeader))
1247                 goto not_mailslot;
1248             data += (trans->sc*2);
1249             len = *((const uint16_t*)data);
1250             data += sizeof(uint16_t);
1251             if (end-data < len)
1252                 goto not_mailslot;
1253             if (memcmp(data, mailslot, sizeof(mailslot)))
1254                 goto not_mailslot;
1255             data += sizeof(mailslot);
1256             browser = (const ServiceSMBBrowserHeader*)data;
1257             if (browser->command != SERVICE_SMB_MAILSLOT_HOST and
1258                 browser->command != SERVICE_SMB_MAILSLOT_LOCAL_MASTER)
1259             {
1260                 goto not_mailslot;
1261             }
1262             server_type = LETOHL_UNALIGNED(&browser->server_type);
1263             add_smb_info(args.asd, browser->major, browser->minor, server_type);
1264         }
1265 not_mailslot:
1266         if (source_name[0])
1267             args.asd.set_netbios_name(args.change_bits, (const char*)source_name);
1268         args.asd.set_session_flags(APPID_SESSION_CONTINUE);
1269         goto success;
1270     case NBDGM_TYPE_ERROR:
1271         if (end-data < (int)sizeof(NBDgmError))
1272             goto fail;
1273         err = (const NBDgmError*)data;
1274         data += sizeof(NBDgmError);
1275         if (end != data)
1276             goto fail;
1277         if (err->code < NBDGM_ERROR_CODE_MIN or
1278             err->code > NBDGM_ERROR_CODE_MAX)
1279         {
1280             goto fail;
1281         }
1282         goto success;
1283     default:
1284         break;
1285     }
1286 
1287 fail:
1288     if (!args.asd.is_service_detected())
1289     {
1290         fail_service(args.asd, args.pkt, dir);
1291     }
1292     args.asd.clear_session_flags(APPID_SESSION_CONTINUE);
1293     return APPID_NOMATCH;
1294 
1295 success:
1296     if (!args.asd.is_service_detected())
1297     {
1298         if (dir == APP_ID_FROM_RESPONDER)
1299         {
1300             if (add_service(args.change_bits, args.asd, args.pkt, dir, serviceAppId) == APPID_SUCCESS)
1301                 add_miscellaneous_info(args.asd, miscAppId);
1302         }
1303     }
1304     return APPID_SUCCESS;
1305 
1306 inprocess:
1307     if (!args.asd.is_service_detected())
1308         service_inprocess(args.asd, args.pkt, dir);
1309     return APPID_INPROCESS;
1310 }
1311 
add_smb_info(AppIdSession & asd,unsigned major,unsigned minor,uint32_t flags)1312 void NbdgmServiceDetector::add_smb_info(AppIdSession& asd, unsigned major, unsigned minor,
1313     uint32_t flags)
1314 {
1315     if (flags & FINGERPRINT_UDP_FLAGS_XENIX)
1316         return;
1317     if (asd.get_session_flags(APPID_SESSION_HAS_SMB_INFO))
1318         return;
1319     asd.set_session_flags(APPID_SESSION_HAS_SMB_INFO);
1320     Packet* p = DetectionEngine::get_current_packet();
1321     FpSMBDataEvent event(p, major, minor, (flags & FINGERPRINT_UDP_FLAGS_MASK));
1322     DataBus::publish(FP_SMB_DATA_EVENT, event, p->flow);
1323 }
1324