1 /****************************************************************************
2  *
3  * Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
4  * Copyright (C) 2004-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 /*
24 **  @file       portscan.c
25 **
26 **  @author     Daniel Roelker <droelker@sourcefire.com>
27 **
28 **  @brief      Detect portscans
29 **
30 **  NOTES
31 **    - Marc Norton and Jeremy Hewlett were involved in the requirements and
32 **      design of this portscan detection engine.
33 **    - Thanks to Judy Novak for her suggestion to log open ports
34 **      on hosts that are portscanned.  This idea makes portscan a lot more
35 **      useful for analysts.
36 **
37 **  The philosophy of portscan detection that we use is based on a generic
38 **  network attack methodology: reconnaissance, network service enumeration,
39 **  and service exploitation.
40 **
41 **  The reconnaissance phase determines what types of network protocols and
42 **  services that a host supports.  This is the traditional phase where a
43 **  portscan occurs.  An important requirement of this phase is that an
44 **  attacker does not already know what protocols and services are supported
45 **  by the destination host.  If an attacker does know what services are
46 **  open on the destination host then there is no need for this phase.
47 **  Because of this requirement, we assume that if an attacker engages in this
48 **  phase that they do not have prior knowledege to what services are open.
49 **  So, the attacker will need to query the ports or protocols they are
50 **  interested in.  Most or at least some of these queries will be negative
51 **  and take the form of either an invalid response (TCP RSTs, ICMP
52 **  unreachables) or no response (in which case the host is firewalled or
53 **  filtered).  We detect portscans from these negative queries.
54 **
55 **  The primary goal of this portscan detection engine is to catch nmap and
56 **  variant scanners.  The engine tracks connection attempts on TCP, UDP,
57 **  ICMP, and IP Protocols.  If there is a valid response, the connection
58 **  is marked as valid.  If there is no response or a invalid response
59 **  (TCP RST), then we track these attempts separately, so we know the
60 **  number of invalid responses and the number of connection attempts that
61 **  generated no response.  These two values differentiate between a
62 **  normal scan and a filtered scan.
63 **
64 **  We detect four different scan types, and each scan type has its own
65 **  negative query characteristics.  This is how we determine what type
66 **  of scan we are seeing.  The different scans are:
67 **
68 **    - Portscan
69 **    - Decoy Portscan
70 **    - Distributed Portscan
71 **    - Portsweep
72 **
73 **  Portscan:  A portscan is a basic one host to one host scan where
74 **  multiple ports are scanned on the destination host.  We detect these
75 **  scans by looking for a low number of hosts that contacted the
76 **  destination host and a high number of unique ports and a high number
77 **  of invalid responses or connections.
78 **
79 **  Distributed Portscan:  A distributed portscan occurs when many hosts
80 **  connect to a single destination host and multiple ports are scanned
81 **  on the destination host.  We detect these scans by looking for a high
82 **  number of hosts that contacted the destination host and a high number
83 **  of unique ports with a high number of invalid responses or connections.
84 **
85 **  Decoy Portscan:  A decoy portscan is a variation on a distributed
86 **  portscan, the difference being that a decoy portscan connects to a
87 **  single port multiple times.  This shows up in the unqiue port count that
88 **  is tracked.  There's still many hosts connecting to the destination host.
89 **
90 **  Portsweep:  A portsweep is a basic one host to many host scan where
91 **  one to a few ports are scanned on each host.  We detect these scans by
92 **  looking at src hosts for a high number of contacted hosts and a low
93 **  number of unique ports with a high number of invalid responses or
94 **  connections.
95 **
96 **  Each of these scans can also be detected as a filtered portscan, or a
97 **  portscan where there wasn't invalid responses and the responses have
98 **  been firewalled in some way.
99 **
100 */
101 #include <stdlib.h>
102 #include <string.h>
103 #include <sys/types.h>
104 
105 #ifndef WIN32
106 # include <sys/socket.h>
107 # include <netinet/in.h>
108 # include <arpa/inet.h>
109 #endif /* !WIN32 */
110 
111 #ifdef HAVE_CONFIG_H
112 #include "config.h"
113 #endif
114 
115 #include "snort.h"
116 #include "decode.h"
117 #include "portscan.h"
118 #include "packet_time.h"
119 #include "sfxhash.h"
120 #include "ipobj.h"
121 #include "session_common.h"
122 #include "session_api.h"
123 #include "stream_api.h"
124 #include "sfPolicyData.h"
125 #include "sfPolicyUserData.h"
126 #include "event_wrapper.h"
127 
128 #ifdef REG_TEST
129 #include "reg_test.h"
130 #endif
131 
132 
133 # define CLEARED &cleared
134 
135 typedef struct s_PS_HASH_KEY
136 {
137     int protocol;
138     struct in6_addr scanner;
139     struct in6_addr scanned;
140     tSfPolicyId      policyId;
141 } PS_HASH_KEY;
142 
143 typedef struct s_PS_ALERT_CONF
144 {
145     short connection_count;
146     short priority_count;
147     short u_ip_count;
148     short u_port_count;
149 
150 } PS_ALERT_CONF;
151 
152 extern tSfPolicyUserContextId portscan_config;
153 extern PortscanConfig *portscan_eval_config;
154 
155 static SFXHASH *portscan_hash = NULL;
156 
157 /*
158 **  Scanning configurations.  This is where we configure what the thresholds
159 **  are for the different types of scans, protocols, and sense levels.  If
160 **  you want to tweak the sense levels, change the values here.
161 */
162 /*
163 **  TCP alert configurations
164 */
165 static PS_ALERT_CONF g_tcp_low_ps =       {0,5,25,5};
166 static PS_ALERT_CONF g_tcp_low_decoy_ps = {0,15,50,30};
167 static PS_ALERT_CONF g_tcp_low_sweep =    {0,5,5,15};
168 static PS_ALERT_CONF g_tcp_low_dist_ps =  {0,15,50,15};
169 
170 static PS_ALERT_CONF g_tcp_med_ps =       {200,10,60,15};
171 static PS_ALERT_CONF g_tcp_med_decoy_ps = {200,30,120,60};
172 static PS_ALERT_CONF g_tcp_med_sweep =    {30,7,7,10};
173 static PS_ALERT_CONF g_tcp_med_dist_ps =  {200,30,120,30};
174 
175 static PS_ALERT_CONF g_tcp_hi_ps =        {200,5,100,10};
176 static PS_ALERT_CONF g_tcp_hi_decoy_ps =  {200,7,200,60};
177 static PS_ALERT_CONF g_tcp_hi_sweep =     {30,3,3,10};
178 static PS_ALERT_CONF g_tcp_hi_dist_ps =   {200,5,200,10};
179 
180 /*
181 **  UDP alert configurations
182 */
183 static PS_ALERT_CONF g_udp_low_ps =       {0,5,25,5};
184 static PS_ALERT_CONF g_udp_low_decoy_ps = {0,15,50,30};
185 static PS_ALERT_CONF g_udp_low_sweep =    {0,5,5,15};
186 static PS_ALERT_CONF g_udp_low_dist_ps =  {0,15,50,15};
187 
188 static PS_ALERT_CONF g_udp_med_ps =       {200,10,60,15};
189 static PS_ALERT_CONF g_udp_med_decoy_ps = {200,30,120,60};
190 static PS_ALERT_CONF g_udp_med_sweep =    {30,5,5,20};
191 static PS_ALERT_CONF g_udp_med_dist_ps =  {200,30,120,30};
192 
193 static PS_ALERT_CONF g_udp_hi_ps =        {200,3,100,10};
194 static PS_ALERT_CONF g_udp_hi_decoy_ps =  {200,7,200,60};
195 static PS_ALERT_CONF g_udp_hi_sweep =     {30,3,3,10};
196 static PS_ALERT_CONF g_udp_hi_dist_ps =   {200,3,200,10};
197 
198 /*
199 **  IP Protocol alert configurations
200 */
201 static PS_ALERT_CONF g_ip_low_ps =        {0,10,10,50};
202 static PS_ALERT_CONF g_ip_low_decoy_ps =  {0,40,50,25};
203 static PS_ALERT_CONF g_ip_low_sweep =     {0,10,10,10};
204 static PS_ALERT_CONF g_ip_low_dist_ps =   {0,15,25,50};
205 
206 static PS_ALERT_CONF g_ip_med_ps =        {200,10,10,50};
207 static PS_ALERT_CONF g_ip_med_decoy_ps =  {200,40,50,25};
208 static PS_ALERT_CONF g_ip_med_sweep =     {30,10,10,10};
209 static PS_ALERT_CONF g_ip_med_dist_ps =   {200,15,25,50};
210 
211 static PS_ALERT_CONF g_ip_hi_ps =         {200,3,3,10};
212 static PS_ALERT_CONF g_ip_hi_decoy_ps =   {200,7,15,5};
213 static PS_ALERT_CONF g_ip_hi_sweep =      {30,3,3,7};
214 static PS_ALERT_CONF g_ip_hi_dist_ps =    {200,3,11,10};
215 
216 /*
217 **  ICMP alert configurations
218 */
219 static PS_ALERT_CONF g_icmp_low_sweep =   {0,5,5,5};
220 static PS_ALERT_CONF g_icmp_med_sweep =   {20,5,5,5};
221 static PS_ALERT_CONF g_icmp_hi_sweep =    {10,3,3,5};
222 
223 static int ps_get_proto(PS_PKT *, int *);
224 
225 /*
226 **  NAME
227 **    ps_tracker_free::
228 */
229 /**
230 **  This function is passed into the hash algorithm, so that
231 **  we only reuse nodes that aren't priority nodes.  We have to make
232 **  sure that we only track so many priority nodes, otherwise we could
233 **  have all priority nodes and not be able to allocate more.
234 */
ps_tracker_free(void * key,void * data)235 static int ps_tracker_free(void *key, void *data)
236 {
237     PS_TRACKER *tracker;
238 
239     if(!key || !data)
240         return 0;
241 
242     tracker = (PS_TRACKER *)data;
243     if(!tracker->priority_node)
244         return 0;
245 
246     /*
247     **  Cycle through the protos to see if it's past the time.
248     **  We only get here if we ARE a priority node.
249     */
250     if(tracker->proto.window >= packet_time())
251         return 1;
252 
253     return 0;
254 }
255 
256 /*
257 **  NAME
258 **    ps_init::
259 */
260 /*
261 **  Initialize the portscan infrastructure.  We check to make sure that
262 **  we have enough memory to support at least 100 nodes.
263 **
264 **  @return int
265 **
266 **  @retval -2 memcap is too low
267 */
ps_init(struct _SnortConfig * sc,PortscanConfig * config,int detect_scans,int detect_scan_type,int sense_level,IPSET * scanner,IPSET * scanned,IPSET * watch,unsigned long memcap)268 int ps_init(struct _SnortConfig *sc, PortscanConfig *config, int detect_scans, int detect_scan_type,
269             int sense_level, IPSET *scanner, IPSET *scanned, IPSET *watch, unsigned long memcap)
270 {
271     if (getParserPolicy(sc) != getDefaultPolicy())
272     {
273         /**checks valid for non-default policy only. Default is allowed to specify
274          * just memcap.
275          */
276         if (!(detect_scans & PS_PROTO_ALL))
277             return -1;
278 
279         if(!(detect_scan_type & PS_TYPE_ALL))
280             return -1;
281 
282         if(sense_level < 1 || sense_level > 3)
283             return -1;
284 
285     }
286     else
287     {
288         /**memcap from non-default is ignored, so check is valid for default policy
289          * only
290          */
291         if(memcap <= 0 || (unsigned)memcap < (sizeof(PS_TRACKER) * 100))
292             return -2;
293     }
294 
295     config->memcap           = memcap;
296     config->detect_scans     = detect_scans;
297     config->detect_scan_type = detect_scan_type;
298     config->sense_level      = sense_level;
299     config->ignore_scanners  = scanner;
300     config->ignore_scanned   = scanned;
301     config->watch_ip         = watch;
302 
303     return 0;
304 }
305 
306 /*
307 **  NAME
308 **    ps_cleanup::
309 */
310 /**
311 **  Cleanup the portscan infrastructure.
312 */
ps_cleanup(void)313 void ps_cleanup(void)
314 {
315     if (portscan_hash != NULL)
316     {
317         sfxhash_delete(portscan_hash);
318         portscan_hash = NULL;
319     }
320 }
321 
ps_init_hash(unsigned long memcap)322 void ps_init_hash(unsigned long memcap)
323 {
324     int rows = memcap/(sizeof(PS_HASH_KEY) + sizeof(PS_TRACKER));
325 
326     portscan_hash = sfxhash_new(rows, sizeof(PS_HASH_KEY), sizeof(PS_TRACKER),
327                                 memcap, 1, ps_tracker_free, NULL, 1);
328 
329     if (portscan_hash == NULL)
330         FatalError("Failed to initialize portscan hash table.\n");
331 }
332 
333 /*
334 **  NAME
335 **    ps_reset::
336 */
337 /**
338 **  Reset the portscan infrastructure.
339 */
ps_reset(void)340 void ps_reset(void)
341 {
342     if (portscan_hash != NULL)
343         sfxhash_make_empty(portscan_hash);
344 }
345 
346 /*
347 **  NAME
348 **    ps_ignore_ip::
349 */
350 /**
351 **  Check scanner and scanned ips to see if we can filter them out.
352 */
ps_ignore_ip(sfaddr_t * scanner,uint16_t scanner_port,sfaddr_t * scanned,uint16_t scanned_port)353 static int ps_ignore_ip(sfaddr_t* scanner, uint16_t scanner_port,
354                         sfaddr_t* scanned, uint16_t scanned_port)
355 {
356     if (portscan_eval_config->ignore_scanners)
357     {
358         if (ipset_contains(portscan_eval_config->ignore_scanners, scanner, &scanner_port))
359             return 1;
360     }
361 
362     if(portscan_eval_config->ignore_scanned)
363     {
364         if (ipset_contains(portscan_eval_config->ignore_scanned, scanned, &scanned_port))
365             return 1;
366     }
367 
368     return 0;
369 }
370 
371 /*
372 **  NAME
373 **    ps_filter_ignore::
374 */
375 /**
376 **  Check the incoming packet to decide whether portscan detection cares
377 **  about this packet.  We try to ignore as many packets as possible.
378 */
ps_filter_ignore(PS_PKT * ps_pkt)379 static int ps_filter_ignore(PS_PKT *ps_pkt)
380 {
381     Packet  *p;
382     int      reverse_pkt = 0;
383     sfaddr_t* scanner;
384     sfaddr_t* scanned;
385 
386     p = (Packet *)ps_pkt->pkt;
387 
388     if(!IPH_IS_VALID(p))
389         return 1;
390 
391     if(p->tcph)
392     {
393         if(!(portscan_eval_config->detect_scans & PS_PROTO_TCP))
394             return 1;
395 
396         /*
397         **  This is where we check all of snort's flags for different
398         **  TCP session scenarios.  The checks cover:
399         **
400         **    - dropping packets in established sessions, but not the
401         **      TWH packet.
402         **    - dropping the SYN/ACK packet from the server on a valid
403         **      connection (we'll catch the TWH later if it happens).
404         */
405         /*
406         **  Ignore packets that are already part of an established TCP
407         **  stream.
408         */
409         if(((p->packet_flags & (PKT_STREAM_EST | PKT_STREAM_TWH))
410                 == PKT_STREAM_EST) && !(p->tcph->th_flags & TH_RST))
411         {
412             return 1;
413         }
414 
415         /*
416         **  Ignore the server's initial response, unless it's to RST
417         **  the connection.
418         */
419         /*
420         if(!(p->tcph->th_flags & TH_RST) &&
421            !(p->packet_flags & (PKT_STREAM_EST)) &&
422             (p->packet_flags & PKT_FROM_SERVER))
423         {
424             return 1;
425         }
426         */
427     }
428     else if(p->udph)
429     {
430         if(!(portscan_eval_config->detect_scans & PS_PROTO_UDP))
431             return 1;
432     }
433     else if(p->icmph)
434     {
435         if(p->icmph->type != ICMP_DEST_UNREACH &&
436            !(portscan_eval_config->detect_scans & PS_PROTO_ICMP))
437         {
438             return 1;
439         }
440     }
441     else
442     {
443         if(!(portscan_eval_config->detect_scans & PS_PROTO_IP))
444             return 1;
445     }
446 
447     /*
448     **  Check if the packet is reversed
449     */
450     if((p->packet_flags & PKT_FROM_SERVER))
451     {
452         reverse_pkt = 1;
453     }
454     else if(p->icmph && p->icmph->type == ICMP_DEST_UNREACH)
455     {
456         reverse_pkt = 1;
457     }
458     else if (p->udph && ( p->ssnptr != NULL ) &&
459              ( ( SessionControlBlock * ) p->ssnptr )->session_established &&
460              session_api && session_api->version >= SESSION_API_VERSION1)
461     {
462         if (session_api->get_packet_direction(p) & PKT_FROM_SERVER)
463             reverse_pkt = 1;
464     }
465 
466     scanner = GET_SRC_IP(p);
467     scanned = GET_DST_IP(p);
468 
469     if(reverse_pkt)
470     {
471         if(ps_ignore_ip(scanned, p->dp, scanner, p->sp))
472             return 1;
473     }
474     else
475     {
476         if(ps_ignore_ip(scanner, p->sp, scanned, p->dp))
477             return 1;
478     }
479 
480     ps_pkt->reverse_pkt = reverse_pkt;
481 
482     if(portscan_eval_config->watch_ip)
483     {
484         if(ipset_contains(portscan_eval_config->watch_ip, scanner, &(p->sp)))
485             return 0;
486         if(ipset_contains(portscan_eval_config->watch_ip, scanned, &(p->dp)))
487             return 0;
488 
489         return 1;
490     }
491     return 0;
492 }
493 
494 /*
495 **  NAME
496 **    ps_tracker_init::
497 */
498 /**
499 **  Right now all we do is memset, but just in case we want to do more
500 **  initialization has been extracted.
501 */
ps_tracker_init(PS_TRACKER * tracker)502 static int ps_tracker_init(PS_TRACKER *tracker)
503 {
504     memset(tracker, 0x00, sizeof(PS_TRACKER));
505 
506     return 0;
507 }
508 
509 /*
510 **  NAME
511 **    ps_tracker_get::
512 */
513 /**
514 **  Get a tracker node by either finding one or starting a new one.  We may
515 **  return NULL, in which case we wait till the next packet.
516 */
ps_tracker_get(PS_TRACKER ** ht,PS_HASH_KEY * key)517 static int ps_tracker_get(PS_TRACKER **ht, PS_HASH_KEY *key)
518 {
519     int iRet;
520 
521     *ht = (PS_TRACKER *)sfxhash_find(portscan_hash, (void *)key);
522     if(!(*ht))
523     {
524         iRet = sfxhash_add(portscan_hash, (void *)key, NULL);
525         if(iRet == SFXHASH_OK)
526         {
527             *ht = (PS_TRACKER *)sfxhash_mru(portscan_hash);
528             if(!(*ht))
529                 return -1;
530 
531             ps_tracker_init(*ht);
532         }
533         else
534         {
535             return -1;
536         }
537     }
538 
539     return 0;
540 }
541 
ps_tracker_lookup(PS_PKT * ps_pkt,PS_TRACKER ** scanner,PS_TRACKER ** scanned)542 static int ps_tracker_lookup(PS_PKT *ps_pkt, PS_TRACKER **scanner,
543                              PS_TRACKER **scanned)
544 {
545     PS_HASH_KEY key;
546     Packet *p;
547 
548     if (ps_pkt->pkt == NULL)
549         return -1;
550 
551     p = (Packet *)ps_pkt->pkt;
552 
553     if (ps_get_proto(ps_pkt, &key.protocol) == -1)
554         return -1;
555 
556     ps_pkt->proto = key.protocol;
557     key.policyId = getNapRuntimePolicy();
558 
559     /*
560     **  Let's lookup the host that is being scanned, taking into account
561     **  the pkt may be reversed.
562     */
563     if (portscan_eval_config->detect_scan_type &
564         (PS_TYPE_PORTSCAN | PS_TYPE_DECOYSCAN | PS_TYPE_DISTPORTSCAN))
565     {
566         memset(&key.scanner.s6_addr, 0, sizeof(key.scanner.s6_addr));
567 
568         if(ps_pkt->reverse_pkt)
569             sfaddr_copy_to_raw(&key.scanned, GET_SRC_IP(p));
570         else
571             sfaddr_copy_to_raw(&key.scanned, GET_DST_IP(p));
572 
573         /*
574         **  Get the scanned tracker.
575         */
576         ps_tracker_get(scanned, &key);
577     }
578 
579     /*
580     **  Let's lookup the host that is scanning.
581     */
582     if(portscan_eval_config->detect_scan_type & PS_TYPE_PORTSWEEP)
583     {
584         memset(&key.scanned.s6_addr, 0, sizeof(key.scanned.s6_addr));
585 
586         if(ps_pkt->reverse_pkt)
587             sfaddr_copy_to_raw(&key.scanner, GET_DST_IP(p));
588         else
589             sfaddr_copy_to_raw(&key.scanner, GET_SRC_IP(p));
590 
591         /*
592         **  Get the scanner tracker
593         */
594         ps_tracker_get(scanner, &key);
595     }
596 
597     if ((*scanner == NULL) && (*scanned == NULL))
598         return -1;
599 
600     return 0;
601 }
602 
603 /*
604 **  NAME
605 **    ps_get_proto_index::
606 */
607 /**
608 **  This logic finds the index to the proto array based on the
609 **  portscan configuration.  We need special logic because the
610 **  index of the protocol changes based on the configuration.
611 */
ps_get_proto(PS_PKT * ps_pkt,int * proto)612 static int ps_get_proto(PS_PKT *ps_pkt, int *proto)
613 {
614     Packet *p;
615 
616     if(!ps_pkt || !ps_pkt->pkt || !proto)
617         return -1;
618 
619     p = (Packet *)ps_pkt->pkt;
620     *proto = 0;
621 
622     if (portscan_eval_config->detect_scans & PS_PROTO_TCP)
623     {
624         if ((p->tcph != NULL)
625                 || ((p->icmph != NULL) && (p->icmph->type == ICMP_DEST_UNREACH)
626                     && ((p->icmph->code == ICMP_PORT_UNREACH)
627                         || (p->icmph->code == ICMP_PKT_FILTERED))
628                     && (p->orig_tcph != NULL)))
629         {
630             *proto = PS_PROTO_TCP;
631             return 0;
632         }
633     }
634 
635     if (portscan_eval_config->detect_scans & PS_PROTO_UDP)
636     {
637         if ((p->udph != NULL)
638                 || ((p->icmph != NULL) && (p->icmph->type == ICMP_DEST_UNREACH)
639                     && ((p->icmph->code == ICMP_PORT_UNREACH)
640                         || (p->icmph->code == ICMP_PKT_FILTERED))
641                     && (p->orig_udph != NULL)))
642         {
643             *proto = PS_PROTO_UDP;
644             return 0;
645         }
646     }
647 
648     if (portscan_eval_config->detect_scans & PS_PROTO_IP)
649     {
650         if ((IPH_IS_VALID(p) && (p->icmph == NULL))
651                 || ((p->icmph != NULL) && (p->icmph->type == ICMP_DEST_UNREACH)
652                     && ((p->icmph->code == ICMP_PROT_UNREACH)
653                         || (p->icmph->code == ICMP_PKT_FILTERED))))
654         {
655             *proto = PS_PROTO_IP;
656             return 0;
657         }
658     }
659 
660     if (portscan_eval_config->detect_scans & PS_PROTO_ICMP)
661     {
662         if (p->icmph != NULL)
663         {
664             *proto = PS_PROTO_ICMP;
665             return 0;
666         }
667     }
668 
669     return -1;
670 }
671 
672 /*
673 **  NAME
674 **    ps_proto_update_window::
675 */
676 /**
677 **  Update the proto time windows based on the portscan sensitivity
678 **  level.
679 */
ps_proto_update_window(PS_PROTO * proto,time_t pkt_time)680 static int ps_proto_update_window(PS_PROTO *proto, time_t pkt_time)
681 {
682     time_t interval;
683 
684     switch(portscan_eval_config->sense_level)
685     {
686         case PS_SENSE_LOW:
687             //interval = 15;
688             interval = 60;
689             break;
690 
691         case PS_SENSE_MEDIUM:
692             //interval = 15;
693             interval = 90;
694             break;
695 
696         case PS_SENSE_HIGH:
697             interval = 600;
698             break;
699 
700         default:
701             return -1;
702     }
703 
704     /*
705     **  If we are outside of the window, reset our ps counters.
706     */
707     if(pkt_time > proto->window)
708     {
709         memset(proto, 0x00, sizeof(PS_PROTO));
710 
711         proto->window = pkt_time + interval;
712 
713         return 0;
714     }
715 
716     return 0;
717 }
718 
719 /*
720 **  NAME
721 **    ps_proto_update::
722 */
723 /**
724 **  This function updates the PS_PROTO structure.
725 **
726 **  @param PS_PROTO pointer to structure to update
727 **  @param int      number to increment portscan counter
728 **  @param u_long   IP address of other host
729 **  @param u_short  port/ip_proto to track
730 **  @param time_t   time the packet was received. update windows.
731 */
ps_proto_update(PS_PROTO * proto,int ps_cnt,int pri_cnt,sfaddr_t * ip,u_short port,time_t pkt_time)732 static int ps_proto_update(PS_PROTO *proto, int ps_cnt, int pri_cnt, sfaddr_t* ip,
733         u_short port, time_t pkt_time)
734 {
735     if(!proto)
736         return 0;
737 
738     /*
739     **  If the ps_cnt is negative, that means we are just taking off
740     **  for valid connection, and we don't want to do anything else,
741     **  like update ip/port, etc.
742     */
743     if(ps_cnt < 0)
744     {
745         proto->connection_count += ps_cnt;
746         if(proto->connection_count < 0)
747             proto->connection_count = 0;
748 
749         return 0;
750     }
751 
752     /*
753     **  If we are updating a priority cnt, it means we already did the
754     **  unique port and IP on the connection packet.
755     **
756     **  Priority points are only added for invalid response packets.
757     */
758     if(pri_cnt)
759     {
760         proto->priority_count += pri_cnt;
761         if(proto->priority_count < 0)
762             proto->priority_count = 0;
763 
764         return 0;
765     }
766 
767     /*
768     **  Do time check first before we update the counters, so if
769     **  we need to reset them we do it before we update them.
770     */
771     if(ps_proto_update_window(proto, pkt_time))
772         return -1;
773 
774     /*
775     **  Update ps counter
776     */
777     proto->connection_count += ps_cnt;
778     if(proto->connection_count < 0)
779         proto->connection_count = 0;
780 
781     if(!IP_EQUALITY_UNSET(&proto->u_ips, ip))
782     {
783         proto->u_ip_count++;
784         IP_COPY_VALUE(proto->u_ips, ip);
785     }
786 
787     /* we need to do the IP comparisons in host order */
788 
789     if(sfaddr_is_set(&proto->low_ip))
790     {
791         if(IP_GREATER(&proto->low_ip, ip))
792             IP_COPY_VALUE(proto->low_ip, ip);
793     }
794     else
795     {
796         IP_COPY_VALUE(proto->low_ip, ip);
797     }
798 
799     if(sfaddr_is_set(&proto->high_ip))
800     {
801         if(IP_LESSER(&proto->high_ip, ip))
802             IP_COPY_VALUE(proto->high_ip, ip);
803     }
804     else
805     {
806         IP_COPY_VALUE(proto->high_ip, ip);
807     }
808 
809     if(proto->u_ports != port)
810     {
811         proto->u_port_count++;
812         proto->u_ports = port;
813     }
814 
815     if(proto->low_p)
816     {
817         if(proto->low_p > port)
818             proto->low_p = port;
819     }
820     else
821     {
822         proto->low_p = port;
823     }
824 
825     if(proto->high_p)
826     {
827         if(proto->high_p < port)
828             proto->high_p = port;
829     }
830     else
831     {
832         proto->high_p = port;
833     }
834 
835     return 0;
836 }
837 
ps_update_open_ports(PS_PROTO * proto,unsigned short port)838 static int ps_update_open_ports(PS_PROTO *proto, unsigned short port)
839 {
840     int iCtr;
841 
842     for(iCtr = 0; iCtr < proto->open_ports_cnt; iCtr++)
843     {
844         if(port == proto->open_ports[iCtr])
845             return 0;
846     }
847 
848     if(iCtr < (PS_OPEN_PORTS - 1))
849     {
850         proto->open_ports[iCtr] = port;
851         proto->open_ports_cnt++;
852 
853         if(proto->alerts == PS_ALERT_GENERATED)
854         {
855             proto->alerts = PS_ALERT_OPEN_PORT;
856         }
857     }
858 
859     return 0;
860 }
861 
862 /*
863 **  NAME
864 **    ps_tracker_update_tcp::
865 */
866 /**
867 **  Determine how to update the portscan counter depending on the type
868 **  of TCP packet we have.
869 **
870 **  We are concerned with three types of TCP packets:
871 **
872 **    - initiating TCP packets (we don't care about flags)
873 **    - TCP 3-way handshake packets (we decrement the counter)
874 **    - TCP reset packets on unestablished streams.
875 */
ps_tracker_update_tcp(PS_PKT * ps_pkt,PS_TRACKER * scanner,PS_TRACKER * scanned)876 static int ps_tracker_update_tcp(PS_PKT *ps_pkt, PS_TRACKER *scanner,
877                                  PS_TRACKER *scanned)
878 {
879     Packet  *p;
880     uint32_t session_flags;
881     sfaddr_t cleared;
882     IP_CLEAR(cleared);
883 
884     p = (Packet *)ps_pkt->pkt;
885 
886     /*
887     **  Handle the initiating packet.
888     **
889     **  If this what stream4 considers to be a valid initiator, then
890     **  we will use the available stream4 information.  Otherwise, we
891     **  can just revert to flow and look for initiators and responders.
892     **
893     **  For Stream, depending on the configuration, there might not
894     **  be a session created only based on the SYN packet.  Stream
895     **  by default has code that helps deal with SYN flood attacks,
896     **  and may simply ignore the SYN.  In this case, we fall through
897     **  to the checks for specific TCP header files (SYN, SYN-ACK, RST).
898     **
899     **  The "midstream" logic below says that, if we include sessions
900     **  picked up midstream, then we don't care about the MIDSTREAM flag.
901     **  Otherwise, only consider streams not picked up midstream.
902     */
903     if( ( p->ssnptr != NULL ) &&
904         ( ( SessionControlBlock * ) p->ssnptr )->session_established && session_api )
905     {
906         session_flags = session_api->get_session_flags(p->ssnptr);
907 
908         if((session_flags & SSNFLAG_SEEN_CLIENT) &&
909            !(session_flags & SSNFLAG_SEEN_SERVER) &&
910            (portscan_eval_config->include_midstream || !(session_flags & SSNFLAG_MIDSTREAM)))
911         {
912             if(scanned)
913             {
914                 ps_proto_update(&scanned->proto,1,0,
915                                  GET_SRC_IP(p),p->dp, packet_time());
916             }
917 
918             if(scanner)
919             {
920                 ps_proto_update(&scanner->proto,1,0,
921                                  GET_DST_IP(p),p->dp, packet_time());
922             }
923         }
924         /*
925         **  Handle the final packet of the three-way handshake.
926         */
927         else if(p->packet_flags & PKT_STREAM_TWH)
928         {
929             if(scanned)
930             {
931                 ps_proto_update(&scanned->proto,-1,0,CLEARED,0,0);
932             }
933 
934             if(scanner)
935             {
936                 ps_proto_update(&scanner->proto,-1,0,CLEARED,0,0);
937             }
938         }
939         /*
940         **  RST packet on unestablished streams
941         */
942         else if((p->packet_flags & PKT_FROM_SERVER) &&
943                 (p->tcph && (p->tcph->th_flags & TH_RST)) &&
944                 (!(p->packet_flags & PKT_STREAM_EST) ||
945                 (session_flags & SSNFLAG_MIDSTREAM)))
946         {
947             if(scanned)
948             {
949                 ps_proto_update(&scanned->proto,0,1,CLEARED,0,0);
950                 scanned->priority_node = 1;
951             }
952 
953             if(scanner)
954             {
955                 ps_proto_update(&scanner->proto,0,1,CLEARED,0,0);
956                 scanner->priority_node = 1;
957             }
958         }
959         /*
960         **  We only get here on the server's response to the intial
961         **  client connection.
962         **
963         **  That's why we use the sp, because that's the port that is
964         **  open.
965         */
966         else if((p->packet_flags & PKT_FROM_SERVER) &&
967                 !(p->packet_flags & PKT_STREAM_EST))
968         {
969             if(scanned)
970             {
971                 ps_update_open_ports(&scanned->proto, p->sp);
972             }
973 
974             if(scanner)
975             {
976                 if(scanner->proto.alerts == PS_ALERT_GENERATED)
977                     scanner->proto.alerts = PS_ALERT_OPEN_PORT;
978             }
979         }
980     }
981     /*
982     ** Stream didn't create a session on the SYN packet,
983     ** so check specifically for SYN here.
984     */
985     else if (p->tcph && (p->tcph->th_flags == TH_SYN))
986     {
987         /* No session established, packet only has SYN.  SYN only
988         ** packet always from client, so use dp.
989         */
990         if(scanned)
991         {
992             ps_proto_update(&scanned->proto,1,0,
993                              GET_SRC_IP(p),p->dp, packet_time());
994         }
995 
996         if(scanner)
997         {
998             ps_proto_update(&scanner->proto,1,0,
999                              GET_DST_IP(p),p->dp, packet_time());
1000         }
1001     }
1002     /*
1003     ** Stream didn't create a session on the SYN packet,
1004     ** so check specifically for SYN & ACK here.  Clear based
1005     ** on the 'completion' of three-way handshake.
1006     */
1007     else if(p->tcph && (p->tcph->th_flags == (TH_SYN|TH_ACK)))
1008     {
1009         if(scanned)
1010         {
1011             ps_proto_update(&scanned->proto,-1,0,CLEARED,0,0);
1012         }
1013 
1014         if(scanner)
1015         {
1016             ps_proto_update(&scanner->proto,-1,0,CLEARED,0,0);
1017         }
1018     }
1019     /*
1020     ** No session created, clear based on the RST on non
1021     ** established session.
1022     */
1023     else if (p->tcph && (p->tcph->th_flags & TH_RST))
1024     {
1025         if(scanned)
1026         {
1027             ps_proto_update(&scanned->proto,0,1,CLEARED,0,0);
1028             scanned->priority_node = 1;
1029         }
1030 
1031         if(scanner)
1032         {
1033             ps_proto_update(&scanner->proto,0,1,CLEARED,0,0);
1034             scanner->priority_node = 1;
1035         }
1036     }
1037     /*
1038     **  If we are an icmp unreachable, deal with it here.
1039     */
1040     else if(p->icmph)
1041     {
1042         if(scanned)
1043         {
1044             ps_proto_update(&scanned->proto,0,1,CLEARED,0,0);
1045             scanned->priority_node = 1;
1046         }
1047 
1048         if(scanner)
1049         {
1050             ps_proto_update(&scanner->proto,0,1,CLEARED,0,0);
1051             scanner->priority_node = 1;
1052         }
1053     }
1054     return 0;
1055 }
1056 
ps_tracker_update_ip(PS_PKT * ps_pkt,PS_TRACKER * scanner,PS_TRACKER * scanned)1057 static int ps_tracker_update_ip(PS_PKT *ps_pkt, PS_TRACKER *scanner,
1058                                 PS_TRACKER *scanned)
1059 {
1060     Packet *p;
1061     sfaddr_t cleared;
1062     IP_CLEAR(cleared);
1063 
1064     p = (Packet *)ps_pkt->pkt;
1065 
1066     if(p->iph)
1067     {
1068         /*
1069          * If the packet is of icmp type 3(destination
1070          * unreachable), then unset the connection count so
1071          * that the connection count will not be incremented for
1072          * the reply packet and set the priority count.
1073          */
1074         if(p->icmph && p->icmph->type == ICMP_DEST_UNREACH &&
1075             p->icmph->code == ICMP_PROT_UNREACH)
1076         {
1077             if(scanned)
1078             {
1079                 ps_proto_update(&scanned->proto,0,1,CLEARED,0,0);
1080                 scanned->priority_node = 1;
1081             }
1082 
1083             if(scanner)
1084             {
1085                 ps_proto_update(&scanner->proto,0,1,CLEARED,0,0);
1086                 scanner->priority_node = 1;
1087             }
1088         }
1089         else
1090         {
1091             if(scanned)
1092             {
1093                 ps_proto_update(&scanned->proto,1,0,
1094                                 GET_SRC_IP(p),p->iph->ip_proto, packet_time());
1095             }
1096 
1097             if(scanner)
1098             {
1099                 ps_proto_update(&scanner->proto,1,0,
1100                                 GET_DST_IP(p),p->iph->ip_proto, packet_time());
1101             }
1102         }
1103     }
1104     return 0;
1105 }
1106 
ps_tracker_update_udp(PS_PKT * ps_pkt,PS_TRACKER * scanner,PS_TRACKER * scanned)1107 static int ps_tracker_update_udp(PS_PKT *ps_pkt, PS_TRACKER *scanner,
1108                                  PS_TRACKER *scanned)
1109 {
1110     Packet  *p;
1111     sfaddr_t    cleared;
1112     IP_CLEAR(cleared);
1113 
1114     p = (Packet *)ps_pkt->pkt;
1115 
1116     if(p->icmph)
1117     {
1118         if(scanned)
1119         {
1120             ps_proto_update(&scanned->proto,0,1,CLEARED,0,0);
1121             scanned->priority_node = 1;
1122         }
1123 
1124         if(scanner)
1125         {
1126             ps_proto_update(&scanner->proto,0,1,CLEARED,0,0);
1127             scanner->priority_node = 1;
1128         }
1129     }
1130     else if(p->udph)
1131     {
1132         if (session_api && (session_api->version >= SESSION_API_VERSION1) &&
1133             ( p->ssnptr != NULL ) && ( ( SessionControlBlock * ) p->ssnptr )->session_established)
1134         {
1135             uint32_t direction = session_api->get_packet_direction(p);
1136 
1137             if (direction == PKT_FROM_CLIENT)
1138             {
1139                 if(scanned)
1140                 {
1141                     ps_proto_update(&scanned->proto,1,0,
1142                                      GET_SRC_IP(p),p->dp, packet_time());
1143                 }
1144 
1145                 if(scanner)
1146                 {
1147                     ps_proto_update(&scanner->proto,1,0,
1148                                      GET_DST_IP(p),p->dp, packet_time());
1149                 }
1150             }
1151             else if (direction == PKT_FROM_SERVER)
1152             {
1153                 if(scanned)
1154                     ps_proto_update(&scanned->proto,-1,0,CLEARED,0,0);
1155 
1156                 if(scanner)
1157                     ps_proto_update(&scanner->proto,-1,0,CLEARED,0,0);
1158             }
1159         }
1160     }
1161 
1162     return 0;
1163 }
1164 
ps_tracker_update_icmp(PS_PKT * ps_pkt,PS_TRACKER * scanner,PS_TRACKER * scanned)1165 static int ps_tracker_update_icmp(PS_PKT *ps_pkt, PS_TRACKER *scanner,
1166                                   PS_TRACKER *scanned)
1167 {
1168     Packet  *p;
1169     sfaddr_t cleared;
1170     IP_CLEAR(cleared);
1171 
1172     p = (Packet *)ps_pkt->pkt;
1173 
1174     if(p->icmph)
1175     {
1176         switch(p->icmph->type)
1177         {
1178             case ICMP_ECHO:
1179             case ICMP_TIMESTAMP:
1180             case ICMP_ADDRESS:
1181             case ICMP_INFO_REQUEST:
1182 
1183                 if(scanner)
1184                 {
1185                     ps_proto_update(&scanner->proto,1,0,
1186                                      GET_DST_IP(p), 0, packet_time());
1187                 }
1188 
1189                 break;
1190 
1191             case ICMP_DEST_UNREACH:
1192 
1193                 if(scanner)
1194                 {
1195                     ps_proto_update(&scanner->proto,0,1,CLEARED,0,0);
1196                     scanner->priority_node = 1;
1197                 }
1198 
1199                 break;
1200 
1201             default:
1202                 break;
1203         }
1204     }
1205 
1206     return 0;
1207 }
1208 
1209 /*
1210 **  NAME
1211 **    ps_tracker_update::
1212 */
1213 /**
1214 **  At this point, we should only be looking at tranport protocols
1215 **  that we want to.  For instance, if we aren't doing UDP portscans
1216 **  then we won't see UDP packets here because they were ignored.
1217 **
1218 **  This is where we evaluate the packet to add/subtract portscan
1219 **  tracker values and prioritize a tracker.  We also update the
1220 **  time windows.
1221 */
ps_tracker_update(PS_PKT * ps_pkt,PS_TRACKER * scanner,PS_TRACKER * scanned)1222 static int ps_tracker_update(PS_PKT *ps_pkt, PS_TRACKER *scanner,
1223                              PS_TRACKER *scanned)
1224 {
1225     if(scanner && scanner->proto.alerts)
1226         scanner->proto.alerts = PS_ALERT_GENERATED;
1227 
1228     if(scanned && scanned->proto.alerts)
1229         scanned->proto.alerts = PS_ALERT_GENERATED;
1230 
1231     switch (ps_pkt->proto)
1232     {
1233         case PS_PROTO_TCP:
1234             if(ps_tracker_update_tcp(ps_pkt, scanner, scanned))
1235                 return -1;
1236 
1237             break;
1238 
1239         case PS_PROTO_UDP:
1240             if(ps_tracker_update_udp(ps_pkt, scanner, scanned))
1241                 return -1;
1242 
1243             break;
1244 
1245         case PS_PROTO_ICMP:
1246             if(ps_tracker_update_icmp(ps_pkt, scanner, scanned))
1247                 return -1;
1248 
1249             break;
1250 
1251         case PS_PROTO_IP:
1252             if(ps_tracker_update_ip(ps_pkt, scanner, scanned))
1253                 return -1;
1254 
1255             break;
1256 
1257         default:
1258             return -1;
1259     }
1260 
1261     return 0;
1262 }
1263 
ps_get_tcp_rule_action(int alert_type)1264 static int ps_get_tcp_rule_action(int alert_type)
1265 {
1266     int action = 0;
1267     switch(alert_type)
1268     {
1269         case PS_ALERT_ONE_TO_ONE:
1270             action = GetSnortEventAction(GENERATOR_PSNG,
1271                     PSNG_TCP_PORTSCAN, 0, 0, 3, PSNG_TCP_PORTSCAN_STR);
1272             break;
1273 
1274         case PS_ALERT_ONE_TO_ONE_DECOY:
1275             action = GetSnortEventAction(GENERATOR_PSNG,
1276                     PSNG_TCP_DECOY_PORTSCAN,0,0,3,PSNG_TCP_DECOY_PORTSCAN_STR);
1277             break;
1278 
1279         case PS_ALERT_PORTSWEEP:
1280            action = GetSnortEventAction(GENERATOR_PSNG,
1281                    PSNG_TCP_PORTSWEEP, 0, 0, 3, PSNG_TCP_PORTSWEEP_STR);
1282            break;
1283 
1284         case PS_ALERT_DISTRIBUTED:
1285             action = GetSnortEventAction(GENERATOR_PSNG,
1286                     PSNG_TCP_DISTRIBUTED_PORTSCAN, 0, 0, 3,
1287                     PSNG_TCP_DISTRIBUTED_PORTSCAN_STR);
1288             break;
1289 
1290         case PS_ALERT_ONE_TO_ONE_FILTERED:
1291             action = GetSnortEventAction(GENERATOR_PSNG,
1292                     PSNG_TCP_FILTERED_PORTSCAN,0,0,3,
1293                     PSNG_TCP_FILTERED_PORTSCAN_STR);
1294             break;
1295 
1296         case PS_ALERT_ONE_TO_ONE_DECOY_FILTERED:
1297             action = GetSnortEventAction(GENERATOR_PSNG,
1298                     PSNG_TCP_FILTERED_DECOY_PORTSCAN, 0,0,3,
1299                     PSNG_TCP_FILTERED_DECOY_PORTSCAN_STR);
1300             break;
1301 
1302         case PS_ALERT_PORTSWEEP_FILTERED:
1303             action = GetSnortEventAction(GENERATOR_PSNG,
1304                    PSNG_TCP_PORTSWEEP_FILTERED,0,0,3,
1305                    PSNG_TCP_PORTSWEEP_FILTERED_STR);
1306 
1307             break;
1308         case PS_ALERT_DISTRIBUTED_FILTERED:
1309             action = GetSnortEventAction(GENERATOR_PSNG,
1310                     PSNG_TCP_FILTERED_DISTRIBUTED_PORTSCAN, 0, 0, 3,
1311                     PSNG_TCP_FILTERED_DISTRIBUTED_PORTSCAN_STR);
1312             break;
1313 
1314     }
1315     return action;
1316 }
1317 
ps_get_udp_rule_action(int alert_type)1318 static int ps_get_udp_rule_action (int alert_type)
1319 {
1320     int action = 0;;
1321     switch(alert_type)
1322     {
1323         case PS_ALERT_ONE_TO_ONE:
1324             action = GetSnortEventAction(GENERATOR_PSNG, PSNG_UDP_PORTSCAN, 0, 0, 3,
1325                     PSNG_UDP_PORTSCAN_STR);
1326             break;
1327 
1328         case PS_ALERT_ONE_TO_ONE_DECOY:
1329             action = GetSnortEventAction(GENERATOR_PSNG,PSNG_UDP_DECOY_PORTSCAN,
1330                         0, 0, 3, PSNG_UDP_DECOY_PORTSCAN_STR);
1331             break;
1332 
1333         case PS_ALERT_PORTSWEEP:
1334            action = GetSnortEventAction(GENERATOR_PSNG,PSNG_UDP_PORTSWEEP, 0, 0, 3,
1335                     PSNG_UDP_PORTSWEEP_STR);
1336             break;
1337 
1338         case PS_ALERT_DISTRIBUTED:
1339             action = GetSnortEventAction(GENERATOR_PSNG,PSNG_UDP_DISTRIBUTED_PORTSCAN,
1340                     0, 0, 3, PSNG_UDP_DISTRIBUTED_PORTSCAN_STR);
1341             break;
1342 
1343         case PS_ALERT_ONE_TO_ONE_FILTERED:
1344             action = GetSnortEventAction(GENERATOR_PSNG,PSNG_UDP_FILTERED_PORTSCAN,
1345                      0, 0, 3, PSNG_UDP_FILTERED_PORTSCAN_STR);
1346             break;
1347 
1348         case PS_ALERT_ONE_TO_ONE_DECOY_FILTERED:
1349             action = GetSnortEventAction(GENERATOR_PSNG,
1350                         PSNG_UDP_FILTERED_DECOY_PORTSCAN,
1351                         0, 0, 3, PSNG_UDP_FILTERED_DECOY_PORTSCAN_STR);
1352             break;
1353 
1354         case PS_ALERT_PORTSWEEP_FILTERED:
1355            action = GetSnortEventAction(GENERATOR_PSNG,
1356                             PSNG_UDP_PORTSWEEP_FILTERED,0, 0, 3,
1357                             PSNG_UDP_PORTSWEEP_FILTERED_STR);
1358             break;
1359 
1360         case PS_ALERT_DISTRIBUTED_FILTERED:
1361             action = GetSnortEventAction(GENERATOR_PSNG,
1362                     PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN, 0, 0, 3,
1363                     PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN_STR);
1364             break;
1365 
1366     }
1367     return action;
1368 }
1369 
ps_get_ip_rule_action(int alert_type)1370 static int ps_get_ip_rule_action(int alert_type)
1371 {
1372     int action = 0;
1373     switch (alert_type)
1374     {
1375         case PS_ALERT_ONE_TO_ONE:
1376             action = GetSnortEventAction(GENERATOR_PSNG, PSNG_IP_PORTSCAN, 0, 0, 3,
1377                     PSNG_IP_PORTSCAN_STR);
1378             break;
1379 
1380         case PS_ALERT_ONE_TO_ONE_DECOY:
1381             action = GetSnortEventAction(GENERATOR_PSNG,PSNG_IP_DECOY_PORTSCAN,
1382                             0, 0, 3, PSNG_IP_DECOY_PORTSCAN_STR);
1383             break;
1384 
1385         case PS_ALERT_PORTSWEEP:
1386            action = GetSnortEventAction(GENERATOR_PSNG,PSNG_IP_PORTSWEEP, 0, 0, 3,
1387                     PSNG_IP_PORTSWEEP_STR);
1388             break;
1389 
1390         case PS_ALERT_DISTRIBUTED:
1391             action = GetSnortEventAction(GENERATOR_PSNG,
1392                         PSNG_IP_DISTRIBUTED_PORTSCAN,
1393                         0, 0, 3, PSNG_IP_DISTRIBUTED_PORTSCAN_STR);
1394             break;
1395 
1396         case PS_ALERT_ONE_TO_ONE_FILTERED:
1397             action = GetSnortEventAction(GENERATOR_PSNG,
1398                         PSNG_IP_FILTERED_PORTSCAN,
1399                         0, 0, 3, PSNG_IP_FILTERED_PORTSCAN_STR);
1400             break;
1401 
1402         case PS_ALERT_ONE_TO_ONE_DECOY_FILTERED:
1403             action = GetSnortEventAction(GENERATOR_PSNG,
1404                         PSNG_IP_FILTERED_DECOY_PORTSCAN,
1405                         0, 0, 3, PSNG_IP_FILTERED_DECOY_PORTSCAN_STR);
1406             break;
1407 
1408         case PS_ALERT_PORTSWEEP_FILTERED:
1409            action = GetSnortEventAction(GENERATOR_PSNG,
1410                         PSNG_IP_PORTSWEEP_FILTERED, 0, 0, 3,
1411                         PSNG_IP_PORTSWEEP_FILTERED_STR);
1412             break;
1413 
1414         case PS_ALERT_DISTRIBUTED_FILTERED:
1415             action = GetSnortEventAction(GENERATOR_PSNG,
1416                     PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN, 0, 0, 3,
1417                     PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN_STR);
1418             break;
1419     }
1420     return action;
1421 }
1422 
ps_get_icmp_rule_action(int alert_type)1423 static int ps_get_icmp_rule_action(int alert_type)
1424 {
1425     int action = 0;
1426     switch(alert_type)
1427     {
1428         case PS_ALERT_PORTSWEEP:
1429            action = GetSnortEventAction(GENERATOR_PSNG,
1430                     PSNG_ICMP_PORTSWEEP, 0, 0, 3,
1431                     PSNG_ICMP_PORTSWEEP_STR);
1432             break;
1433 
1434         case PS_ALERT_PORTSWEEP_FILTERED:
1435            action = GetSnortEventAction(GENERATOR_PSNG,
1436                     PSNG_ICMP_PORTSWEEP_FILTERED, 0, 0, 3,
1437                     PSNG_ICMP_PORTSWEEP_FILTERED_STR);
1438             break;
1439     }
1440     return action;
1441 }
1442 
ps_get_rule_action(int proto,int alert_type)1443 static int ps_get_rule_action (int proto, int alert_type)
1444 {
1445     int action = 0;
1446     switch (proto)
1447     {
1448         case PS_PROTO_TCP:
1449             action = ps_get_tcp_rule_action(alert_type);
1450             break;
1451 
1452         case PS_PROTO_UDP:
1453             action = ps_get_udp_rule_action(alert_type);
1454             break;
1455 
1456         case PS_PROTO_ICMP:
1457             action = ps_get_icmp_rule_action(alert_type);
1458             break;
1459 
1460         case PS_PROTO_IP:
1461             action = ps_get_ip_rule_action(alert_type);
1462             break;
1463     }
1464     return action;
1465 }
1466 
ps_alert_one_to_one(PS_PROTO * scanner,PS_PROTO * scanned,PS_ALERT_CONF * conf,int proto)1467 static int ps_alert_one_to_one(PS_PROTO *scanner, PS_PROTO *scanned,
1468         PS_ALERT_CONF *conf, int proto)
1469 {
1470     int action;
1471     if(!conf)
1472         return -1;
1473 
1474     /*
1475     **  Let's evaluate the scanned host.
1476     */
1477 
1478     if(scanned)
1479     {
1480         if(scanned->priority_count >= conf->priority_count)
1481         {
1482             action = ps_get_rule_action(proto, PS_ALERT_ONE_TO_ONE);
1483             if ((action == RULE_TYPE__DROP) ||
1484                 (action == RULE_TYPE__SDROP) ||
1485                 (action == RULE_TYPE__REJECT) ||
1486                 (!scanned->alerts))
1487             {
1488                 if(scanned->u_ip_count < conf->u_ip_count &&
1489                     scanned->u_port_count >= conf->u_port_count)
1490                 {
1491                     if(scanner)
1492                     {
1493                         if(scanner->priority_count >= conf->priority_count)
1494                         {
1495                             /*
1496                              **  Now let's check to make sure this is one
1497                              **  to one
1498                              */
1499                             scanned->alerts = PS_ALERT_ONE_TO_ONE;
1500                             return 0;
1501                         }
1502                     }
1503                     else
1504                     {
1505                         /*
1506                          **  If there is no scanner, then we do the best we can.
1507                          */
1508                         scanned->alerts = PS_ALERT_ONE_TO_ONE;
1509                         return 0;
1510                     }
1511                 }
1512             }
1513         }
1514         if(scanned->connection_count >= conf->connection_count)
1515         {
1516             action = ps_get_rule_action(proto, PS_ALERT_ONE_TO_ONE_FILTERED);
1517             if ((action == RULE_TYPE__DROP) ||
1518                 (action == RULE_TYPE__SDROP) ||
1519                 (action == RULE_TYPE__REJECT) ||
1520                 (!scanned->alerts))
1521             {
1522                 if(conf->connection_count == 0)
1523                     return 0;
1524 
1525                 if(scanned->u_ip_count < conf->u_ip_count &&
1526                    scanned->u_port_count >= conf->u_port_count)
1527                 {
1528                     scanned->alerts = PS_ALERT_ONE_TO_ONE_FILTERED;
1529                     return 0;
1530                 }
1531             }
1532         }
1533     }
1534 
1535     return 0;
1536 
1537 }
1538 
ps_alert_one_to_one_decoy(PS_PROTO * scanner,PS_PROTO * scanned,PS_ALERT_CONF * conf,int proto)1539 static int ps_alert_one_to_one_decoy(PS_PROTO *scanner, PS_PROTO *scanned,
1540         PS_ALERT_CONF *conf, int proto)
1541 {
1542     int action;
1543     if(!conf)
1544         return -1;
1545 
1546     if(scanned)
1547     {
1548         if(scanned->priority_count >= conf->priority_count)
1549         {
1550             action = ps_get_rule_action(proto, PS_ALERT_ONE_TO_ONE_DECOY);
1551             if ((action == RULE_TYPE__DROP) ||
1552                 (action == RULE_TYPE__SDROP) ||
1553                 (action == RULE_TYPE__REJECT) ||
1554                 (!scanned->alerts))
1555             {
1556                 if(scanned->u_ip_count >= conf->u_ip_count &&
1557                    scanned->u_port_count >= conf->u_port_count)
1558                 {
1559                     scanned->alerts = PS_ALERT_ONE_TO_ONE_DECOY;
1560                     return 0;
1561                 }
1562             }
1563         }
1564         if(scanned->connection_count >= conf->connection_count)
1565         {
1566             action = ps_get_rule_action(proto, PS_ALERT_ONE_TO_ONE_DECOY_FILTERED);
1567             if ((action == RULE_TYPE__DROP) ||
1568                 (action == RULE_TYPE__SDROP) ||
1569                 (action == RULE_TYPE__REJECT) ||
1570                 (!scanned->alerts))
1571             {
1572 
1573                 if(conf->connection_count == 0)
1574                     return 0;
1575 
1576                 if(scanned->u_ip_count >= conf->u_ip_count &&
1577                    scanned->u_port_count >= conf->u_port_count)
1578                 {
1579                     scanned->alerts = PS_ALERT_ONE_TO_ONE_DECOY_FILTERED;
1580                     return 0;
1581                 }
1582             }
1583         }
1584     }
1585 
1586     return 0;
1587 }
1588 
ps_alert_many_to_one(PS_PROTO * scanner,PS_PROTO * scanned,PS_ALERT_CONF * conf,int proto)1589 static int ps_alert_many_to_one(PS_PROTO *scanner, PS_PROTO *scanned,
1590         PS_ALERT_CONF *conf, int proto)
1591 {
1592     int action;
1593 
1594     if(!conf)
1595         return -1;
1596 
1597     if(scanned)
1598     {
1599         if(scanned->priority_count >= conf->priority_count)
1600         {
1601             action = ps_get_rule_action(proto, PS_ALERT_DISTRIBUTED);
1602             if ((action == RULE_TYPE__DROP) ||
1603                 (action == RULE_TYPE__SDROP) ||
1604                 (action == RULE_TYPE__REJECT) ||
1605                 (!scanned->alerts))
1606             {
1607                 if(scanned->u_ip_count >= conf->u_ip_count &&
1608                    scanned->u_port_count <= conf->u_port_count)
1609                 {
1610                     scanned->alerts = PS_ALERT_DISTRIBUTED;
1611                     return 0;
1612                 }
1613             }
1614         }
1615         if(scanned->connection_count >= conf->connection_count)
1616         {
1617             if(conf->connection_count == 0)
1618                 return 0;
1619 
1620             action = ps_get_rule_action(proto, PS_ALERT_DISTRIBUTED_FILTERED);
1621             if ((action == RULE_TYPE__DROP) ||
1622                 (action == RULE_TYPE__SDROP) ||
1623                 (action == RULE_TYPE__REJECT) ||
1624                 (!scanned->alerts))
1625             {
1626                 if(scanned->u_ip_count >= conf->u_ip_count &&
1627                    scanned->u_port_count <= conf->u_port_count)
1628                 {
1629                     scanned->alerts = PS_ALERT_DISTRIBUTED_FILTERED;
1630                     return 0;
1631                 }
1632             }
1633         }
1634     }
1635 
1636     return 0;
1637 }
1638 
ps_alert_one_to_many(PS_PROTO * scanner,PS_PROTO * scanned,PS_ALERT_CONF * conf,int proto)1639 static int ps_alert_one_to_many(PS_PROTO *scanner, PS_PROTO *scanned,
1640         PS_ALERT_CONF *conf, int proto)
1641 {
1642     int action;
1643 
1644     if(!conf)
1645         return -1;
1646 
1647     if(scanner)
1648     {
1649         if(scanner->priority_count >= conf->priority_count)
1650         {
1651             action = ps_get_rule_action(proto, PS_ALERT_PORTSWEEP);
1652             if ((action == RULE_TYPE__DROP) ||
1653                 (action == RULE_TYPE__SDROP) ||
1654                 (action == RULE_TYPE__REJECT) ||
1655                 (!scanner->alerts))
1656             {
1657                 if(scanner->u_ip_count >= conf->u_ip_count &&
1658                    scanner->u_port_count <= conf->u_port_count)
1659                 {
1660                     scanner->alerts = PS_ALERT_PORTSWEEP;
1661                     return 1;
1662                 }
1663             }
1664         }
1665         if(scanner->connection_count >= conf->connection_count)
1666         {
1667             if(conf->connection_count == 0)
1668                 return 0;
1669 
1670             action = ps_get_rule_action(proto, PS_ALERT_PORTSWEEP);
1671             if ((action == RULE_TYPE__DROP) ||
1672                 (action == RULE_TYPE__SDROP) ||
1673                 (action == RULE_TYPE__REJECT) ||
1674                 (!scanner->alerts))
1675             {
1676                 if(scanner->u_ip_count >= conf->u_ip_count &&
1677                    scanner->u_port_count <= conf->u_port_count)
1678                 {
1679                     scanner->alerts = PS_ALERT_PORTSWEEP_FILTERED;
1680                     return 1;
1681                 }
1682             }
1683         }
1684     }
1685 
1686     return 0;
1687 }
1688 
ps_alert_tcp(PS_PROTO * scanner,PS_PROTO * scanned)1689 static int ps_alert_tcp(PS_PROTO *scanner, PS_PROTO *scanned)
1690 {
1691     static PS_ALERT_CONF *one_to_one;
1692     static PS_ALERT_CONF *one_to_one_decoy;
1693     static PS_ALERT_CONF *one_to_many;
1694     static PS_ALERT_CONF *many_to_one;
1695 
1696     /*
1697     ** Set the configurations depending on the sensitivity
1698     ** level.
1699     */
1700     switch(portscan_eval_config->sense_level)
1701     {
1702         case PS_SENSE_HIGH:
1703             one_to_one       = &g_tcp_hi_ps;
1704             one_to_one_decoy = &g_tcp_hi_decoy_ps;
1705             one_to_many      = &g_tcp_hi_sweep;
1706             many_to_one      = &g_tcp_hi_dist_ps;
1707 
1708             break;
1709 
1710         case PS_SENSE_MEDIUM:
1711             one_to_one       = &g_tcp_med_ps;
1712             one_to_one_decoy = &g_tcp_med_decoy_ps;
1713             one_to_many      = &g_tcp_med_sweep;
1714             many_to_one      = &g_tcp_med_dist_ps;
1715 
1716             break;
1717 
1718         case PS_SENSE_LOW:
1719             one_to_one       = &g_tcp_low_ps;
1720             one_to_one_decoy = &g_tcp_low_decoy_ps;
1721             one_to_many      = &g_tcp_low_sweep;
1722             many_to_one      = &g_tcp_low_dist_ps;
1723 
1724             break;
1725 
1726         default:
1727             return -1;
1728     }
1729 
1730     /*
1731     **  Do detection on the different portscan types.
1732     */
1733     if((portscan_eval_config->detect_scan_type & PS_TYPE_PORTSCAN) &&
1734         ps_alert_one_to_one(scanner, scanned, one_to_one, PS_PROTO_TCP))
1735     {
1736         return 0;
1737     }
1738 
1739     if((portscan_eval_config->detect_scan_type & PS_TYPE_DECOYSCAN) &&
1740         ps_alert_one_to_one_decoy(scanner, scanned, one_to_one_decoy, PS_PROTO_TCP))
1741     {
1742         return 0;
1743     }
1744 
1745     if((portscan_eval_config->detect_scan_type & PS_TYPE_PORTSWEEP) &&
1746         ps_alert_one_to_many(scanner, scanned, one_to_many, PS_PROTO_TCP))
1747     {
1748         return 0;
1749     }
1750 
1751     if((portscan_eval_config->detect_scan_type & PS_TYPE_DISTPORTSCAN) &&
1752         ps_alert_many_to_one(scanner, scanned, many_to_one, PS_PROTO_TCP))
1753     {
1754         return 0;
1755     }
1756 
1757     return 0;
1758 }
1759 
ps_alert_ip(PS_PROTO * scanner,PS_PROTO * scanned)1760 static int ps_alert_ip(PS_PROTO *scanner, PS_PROTO *scanned)
1761 {
1762     static PS_ALERT_CONF *one_to_one;
1763     static PS_ALERT_CONF *one_to_one_decoy;
1764     static PS_ALERT_CONF *one_to_many;
1765     static PS_ALERT_CONF *many_to_one;
1766 
1767     /*
1768     ** Set the configurations depending on the sensitivity
1769     ** level.
1770     */
1771     switch(portscan_eval_config->sense_level)
1772     {
1773         case PS_SENSE_HIGH:
1774             one_to_one       = &g_ip_hi_ps;
1775             one_to_one_decoy = &g_ip_hi_decoy_ps;
1776             one_to_many      = &g_ip_hi_sweep;
1777             many_to_one      = &g_ip_hi_dist_ps;
1778 
1779             break;
1780 
1781         case PS_SENSE_MEDIUM:
1782             one_to_one       = &g_ip_med_ps;
1783             one_to_one_decoy = &g_ip_med_decoy_ps;
1784             one_to_many      = &g_ip_med_sweep;
1785             many_to_one      = &g_ip_med_dist_ps;
1786 
1787             break;
1788 
1789         case PS_SENSE_LOW:
1790             one_to_one       = &g_ip_low_ps;
1791             one_to_one_decoy = &g_ip_low_decoy_ps;
1792             one_to_many      = &g_ip_low_sweep;
1793             many_to_one      = &g_ip_low_dist_ps;
1794 
1795             break;
1796 
1797         default:
1798             return -1;
1799     }
1800 
1801     /*
1802     **  Do detection on the different portscan types.
1803     */
1804     if((portscan_eval_config->detect_scan_type & PS_TYPE_PORTSCAN) &&
1805         ps_alert_one_to_one(scanner, scanned, one_to_one, PS_PROTO_IP))
1806     {
1807         return 0;
1808     }
1809 
1810     if((portscan_eval_config->detect_scan_type & PS_TYPE_DECOYSCAN) &&
1811         ps_alert_one_to_one_decoy(scanner, scanned, one_to_one_decoy, PS_PROTO_IP))
1812     {
1813         return 0;
1814     }
1815 
1816     if((portscan_eval_config->detect_scan_type & PS_TYPE_PORTSWEEP) &&
1817         ps_alert_one_to_many(scanner, scanned, one_to_many, PS_PROTO_IP))
1818     {
1819         return 0;
1820     }
1821 
1822     if((portscan_eval_config->detect_scan_type & PS_TYPE_DISTPORTSCAN) &&
1823         ps_alert_many_to_one(scanner, scanned, many_to_one, PS_PROTO_IP))
1824     {
1825         return 0;
1826     }
1827 
1828     return 0;
1829 }
1830 
ps_alert_udp(PS_PROTO * scanner,PS_PROTO * scanned)1831 static int ps_alert_udp(PS_PROTO *scanner, PS_PROTO *scanned)
1832 {
1833     static PS_ALERT_CONF *one_to_one;
1834     static PS_ALERT_CONF *one_to_one_decoy;
1835     static PS_ALERT_CONF *one_to_many;
1836     static PS_ALERT_CONF *many_to_one;
1837 
1838     /*
1839     ** Set the configurations depending on the sensitivity
1840     ** level.
1841     */
1842     switch(portscan_eval_config->sense_level)
1843     {
1844         case PS_SENSE_HIGH:
1845             one_to_one       = &g_udp_hi_ps;
1846             one_to_one_decoy = &g_udp_hi_decoy_ps;
1847             one_to_many      = &g_udp_hi_sweep;
1848             many_to_one      = &g_udp_hi_dist_ps;
1849 
1850             break;
1851 
1852         case PS_SENSE_MEDIUM:
1853             one_to_one       = &g_udp_med_ps;
1854             one_to_one_decoy = &g_udp_med_decoy_ps;
1855             one_to_many      = &g_udp_med_sweep;
1856             many_to_one      = &g_udp_med_dist_ps;
1857 
1858             break;
1859 
1860         case PS_SENSE_LOW:
1861             one_to_one       = &g_udp_low_ps;
1862             one_to_one_decoy = &g_udp_low_decoy_ps;
1863             one_to_many      = &g_udp_low_sweep;
1864             many_to_one      = &g_udp_low_dist_ps;
1865 
1866             break;
1867 
1868         default:
1869             return -1;
1870     }
1871 
1872     /*
1873     **  Do detection on the different portscan types.
1874     */
1875     if((portscan_eval_config->detect_scan_type & PS_TYPE_PORTSCAN) &&
1876         ps_alert_one_to_one(scanner, scanned, one_to_one, PS_PROTO_UDP))
1877     {
1878         return 0;
1879     }
1880 
1881     if((portscan_eval_config->detect_scan_type & PS_TYPE_DECOYSCAN) &&
1882         ps_alert_one_to_one_decoy(scanner, scanned, one_to_one_decoy, PS_PROTO_UDP))
1883     {
1884         return 0;
1885     }
1886 
1887     if((portscan_eval_config->detect_scan_type & PS_TYPE_PORTSWEEP) &&
1888         ps_alert_one_to_many(scanner, scanned, one_to_many, PS_PROTO_UDP))
1889     {
1890         return 0;
1891     }
1892 
1893     if((portscan_eval_config->detect_scan_type & PS_TYPE_DISTPORTSCAN) &&
1894         ps_alert_many_to_one(scanner, scanned, many_to_one, PS_PROTO_UDP))
1895     {
1896         return 0;
1897     }
1898 
1899     return 0;
1900 }
1901 
ps_alert_icmp(PS_PROTO * scanner,PS_PROTO * scanned)1902 static int ps_alert_icmp(PS_PROTO *scanner, PS_PROTO *scanned)
1903 {
1904     static PS_ALERT_CONF *one_to_many;
1905 
1906     /*
1907     ** Set the configurations depending on the sensitivity
1908     ** level.
1909     */
1910     switch(portscan_eval_config->sense_level)
1911     {
1912         case PS_SENSE_HIGH:
1913             one_to_many = &g_icmp_hi_sweep;
1914 
1915             break;
1916 
1917         case PS_SENSE_MEDIUM:
1918             one_to_many = &g_icmp_med_sweep;
1919 
1920             break;
1921 
1922         case PS_SENSE_LOW:
1923             one_to_many = &g_icmp_low_sweep;
1924 
1925             break;
1926 
1927         default:
1928             return -1;
1929     }
1930 
1931     /*
1932     **  Do detection on the different portscan types.
1933     */
1934     if((portscan_eval_config->detect_scan_type & PS_TYPE_PORTSWEEP) &&
1935         ps_alert_one_to_many(scanner, scanned, one_to_many, PS_PROTO_ICMP))
1936     {
1937         return 0;
1938     }
1939 
1940     return 0;
1941 }
1942 /*
1943 **  NAME
1944 **    ps_tracker_alert::
1945 */
1946 /**
1947 **  This function evaluates the scanner and scanned trackers and if
1948 **  applicable, generate an alert or alerts for either of the trackers.
1949 **
1950 **  The following alerts can be generated:
1951 **    - One to One Portscan
1952 **    - One to One Decoy Portscan
1953 **    - One to Many Portsweep
1954 **    - Distributed Portscan (Many to One)
1955 **    - Filtered Portscan?
1956 */
ps_tracker_alert(PS_PKT * ps_pkt,PS_TRACKER * scanner,PS_TRACKER * scanned)1957 static int ps_tracker_alert(PS_PKT *ps_pkt, PS_TRACKER *scanner,
1958         PS_TRACKER *scanned)
1959 {
1960     if(!ps_pkt)
1961         return -1;
1962 
1963     switch(ps_pkt->proto)
1964     {
1965         case PS_PROTO_TCP:
1966             ps_alert_tcp((scanner ? &scanner->proto : NULL),
1967                          (scanned ? &scanned->proto : NULL));
1968             break;
1969 
1970         case PS_PROTO_UDP:
1971             ps_alert_udp((scanner ? &scanner->proto : NULL),
1972                          (scanned ? &scanned->proto : NULL));
1973             break;
1974 
1975         case PS_PROTO_ICMP:
1976             ps_alert_icmp((scanner ? &scanner->proto : NULL),
1977                           (scanned ? &scanned->proto : NULL));
1978             break;
1979 
1980         case PS_PROTO_IP:
1981             ps_alert_ip((scanner ? &scanner->proto : NULL),
1982                         (scanned ? &scanned->proto : NULL));
1983             break;
1984 
1985         default:
1986             return -1;
1987     }
1988 
1989     return 0;
1990 }
1991 
1992 /*
1993 **  NAME
1994 **    ps_detect::
1995 */
1996 /**
1997 **  The design of portscan is as follows:
1998 **
1999 **    - Filter Packet.  Is the packet part of the ignore or watch list?  Is
2000 **      the packet part of an established TCP session (we ignore it)?
2001 **
2002 **    - Tracker Lookup.  We lookup trackers for src and dst if either is in
2003 **      the watch list, or not in the ignore list if there is no watch list.
2004 **      If there is not tracker, we create a new one and keep track, both of
2005 **      the scanned host and the scanning host.
2006 **
2007 **    - Tracker Update.  We update the tracker using the incoming packet.  If
2008 **      the update causes a portscan alert, then we move into the log alert
2009 **      phase.
2010 **
2011 **    - Tracker Evaluate.  Generate an alert from the updated tracker.  We
2012 **      decide whether we are logging a portscan or sweep (based on the
2013 **      scanning or scanned host, we decide which is more relevant).
2014 */
ps_detect(PS_PKT * ps_pkt)2015 int ps_detect(PS_PKT *ps_pkt)
2016 {
2017     PS_TRACKER *scanner = NULL;
2018     PS_TRACKER *scanned = NULL;
2019     int check_tcp_rst_other_dir = 1;
2020     Packet *p;
2021 
2022     if(!ps_pkt || !ps_pkt->pkt)
2023         return -1;
2024 
2025     if(ps_filter_ignore(ps_pkt))
2026         return 0;
2027 
2028     p = (Packet *)ps_pkt->pkt;
2029 
2030     do
2031     {
2032         if(ps_tracker_lookup(ps_pkt, &scanner, &scanned))
2033             return 0;
2034 
2035         if(ps_tracker_update(ps_pkt, scanner, scanned))
2036             return 0;
2037 
2038         if(ps_tracker_alert(ps_pkt, scanner, scanned))
2039             return 0;
2040 
2041         /* This is added to address the case of no Stream
2042          * session and a RST packet going back from the Server. */
2043         if (p->tcph && (p->tcph->th_flags & TH_RST)
2044             && ( p->ssnptr != NULL ) && !( ( SessionControlBlock * ) p->ssnptr )->session_established
2045             && stream_api )
2046         {
2047             if (ps_pkt->reverse_pkt == 1)
2048             {
2049                 check_tcp_rst_other_dir = 0;
2050             }
2051             else
2052             {
2053                 ps_pkt->reverse_pkt = 1;
2054             }
2055         }
2056         else
2057         {
2058             check_tcp_rst_other_dir = 0;
2059         }
2060     } while (check_tcp_rst_other_dir);
2061 
2062     //printf("** alert\n");
2063     ps_pkt->scanner = scanner;
2064     ps_pkt->scanned = scanned;
2065 
2066     return 1;
2067 }
2068 
2069 #if 0
2070 /* Not currently used */
2071 static void ps_proto_print(PS_PROTO *proto)
2072 {
2073 // XXX-IPv6 debugging
2074 
2075     return;
2076 }
2077 
2078 void ps_tracker_print(PS_TRACKER* ps_tracker)
2079 {
2080     int proto_index = 0;
2081     tPortScanPolicyConfig *ppConfig = &psPolicyConfig[getCurrentPolicy()];
2082 
2083     if(!ps_tracker)
2084         return;
2085 
2086     printf("    -- PS_TRACKER --\n");
2087     printf("    priority_node = %d\n", ps_tracker->priority_node);
2088 
2089     if(portscan_eval_config->detect_scans & PS_PROTO_TCP)
2090     {
2091         printf("    ** TCP **\n");
2092         ps_proto_print(&ps_tracker->proto);
2093         proto_index++;
2094     }
2095     if(portscan_eval_config->detect_scans & PS_PROTO_UDP)
2096     {
2097         printf("    ** UDP **\n");
2098         ps_proto_print(&ps_tracker->proto);
2099         proto_index++;
2100     }
2101     if(portscan_eval_config->detect_scans & PS_PROTO_IP)
2102     {
2103         printf("    ** IP **\n");
2104         ps_proto_print(&ps_tracker->proto);
2105         proto_index++;
2106     }
2107     if(portscan_eval_config->detect_scans & PS_PROTO_ICMP)
2108     {
2109         printf("    ** ICMP **\n");
2110         ps_proto_print(&ps_tracker->proto);
2111         proto_index++;
2112     }
2113 
2114     printf("    -- END --\n\n");
2115 
2116     return;
2117 }
2118 #endif
2119 
ps_get_protocols(struct _SnortConfig * sc,tSfPolicyId policyId)2120 int ps_get_protocols(struct _SnortConfig *sc, tSfPolicyId policyId)
2121 {
2122     tSfPolicyUserContextId config = portscan_config;
2123     PortscanConfig *pPolicyConfig = NULL;
2124 
2125 #ifdef SNORT_RELOAD
2126     /* This is called during configuration time so use the swap
2127      * config if it exists */
2128     tSfPolicyUserContextId portscan_swap_config;
2129     portscan_swap_config = (tSfPolicyUserContextId)GetRelatedReloadData(sc, "sfportscan");
2130     if (portscan_swap_config != NULL)
2131         config = portscan_swap_config;
2132 #endif
2133     if( config == NULL)
2134         return 0;
2135     pPolicyConfig = (PortscanConfig *)sfPolicyUserDataGet(config, policyId);
2136 
2137     if (pPolicyConfig == NULL)
2138         return 0;
2139 
2140     /* Disabled in this policy */
2141     if (pPolicyConfig->disabled == 1)
2142         return 0;
2143 
2144     return pPolicyConfig->detect_scans;
2145 }
2146 
2147 #ifdef SNORT_RELOAD
ps_reload_adjust(unsigned long memcap,unsigned max_work)2148 bool ps_reload_adjust(unsigned long memcap, unsigned max_work)
2149 {
2150     int ret = sfxhash_change_memcap(portscan_hash, memcap, &max_work);
2151 #ifdef REG_TEST
2152     if (REG_TEST_FLAG_PORTSCAN_RELOAD & getRegTestFlags() && ret == SFXHASH_OK)
2153     {
2154         printf("portscanhash memused:%lu\n",portscan_hash->mc.memused);
2155         printf("portscanhash memcap:%lu\n",portscan_hash->mc.memcap);
2156     }
2157 #endif
2158     return ret == SFXHASH_OK;
2159 }
2160 
ps_hash_overhead_bytes()2161 unsigned int ps_hash_overhead_bytes()
2162 {
2163     if(portscan_hash)
2164     {
2165         return portscan_hash->overhead_bytes;
2166     }
2167     return 0;
2168 }
2169 #endif
2170 
2171 
2172