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