1 /****************************************************************************
2 *
3 * Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
4 * Copyright (C) 2005-2013 Sourcefire, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License Version 2 as
8 * published by the Free Software Foundation. You may not use, modify or
9 * distribute this program under any other version of the GNU General
10 * Public License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 ****************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "sf_types.h"
28 #include "snort_debug.h"
29 #include "decode.h"
30 #include "log.h"
31 #include "util.h"
32 #include "generators.h"
33 #include "event_queue.h"
34 #include "snort.h"
35 #include "memory_stats.h"
36
37 #include "session_api.h"
38
39 #include "stream_common.h"
40 #include "portscan.h"
41 #include "sftarget_protocol_reference.h"
42 #include "sp_dynamic.h"
43 #include "snort_stream_tcp.h"
44 #include "snort_stream_udp.h"
45 #include "snort_stream_icmp.h"
46 #include "snort_stream_ip.h"
47 #include "parser.h"
48 #include "active.h"
49 #ifdef ENABLE_HA
50 #include "stream5_ha.h"
51 #endif
52
53 static void printIgnoredRules(
54 IgnoredRuleList *pIgnoredRuleList,
55 int any_any_flow
56 );
57 static void addRuleToIgnoreList(
58 IgnoredRuleList **ppIgnoredRuleList,
59 OptTreeNode *otn);
60
61 /* M A C R O S **************************************************/
62
StreamExpireSession(SessionControlBlock * scb)63 int StreamExpireSession(SessionControlBlock *scb)
64 {
65 #ifdef ENABLE_HA
66 /* Sessions in standby cannot be locally expired. */
67 if (scb->ha_flags & HA_FLAG_STANDBY)
68 return 0;
69 #endif
70
71 sfBase.iStreamTimeouts++;
72 scb->ha_state.session_flags |= SSNFLAG_TIMEDOUT;
73 scb->session_state |= STREAM_STATE_TIMEDOUT;
74
75 switch (scb->protocol)
76 {
77 case IPPROTO_TCP:
78 s5stats.tcp_timeouts++;
79 break;
80 case IPPROTO_UDP:
81 s5stats.udp_timeouts++;
82 break;
83 case IPPROTO_ICMP:
84 s5stats.icmp_timeouts++;
85 break;
86 }
87
88 return 1;
89 }
90
StreamDeleteSession(SessionControlBlock * scb)91 void StreamDeleteSession(SessionControlBlock *scb)
92 {
93 sfBase.iStreamTimeouts++;
94 scb->ha_state.session_flags |= SSNFLAG_TIMEDOUT;
95
96 switch (scb->protocol)
97 {
98 case IPPROTO_TCP:
99 s5stats.tcp_timeouts++;
100 break;
101 case IPPROTO_UDP:
102 s5stats.udp_timeouts++;
103 break;
104 case IPPROTO_ICMP:
105 s5stats.icmp_timeouts++;
106 case IPPROTO_IP:
107 s5stats.ip_timeouts++;
108 break;
109 }
110
111 if ( session_api->delete_session_by_key(scb, "timeout") != SFXHASH_OK )
112 {
113 LogMessage("WARNING: failed to delete session. \n");
114 }
115 }
116
StreamExpire(Packet * p,SessionControlBlock * scb)117 int StreamExpire(Packet *p, SessionControlBlock *scb)
118 {
119 uint64_t pkttime = CalcJiffies(p);
120
121 if (scb->expire_time == 0)
122 {
123 /* Not yet set, not expired */
124 return 0;
125 }
126
127 if((int)(pkttime - scb->expire_time) > 0)
128 {
129 /* Expiration time has passed. */
130 return StreamExpireSession(scb);
131 }
132
133 return 0;
134 }
135
136 #ifdef ACTIVE_RESPONSE
StreamGetExpire(Packet * p,SessionControlBlock * scb)137 int StreamGetExpire(Packet *p, SessionControlBlock *scb)
138 {
139 return ( CalcJiffies(p) > scb->expire_time );
140 }
141
142 // *DROP* flags are set to mark the direction(s) for which traffic was
143 // seen since last reset and then cleared after sending new attempt so
144 // that we only send in the still active direction(s).
StreamActiveResponse(Packet * p,SessionControlBlock * scb)145 void StreamActiveResponse(Packet* p, SessionControlBlock *scb)
146 {
147 StreamConfig *config = sfPolicyUserDataGet(stream_online_config, getNapRuntimePolicy());
148 uint8_t max = config->session_config->max_active_responses;
149
150 if ( p->packet_flags & PKT_FROM_CLIENT )
151 scb->session_state |= STREAM_STATE_DROP_CLIENT;
152 else
153 scb->session_state |= STREAM_STATE_DROP_SERVER;
154
155 if ( (scb->response_count < max) && session_api->get_expire_timer(p, scb) )
156 {
157 uint32_t delay = config->session_config->min_response_seconds;
158 EncodeFlags flags =
159 ( (scb->session_state & STREAM_STATE_DROP_CLIENT) &&
160 (scb->session_state & STREAM_STATE_DROP_SERVER) ) ?
161 ENC_FLAG_FWD : 0; // reverse dir is always true
162
163 Active_KillSession(p, &flags);
164 ++scb->response_count;
165 #if defined(DAQ_CAPA_CST_TIMEOUT)
166 if (!Daq_Capa_Timeout)
167 #endif
168 session_api->set_expire_timer(p, scb, delay);
169
170 scb->session_state &= ~(STREAM_STATE_DROP_CLIENT|STREAM_STATE_DROP_SERVER);
171 }
172 }
173
SetTTL(SessionControlBlock * ssn,Packet * p,int client)174 void SetTTL (SessionControlBlock* ssn, Packet* p, int client)
175 {
176 uint8_t inner_ttl = 0, outer_ttl = 0;
177 if ( p->outer_iph_api )
178 outer_ttl = p->outer_iph_api->iph_ret_ttl(p);
179
180 if ( p->iph_api )
181 inner_ttl = p->iph_api->iph_ret_ttl(p);
182 if ( client )
183 {
184 ssn->outer_client_ttl = outer_ttl;
185 ssn->inner_client_ttl = inner_ttl;
186 }
187 else
188 {
189 ssn->outer_server_ttl = outer_ttl;
190 ssn->inner_server_ttl = inner_ttl;
191 }
192 }
193 #endif
194
MarkupPacketFlags(Packet * p,SessionControlBlock * scb)195 void MarkupPacketFlags(Packet *p, SessionControlBlock *scb)
196 {
197 if(!scb)
198 return;
199
200 if((scb->ha_state.session_flags & SSNFLAG_ESTABLISHED) != SSNFLAG_ESTABLISHED)
201 {
202 if((scb->ha_state.session_flags & (SSNFLAG_SEEN_SERVER|SSNFLAG_SEEN_CLIENT)) !=
203 (SSNFLAG_SEEN_SERVER|SSNFLAG_SEEN_CLIENT))
204 {
205 p->packet_flags |= PKT_STREAM_UNEST_UNI;
206 }
207 }
208 else
209 {
210 p->packet_flags |= PKT_STREAM_EST;
211 if(p->packet_flags & PKT_STREAM_UNEST_UNI)
212 {
213 p->packet_flags ^= PKT_STREAM_UNEST_UNI;
214 }
215 }
216 }
217
218 #if 0
219 /** Get rule list for a specific protocol
220 *
221 * @param rule
222 * @param ptocool protocol type
223 * @returns RuleTreeNode* rule list for specific protocol
224 */
225 static inline RuleTreeNode * protocolRuleList(RuleListNode *rule, IpProto protocol)
226 {
227 switch (protocol)
228 {
229 case IPPROTO_TCP:
230 return rule->RuleList->TcpList;
231 case IPPROTO_UDP:
232 return rule->RuleList->UdpList;
233 case IPPROTO_ICMP:
234 break;
235 default:
236 break;
237 }
238 return NULL;
239 }
240 #endif
getProtocolName(IpProto protocol)241 static inline char * getProtocolName (IpProto protocol)
242 {
243 static char *protocolName[] = {"TCP", "UDP", "ICMP"};
244 switch (protocol)
245 {
246 case IPPROTO_TCP:
247 return protocolName[0];
248 case IPPROTO_UDP:
249 return protocolName[1];
250 case IPPROTO_ICMP:
251 return protocolName[2];
252 break;
253 default:
254 break;
255 }
256 return NULL;
257 }
258
259 /**check whether a flow bit is set for an option node.
260 *
261 * @param otn Option Tree Node
262 * @returns 0 - no flow bit is set, 1 otherwise
263 */
StreamOtnHasFlowOrFlowbit(OptTreeNode * otn)264 int StreamOtnHasFlowOrFlowbit(OptTreeNode *otn)
265 {
266 if (otn->ds_list[PLUGIN_CLIENTSERVER] ||
267 DynamicHasFlow(otn) ||
268 DynamicHasFlowbit(otn) ||
269 otn->ds_list[PLUGIN_FLOWBIT])
270 {
271 return 1;
272 }
273 return 0;
274 }
275
276 /**initialize given port list from the given ruleset, for a given policy
277 * @param portList pointer to array of MAX_PORTS+1 uint8_t. This array content
278 * is changed by walking through the rulesets.
279 * @param protocol - protocol type
280 */
setPortFilterList(struct _SnortConfig * sc,uint16_t * portList,IpProto protocol,int ignoreAnyAnyRules,tSfPolicyId policyId)281 void setPortFilterList(
282 struct _SnortConfig *sc,
283 uint16_t *portList,
284 IpProto protocol,
285 int ignoreAnyAnyRules,
286 tSfPolicyId policyId
287 )
288 {
289 char *port_array = NULL;
290 int num_ports = 0;
291 int i;
292 RuleTreeNode *rtn;
293 OptTreeNode *otn;
294 int inspectSrc, inspectDst;
295 char any_any_flow = 0;
296 IgnoredRuleList *pIgnoredRuleList = NULL; ///list of ignored rules
297 char *protocolName;
298 SFGHASH_NODE *hashNode;
299 int flowBitIsSet = 0;
300
301 if (sc == NULL)
302 {
303 FatalError("%s(%d) Snort conf for parsing is NULL.\n",
304 __FILE__, __LINE__);
305 }
306
307 if (((protocol == IPPROTO_TCP) || (protocol == IPPROTO_UDP)) && (ignoreAnyAnyRules == 0))
308 {
309 int j;
310 for (j=0; j<MAX_PORTS; j++)
311 {
312 portList[j] |= PORT_MONITOR_SESSION | PORT_MONITOR_INSPECT;
313 }
314 return;
315 }
316
317 protocolName = getProtocolName(protocol);
318
319 /* Post-process TCP rules to establish TCP ports to inspect. */
320 for (hashNode = sfghash_findfirst(sc->otn_map);
321 hashNode;
322 hashNode = sfghash_findnext(sc->otn_map))
323 {
324 otn = (OptTreeNode *)hashNode->data;
325 flowBitIsSet = StreamOtnHasFlowOrFlowbit(otn);
326
327 rtn = getRtnFromOtn(otn, policyId);
328
329 if (!rtn)
330 {
331 continue;
332 }
333
334 if (rtn->proto == protocol)
335 {
336 //do operation
337 inspectSrc = inspectDst = 0;
338 if (PortObjectHasAny(rtn->src_portobject))
339 {
340 inspectSrc = -1;
341 }
342 else
343 {
344 port_array = PortObjectCharPortArray(port_array, rtn->src_portobject, &num_ports);
345 if (port_array && num_ports != 0)
346 {
347 inspectSrc = 1;
348 for (i=0;i<SFPO_MAX_PORTS;i++)
349 {
350 if (port_array[i])
351 {
352 portList[i] |= PORT_MONITOR_INSPECT;
353 /* port specific rule */
354 /* Look for an OTN with flow or flowbits keyword */
355 if (flowBitIsSet)
356 {
357 portList[i] |= PORT_MONITOR_SESSION;
358 }
359 }
360 }
361 }
362 if ( port_array )
363 {
364 free(port_array);
365 port_array = NULL;
366 }
367 }
368 if (PortObjectHasAny(rtn->dst_portobject))
369 {
370 inspectDst = -1;
371 }
372 else
373 {
374 port_array = PortObjectCharPortArray(port_array, rtn->dst_portobject, &num_ports);
375 if (port_array && num_ports != 0)
376 {
377 inspectDst = 1;
378 for (i=0;i<SFPO_MAX_PORTS;i++)
379 {
380 if (port_array[i])
381 {
382 portList[i] |= PORT_MONITOR_INSPECT;
383 /* port specific rule */
384 if (flowBitIsSet)
385 {
386 portList[i] |= PORT_MONITOR_SESSION;
387 }
388 }
389 }
390 }
391 if ( port_array )
392 {
393 free(port_array);
394 port_array = NULL;
395 }
396 }
397 if ((inspectSrc == -1) && (inspectDst == -1))
398 {
399 /* any -> any rule */
400 if (any_any_flow == 0)
401 {
402 any_any_flow = StreamAnyAnyFlow(portList, otn, rtn, any_any_flow,
403 &pIgnoredRuleList, ignoreAnyAnyRules);
404 }
405 }
406 }
407 }
408
409 /* If portscan is tracking TCP/UDP, need to create
410 * sessions for all ports */
411 if (((protocol == IPPROTO_UDP) && (ps_get_protocols(sc, policyId) & PS_PROTO_UDP))
412 || ((protocol == IPPROTO_TCP) && (ps_get_protocols(sc, policyId) & PS_PROTO_TCP)))
413 {
414 int j;
415 for (j=0; j<MAX_PORTS; j++)
416 {
417 portList[j] |= PORT_MONITOR_SESSION;
418 }
419 }
420
421 if (any_any_flow == 1)
422 {
423 LogMessage("WARNING: 'ignore_any_rules' option for Stream %s "
424 "disabled because of %s rule with flow or flowbits option.\n",
425 protocolName, protocolName);
426 }
427
428 else if (pIgnoredRuleList)
429 {
430 LogMessage("WARNING: Rules (GID:SID) effectively ignored because of "
431 "'ignore_any_rules' option for Stream %s.\n", protocolName);
432 }
433 // free list; print iff any_any_flow
434 printIgnoredRules(pIgnoredRuleList, any_any_flow);
435
436 }
437
438 /**Determines whether any_any_flow should be ignored or not.
439 *
440 * Dont ignore any_any_flows if flow bit is set on an any_any_flow,
441 * or ignoreAnyAnyRules is not set.
442 * @param portList port list
443 * @param rtn Rule tree node
444 * @param any_any_flow - set if any_any_flow is ignored,0 otherwise
445 * @param ppIgnoredRuleList
446 * @param ignoreAnyAnyRules
447 * @returns
448 */
StreamAnyAnyFlow(uint16_t * portList,OptTreeNode * otn,RuleTreeNode * rtn,int any_any_flow,IgnoredRuleList ** ppIgnoredRuleList,int ignoreAnyAnyRules)449 int StreamAnyAnyFlow(
450 uint16_t *portList,
451 OptTreeNode *otn,
452 RuleTreeNode *rtn,
453 int any_any_flow,
454 IgnoredRuleList **ppIgnoredRuleList,
455 int ignoreAnyAnyRules
456 )
457 {
458 /**if any_any_flow is set then following code has no effect.*/
459 if (any_any_flow)
460 {
461 return any_any_flow;
462 }
463
464 /* Look for an OTN with flow or flowbits keyword */
465 if (StreamOtnHasFlowOrFlowbit(otn))
466 {
467 int i;
468
469 for (i=1;i<=MAX_PORTS;i++)
470 {
471 /* track sessions for ALL ports becuase
472 * of any -> any with flow/flowbits */
473 portList[i] |= PORT_MONITOR_SESSION;
474 }
475 return 1;
476 }
477
478 if (ignoreAnyAnyRules)
479 {
480
481 /* if not, then ignore the content/pcre/etc */
482 if (otn->ds_list[PLUGIN_PATTERN_MATCH] ||
483 otn->ds_list[PLUGIN_PATTERN_MATCH_OR] ||
484 otn->ds_list[PLUGIN_PATTERN_MATCH_URI] ||
485 DynamicHasContent(otn) ||
486 DynamicHasByteTest(otn) ||
487 DynamicHasPCRE(otn) ||
488 otn->ds_list[PLUGIN_BYTE_TEST] ||
489 otn->ds_list[PLUGIN_PCRE])
490 {
491 /* Ignoring this rule.... */
492 addRuleToIgnoreList(ppIgnoredRuleList, otn);
493 }
494 }
495
496 return 0;
497 }
498
499 /**add rule to the ignore rule list.
500 */
addRuleToIgnoreList(IgnoredRuleList ** ppIgnoredRuleList,OptTreeNode * otn)501 static void addRuleToIgnoreList(IgnoredRuleList **ppIgnoredRuleList, OptTreeNode *otn)
502 {
503 IgnoredRuleList *ignored_rule;
504
505 ignored_rule = SnortPreprocAlloc(1, sizeof(*ignored_rule), PP_STREAM,
506 PP_MEM_CATEGORY_CONFIG);
507 ignored_rule->otn = otn;
508 ignored_rule->next = *ppIgnoredRuleList;
509 *ppIgnoredRuleList = ignored_rule;
510 }
511
512
513 /**print the ignored rule list.
514 */
printIgnoredRules(IgnoredRuleList * pIgnoredRuleList,int any_any_flow)515 static void printIgnoredRules(
516 IgnoredRuleList *pIgnoredRuleList,
517 int any_any_flow
518 )
519 {
520 char six_sids = 0;
521 int sids_ignored = 0;
522 char buf[STD_BUF];
523 IgnoredRuleList *ignored_rule;
524 IgnoredRuleList *next_ignored_rule;
525
526 buf[0] = '\0';
527
528 for (ignored_rule = pIgnoredRuleList; ignored_rule != NULL; )
529 {
530 if (any_any_flow == 0)
531 {
532 if (six_sids == 1)
533 {
534 SnortSnprintfAppend(buf, STD_BUF-1, "\n");
535 LogMessage("%s", buf);
536 six_sids = 0;
537 }
538
539 if (sids_ignored == 0)
540 {
541 SnortSnprintf(buf, STD_BUF-1, " %d:%d",
542 ignored_rule->otn->sigInfo.generator,
543 ignored_rule->otn->sigInfo.id);
544 }
545 else
546 {
547 SnortSnprintfAppend(buf, STD_BUF-1, ", %d:%d",
548 ignored_rule->otn->sigInfo.generator,
549 ignored_rule->otn->sigInfo.id);
550 }
551 sids_ignored++;
552 if (sids_ignored %6 == 0)
553 {
554 /* Have it print next time through */
555 six_sids = 1;
556 sids_ignored = 0;
557 }
558 }
559 next_ignored_rule = ignored_rule->next;
560 SnortPreprocFree(ignored_rule, sizeof(*ignored_rule), PP_STREAM,
561 PP_MEM_CATEGORY_CONFIG);
562 ignored_rule = next_ignored_rule;
563 }
564
565 if (sids_ignored || six_sids)
566 {
567 SnortSnprintfAppend(buf, STD_BUF-1, "\n");
568 LogMessage("%s", buf);
569 }
570 }
571
StreamFreeConfigsPolicy(tSfPolicyUserContextId config,tSfPolicyId policyId,void * pData)572 static int StreamFreeConfigsPolicy(
573 tSfPolicyUserContextId config,
574 tSfPolicyId policyId,
575 void* pData
576 )
577 {
578 StreamConfig *pPolicyConfig = (StreamConfig *)pData;
579
580 //do any housekeeping before freeing StreamConfig
581 sfPolicyUserDataClear (config, policyId);
582 StreamFreeConfig(pPolicyConfig);
583
584 return 0;
585 }
586
StreamFreeConfigs(tSfPolicyUserContextId config)587 void StreamFreeConfigs(tSfPolicyUserContextId config)
588 {
589 if (config == NULL)
590 return;
591
592 sfPolicyUserDataFreeIterate(config, StreamFreeConfigsPolicy);
593
594 sfPolicyConfigDelete(config);
595 }
596
StreamFreeConfig(StreamConfig * config)597 void StreamFreeConfig(StreamConfig *config)
598 {
599 if (config == NULL)
600 return;
601
602 if (config->tcp_config != NULL)
603 {
604 StreamTcpConfigFree(config->tcp_config);
605 config->tcp_config = NULL;
606 }
607
608 if (config->udp_config != NULL)
609 {
610 StreamUdpConfigFree(config->udp_config);
611 config->udp_config = NULL;
612 }
613
614 if (config->icmp_config != NULL)
615 {
616 StreamIcmpConfigFree(config->icmp_config);
617 config->icmp_config = NULL;
618 }
619
620 if (config->ip_config != NULL)
621 {
622 StreamIpConfigFree(config->ip_config);
623 config->ip_config = NULL;
624 }
625
626 SnortPreprocFree(config, sizeof(*config), PP_STREAM, PP_MEM_CATEGORY_CONFIG);
627 }
628
StreamSetRuntimeConfiguration(SessionControlBlock * scb,uint8_t protocol)629 int StreamSetRuntimeConfiguration( SessionControlBlock *scb, uint8_t protocol )
630 {
631 StreamConfig *pPolicyConfig;
632
633 pPolicyConfig = ( StreamConfig * ) sfPolicyUserDataGet( stream_online_config, getNapRuntimePolicy() );
634 if (pPolicyConfig == NULL)
635 return -1;
636
637 stream_session_config = pPolicyConfig->session_config;
638
639 return 0;
640 }
641
getStreamIgnoreAnyConfig(struct _SnortConfig * sc,IpProto protocol)642 bool getStreamIgnoreAnyConfig (struct _SnortConfig *sc, IpProto protocol)
643 {
644 StreamConfig *config;
645 tSfPolicyId policyId;
646
647 for (policyId = 0; policyId < sfPolicyNumAllocated(sc->policy_config); policyId++) {
648
649 if ((config = getStreamPolicyConfig(policyId, 0))) {
650 switch (protocol) {
651 case IPPROTO_TCP :
652 if ((config->tcp_config) && (config->tcp_config->default_policy->flags & STREAM_CONFIG_IGNORE_ANY))
653 return true;
654 case IPPROTO_UDP :
655 if ((config->udp_config) && (config->udp_config->default_policy->flags & STREAM_CONFIG_IGNORE_ANY))
656 return true;
657 default:
658 break;
659 }
660 }
661 }
662 return false;
663 }
664