http_inspect = { }
imap = { }
pop = { }
-port_scan = { }
reputation = { }
rpc_decode = { }
sip = { }
-- see snort_defaults.lua for default_*
gtp_inspect = default_gtp
+port_scan = default_med_port_scan
smtp = default_smtp
ftp_server = default_ftp_server
{ version = 2, messages = gtp_v2_msg, infos = gtp_v2_info },
}
+---------------------------------------------------------------------------
+-- port_scan defaults
+---------------------------------------------------------------------------
+
+tcp_low_ports = { scans = 0, rejects = 5, nets = 25, ports = 5 }
+tcp_low_decoy = { scans = 0, rejects = 15, nets = 50, ports = 30 }
+tcp_low_sweep = { scans = 0, rejects = 5, nets = 5, ports = 15 }
+tcp_low_dist = { scans = 0, rejects = 15, nets = 50, ports = 15 }
+
+tcp_med_ports = { scans = 200, rejects = 10, nets = 60, ports = 15 }
+tcp_med_decoy = { scans = 200, rejects = 30, nets = 120, ports = 60 }
+tcp_med_sweep = { scans = 30, rejects = 7, nets = 7, ports = 10 }
+tcp_med_dist = { scans = 200, rejects = 30, nets = 120, ports = 30 }
+
+tcp_hi_ports = { scans = 200, rejects = 5, nets = 100, ports = 10 }
+tcp_hi_decoy = { scans = 200, rejects = 7, nets = 200, ports = 60 }
+tcp_hi_sweep = { scans = 30, rejects = 3, nets = 3, ports = 10 }
+tcp_hi_dist = { scans = 200, rejects = 5, nets = 200, ports = 10 }
+
+udp_low_ports = { scans = 0, rejects = 5, nets = 25, ports = 5 }
+udp_low_decoy = { scans = 0, rejects = 15, nets = 50, ports = 30 }
+udp_low_sweep = { scans = 0, rejects = 5, nets = 5, ports = 15 }
+udp_low_dist = { scans = 0, rejects = 15, nets = 50, ports = 15 }
+
+udp_med_ports = { scans = 200, rejects = 10, nets = 60, ports = 15 }
+udp_med_decoy = { scans = 200, rejects = 30, nets = 120, ports = 60 }
+udp_med_sweep = { scans = 30, rejects = 5, nets = 5, ports = 20 }
+udp_med_dist = { scans = 200, rejects = 30, nets = 120, ports = 30 }
+
+udp_hi_ports = { scans = 200, rejects = 3, nets = 100, ports = 10 }
+udp_hi_decoy = { scans = 200, rejects = 7, nets = 200, ports = 60 }
+udp_hi_sweep = { scans = 30, rejects = 3, nets = 3, ports = 10 }
+udp_hi_dist = { scans = 200, rejects = 3, nets = 200, ports = 10 }
+
+ip_low_proto = { scans = 0, rejects = 10, nets = 10, ports = 50 }
+ip_low_decoy = { scans = 0, rejects = 40, nets = 50, ports = 25 }
+ip_low_sweep = { scans = 0, rejects = 10, nets = 10, ports = 10 }
+ip_low_dist = { scans = 0, rejects = 15, nets = 25, ports = 50 }
+
+ip_med_proto = { scans = 200, rejects = 10, nets = 10, ports = 50 }
+ip_med_decoy = { scans = 200, rejects = 40, nets = 50, ports = 25 }
+ip_med_sweep = { scans = 30, rejects = 10, nets = 10, ports = 10 }
+ip_med_dist = { scans = 200, rejects = 15, nets = 25, ports = 50 }
+
+ip_hi_proto = { scans = 200, rejects = 3, nets = 3, ports = 10 }
+ip_hi_decoy = { scans = 200, rejects = 7, nets = 15, ports = 5 }
+ip_hi_sweep = { scans = 30, rejects = 3, nets = 3, ports = 7 }
+ip_hi_dist = { scans = 200, rejects = 3, nets = 11, ports = 10 }
+
+icmp_low_sweep = { scans = 0, rejects = 5, nets = 5, ports = 5 }
+icmp_med_sweep = { scans = 20, rejects = 5, nets = 5, ports = 5 }
+icmp_hi_sweep = { scans = 10, rejects = 3, nets = 3, ports = 5 }
+
+default_hi_port_scan =
+{
+ protos = 'all',
+ scan_types = 'all',
+
+ tcp_window = 600,
+ udp_window = 600,
+ ip_window = 600,
+ icmp_window = 600,
+
+ tcp_ports = tcp_hi_ports,
+ tcp_decoy = tcp_hi_decoy,
+ tcp_sweep = tcp_hi_sweep,
+ tcp_dist = tcp_hi_dist,
+
+ udp_ports = udp_hi_ports,
+ udp_decoy = udp_hi_decoy,
+ udp_sweep = udp_hi_sweep,
+ udp_dist = udp_hi_dist,
+
+ ip_proto = ip_hi_proto,
+ ip_decoy = ip_hi_decoy,
+ ip_sweep = ip_hi_sweep,
+ ip_dist = ip_hi_dist,
+
+ icmp_sweep = icmp_hi_sweep,
+}
+
+default_med_port_scan =
+{
+ protos = 'all',
+ scan_types = 'all',
+
+ tcp_window = 90,
+ udp_window = 90,
+ ip_window = 90,
+ icmp_window = 90,
+
+ tcp_ports = tcp_med_ports,
+ tcp_decoy = tcp_med_decoy,
+ tcp_sweep = tcp_med_sweep,
+ tcp_dist = tcp_med_dist,
+
+ udp_ports = udp_med_ports,
+ udp_decoy = udp_med_decoy,
+ udp_sweep = udp_med_sweep,
+ udp_dist = udp_med_dist,
+
+ ip_proto = ip_med_proto,
+ ip_decoy = ip_med_decoy,
+ ip_sweep = ip_med_sweep,
+ ip_dist = ip_med_dist,
+
+ icmp_sweep = icmp_med_sweep,
+}
+
+default_low_port_scan =
+{
+ protos = 'all',
+ scan_types = 'all',
+
+ tcp_window = 60,
+ udp_window = 60,
+ ip_window = 60,
+ icmp_window = 60,
+
+ tcp_ports = tcp_low_ports,
+ tcp_decoy = tcp_low_decoy,
+ tcp_sweep = tcp_low_sweep,
+ tcp_dist = tcp_low_dist,
+
+ udp_ports = udp_low_ports,
+ udp_decoy = udp_low_decoy,
+ udp_sweep = udp_low_sweep,
+ udp_dist = udp_low_dist,
+
+ ip_proto = ip_low_proto,
+ ip_decoy = ip_low_decoy,
+ ip_sweep = ip_low_sweep,
+ ip_dist = ip_low_dist,
+
+ icmp_sweep = icmp_low_sweep,
+}
+
add_library (events STATIC
event.cc
event_queue.cc
- event_wrapper.cc
- event_wrapper.h
sfeventq.cc
sfeventq.h
${INCLUDES}
libevents_a_SOURCES = \
event.cc \
event_queue.cc \
-event_wrapper.cc \
-event_wrapper.h \
sfeventq.cc \
sfeventq.h
** event (gid,sid pair). This is now required to get events
** to be logged. The decoders and preprocessors are still
** configured independently, which allows them to inspect and
-** call the alerting functions DetectionEngine::queue_event, GenerateSnortEvent()
-** and GenerateEvent2() for portscan.cc. The GenerateSnortEvent()
-** function now finds and otn and calls fpLogEvent.
+** call the alerting functions DetectionEngine::queue_event.
**
** Any event that has no otn associated with it's gid,sid pair
** will/should not alert, even if the preprocessor or decoder is
+++ /dev/null
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2017 Cisco and/or its affiliates. All rights reserved.
-// Copyright (C) 1998-2013 Sourcefire, Inc.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License Version 2 as published
-// by the Free Software Foundation. You may not use, modify or distribute
-// this program under any other version of the GNU General Public License.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//--------------------------------------------------------------------------
-/*
- * @file event_wrapper.c
- * @author Chris Green <cmg@sourcefire.com>
- *
- * @date Wed Jun 18 10:49:59 2003
- *
- * 10/31/05 - Marc Norton
- * Changes to support every event being controlled via a rule.
- * Modified GenerateSnortEvent() to re-route events to 'fpLogEvent'
- * if a suitable otn was found. If no otn was found, than we do
- * not log the event at all, as no rule was provided.
- * Preprocessors are configured independently, and may detect
- * an event, but the rule controls the alert/drop functionality.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "event_wrapper.h"
-
-#include "detection/fp_detect.h"
-#include "parser/parser.h"
-
-/*
- * This function has been updated to find an otn and route the call to fpLogEvent
- * if possible. This requires a rule be written for each decoder event,
- * and possibly some preporcessor events. The bulk of eventing is handled vie the
- * DetectionEngine::queue_event() and SnortEventLog() functions - which already
- * route the events to the fpLogEvent()function.
- */
-uint32_t GenerateSnortEvent(Packet* p, uint32_t gid, uint32_t sid)
-{
- OptTreeNode* otn = GetOTN(gid, sid);
-
- if ( !otn )
- return 0;
-
- RuleTreeNode* rtn = getRuntimeRtnFromOtn(otn);
-
- if ( !rtn )
- return 0;
-
- fpLogEvent(rtn, otn, p);
-
- return 0; //otn->event_data.event_id; // FIXIT-M EVENT
-}
-
+++ /dev/null
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2017 Cisco and/or its affiliates. All rights reserved.
-// Copyright (C) 2003-2013 Sourcefire, Inc.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License Version 2 as published
-// by the Free Software Foundation. You may not use, modify or distribute
-// this program under any other version of the GNU General Public License.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//--------------------------------------------------------------------------
-
-#ifndef EVENT_WRAPPER_H
-#define EVENT_WRAPPER_H
-
-#include <cstdint>
-
-uint32_t GenerateSnortEvent(struct Packet* p, uint32_t gen_id, uint32_t sig_id);
-
-#endif
-
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-/*
- ipobj.c
-
- IP address encapsulation interface
-
- This module provides encapsulation of single IP ADDRESSes as
- objects, and collections of IP ADDRESSes as objects
-*/
+// ipobj.c
#ifdef HAVE_CONFIG_H
#include "config.h"
and individual addresses.
For a single IPAddress the implied Mask is 32 bits,or 255.255.255.255, or 0xffffffff, or -1.
-
*/
IPSET* ipset_new()
{
SF_LNODE* cursor;
for (ip_port =(IP_PORT*)sflist_first(&ipsp->ip_list, &cursor);
- ip_port !=NULL;
+ ip_port;
ip_port =(IP_PORT*)sflist_next(&cursor) )
{
ipset_add(newset, &ip_port->ip, &ip_port->portset, ip_port->notflag);
char* lasts = nullptr;
strtok_r(ipstr, " \t", &lasts);
- /* Is either the port after the 1st space, or NULL */
- port_str = strtok_r(NULL, " \t", &lasts);
+ /* Is either the port after the 1st space, or null */
+ port_str = strtok_r(nullptr, " \t", &lasts);
while (port_str)
{
}
port_parse(port_str, portset);
- port_str = strtok_r(NULL, " \t", &lasts);
+ port_str = strtok_r(nullptr, " \t", &lasts);
}
if (portset->port_list.count == 0)
"0/0",
"0.0.0.0/0.0.0.0:25-26 28-29 31",
"0.0.0.0/0.0.2.0",
- NULL
+ nullptr
};
- for (curip = ips; curip[0] != NULL; curip++)
+ for (curip = ips; curip[0]; curip++)
{
portset_init(&portset);
"0/0",
"0.0.0.0/0.0.0.0",
"0.0.0.0/0.0.2.0",
- NULL
+ nullptr
};
- for (curip = ips; curip[0] != NULL; curip++)
+ for (curip = ips; curip[0]; curip++)
{
IPSET* ipset = ipset_new(IPV4_FAMILY);
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-/*
- ipobj.h
+// ipobj.h
+
+#ifndef IPOBJ_H
+#define IPOBJ_H
+/*
IP address encapsulation interface
This module provides encapsulation of single IP ADDRESSes as objects,
and collections of IP ADDRESSes as objects
- Interaction with this library should be done in HOST byte order.
+ Interaction with this library should be done in HOST byte order.
*/
-#ifndef IPOBJ_H
-#define IPOBJ_H
#include "sfip/sf_cidr.h"
#include "utils/sflsq.h"
void ipset_free(IPSET* ipset);
int ipset_print(IPSET* ipset);
-/* helper functions -- all the sets work in host order
-*/
+// helper functions -- all the sets work in host order
int ipset_parse(IPSET* ipset, const char* ipstr);
#endif
/*
** @file sfportscan.c
-**
** @author Daniel Roelker <droelker@sourcefire.com>
-**
-** @brief Portscan detection
-**
-** NOTES
-** - User Configuration: The following is a list of parameters that can
-** be configured through the user interface:
-**
-** proto { tcp udp icmp ip all }
-** scan_type { portscan portsweep decoy_portscan distributed_portscan all }
-** sense_level { high } # high, medium, low
-** watch_ip { } # list of IPs, CIDR blocks
-** ignore_scanners { } # list of IPs, CIDR blocks
-** ignore_scanned { } # list of IPs, CIDR blocks
-** memcap { 10000000 } # number of max bytes to allocate
-** logfile { /tmp/ps.log } # file to log detailed portscan info
*/
#ifdef HAVE_CONFIG_H
#endif
#include "detection/detect.h"
+#include "detection/detection_engine.h"
#include "detection/signature.h"
#include "events/event.h"
-#include "events/event_wrapper.h"
#include "filters/sfthreshold.h"
#include "log/messages.h"
#include "managers/inspector_manager.h"
#define PROTO_BUFFER_SIZE 256
-static THREAD_LOCAL Packet* g_tmp_pkt = NULL;
-static THREAD_LOCAL FILE* g_logfile = NULL;
+static THREAD_LOCAL Packet* g_tmp_pkt = nullptr;
+static THREAD_LOCAL FILE* g_logfile = nullptr;
THREAD_LOCAL SimpleStats spstats;
THREAD_LOCAL ProfileStats psPerfStats;
-/*
-** NAME
-** MakeProtoInfo::
-*/
/**
** This routine makes the portscan payload for the events. The listed
** info is:
** - ip range (low to high range of IPs)
** - port count (number of port changes that occurred on host)
** - port range (low to high range of ports connected too)
-**
-** @return integer
-**
-** @retval -1 buffer not large enough
-** @retval 0 successful
*/
-static int MakeProtoInfo(PS_PROTO* proto, const u_char* buffer, u_int* total_size)
+static bool MakeProtoInfo(PS_PROTO* proto, const uint8_t* buffer, unsigned& total_size)
{
- int dsize;
- SfIp* ip1, * ip2;
+ assert(buffer);
- if (!total_size || !buffer)
- return -1;
-
- dsize = (g_tmp_pkt->max_dsize - *total_size);
+ int dsize = (g_tmp_pkt->max_dsize - total_size);
if (dsize < PROTO_BUFFER_SIZE)
- return -1;
+ return false;
+ SfIp* ip1, * ip2;
ip1 = &proto->low_ip;
ip2 = &proto->high_ip;
}
dsize = SnortStrnlen((const char*)buffer, PROTO_BUFFER_SIZE);
- *total_size += dsize;
+ total_size += dsize;
- /*
- ** Set the payload size. This is protocol independent.
- */
+ // Set the payload size. This is protocol independent.
g_tmp_pkt->dsize = dsize;
- return 0;
+ return true;
}
-static int LogPortscanAlert(Packet* p, uint32_t event_id,
- uint32_t event_ref, uint32_t gen_id, uint32_t sig_id)
+static void LogPortscanAlert(Packet* p, uint32_t event_id,
+ uint32_t event_ref, uint32_t gid, uint32_t sid)
{
- char timebuf[TIMEBUF_SIZE];
- const SfIp* src_addr;
- const SfIp* dst_addr;
-
if(!p->ptrs.ip_api.is_ip())
- return -1;
+ return;
/* Do not log if being suppressed */
- src_addr = p->ptrs.ip_api.get_src();
- dst_addr = p->ptrs.ip_api.get_dst();
+ const SfIp* src_addr = p->ptrs.ip_api.get_src();
+ const SfIp* dst_addr = p->ptrs.ip_api.get_dst();
- if ( sfthreshold_test(gen_id, sig_id, src_addr, dst_addr, p->pkth->ts.tv_sec) )
+ if ( sfthreshold_test(gid, sid, src_addr, dst_addr, p->pkth->ts.tv_sec) )
{
- return 0;
+ return;
}
+ char timebuf[TIMEBUF_SIZE];
ts_print((struct timeval*)&p->pkth->ts, timebuf);
-
fprintf(g_logfile, "Time: %s\n", timebuf);
if (event_id)
fprintf(g_logfile, "%.*s\n", p->dsize, p->data);
fflush(g_logfile);
-
- return 0;
}
-static int GeneratePSSnortEvent(Packet* p,uint32_t gen_id,uint32_t sig_id)
+static int GeneratePSSnortEvent(Packet* p, uint32_t gid, uint32_t sid)
{
- unsigned int event_id;
+ unsigned int event_id = 0; // FIXIT-H eliminate this
- event_id = GenerateSnortEvent(p,gen_id,sig_id);
+ DetectionEngine de;
+ de.queue_event(gid, sid);
if (g_logfile)
- LogPortscanAlert(p, event_id, 0, gen_id, sig_id);
+ LogPortscanAlert(p, event_id, 0, gid, sid);
return event_id;
}
-/*
-** NAME
-** GenerateOpenPortEvent::
-*/
/**
** We have to generate open port events differently because we tag these
** to the original portscan event.
**
-** @return int
-**
** @retval 0 success
*/
-static int GenerateOpenPortEvent(Packet* p, uint32_t gen_id, uint32_t sig_id,
- uint32_t sig_rev, uint32_t cls, uint32_t pri,
- uint32_t event_ref, struct timeval* event_time, const char* msg)
+static int GenerateOpenPortEvent(
+ Packet* p, uint32_t gid, uint32_t sid, uint32_t sig_rev, uint32_t cls,
+ uint32_t pri, uint32_t event_ref, struct timeval& event_time, const char* msg)
{
/*
** This means that we logged an open port, but we don't have a event
SigInfo info;
Event event(info);
- SetEvent(event, gen_id, sig_id, sig_rev, cls, pri, event_ref);
+ SetEvent(event, gid, sid, sig_rev, cls, pri, event_ref);
- event.ref_time.tv_sec = event_time->tv_sec;
- event.ref_time.tv_usec = event_time->tv_usec;
+ event.ref_time.tv_sec = event_time.tv_sec;
+ event.ref_time.tv_usec = event_time.tv_usec;
if (p)
{
* here since these are tagged packets, which aren't subject to thresholding,
* but we want to do it for open port events.
*/
- if ( sfthreshold_test(gen_id, sig_id, p->ptrs.ip_api.get_src(),
+ if ( sfthreshold_test(gid, sid, p->ptrs.ip_api.get_src(),
p->ptrs.ip_api.get_dst(), p->pkth->ts.tv_sec) )
{
return 0;
}
- CallLogFuncs(p, NULL, &event, msg);
+ CallLogFuncs(p, nullptr, &event, msg);
}
else
{
}
if (g_logfile)
- LogPortscanAlert(p, 0, event_ref, gen_id, sig_id);
+ LogPortscanAlert(p, 0, event_ref, gid, sid);
return event.event_id;
}
-/*
-** NAME
-** MakeOpenPortInfo::
-*/
-/**
-** Write out the open ports info for open port alerts.
-**
-** @return integer
-*/
-static int MakeOpenPortInfo(
- PS_PROTO*, const u_char* buffer, u_int* total_size, void* user)
+// Write out the open ports info for open port alerts.
+static bool MakeOpenPortInfo(
+ PS_PROTO*, const uint8_t* buffer, unsigned& total_size, void* user)
{
- int dsize;
+ assert(buffer);
- if ( !total_size || !buffer || !user )
- return -1;
+ if ( !user )
+ return false;
- dsize = (g_tmp_pkt->max_dsize - *total_size);
+ int dsize = (g_tmp_pkt->max_dsize - total_size);
if (dsize < PROTO_BUFFER_SIZE)
- return -1;
+ return false;
SnortSnprintf((char*)buffer, PROTO_BUFFER_SIZE,
"Open Port: %hu\n", *((unsigned short*)user));
dsize = SnortStrnlen((const char*)buffer, PROTO_BUFFER_SIZE);
- *total_size += dsize;
+ total_size += dsize;
- /*
- ** Set the payload size. This is protocol independent.
- */
+ // Set the payload size. This is protocol independent.
g_tmp_pkt->dsize = dsize;
- return 0;
+ return true;
}
-/*
-** NAME
-** MakePortscanPkt::
-*/
/*
** We have to create this fake packet so portscan data can be passed
** through the unified output.
**
** We want to copy the network and transport layer headers into our
** fake packet.
-**
*/
-static int MakePortscanPkt(PS_PKT* ps_pkt, PS_PROTO* proto, int proto_type,
- void* user)
+static bool MakePortscanPkt(PS_PKT* ps_pkt, PS_PROTO* proto, int proto_type, void* user)
{
- unsigned int ip_size = 0;
Packet* p = (Packet*)ps_pkt->pkt;
- EncodeFlags flags = ENC_FLAG_NET;
if (!p->has_ip())
- return -1;
+ return false;
+
+ EncodeFlags flags = ENC_FLAG_NET;
if ( !ps_pkt->reverse_pkt )
flags |= ENC_FLAG_FWD;
- if (p != g_tmp_pkt)
- {
- PacketManager::encode_format(flags, p, g_tmp_pkt, PSEUDO_PKT_PS);
- }
+ PacketManager::encode_format(flags, p, g_tmp_pkt, PSEUDO_PKT_PS);
switch (proto_type)
{
g_tmp_pkt->ps_proto = p->get_ip_proto_next();
break;
default:
- return -1;
+ return false;
}
if (g_tmp_pkt->is_ip4())
- {
((IP4Hdr*)g_tmp_pkt->ptrs.ip_api.get_ip4h())->set_proto(IpProtocol::PORT_SCAN);
- }
- else
- {
- // since ip_api.is_ip() && !ip4h, this is automatically ip6h
+
+ else if (g_tmp_pkt->is_ip6())
((ip::IP6Hdr*)g_tmp_pkt->ptrs.ip_api.get_ip6h())->set_proto(IpProtocol::PORT_SCAN);
- }
+
+ else
+ return false;
+
+ unsigned int ip_size = 0; // FIXIT-H this doesn't look correct
switch (proto_type)
{
case PS_PROTO_UDP:
case PS_PROTO_ICMP:
case PS_PROTO_IP:
- if (MakeProtoInfo(proto, g_tmp_pkt->data, &ip_size))
- return -1;
+ if ( !MakeProtoInfo(proto, g_tmp_pkt->data, ip_size) )
+ return false;
break;
case PS_PROTO_OPEN_PORT:
- if (MakeOpenPortInfo(proto, g_tmp_pkt->data, &ip_size, user))
- return -1;
+ if ( !MakeOpenPortInfo(proto, g_tmp_pkt->data, ip_size, user) )
+ return false;
break;
default:
- return -1;
+ return false;
}
- /*
- ** Let's finish up the IP header and checksum.
- */
+ // Let's finish up the IP header and checksum.
PacketManager::encode_update(g_tmp_pkt);
- // FIXIT-L IP4 is guaranteed to have been set in update(). Is IP6() also guaranteed?
if (g_tmp_pkt->ptrs.ip_api.is_ip6())
((ip::IP6Hdr*)g_tmp_pkt->ptrs.ip_api.get_ip6h())->set_len((uint16_t)ip_size);
- return 0;
+ return true;
}
-static int PortscanAlertTcp(Packet* p, PS_PROTO* proto, int)
+static void PortscanAlertTcp(Packet* p, PS_PROTO* proto, int)
{
- int iCtr;
- unsigned int event_ref;
- int portsweep = 0;
+ assert(proto);
- if (!proto)
- return -1;
+ unsigned int event_ref;
+ bool portsweep = false;
switch (proto->alerts)
{
break;
case PS_ALERT_ONE_TO_ONE_DECOY:
- event_ref = GeneratePSSnortEvent(p,GID_PORT_SCAN, PSNG_TCP_DECOY_PORTSCAN);
+ event_ref = GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_TCP_DECOY_PORTSCAN);
break;
case PS_ALERT_PORTSWEEP:
- event_ref = GeneratePSSnortEvent(p,GID_PORT_SCAN, PSNG_TCP_PORTSWEEP);
- portsweep = 1;
-
+ event_ref = GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_TCP_PORTSWEEP);
+ portsweep = true;
break;
case PS_ALERT_DISTRIBUTED:
- event_ref = GeneratePSSnortEvent(p,GID_PORT_SCAN, PSNG_TCP_DISTRIBUTED_PORTSCAN);
+ event_ref = GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_TCP_DISTRIBUTED_PORTSCAN);
break;
case PS_ALERT_ONE_TO_ONE_FILTERED:
- event_ref = GeneratePSSnortEvent(p,GID_PORT_SCAN, PSNG_TCP_FILTERED_PORTSCAN);
+ event_ref = GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_TCP_FILTERED_PORTSCAN);
break;
case PS_ALERT_ONE_TO_ONE_DECOY_FILTERED:
- event_ref = GeneratePSSnortEvent(p,GID_PORT_SCAN, PSNG_TCP_FILTERED_DECOY_PORTSCAN);
+ event_ref = GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_TCP_FILTERED_DECOY_PORTSCAN);
break;
case PS_ALERT_PORTSWEEP_FILTERED:
- event_ref = GeneratePSSnortEvent(p,GID_PORT_SCAN, PSNG_TCP_PORTSWEEP_FILTERED);
- portsweep = 1;
+ event_ref = GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_TCP_PORTSWEEP_FILTERED);
+ portsweep = true;
break;
case PS_ALERT_DISTRIBUTED_FILTERED:
- event_ref = GeneratePSSnortEvent(p,GID_PORT_SCAN,
- PSNG_TCP_FILTERED_DISTRIBUTED_PORTSCAN);
+ event_ref = GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_TCP_FILTERED_DISTRIBUTED_PORTSCAN);
break;
default:
- return 0;
+ return;
}
- /*
- ** Set the current event reference information for any open ports.
- */
+ // Set the current event reference information for any open ports.
proto->event_ref = event_ref;
proto->event_time.tv_sec = p->pkth->ts.tv_sec;
proto->event_time.tv_usec = p->pkth->ts.tv_usec;
- /*
- ** Only log open ports for portsweeps after the alert has been
- ** generated.
- */
- if (proto->open_ports_cnt && !portsweep)
+ // Only log open ports for portsweeps after the alert has been generated.
+ if (proto->open_ports_cnt and !portsweep)
{
- for (iCtr = 0; iCtr < proto->open_ports_cnt; iCtr++)
+ for ( int iCtr = 0; iCtr < proto->open_ports_cnt; iCtr++ )
{
DAQ_PktHdr_t* pkth = (DAQ_PktHdr_t*)g_tmp_pkt->pkth;
PS_PKT ps_pkt;
memset(&ps_pkt, 0x00, sizeof(PS_PKT));
ps_pkt.pkt = (void*)p;
- if (MakePortscanPkt(&ps_pkt, proto, PS_PROTO_OPEN_PORT,
- (void*)&proto->open_ports[iCtr]))
- return -1;
+ if ( !MakePortscanPkt(&ps_pkt, proto, PS_PROTO_OPEN_PORT,
+ (void*)&proto->open_ports[iCtr]) )
+ return;
pkth->ts.tv_usec += 1;
- GenerateOpenPortEvent(g_tmp_pkt,GID_PORT_SCAN,PSNG_OPEN_PORT,
- 0,0,3, proto->event_ref, &proto->event_time,
- PSNG_OPEN_PORT_STR);
+ GenerateOpenPortEvent(g_tmp_pkt, GID_PORT_SCAN, PSNG_OPEN_PORT,
+ 0, 0, 3 , proto->event_ref, proto->event_time, PSNG_OPEN_PORT_STR);
}
}
-
- return 0;
}
-static int PortscanAlertUdp(Packet* p, PS_PROTO* proto, int)
+static void PortscanAlertUdp(Packet* p, PS_PROTO* proto, int)
{
- if (!proto)
- return -1;
+ assert(proto);
switch (proto->alerts)
{
break;
case PS_ALERT_ONE_TO_ONE_DECOY:
- GeneratePSSnortEvent(p,GID_PORT_SCAN,PSNG_UDP_DECOY_PORTSCAN);
+ GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_UDP_DECOY_PORTSCAN);
break;
case PS_ALERT_PORTSWEEP:
- GeneratePSSnortEvent(p,GID_PORT_SCAN,PSNG_UDP_PORTSWEEP);
+ GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_UDP_PORTSWEEP);
break;
case PS_ALERT_DISTRIBUTED:
- GeneratePSSnortEvent(p,GID_PORT_SCAN,PSNG_UDP_DISTRIBUTED_PORTSCAN);
+ GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_UDP_DISTRIBUTED_PORTSCAN);
break;
case PS_ALERT_ONE_TO_ONE_FILTERED:
- GeneratePSSnortEvent(p,GID_PORT_SCAN,PSNG_UDP_FILTERED_PORTSCAN);
+ GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_UDP_FILTERED_PORTSCAN);
break;
case PS_ALERT_ONE_TO_ONE_DECOY_FILTERED:
- GeneratePSSnortEvent(p,GID_PORT_SCAN,PSNG_UDP_FILTERED_DECOY_PORTSCAN);
+ GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_UDP_FILTERED_DECOY_PORTSCAN);
break;
case PS_ALERT_PORTSWEEP_FILTERED:
- GeneratePSSnortEvent(p,GID_PORT_SCAN,PSNG_UDP_PORTSWEEP_FILTERED);
+ GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_UDP_PORTSWEEP_FILTERED);
break;
case PS_ALERT_DISTRIBUTED_FILTERED:
- GeneratePSSnortEvent(p,GID_PORT_SCAN,
- PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN);
+ GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN);
break;
default:
break;
}
-
- return 0;
}
-static int PortscanAlertIp(Packet* p, PS_PROTO* proto, int)
+static void PortscanAlertIp(Packet* p, PS_PROTO* proto, int)
{
- if (!proto)
- return -1;
+ assert(proto);
switch (proto->alerts)
{
break;
case PS_ALERT_ONE_TO_ONE_DECOY:
- GeneratePSSnortEvent(p,GID_PORT_SCAN,PSNG_IP_DECOY_PORTSCAN);
+ GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_IP_DECOY_PORTSCAN);
break;
case PS_ALERT_PORTSWEEP:
- GeneratePSSnortEvent(p,GID_PORT_SCAN,PSNG_IP_PORTSWEEP);
+ GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_IP_PORTSWEEP);
break;
case PS_ALERT_DISTRIBUTED:
- GeneratePSSnortEvent(p,GID_PORT_SCAN,PSNG_IP_DISTRIBUTED_PORTSCAN);
+ GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_IP_DISTRIBUTED_PORTSCAN);
break;
case PS_ALERT_ONE_TO_ONE_FILTERED:
- GeneratePSSnortEvent(p,GID_PORT_SCAN,PSNG_IP_FILTERED_PORTSCAN);
+ GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_IP_FILTERED_PORTSCAN);
break;
case PS_ALERT_ONE_TO_ONE_DECOY_FILTERED:
- GeneratePSSnortEvent(p,GID_PORT_SCAN,PSNG_IP_FILTERED_DECOY_PORTSCAN);
+ GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_IP_FILTERED_DECOY_PORTSCAN);
break;
case PS_ALERT_PORTSWEEP_FILTERED:
- GeneratePSSnortEvent(p,GID_PORT_SCAN,PSNG_IP_PORTSWEEP_FILTERED);
+ GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_IP_PORTSWEEP_FILTERED);
break;
case PS_ALERT_DISTRIBUTED_FILTERED:
- GeneratePSSnortEvent(p,GID_PORT_SCAN, PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN);
+ GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN);
break;
default:
break;
}
-
- return 0;
}
-static int PortscanAlertIcmp(Packet* p, PS_PROTO* proto, int)
+static void PortscanAlertIcmp(Packet* p, PS_PROTO* proto, int)
{
- if (!proto)
- return -1;
+ assert(proto);
switch (proto->alerts)
{
case PS_ALERT_PORTSWEEP:
- GeneratePSSnortEvent(p,GID_PORT_SCAN,PSNG_ICMP_PORTSWEEP);
+ GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_ICMP_PORTSWEEP);
break;
case PS_ALERT_PORTSWEEP_FILTERED:
- GeneratePSSnortEvent(p,GID_PORT_SCAN,PSNG_ICMP_PORTSWEEP_FILTERED);
+ GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_ICMP_PORTSWEEP_FILTERED);
break;
default:
break;
}
-
- return 0;
}
-static int PortscanAlert(PS_PKT* ps_pkt, PS_PROTO* proto, int proto_type)
+static void PortscanAlert(PS_PKT* ps_pkt, PS_PROTO* proto, int proto_type)
{
- Packet* p;
-
- if (!ps_pkt || !ps_pkt->pkt)
- return -1;
-
- p = (Packet*)ps_pkt->pkt;
+ Packet* p = (Packet*)ps_pkt->pkt;
+ g_tmp_pkt = DetectionEngine::set_next_packet();
if (proto->alerts == PS_ALERT_OPEN_PORT)
{
- if (MakePortscanPkt(ps_pkt, proto, PS_PROTO_OPEN_PORT, (void*)&p->ptrs.sp))
- return -1;
+ if ( !MakePortscanPkt(ps_pkt, proto, PS_PROTO_OPEN_PORT, (void*)&p->ptrs.sp) )
+ return;
- GenerateOpenPortEvent(g_tmp_pkt,GID_PORT_SCAN,PSNG_OPEN_PORT,0,0,3,
- proto->event_ref, &proto->event_time, PSNG_OPEN_PORT_STR);
+ GenerateOpenPortEvent(g_tmp_pkt, GID_PORT_SCAN, PSNG_OPEN_PORT, 0, 0, 3,
+ proto->event_ref, proto->event_time, PSNG_OPEN_PORT_STR);
}
else
{
- if (MakePortscanPkt(ps_pkt, proto, proto_type, NULL))
- return -1;
+ if ( !MakePortscanPkt(ps_pkt, proto, proto_type, nullptr) )
+ return;
switch (proto_type)
{
}
sfthreshold_reset();
-
- return 0;
+ g_tmp_pkt = nullptr;
}
static void PrintIPPortSet(IP_PORT* p)
{
char ip_str[80], output_str[80];
- PORTRANGE* pr;
SnortSnprintf(ip_str, sizeof(ip_str), "%s", p->ip.get_addr()->ntoa());
else
SnortSnprintf(output_str, sizeof(output_str), " %s", ip_str);
- if (((p->ip.get_family() == AF_INET6) && (p->ip.get_bits() != 128)) ||
- ((p->ip.get_family() == AF_INET ) && (p->ip.get_bits() != 32 )))
+ if (((p->ip.get_family() == AF_INET6) and (p->ip.get_bits() != 128)) ||
+ ((p->ip.get_family() == AF_INET ) and (p->ip.get_bits() != 32 )))
SnortSnprintfAppend(output_str, sizeof(output_str), "/%d", p->ip.get_bits());
SF_LNODE* cursor;
- pr=(PORTRANGE*)sflist_first(&p->portset.port_list, &cursor);
+ PORTRANGE* pr =(PORTRANGE*)sflist_first(&p->portset.port_list, &cursor);
- if ( pr && pr->port_lo != 0 )
+ if ( pr and pr->port_lo != 0 )
SnortSnprintfAppend(output_str, sizeof(output_str), " : ");
for (; pr != 0;
{
char buf[STD_BUF + 1];
int proto_cnt = 0;
- IP_PORT* p;
LogMessage("Portscan Detection Config:\n");
- if (config->disabled)
- {
- LogMessage(" Portscan Detection: INACTIVE\n");
- }
memset(buf, 0, STD_BUF + 1);
- if (!config->disabled)
- {
- SnortSnprintf(buf, STD_BUF + 1, " Detect Protocols: ");
- if (config->detect_scans & PS_PROTO_TCP)
- {
- sfsnprintfappend(buf, STD_BUF, "TCP "); proto_cnt++;
- }
- if (config->detect_scans & PS_PROTO_UDP)
- {
- sfsnprintfappend(buf, STD_BUF, "UDP "); proto_cnt++;
- }
- if (config->detect_scans & PS_PROTO_ICMP)
- {
- sfsnprintfappend(buf, STD_BUF, "ICMP "); proto_cnt++;
- }
- if (config->detect_scans & PS_PROTO_IP)
- {
- sfsnprintfappend(buf, STD_BUF, "IP"); proto_cnt++;
- }
- LogMessage("%s\n", buf);
- }
- if (!config->disabled)
- {
- memset(buf, 0, STD_BUF + 1);
- SnortSnprintf(buf, STD_BUF + 1, " Detect Scan Type: ");
- if (config->detect_scan_type & PS_TYPE_PORTSCAN)
- sfsnprintfappend(buf, STD_BUF, "portscan ");
- if (config->detect_scan_type & PS_TYPE_PORTSWEEP)
- sfsnprintfappend(buf, STD_BUF, "portsweep ");
- if (config->detect_scan_type & PS_TYPE_DECOYSCAN)
- sfsnprintfappend(buf, STD_BUF, "decoy_portscan ");
- if (config->detect_scan_type & PS_TYPE_DISTPORTSCAN)
- sfsnprintfappend(buf, STD_BUF, "distributed_portscan");
- LogMessage("%s\n", buf);
- }
+ SnortSnprintf(buf, STD_BUF + 1, " Detect Protocols: ");
- if (!config->disabled)
- {
- memset(buf, 0, STD_BUF + 1);
- SnortSnprintf(buf, STD_BUF + 1, " Sensitivity Level: ");
- if (config->sense_level == PS_SENSE_HIGH)
- sfsnprintfappend(buf, STD_BUF, "High/Experimental");
- if (config->sense_level == PS_SENSE_MEDIUM)
- sfsnprintfappend(buf, STD_BUF, "Medium");
- if (config->sense_level == PS_SENSE_LOW)
- sfsnprintfappend(buf, STD_BUF, "Low");
- LogMessage("%s\n", buf);
- }
+ if ( config->detect_scans & PS_PROTO_TCP )
+ sfsnprintfappend(buf, STD_BUF, "TCP "); proto_cnt++;
- LogMessage(" Memcap (in bytes): %lu\n", config->common->memcap);
+ if ( config->detect_scans & PS_PROTO_UDP )
+ sfsnprintfappend(buf, STD_BUF, "UDP "); proto_cnt++;
- if (!config->disabled)
- {
- LogMessage(" Number of Nodes: %ld\n",
- config->common->memcap / (sizeof(PS_PROTO)*proto_cnt-1));
+ if ( config->detect_scans & PS_PROTO_ICMP )
+ sfsnprintfappend(buf, STD_BUF, "ICMP "); proto_cnt++;
- if ( config->logfile )
- LogMessage(" Logfile: %s\n", "yes");
+ if ( config->detect_scans & PS_PROTO_IP )
+ sfsnprintfappend(buf, STD_BUF, "IP"); proto_cnt++;
- if (config->ignore_scanners)
- {
- LogMessage(" Ignore Scanner IP List:\n");
- SF_LNODE* cursor;
+ LogMessage("%s\n", buf);
+ memset(buf, 0, STD_BUF + 1);
- for (p = (IP_PORT*)sflist_first(&config->ignore_scanners->ip_list, &cursor);
- p;
- p = (IP_PORT*)sflist_next(&cursor))
- {
- PrintIPPortSet(p);
- }
- }
+ SnortSnprintf(buf, STD_BUF + 1, " Detect Scan Type: ");
- if (config->ignore_scanned)
- {
- LogMessage(" Ignore Scanned IP List:\n");
- SF_LNODE* cursor;
+ if (config->detect_scan_type & PS_TYPE_PORTSCAN)
+ sfsnprintfappend(buf, STD_BUF, "portscan ");
- for (p = (IP_PORT*)sflist_first(&config->ignore_scanned->ip_list, &cursor);
- p;
- p = (IP_PORT*)sflist_next(&cursor))
- {
- PrintIPPortSet(p);
- }
- }
+ if (config->detect_scan_type & PS_TYPE_PORTSWEEP)
+ sfsnprintfappend(buf, STD_BUF, "portsweep ");
- if (config->watch_ip)
- {
- LogMessage(" Watch IP List:\n");
- SF_LNODE* cursor;
+ if (config->detect_scan_type & PS_TYPE_DECOYSCAN)
+ sfsnprintfappend(buf, STD_BUF, "decoy_portscan ");
- for (p = (IP_PORT*)sflist_first(&config->watch_ip->ip_list, &cursor);
- p;
- p = (IP_PORT*)sflist_next(&cursor))
- {
- PrintIPPortSet(p);
- }
- }
- }
-}
+ if (config->detect_scan_type & PS_TYPE_DISTPORTSCAN)
+ sfsnprintfappend(buf, STD_BUF, "distributed_portscan");
-#if 0
-static int PortscanGetProtoBits(int detect_scans)
-{
- unsigned proto_bits = PktType::IP;
+ LogMessage("%s\n", buf);
+ LogMessage(" Memcap (in bytes): %lu\n", config->common->memcap);
+
+ LogMessage(" Number of Nodes: %ld\n",
+ config->common->memcap / (sizeof(PS_PROTO)*proto_cnt-1));
+
+ if ( config->logfile )
+ LogMessage(" Logfile: %s\n", "yes");
- if (detect_scans & PS_PROTO_IP)
+ if (config->ignore_scanners)
{
- proto_bits |= PktType::ICMP;
+ LogMessage(" Ignore Scanner IP List:\n");
+ SF_LNODE* cursor;
+
+ IP_PORT* p = (IP_PORT*)sflist_first(&config->ignore_scanners->ip_list, &cursor);
+
+ for ( ; p; p = (IP_PORT*)sflist_next(&cursor) )
+ PrintIPPortSet(p);
}
- if (detect_scans & PS_PROTO_UDP)
+ if (config->ignore_scanned)
{
- proto_bits |= PktType::ICMP;
- proto_bits |= PktType::UDP;
- }
+ LogMessage(" Ignore Scanned IP List:\n");
+ SF_LNODE* cursor;
- if (detect_scans & PS_PROTO_ICMP)
- proto_bits |= PktType::ICMP;
+ IP_PORT* p = (IP_PORT*)sflist_first(&config->ignore_scanned->ip_list, &cursor);
- if (detect_scans & PS_PROTO_TCP)
- {
- proto_bits |= PktType::ICMP;
- proto_bits |= PktType::TCP;
+ for ( ; p; p = (IP_PORT*)sflist_next(&cursor) )
+ PrintIPPortSet(p);
}
- return proto_bits;
-}
+ if (config->watch_ip)
+ {
+ LogMessage(" Watch IP List:\n");
+ SF_LNODE* cursor;
-#endif
+ IP_PORT* p = (IP_PORT*)sflist_first(&config->watch_ip->ip_list, &cursor);
+
+ for ( ; p; p = (IP_PORT*)sflist_next(&cursor) )
+ PrintIPPortSet(p);
+ }
+}
//-------------------------------------------------------------------------
// class stuff
void PortScan::tinit()
{
- g_tmp_pkt = new Packet;
ps_init_hash(config->common->memcap);
if ( !config->logfile )
g_logfile = nullptr;
}
ps_cleanup();
- delete g_tmp_pkt;
- g_tmp_pkt = nullptr;
}
void PortScan::show(SnortConfig*)
void PortScan::eval(Packet* p)
{
Profile profile(psPerfStats);
-
assert(p->ptrs.ip_api.is_ip());
if ( p->packet_flags & PKT_REBUILT_STREAM )
++spstats.total_packets;
PS_PKT ps_pkt;
- memset(&ps_pkt, 0x00, sizeof(PS_PKT)); // FIXIT-P don't zap unless necessary
+ memset(&ps_pkt, 0x00, sizeof(PS_PKT));
ps_pkt.pkt = (void*)p;
- /* See if there is already an existing node in the hash table */
ps_detect(&ps_pkt);
- if (ps_pkt.scanner && ps_pkt.scanner->proto.alerts &&
+ if (ps_pkt.scanner and ps_pkt.scanner->proto.alerts and
(ps_pkt.scanner->proto.alerts != PS_ALERT_GENERATED))
{
PortscanAlert(&ps_pkt, &ps_pkt.scanner->proto, ps_pkt.proto);
}
- if (ps_pkt.scanned && ps_pkt.scanned->proto.alerts &&
+ if (ps_pkt.scanned and ps_pkt.scanned->proto.alerts and
(ps_pkt.scanned->proto.alerts != PS_ALERT_GENERATED))
{
PortscanAlert(&ps_pkt, &ps_pkt.scanned->proto, ps_pkt.proto);
#include "ps_inspect.h"
PADDING_GUARD_BEGIN
-typedef struct s_PS_HASH_KEY
+struct PS_HASH_KEY
{
int protocol;
SfIp scanner;
SfIp scanned;
-} PS_HASH_KEY;
+};
PADDING_GUARD_END
-typedef struct s_PS_ALERT_CONF
-{
- short connection_count;
- short priority_count;
- short u_ip_count;
- short u_port_count;
-} PS_ALERT_CONF;
-
-static THREAD_LOCAL SFXHASH* portscan_hash = NULL;
-
-/*
-** Scanning configurations. This is where we configure what the thresholds
-** are for the different types of scans, protocols, and sense levels. If
-** you want to tweak the sense levels, change the values here.
-*/
-/*
-** TCP alert configurations
-*/
-static const PS_ALERT_CONF g_tcp_low_ps = { 0,5,25,5 };
-static const PS_ALERT_CONF g_tcp_low_decoy_ps = { 0,15,50,30 };
-static const PS_ALERT_CONF g_tcp_low_sweep = { 0,5,5,15 };
-static const PS_ALERT_CONF g_tcp_low_dist_ps = { 0,15,50,15 };
-
-static const PS_ALERT_CONF g_tcp_med_ps = { 200,10,60,15 };
-static const PS_ALERT_CONF g_tcp_med_decoy_ps = { 200,30,120,60 };
-static const PS_ALERT_CONF g_tcp_med_sweep = { 30,7,7,10 };
-static const PS_ALERT_CONF g_tcp_med_dist_ps = { 200,30,120,30 };
-
-static const PS_ALERT_CONF g_tcp_hi_ps = { 200,5,100,10 };
-static const PS_ALERT_CONF g_tcp_hi_decoy_ps = { 200,7,200,60 };
-static const PS_ALERT_CONF g_tcp_hi_sweep = { 30,3,3,10 };
-static const PS_ALERT_CONF g_tcp_hi_dist_ps = { 200,5,200,10 };
-
-/*
-** UDP alert configurations
-*/
-static const PS_ALERT_CONF g_udp_low_ps = { 0,5,25,5 };
-static const PS_ALERT_CONF g_udp_low_decoy_ps = { 0,15,50,30 };
-static const PS_ALERT_CONF g_udp_low_sweep = { 0,5,5,15 };
-static const PS_ALERT_CONF g_udp_low_dist_ps = { 0,15,50,15 };
-
-static const PS_ALERT_CONF g_udp_med_ps = { 200,10,60,15 };
-static const PS_ALERT_CONF g_udp_med_decoy_ps = { 200,30,120,60 };
-static const PS_ALERT_CONF g_udp_med_sweep = { 30,5,5,20 };
-static const PS_ALERT_CONF g_udp_med_dist_ps = { 200,30,120,30 };
-
-static const PS_ALERT_CONF g_udp_hi_ps = { 200,3,100,10 };
-static const PS_ALERT_CONF g_udp_hi_decoy_ps = { 200,7,200,60 };
-static const PS_ALERT_CONF g_udp_hi_sweep = { 30,3,3,10 };
-static const PS_ALERT_CONF g_udp_hi_dist_ps = { 200,3,200,10 };
-
-/*
-** IP Protocol alert configurations
-*/
-static const PS_ALERT_CONF g_ip_low_ps = { 0,10,10,50 };
-static const PS_ALERT_CONF g_ip_low_decoy_ps = { 0,40,50,25 };
-static const PS_ALERT_CONF g_ip_low_sweep = { 0,10,10,10 };
-static const PS_ALERT_CONF g_ip_low_dist_ps = { 0,15,25,50 };
-
-static const PS_ALERT_CONF g_ip_med_ps = { 200,10,10,50 };
-static const PS_ALERT_CONF g_ip_med_decoy_ps = { 200,40,50,25 };
-static const PS_ALERT_CONF g_ip_med_sweep = { 30,10,10,10 };
-static const PS_ALERT_CONF g_ip_med_dist_ps = { 200,15,25,50 };
-
-static const PS_ALERT_CONF g_ip_hi_ps = { 200,3,3,10 };
-static const PS_ALERT_CONF g_ip_hi_decoy_ps = { 200,7,15,5 };
-static const PS_ALERT_CONF g_ip_hi_sweep = { 30,3,3,7 };
-static const PS_ALERT_CONF g_ip_hi_dist_ps = { 200,3,11,10 };
-
-/*
-** ICMP alert configurations
-*/
-static const PS_ALERT_CONF g_icmp_low_sweep = { 0,5,5,5 };
-static const PS_ALERT_CONF g_icmp_med_sweep = { 20,5,5,5 };
-static const PS_ALERT_CONF g_icmp_hi_sweep = { 10,3,3,5 };
+static THREAD_LOCAL SFXHASH* portscan_hash = nullptr;
PortscanConfig::PortscanConfig()
{
}
/*
-** NAME
-** ps_tracker_free::
-*/
-/**
** This function is passed into the hash algorithm, so that
** we only reuse nodes that aren't priority nodes. We have to make
** sure that we only track so many priority nodes, otherwise we could
*/
static int ps_tracker_free(void* key, void* data)
{
- PS_TRACKER* tracker;
-
if (!key || !data)
return 0;
- tracker = (PS_TRACKER*)data;
+ PS_TRACKER* tracker = (PS_TRACKER*)data;
+
if (!tracker->priority_node)
return 0;
void ps_cleanup()
{
- if (portscan_hash != NULL)
+ if ( portscan_hash )
{
sfxhash_delete(portscan_hash);
- portscan_hash = NULL;
+ portscan_hash = nullptr;
}
}
if ( portscan_hash )
return;
- int rows = 0;
- int factor = 0;
-#if SIZEOF_LONG_INT == 8
- factor = 125;
+#if SIZEOF_LONG_INT == 8 // FIXIT-L explain this
+ int factor = 125;
#else
- factor = 250;
+ int factor = 250;
#endif
- rows = memcap/factor;
+ int rows = memcap/factor;
portscan_hash = sfxhash_new(rows, sizeof(PS_HASH_KEY), sizeof(PS_TRACKER),
- memcap, 1, ps_tracker_free, NULL, 1);
+ memcap, 1, ps_tracker_free, nullptr, 1);
- if (portscan_hash == NULL)
+ if ( !portscan_hash )
FatalError("Failed to initialize portscan hash table.\n");
}
-/*
-** NAME
-** ps_reset::
-*/
-/**
-** Reset the portscan infrastructure.
-*/
void ps_reset()
{
- if (portscan_hash != NULL)
+ if ( portscan_hash )
sfxhash_make_empty(portscan_hash);
}
-/*
-** NAME
-** ps_ignore_ip::
-*/
-/**
-** Check scanner and scanned ips to see if we can filter them out.
-*/
-int PortScan::ps_ignore_ip(const SfIp* scanner, uint16_t scanner_port,
+// Check scanner and scanned ips to see if we can filter them out.
+bool PortScan::ps_ignore_ip(const SfIp* scanner, uint16_t scanner_port,
const SfIp* scanned, uint16_t scanned_port)
{
if (config->ignore_scanners)
{
if (ipset_contains(config->ignore_scanners, scanner, &scanner_port))
- return 1;
+ return true;
}
if (config->ignore_scanned)
{
if (ipset_contains(config->ignore_scanned, scanned, &scanned_port))
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/*
-** NAME
-** ps_filter_ignore::
-*/
-/**
** Check the incoming packet to decide whether portscan detection cares
** about this packet. We try to ignore as many packets as possible.
*/
-int PortScan::ps_filter_ignore(PS_PKT* ps_pkt)
+bool PortScan::ps_filter_ignore(PS_PKT* ps_pkt)
{
Packet* p;
int reverse_pkt = 0;
p = (Packet*)ps_pkt->pkt;
if(!p->ptrs.ip_api.is_ip())
- return 1;
+ return true;
if (p->ptrs.tcph)
{
- if (!(config->detect_scans & PS_PROTO_TCP))
- return 1;
+ if ( !(config->detect_scans & PS_PROTO_TCP) )
+ return true;
/*
** This is where we check all of snort's flags for different
if (((p->packet_flags & (PKT_STREAM_EST | PKT_STREAM_TWH))
== PKT_STREAM_EST) && !(p->ptrs.tcph->th_flags & TH_RST))
{
- return 1;
+ return true;
}
/*
!(p->packet_flags & (PKT_STREAM_EST)) &&
(p->is_from_server()))
{
- return 1;
+ return true;
}
*/
}
else if (p->ptrs.udph)
{
- if (!(config->detect_scans & PS_PROTO_UDP))
- return 1;
+ if ( !(config->detect_scans & PS_PROTO_UDP) )
+ return true;
}
else if (p->ptrs.icmph)
{
- if (p->ptrs.icmph->type != ICMP_DEST_UNREACH &&
- !(config->detect_scans & PS_PROTO_ICMP))
- {
- return 1;
- }
+ if ( p->ptrs.icmph->type != ICMP_DEST_UNREACH and !(config->detect_scans & PS_PROTO_ICMP) )
+ return true;
}
else
{
- if (!(config->detect_scans & PS_PROTO_IP))
- return 1;
+ if ( !(config->detect_scans & PS_PROTO_IP) )
+ return true;
}
- /*
- ** Check if the packet is reversed
- */
+ // Check if the packet is reversed
if ((p->is_from_server()))
{
reverse_pkt = 1;
if (reverse_pkt)
{
if (ps_ignore_ip(scanned, p->ptrs.dp, scanner, p->ptrs.sp))
- return 1;
+ return true;
}
else
{
if (ps_ignore_ip(scanner, p->ptrs.sp, scanned, p->ptrs.dp))
- return 1;
+ return true;
}
ps_pkt->reverse_pkt = reverse_pkt;
if (config->watch_ip)
{
if (ipset_contains(config->watch_ip, scanner, &(p->ptrs.sp)))
- return 0;
+ return false;
+
if (ipset_contains(config->watch_ip, scanned, &(p->ptrs.dp)))
- return 0;
+ return false;
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/*
-** NAME
-** ps_tracker_init::
-*/
-/**
-** Right now all we do is memset, but just in case we want to do more
-** initialization has been extracted.
+** Get a tracker node by either finding one or starting a new one. We may
+** return null, in which case we wait `til the next packet.
*/
-static int ps_tracker_init(PS_TRACKER* tracker)
+static PS_TRACKER* ps_tracker_get(PS_HASH_KEY* key)
{
- memset(tracker, 0x00, sizeof(PS_TRACKER));
+ PS_TRACKER* ht = (PS_TRACKER*)sfxhash_find(portscan_hash, (void*)key);
- return 0;
-}
+ if ( ht )
+ return ht;
-/*
-** NAME
-** ps_tracker_get::
-*/
-/**
-** Get a tracker node by either finding one or starting a new one. We may
-** return NULL, in which case we wait till the next packet.
-*/
-static int ps_tracker_get(PS_TRACKER** ht, PS_HASH_KEY* key)
-{
- int iRet;
+ if ( sfxhash_add(portscan_hash, (void*)key, nullptr) != SFXHASH_OK )
+ return nullptr;
- *ht = (PS_TRACKER*)sfxhash_find(portscan_hash, (void*)key);
- if (!(*ht))
- {
- iRet = sfxhash_add(portscan_hash, (void*)key, NULL);
- if (iRet == SFXHASH_OK)
- {
- *ht = (PS_TRACKER*)sfxhash_mru(portscan_hash);
- if (!(*ht))
- return -1;
+ ht = (PS_TRACKER*)sfxhash_mru(portscan_hash);
- ps_tracker_init(*ht);
- }
- else
- {
- return -1;
- }
- }
+ if ( ht )
+ memset(ht, 0x00, sizeof(PS_TRACKER));
- return 0;
+ return ht;
}
-int PortScan::ps_tracker_lookup(PS_PKT* ps_pkt, PS_TRACKER** scanner,
- PS_TRACKER** scanned)
+bool PortScan::ps_tracker_lookup(
+ PS_PKT* ps_pkt, PS_TRACKER** scanner, PS_TRACKER** scanned)
{
PS_HASH_KEY key;
- Packet* p;
-
- if (ps_pkt->pkt == NULL)
- return -1;
-
- p = (Packet*)ps_pkt->pkt;
+ Packet* p = (Packet*)ps_pkt->pkt;
if (ps_get_proto(ps_pkt, &key.protocol) == -1)
- return -1;
+ return false;
ps_pkt->proto = key.protocol;
else
key.scanned.set(*p->ptrs.ip_api.get_dst());
- /*
- ** Get the scanned tracker.
- */
- ps_tracker_get(scanned, &key);
+ *scanned = ps_tracker_get(&key);
}
- /*
- ** Let's lookup the host that is scanning.
- */
+ // Let's lookup the host that is scanning.
if (config->detect_scan_type & PS_TYPE_PORTSWEEP)
{
key.scanned.clear();
else
key.scanner.set(*p->ptrs.ip_api.get_src());
- /*
- ** Get the scanner tracker
- */
- ps_tracker_get(scanner, &key);
+ *scanner = ps_tracker_get(&key);
}
- if ((*scanner == NULL) && (*scanned == NULL))
- return -1;
-
- return 0;
+ return *scanner or *scanned;
}
/*
-** NAME
-** ps_get_proto_index::
-*/
-/**
** This logic finds the index to the proto array based on the
** portscan configuration. We need special logic because the
** index of the protocol changes based on the configuration.
p = (Packet*)ps_pkt->pkt;
*proto = 0;
- if (config->detect_scans & PS_PROTO_TCP)
+ if ( config->detect_scans & PS_PROTO_TCP )
{
- if ((p->ptrs.tcph != NULL)
- || ((p->ptrs.icmph != NULL) && (p->ptrs.icmph->type == ICMP_DEST_UNREACH)
+ if ((p->ptrs.tcph)
+ || ((p->ptrs.icmph) && (p->ptrs.icmph->type == ICMP_DEST_UNREACH)
&& ((p->ptrs.icmph->code == ICMP_PORT_UNREACH)
|| (p->ptrs.icmph->code == ICMP_PKT_FILTERED))
&& (p->proto_bits & PROTO_BIT__TCP_EMBED_ICMP)))
}
}
- if (config->detect_scans & PS_PROTO_UDP)
+ if ( config->detect_scans & PS_PROTO_UDP )
{
- if ((p->ptrs.udph != NULL)
- || ((p->ptrs.icmph != NULL) && (p->ptrs.icmph->type == ICMP_DEST_UNREACH)
+ if ((p->ptrs.udph)
+ || ((p->ptrs.icmph) && (p->ptrs.icmph->type == ICMP_DEST_UNREACH)
&& ((p->ptrs.icmph->code == ICMP_PORT_UNREACH)
|| (p->ptrs.icmph->code == ICMP_PKT_FILTERED))
&& (p->proto_bits & PROTO_BIT__UDP_EMBED_ICMP)))
}
}
- if (config->detect_scans & PS_PROTO_IP)
+ if ( config->detect_scans & PS_PROTO_IP )
{
- if ((p->ptrs.ip_api.is_ip() && (p->ptrs.icmph == NULL))
- || ((p->ptrs.icmph != NULL) && (p->ptrs.icmph->type == ICMP_DEST_UNREACH)
- && ((p->ptrs.icmph->code == ICMP_PROT_UNREACH)
- || (p->ptrs.icmph->code == ICMP_PKT_FILTERED))))
+ if ((p->ptrs.ip_api.is_ip() && (!p->ptrs.icmph))
+ || ((p->ptrs.icmph) && (p->ptrs.icmph->type == ICMP_DEST_UNREACH)
+ && ((p->ptrs.icmph->code == ICMP_PROT_UNREACH)
+ || (p->ptrs.icmph->code == ICMP_PKT_FILTERED))))
{
*proto = PS_PROTO_IP;
return 0;
}
}
- if (config->detect_scans & PS_PROTO_ICMP)
+ if ( config->detect_scans & PS_PROTO_ICMP )
{
- if (p->ptrs.icmph != NULL)
+ if (p->ptrs.icmph)
{
*proto = PS_PROTO_ICMP;
return 0;
return -1;
}
-/*
-** NAME
-** ps_proto_update_window::
-*/
-/**
-** Update the proto time windows based on the portscan sensitivity
-** level.
-*/
-int PortScan::ps_proto_update_window(PS_PROTO* proto, time_t pkt_time)
+void PortScan::ps_proto_update_window(unsigned interval, PS_PROTO* proto, time_t pkt_time)
{
- time_t interval;
-
- switch (config->sense_level)
- {
- case PS_SENSE_LOW:
- //interval = 15;
- interval = 60;
- break;
-
- case PS_SENSE_MEDIUM:
- //interval = 15;
- interval = 90;
- break;
-
- case PS_SENSE_HIGH:
- interval = 600;
- break;
-
- default:
- return -1;
- }
-
- /*
- ** If we are outside of the window, reset our ps counters.
- */
if (pkt_time > proto->window)
{
memset(proto, 0x00, sizeof(PS_PROTO));
proto->window = pkt_time + interval;
-
- return 0;
}
-
- return 0;
}
/*
-** NAME
-** ps_proto_update::
-*/
-/**
** This function updates the PS_PROTO structure.
**
** @param PS_PROTO pointer to structure to update
** @param u_short port/ip_proto to track
** @param time_t time the packet was received. update windows.
*/
-int PortScan::ps_proto_update(PS_PROTO* proto, int ps_cnt, int pri_cnt, const SfIp* ip,
- u_short port, time_t pkt_time)
+int PortScan::ps_proto_update(PS_PROTO* proto, int ps_cnt, int pri_cnt,
+ unsigned window, const SfIp* ip, u_short port, time_t pkt_time)
{
if (!proto)
return 0;
** Do time check first before we update the counters, so if
** we need to reset them we do it before we update them.
*/
- if (ps_proto_update_window(proto, pkt_time))
- return -1;
+ ps_proto_update_window(window, proto, pkt_time);
- /*
- ** Update ps counter
- */
+ // Update ps counter
proto->connection_count += ps_cnt;
if (proto->connection_count < 0)
proto->connection_count = 0;
}
/*
-** NAME
-** ps_tracker_update_tcp::
-*/
-/**
** Determine how to update the portscan counter depending on the type
** of TCP packet we have.
**
** - TCP 3-way handshake packets (we decrement the counter)
** - TCP reset packets on unestablished streams.
*/
-int PortScan::ps_tracker_update_tcp(PS_PKT* ps_pkt, PS_TRACKER* scanner,
+void PortScan::ps_tracker_update_tcp(PS_PKT* ps_pkt, PS_TRACKER* scanner,
PS_TRACKER* scanned)
{
- Packet* p;
+ Packet* p = (Packet*)ps_pkt->pkt;
uint32_t session_flags = 0x0;
+ unsigned win = config->tcp_window;
+
SfIp cleared;
cleared.clear();
- p = (Packet*)ps_pkt->pkt;
-
/*
** Handle the initiating packet.
**
{
if (scanned)
{
- ps_proto_update(&scanned->proto,1,0,
- p->ptrs.ip_api.get_src(),p->ptrs.dp, packet_time());
+ ps_proto_update(&scanned->proto, 1, 0, win,
+ p->ptrs.ip_api.get_src(), p->ptrs.dp, packet_time());
}
if (scanner)
{
- ps_proto_update(&scanner->proto,1,0,
- p->ptrs.ip_api.get_dst(),p->ptrs.dp, packet_time());
+ ps_proto_update(&scanner->proto, 1, 0, win,
+ p->ptrs.ip_api.get_dst(), p->ptrs.dp, packet_time());
}
}
- /*
- ** Handle the final packet of the three-way handshake.
- */
+ // Handle the final packet of the three-way handshake.
else if (p->packet_flags & PKT_STREAM_TWH)
{
if (scanned)
{
- ps_proto_update(&scanned->proto,-1,0,&cleared,0,0);
+ ps_proto_update(&scanned->proto, -1, 0, win, &cleared, 0, 0);
}
if (scanner)
{
- ps_proto_update(&scanner->proto,-1,0,&cleared,0,0);
+ ps_proto_update(&scanner->proto, -1, 0, win, &cleared, 0, 0);
}
}
- /*
- ** RST packet on unestablished streams
- */
+ // RST packet on unestablished streams
else if ((p->is_from_server()) &&
(p->ptrs.tcph && (p->ptrs.tcph->th_flags & TH_RST)) &&
(!(p->packet_flags & PKT_STREAM_EST) ||
{
if (scanned)
{
- ps_proto_update(&scanned->proto,0,1,&cleared,0,0);
+ ps_proto_update(&scanned->proto, 0, 1, win, &cleared, 0, 0);
scanned->priority_node = 1;
}
if (scanner)
{
- ps_proto_update(&scanner->proto,0,1,&cleared,0,0);
+ ps_proto_update(&scanner->proto, 0, 1, win, &cleared, 0, 0);
scanner->priority_node = 1;
}
}
*/
if (scanned)
{
- ps_proto_update(&scanned->proto,1,0,
- p->ptrs.ip_api.get_src(),p->ptrs.dp, packet_time());
+ ps_proto_update(&scanned->proto, 1, 0, win,
+ p->ptrs.ip_api.get_src(), p->ptrs.dp, packet_time());
}
if (scanner)
{
- ps_proto_update(&scanner->proto,1,0,
- p->ptrs.ip_api.get_dst(),p->ptrs.dp, packet_time());
+ ps_proto_update(&scanner->proto, 1, 0, win,
+ p->ptrs.ip_api.get_dst(), p->ptrs.dp, packet_time());
}
}
/*
{
if (scanned)
{
- ps_proto_update(&scanned->proto,-1,0,&cleared,0,0);
+ ps_proto_update(&scanned->proto, -1, 0, win, &cleared, 0, 0);
}
if (scanner)
{
- ps_proto_update(&scanner->proto,-1,0,&cleared,0,0);
+ ps_proto_update(&scanner->proto, -1, 0, win, &cleared, 0, 0);
}
}
/*
{
if (scanned)
{
- ps_proto_update(&scanned->proto,0,1,&cleared,0,0);
+ ps_proto_update(&scanned->proto, 0, 1, win, &cleared, 0, 0);
scanned->priority_node = 1;
}
if (scanner)
{
- ps_proto_update(&scanner->proto,0,1,&cleared,0,0);
+ ps_proto_update(&scanner->proto, 0, 1, win, &cleared, 0, 0);
scanner->priority_node = 1;
}
}
- /*
- ** If we are an icmp unreachable, deal with it here.
- */
+ // If we are an icmp unreachable, deal with it here.
else if (p->ptrs.icmph)
{
if (scanned)
{
- ps_proto_update(&scanned->proto,0,1,&cleared,0,0);
+ ps_proto_update(&scanned->proto, 0, 1, win, &cleared, 0, 0);
scanned->priority_node = 1;
}
if (scanner)
{
- ps_proto_update(&scanner->proto,0,1,&cleared,0,0);
+ ps_proto_update(&scanner->proto, 0, 1, win, &cleared, 0, 0);
scanner->priority_node = 1;
}
}
- return 0;
}
-int PortScan::ps_tracker_update_ip(PS_PKT* ps_pkt, PS_TRACKER* scanner,
+void PortScan::ps_tracker_update_ip(PS_PKT* ps_pkt, PS_TRACKER* scanner,
PS_TRACKER* scanned)
{
- Packet* p;
+ Packet* p = (Packet*)ps_pkt->pkt;
+
+ if ( !p->ptrs.ip_api.is_ip() )
+ return;
+
+ unsigned win = config->ip_window;
SfIp cleared;
cleared.clear();
- p = (Packet*)ps_pkt->pkt;
-
- if(p->ptrs.ip_api.is_ip())
+ if (scanned)
{
- if (p->ptrs.icmph)
- {
- if (scanned)
- {
- ps_proto_update(&scanned->proto,0,1,&cleared,0,0);
- scanned->priority_node = 1;
- }
-
- if (scanner)
- {
- ps_proto_update(&scanner->proto,0,1,&cleared,0,0);
- scanner->priority_node = 1;
- }
-
- return 0;
- }
+ ps_proto_update(&scanned->proto, 1, 0, win, &cleared, (u_short)p->get_ip_proto_next(), 0);
}
- return 0;
+ if (scanner)
+ {
+ ps_proto_update(&scanner->proto, 1, 0, win, &cleared, (u_short)p->get_ip_proto_next(), 0);
+ }
}
-int PortScan::ps_tracker_update_udp(PS_PKT* ps_pkt, PS_TRACKER* scanner,
+void PortScan::ps_tracker_update_udp(PS_PKT* ps_pkt, PS_TRACKER* scanner,
PS_TRACKER* scanned)
{
- Packet* p;
+ Packet* p = (Packet*)ps_pkt->pkt;
+ unsigned win = config->udp_window;
+
SfIp cleared;
cleared.clear();
- p = (Packet*)ps_pkt->pkt;
-
if (p->ptrs.icmph)
{
if (scanned)
{
- ps_proto_update(&scanned->proto,0,1,&cleared,0,0);
+ ps_proto_update(&scanned->proto, 0, 1, win, &cleared, 0, 0);
scanned->priority_node = 1;
}
if (scanner)
{
- ps_proto_update(&scanner->proto,0,1,&cleared,0,0);
+ ps_proto_update(&scanner->proto, 0, 1, win, &cleared, 0, 0);
scanner->priority_node = 1;
}
}
{
if (scanned)
{
- ps_proto_update(&scanned->proto,1,0,
- p->ptrs.ip_api.get_src(),p->ptrs.dp, packet_time());
+ ps_proto_update(&scanned->proto, 1, 0, win,
+ p->ptrs.ip_api.get_src(), p->ptrs.dp, packet_time());
}
if (scanner)
{
- ps_proto_update(&scanner->proto,1,0,
- p->ptrs.ip_api.get_dst(),p->ptrs.dp, packet_time());
+ ps_proto_update(&scanner->proto, 1, 0, win,
+ p->ptrs.ip_api.get_dst(), p->ptrs.dp, packet_time());
}
}
else if (direction == PKT_FROM_SERVER)
{
if (scanned)
- ps_proto_update(&scanned->proto,-1,0,&cleared,0,0);
+ ps_proto_update(&scanned->proto, -1, 0, win, &cleared, 0, 0);
if (scanner)
- ps_proto_update(&scanner->proto,-1,0,&cleared,0,0);
+ ps_proto_update(&scanner->proto, -1, 0, win, &cleared, 0, 0);
}
}
}
-
- return 0;
}
-int PortScan::ps_tracker_update_icmp(
+void PortScan::ps_tracker_update_icmp(
PS_PKT* ps_pkt, PS_TRACKER* scanner, PS_TRACKER*)
{
- Packet* p;
+ Packet* p = (Packet*)ps_pkt->pkt;
+ unsigned win = config->icmp_window;
+
SfIp cleared;
cleared.clear();
- p = (Packet*)ps_pkt->pkt;
-
if (p->ptrs.icmph)
{
switch (p->ptrs.icmph->type)
case ICMP_TIMESTAMP:
case ICMP_ADDRESS:
case ICMP_INFO_REQUEST:
-
- if (scanner)
- {
- ps_proto_update(&scanner->proto,1,0,
- p->ptrs.ip_api.get_dst(), 0, packet_time());
- }
-
+ ps_proto_update(&scanner->proto, 1, 0, win,
+ p->ptrs.ip_api.get_dst(), 0, packet_time());
break;
case ICMP_DEST_UNREACH:
-
- if (scanner)
- {
- ps_proto_update(&scanner->proto,0,1,&cleared,0,0);
- scanner->priority_node = 1;
- }
-
+ ps_proto_update(&scanner->proto, 0, 1, win, &cleared, 0, 0);
+ scanner->priority_node = 1;
break;
default:
break;
}
}
-
- return 0;
}
/*
-** NAME
-** ps_tracker_update::
-*/
-/**
** At this point, we should only be looking at transport protocols
** that we want to. For instance, if we aren't doing UDP portscans
** then we won't see UDP packets here because they were ignored.
** tracker values and prioritize a tracker. We also update the
** time windows.
*/
-int PortScan::ps_tracker_update(PS_PKT* ps_pkt, PS_TRACKER* scanner,
- PS_TRACKER* scanned)
+bool PortScan::ps_tracker_update(PS_PKT* ps_pkt, PS_TRACKER* scanner, PS_TRACKER* scanned)
{
- if (scanner && scanner->proto.alerts)
+ if ( scanner and scanner->proto.alerts )
scanner->proto.alerts = PS_ALERT_GENERATED;
- if (scanned && scanned->proto.alerts)
+ if ( scanned and scanned->proto.alerts )
scanned->proto.alerts = PS_ALERT_GENERATED;
- switch (ps_pkt->proto)
+ switch ( ps_pkt->proto )
{
case PS_PROTO_TCP:
- if (ps_tracker_update_tcp(ps_pkt, scanner, scanned))
- return -1;
-
+ ps_tracker_update_tcp(ps_pkt, scanner, scanned);
break;
case PS_PROTO_UDP:
- if (ps_tracker_update_udp(ps_pkt, scanner, scanned))
- return -1;
-
+ ps_tracker_update_udp(ps_pkt, scanner, scanned);
break;
case PS_PROTO_ICMP:
- if (ps_tracker_update_icmp(ps_pkt, scanner, scanned))
- return -1;
-
+ ps_tracker_update_icmp(ps_pkt, scanner, scanned);
break;
case PS_PROTO_IP:
- if (ps_tracker_update_ip(ps_pkt, scanner, scanned))
- return -1;
-
+ ps_tracker_update_ip(ps_pkt, scanner, scanned);
break;
default:
- return -1;
+ return false;
}
-
- return 0;
+ return true;
}
-static int ps_alert_one_to_one(PS_PROTO* scanner, PS_PROTO* scanned,
- const PS_ALERT_CONF* conf)
+static bool ps_alert_one_to_one(
+ const PS_ALERT_CONF& conf, PS_PROTO* scanner, PS_PROTO* scanned)
{
- if (!conf)
- return -1;
-
- /*
- ** Let's evaluate the scanned host.
- */
+ // Let's evaluate the scanned host.
if (scanned && !scanned->alerts)
{
- if (scanned->priority_count >= conf->priority_count)
+ if (scanned->priority_count >= conf.priority_count)
{
- if (scanned->u_ip_count < conf->u_ip_count &&
- scanned->u_port_count >= conf->u_port_count)
+ if (scanned->u_ip_count < conf.u_ip_count &&
+ scanned->u_port_count >= conf.u_port_count)
{
if (scanner)
{
- if (scanner->priority_count >= conf->priority_count)
+ if (scanner->priority_count >= conf.priority_count)
{
- /*
- ** Now let's check to make sure this is one
- ** to one
- */
+ // Now let's check to make sure this is one to one
scanned->alerts = PS_ALERT_ONE_TO_ONE;
- return 0;
+ return true;
}
}
else
{
- /*
- ** If there is no scanner, then we do the best we can.
- */
+ // If there is no scanner, then we do the best we can.
scanned->alerts = PS_ALERT_ONE_TO_ONE;
- return 0;
+ return true;
}
}
}
- if (scanned->connection_count >= conf->connection_count)
+ if (scanned->connection_count >= conf.connection_count)
{
- if (conf->connection_count == 0)
- return 0;
+ if (conf.connection_count == 0)
+ return false;
- if (scanned->u_ip_count < conf->u_ip_count &&
- scanned->u_port_count >= conf->u_port_count)
+ if (scanned->u_ip_count < conf.u_ip_count &&
+ scanned->u_port_count >= conf.u_port_count)
{
scanned->alerts = PS_ALERT_ONE_TO_ONE_FILTERED;
- return 0;
+ return true;
}
}
}
- return 0;
+ return false;
}
-static int ps_alert_one_to_one_decoy(
- PS_PROTO*, PS_PROTO* scanned, const PS_ALERT_CONF* conf)
+static bool ps_alert_one_to_one_decoy(
+ const PS_ALERT_CONF& conf, PS_PROTO*, PS_PROTO* scanned)
{
- if (!conf)
- return -1;
-
if (scanned && !scanned->alerts)
{
- if (scanned->priority_count >= conf->priority_count)
+ if (scanned->priority_count >= conf.priority_count)
{
- if (scanned->u_ip_count >= conf->u_ip_count &&
- scanned->u_port_count >= conf->u_port_count)
+ if (scanned->u_ip_count >= conf.u_ip_count &&
+ scanned->u_port_count >= conf.u_port_count)
{
scanned->alerts = PS_ALERT_ONE_TO_ONE_DECOY;
- return 0;
+ return true;
}
}
- if (scanned->connection_count >= conf->connection_count)
+ if (scanned->connection_count >= conf.connection_count)
{
- if (conf->connection_count == 0)
- return 0;
+ if (conf.connection_count == 0)
+ return false;
- if (scanned->u_ip_count >= conf->u_ip_count &&
- scanned->u_port_count >= conf->u_port_count)
+ if (scanned->u_ip_count >= conf.u_ip_count &&
+ scanned->u_port_count >= conf.u_port_count)
{
scanned->alerts = PS_ALERT_ONE_TO_ONE_DECOY_FILTERED;
- return 0;
+ return true;
}
}
}
- return 0;
+ return false;
}
-static int ps_alert_many_to_one(
- PS_PROTO*, PS_PROTO* scanned, const PS_ALERT_CONF* conf)
+static bool ps_alert_many_to_one(
+ const PS_ALERT_CONF& conf, PS_PROTO*, PS_PROTO* scanned)
{
- if (!conf)
- return -1;
-
if (scanned && !scanned->alerts)
{
- if (scanned->priority_count >= conf->priority_count)
+ if (scanned->priority_count >= conf.priority_count)
{
- if (scanned->u_ip_count <= conf->u_ip_count &&
- scanned->u_port_count >= conf->u_port_count)
+ if (scanned->u_ip_count <= conf.u_ip_count &&
+ scanned->u_port_count >= conf.u_port_count)
{
scanned->alerts = PS_ALERT_DISTRIBUTED;
- return 0;
+ return true;
}
}
- if (scanned->connection_count >= conf->connection_count)
+ if (scanned->connection_count >= conf.connection_count)
{
- if (conf->connection_count == 0)
- return 0;
+ if (conf.connection_count == 0)
+ return false;
- if (scanned->u_ip_count <= conf->u_ip_count &&
- scanned->u_port_count >= conf->u_port_count)
+ if (scanned->u_ip_count <= conf.u_ip_count &&
+ scanned->u_port_count >= conf.u_port_count)
{
scanned->alerts = PS_ALERT_DISTRIBUTED_FILTERED;
- return 0;
+ return true;
}
}
}
- return 0;
+ return false;
}
-static int ps_alert_one_to_many(
- PS_PROTO* scanner, PS_PROTO*, const PS_ALERT_CONF* conf)
+static bool ps_alert_one_to_many(
+ const PS_ALERT_CONF& conf, PS_PROTO* scanner, PS_PROTO*)
{
- if (!conf)
- return -1;
-
if (scanner && !scanner->alerts)
{
- if (scanner->priority_count >= conf->priority_count)
+ if (scanner->priority_count >= conf.priority_count)
{
- if (scanner->u_ip_count >= conf->u_ip_count &&
- scanner->u_port_count <= conf->u_port_count)
+ if (scanner->u_ip_count >= conf.u_ip_count &&
+ scanner->u_port_count <= conf.u_port_count)
{
scanner->alerts = PS_ALERT_PORTSWEEP;
- return 1;
+ return true;
}
}
- if (scanner->connection_count >= conf->connection_count)
+ if (scanner->connection_count >= conf.connection_count)
{
- if (conf->connection_count == 0)
- return 0;
+ if (conf.connection_count == 0)
+ return false;
- if (scanner->u_ip_count >= conf->u_ip_count &&
- scanner->u_port_count <= conf->u_port_count)
+ if (scanner->u_ip_count >= conf.u_ip_count &&
+ scanner->u_port_count <= conf.u_port_count)
{
scanner->alerts = PS_ALERT_PORTSWEEP_FILTERED;
- return 1;
+ return true;
}
}
}
- return 0;
+ return false;
}
-int PortScan::ps_alert_tcp(PS_PROTO* scanner, PS_PROTO* scanned)
+void PortScan::ps_alert_tcp(PS_PROTO* scanner, PS_PROTO* scanned)
{
- const PS_ALERT_CONF* one_to_one;
- const PS_ALERT_CONF* one_to_one_decoy;
- const PS_ALERT_CONF* one_to_many;
- const PS_ALERT_CONF* many_to_one;
-
- /*
- ** Set the configurations depending on the sensitivity
- ** level.
- */
- switch (config->sense_level)
- {
- case PS_SENSE_HIGH:
- one_to_one = &g_tcp_hi_ps;
- one_to_one_decoy = &g_tcp_hi_decoy_ps;
- one_to_many = &g_tcp_hi_sweep;
- many_to_one = &g_tcp_hi_dist_ps;
-
- break;
-
- case PS_SENSE_MEDIUM:
- one_to_one = &g_tcp_med_ps;
- one_to_one_decoy = &g_tcp_med_decoy_ps;
- one_to_many = &g_tcp_med_sweep;
- many_to_one = &g_tcp_med_dist_ps;
-
- break;
-
- case PS_SENSE_LOW:
- one_to_one = &g_tcp_low_ps;
- one_to_one_decoy = &g_tcp_low_decoy_ps;
- one_to_many = &g_tcp_low_sweep;
- many_to_one = &g_tcp_low_dist_ps;
-
- break;
-
- default:
- return -1;
- }
-
- /*
- ** Do detection on the different portscan types.
- */
if ((config->detect_scan_type & PS_TYPE_PORTSCAN) &&
- ps_alert_one_to_one(scanner, scanned, one_to_one))
+ ps_alert_one_to_one(config->tcp_ports, scanner, scanned))
{
- return 0;
+ return;
}
if ((config->detect_scan_type & PS_TYPE_DECOYSCAN) &&
- ps_alert_one_to_one_decoy(scanner, scanned, one_to_one_decoy))
+ ps_alert_one_to_one_decoy(config->tcp_decoy, scanner, scanned))
{
- return 0;
+ return;
}
if ((config->detect_scan_type & PS_TYPE_PORTSWEEP) &&
- ps_alert_one_to_many(scanner, scanned, one_to_many))
+ ps_alert_one_to_many(config->tcp_sweep, scanner, scanned))
{
- return 0;
+ return;
}
if ((config->detect_scan_type & PS_TYPE_DISTPORTSCAN) &&
- ps_alert_many_to_one(scanner, scanned, many_to_one))
+ ps_alert_many_to_one(config->tcp_dist, scanner, scanned))
{
- return 0;
+ return;
}
-
- return 0;
}
-int PortScan::ps_alert_ip(PS_PROTO* scanner, PS_PROTO* scanned)
+void PortScan::ps_alert_ip(PS_PROTO* scanner, PS_PROTO* scanned)
{
- const PS_ALERT_CONF* one_to_one;
- const PS_ALERT_CONF* one_to_one_decoy;
- const PS_ALERT_CONF* one_to_many;
- const PS_ALERT_CONF* many_to_one;
-
- /*
- ** Set the configurations depending on the sensitivity
- ** level.
- */
- switch (config->sense_level)
- {
- case PS_SENSE_HIGH:
- one_to_one = &g_ip_hi_ps;
- one_to_one_decoy = &g_ip_hi_decoy_ps;
- one_to_many = &g_ip_hi_sweep;
- many_to_one = &g_ip_hi_dist_ps;
-
- break;
-
- case PS_SENSE_MEDIUM:
- one_to_one = &g_ip_med_ps;
- one_to_one_decoy = &g_ip_med_decoy_ps;
- one_to_many = &g_ip_med_sweep;
- many_to_one = &g_ip_med_dist_ps;
-
- break;
-
- case PS_SENSE_LOW:
- one_to_one = &g_ip_low_ps;
- one_to_one_decoy = &g_ip_low_decoy_ps;
- one_to_many = &g_ip_low_sweep;
- many_to_one = &g_ip_low_dist_ps;
-
- break;
-
- default:
- return -1;
- }
-
- /*
- ** Do detection on the different portscan types.
- */
if ((config->detect_scan_type & PS_TYPE_PORTSCAN) &&
- ps_alert_one_to_one(scanner, scanned, one_to_one))
+ ps_alert_one_to_one(config->ip_proto, scanner, scanned))
{
- return 0;
+ return;
}
if ((config->detect_scan_type & PS_TYPE_DECOYSCAN) &&
- ps_alert_one_to_one_decoy(scanner, scanned, one_to_one_decoy))
+ ps_alert_one_to_one_decoy(config->ip_decoy, scanner, scanned))
{
- return 0;
+ return;
}
if ((config->detect_scan_type & PS_TYPE_PORTSWEEP) &&
- ps_alert_one_to_many(scanner, scanned, one_to_many))
+ ps_alert_one_to_many(config->ip_sweep, scanner, scanned))
{
- return 0;
+ return;
}
if ((config->detect_scan_type & PS_TYPE_DISTPORTSCAN) &&
- ps_alert_many_to_one(scanner, scanned, many_to_one))
+ ps_alert_many_to_one(config->ip_dist, scanner, scanned))
{
- return 0;
+ return;
}
- return 0;
+ return;
}
-int PortScan::ps_alert_udp(PS_PROTO* scanner, PS_PROTO* scanned)
+void PortScan::ps_alert_udp(PS_PROTO* scanner, PS_PROTO* scanned)
{
- const PS_ALERT_CONF* one_to_one;
- const PS_ALERT_CONF* one_to_one_decoy;
- const PS_ALERT_CONF* one_to_many;
- const PS_ALERT_CONF* many_to_one;
-
- /*
- ** Set the configurations depending on the sensitivity
- ** level.
- */
- switch (config->sense_level)
- {
- case PS_SENSE_HIGH:
- one_to_one = &g_udp_hi_ps;
- one_to_one_decoy = &g_udp_hi_decoy_ps;
- one_to_many = &g_udp_hi_sweep;
- many_to_one = &g_udp_hi_dist_ps;
-
- break;
-
- case PS_SENSE_MEDIUM:
- one_to_one = &g_udp_med_ps;
- one_to_one_decoy = &g_udp_med_decoy_ps;
- one_to_many = &g_udp_med_sweep;
- many_to_one = &g_udp_med_dist_ps;
-
- break;
-
- case PS_SENSE_LOW:
- one_to_one = &g_udp_low_ps;
- one_to_one_decoy = &g_udp_low_decoy_ps;
- one_to_many = &g_udp_low_sweep;
- many_to_one = &g_udp_low_dist_ps;
-
- break;
-
- default:
- return -1;
- }
-
- /*
- ** Do detection on the different portscan types.
- */
if ((config->detect_scan_type & PS_TYPE_PORTSCAN) &&
- ps_alert_one_to_one(scanner, scanned, one_to_one))
+ ps_alert_one_to_one(config->udp_ports, scanner, scanned))
{
- return 0;
+ return;
}
if ((config->detect_scan_type & PS_TYPE_DECOYSCAN) &&
- ps_alert_one_to_one_decoy(scanner, scanned, one_to_one_decoy))
+ ps_alert_one_to_one_decoy(config->udp_decoy, scanner, scanned))
{
- return 0;
+ return;
}
if ((config->detect_scan_type & PS_TYPE_PORTSWEEP) &&
- ps_alert_one_to_many(scanner, scanned, one_to_many))
+ ps_alert_one_to_many(config->udp_sweep, scanner, scanned))
{
- return 0;
+ return;
}
if ((config->detect_scan_type & PS_TYPE_DISTPORTSCAN) &&
- ps_alert_many_to_one(scanner, scanned, many_to_one))
+ ps_alert_many_to_one(config->udp_dist, scanner, scanned))
{
- return 0;
+ return;
}
-
- return 0;
}
-int PortScan::ps_alert_icmp(PS_PROTO* scanner, PS_PROTO* scanned)
+void PortScan::ps_alert_icmp(PS_PROTO* scanner, PS_PROTO* scanned)
{
- const PS_ALERT_CONF* one_to_many;
-
- /*
- ** Set the configurations depending on the sensitivity
- ** level.
- */
- switch (config->sense_level)
- {
- case PS_SENSE_HIGH:
- one_to_many = &g_icmp_hi_sweep;
-
- break;
-
- case PS_SENSE_MEDIUM:
- one_to_many = &g_icmp_med_sweep;
-
- break;
-
- case PS_SENSE_LOW:
- one_to_many = &g_icmp_low_sweep;
-
- break;
-
- default:
- return -1;
- }
-
- /*
- ** Do detection on the different portscan types.
- */
if ((config->detect_scan_type & PS_TYPE_PORTSWEEP) &&
- ps_alert_one_to_many(scanner, scanned, one_to_many))
+ ps_alert_one_to_many(config->icmp_sweep, scanner, scanned))
{
- return 0;
+ return;
}
-
- return 0;
}
/*
-** NAME
-** ps_tracker_alert::
-*/
-/**
** This function evaluates the scanner and scanned trackers and if
** applicable, generate an alert or alerts for either of the trackers.
**
** - Distributed Portscan (Many to One)
** - Filtered Portscan?
*/
-int PortScan::ps_tracker_alert(PS_PKT* ps_pkt, PS_TRACKER* scanner,
- PS_TRACKER* scanned)
+bool PortScan::ps_tracker_alert(
+ PS_PKT* ps_pkt, PS_TRACKER* scanner, PS_TRACKER* scanned)
{
- if (!ps_pkt)
- return -1;
+ PS_PROTO* scanner_proto = nullptr;
+ PS_PROTO* scanned_proto = nullptr;
+
+ if ( scanner )
+ {
+ scanner->proto.alerts = 0;
+ scanner_proto = &scanner->proto;
+ }
+
+ if ( scanned )
+ {
+ scanned->proto.alerts = 0;
+ scanned_proto = &scanned->proto;
+ }
switch (ps_pkt->proto)
{
case PS_PROTO_TCP:
- ps_alert_tcp((scanner ? &scanner->proto : NULL),
- (scanned ? &scanned->proto : NULL));
+ ps_alert_tcp(scanner_proto, scanned_proto);
break;
case PS_PROTO_UDP:
- ps_alert_udp((scanner ? &scanner->proto : NULL),
- (scanned ? &scanned->proto : NULL));
+ ps_alert_udp(scanner_proto, scanned_proto);
break;
case PS_PROTO_ICMP:
- ps_alert_icmp((scanner ? &scanner->proto : NULL),
- (scanned ? &scanned->proto : NULL));
+ ps_alert_icmp(scanner_proto, scanned_proto);
break;
case PS_PROTO_IP:
- ps_alert_ip((scanner ? &scanner->proto : NULL),
- (scanned ? &scanned->proto : NULL));
+ ps_alert_ip(scanner_proto, scanned_proto);
break;
default:
- return -1;
+ return false;
}
- return 0;
+ return true;
}
/*
-** NAME
-** ps_detect::
-*/
-/**
** The design of portscan is as follows:
**
** - Filter Packet. Is the packet part of the ignore or watch list? Is
*/
int PortScan::ps_detect(PS_PKT* ps_pkt)
{
- PS_TRACKER* scanner = NULL;
- PS_TRACKER* scanned = NULL;
+ PS_TRACKER* scanner = nullptr;
+ PS_TRACKER* scanned = nullptr;
int check_tcp_rst_other_dir = 1;
Packet* p;
do
{
- if (ps_tracker_lookup(ps_pkt, &scanner, &scanned))
+ if ( !ps_tracker_lookup(ps_pkt, &scanner, &scanned) )
return 0;
- if (ps_tracker_update(ps_pkt, scanner, scanned))
+ if ( !ps_tracker_update(ps_pkt, scanner, scanned) )
return 0;
- if (ps_tracker_alert(ps_pkt, scanner, scanned))
+ if ( !ps_tracker_alert(ps_pkt, scanner, scanned) )
return 0;
/* This is added to address the case of no
if ( p->ptrs.tcph && (p->ptrs.tcph->th_flags & TH_RST) && !p->flow )
{
if (ps_pkt->reverse_pkt == 1)
- {
check_tcp_rst_other_dir = 0;
- }
else
- {
ps_pkt->reverse_pkt = 1;
- }
}
else
{
}
while (check_tcp_rst_other_dir);
- //printf("** alert\n");
ps_pkt->scanner = scanner;
ps_pkt->scanned = scanned;
PsCommon() { memcap = 0; }
};
+struct PS_ALERT_CONF
+{
+ short connection_count;
+ short priority_count;
+ short u_ip_count;
+ short u_port_count;
+};
+
struct PortscanConfig
{
- int disabled;
int detect_scans;
int detect_scan_type;
- int sense_level;
int proto_cnt;
int include_midstream;
int print_tracker;
+
bool logfile;
+ unsigned tcp_window;
+ unsigned udp_window;
+ unsigned ip_window;
+ unsigned icmp_window;
+
IPSET* ignore_scanners;
IPSET* ignore_scanned;
IPSET* watch_ip;
PsCommon* common;
+ PS_ALERT_CONF tcp_ports;
+ PS_ALERT_CONF tcp_decoy;
+ PS_ALERT_CONF tcp_sweep;
+ PS_ALERT_CONF tcp_dist;
+
+ PS_ALERT_CONF udp_ports;
+ PS_ALERT_CONF udp_decoy;
+ PS_ALERT_CONF udp_sweep;
+ PS_ALERT_CONF udp_dist;
+
+ PS_ALERT_CONF ip_proto;
+ PS_ALERT_CONF ip_decoy;
+ PS_ALERT_CONF ip_sweep;
+ PS_ALERT_CONF ip_dist;
+
+ PS_ALERT_CONF icmp_sweep;
+
PortscanConfig();
~PortscanConfig();
};
struct PS_PKT
{
void* pkt;
- int proto;
- int reverse_pkt;
+
PS_TRACKER* scanner;
PS_TRACKER* scanned;
+
+ int proto;
+ int reverse_pkt;
};
//-------------------------------------------------------------------------
#define PS_ALERT_GENERATED 255
-//-------------------------------------------------------------------------
-// gid - sids
-//-------------------------------------------------------------------------
-
-#define GID_PORT_SCAN 122
-
-#define PSNG_TCP_PORTSCAN 1
-#define PSNG_TCP_DECOY_PORTSCAN 2
-#define PSNG_TCP_PORTSWEEP 3
-#define PSNG_TCP_DISTRIBUTED_PORTSCAN 4
-#define PSNG_TCP_FILTERED_PORTSCAN 5
-#define PSNG_TCP_FILTERED_DECOY_PORTSCAN 6
-#define PSNG_TCP_PORTSWEEP_FILTERED 7
-#define PSNG_TCP_FILTERED_DISTRIBUTED_PORTSCAN 8
-
-#define PSNG_IP_PORTSCAN 9
-#define PSNG_IP_DECOY_PORTSCAN 10
-#define PSNG_IP_PORTSWEEP 11
-#define PSNG_IP_DISTRIBUTED_PORTSCAN 12
-#define PSNG_IP_FILTERED_PORTSCAN 13
-#define PSNG_IP_FILTERED_DECOY_PORTSCAN 14
-#define PSNG_IP_PORTSWEEP_FILTERED 15
-#define PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN 16
-
-#define PSNG_UDP_PORTSCAN 17
-#define PSNG_UDP_DECOY_PORTSCAN 18
-#define PSNG_UDP_PORTSWEEP 19
-#define PSNG_UDP_DISTRIBUTED_PORTSCAN 20
-#define PSNG_UDP_FILTERED_PORTSCAN 21
-#define PSNG_UDP_FILTERED_DECOY_PORTSCAN 22
-#define PSNG_UDP_PORTSWEEP_FILTERED 23
-#define PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN 24
-
-#define PSNG_ICMP_PORTSWEEP 25
-#define PSNG_ICMP_PORTSWEEP_FILTERED 26
-
-#define PSNG_OPEN_PORT 27
-
-//-------------------------------------------------------------------------
-// rule msgs
-//-------------------------------------------------------------------------
-
-#define PSNG_TCP_PORTSCAN_STR \
- "TCP portscan"
-#define PSNG_TCP_DECOY_PORTSCAN_STR \
- "TCP decoy portscan"
-#define PSNG_TCP_PORTSWEEP_STR \
- "TCP portsweep"
-#define PSNG_TCP_DISTRIBUTED_PORTSCAN_STR \
- "TCP distributed portscan"
-#define PSNG_TCP_FILTERED_PORTSCAN_STR \
- "TCP filtered portscan"
-#define PSNG_TCP_FILTERED_DECOY_PORTSCAN_STR \
- "TCP filtered decoy portscan"
-#define PSNG_TCP_FILTERED_DISTRIBUTED_PORTSCAN_STR \
- "TCP filtered distributed portscan"
-#define PSNG_TCP_PORTSWEEP_FILTERED_STR \
- "TCP filtered portsweep"
-
-#define PSNG_IP_PORTSCAN_STR \
- "IP protocol scan"
-#define PSNG_IP_DECOY_PORTSCAN_STR \
- "IP decoy protocol scan"
-#define PSNG_IP_PORTSWEEP_STR \
- "IP protocol sweep"
-#define PSNG_IP_DISTRIBUTED_PORTSCAN_STR \
- "IP distributed protocol scan"
-#define PSNG_IP_FILTERED_PORTSCAN_STR \
- "IP filtered protocol scan"
-#define PSNG_IP_FILTERED_DECOY_PORTSCAN_STR \
- "IP filtered decoy protocol scan"
-#define PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN_STR \
- "IP filtered distributed protocol scan"
-#define PSNG_IP_PORTSWEEP_FILTERED_STR \
- "IP filtered protocol sweep"
-
-#define PSNG_UDP_PORTSCAN_STR \
- "UDP portscan"
-#define PSNG_UDP_DECOY_PORTSCAN_STR \
- "UDP decoy portscan"
-#define PSNG_UDP_PORTSWEEP_STR \
- "UDP portsweep"
-#define PSNG_UDP_DISTRIBUTED_PORTSCAN_STR \
- "UDP distributed portscan"
-#define PSNG_UDP_FILTERED_PORTSCAN_STR \
- "UDP filtered portscan"
-#define PSNG_UDP_FILTERED_DECOY_PORTSCAN_STR \
- "UDP filtered decoy portscan"
-#define PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN_STR \
- "UDP filtered distributed portscan"
-#define PSNG_UDP_PORTSWEEP_FILTERED_STR \
- "UDP filtered portsweep"
-
-#define PSNG_ICMP_PORTSWEEP_STR \
- "ICMP sweep"
-#define PSNG_ICMP_PORTSWEEP_FILTERED_STR \
- "ICMP filtered sweep"
-
-#define PSNG_OPEN_PORT_STR \
- "open port"
-
#endif
private:
void ps_parse(SnortConfig*, char*);
- int ps_ignore_ip(
+ bool ps_ignore_ip(
const SfIp* scanner, uint16_t scanner_port,
const SfIp* scanned, uint16_t scanned_port);
- int ps_filter_ignore(PS_PKT* ps_pkt);
- int ps_tracker_lookup(
+ bool ps_tracker_lookup(
PS_PKT* ps_pkt, PS_TRACKER** scanner, PS_TRACKER** scanned);
- int ps_get_proto(PS_PKT* ps_pkt, int* proto);
- int ps_proto_update_window(PS_PROTO* proto, time_t pkt_time);
+ bool ps_filter_ignore(PS_PKT* ps_pkt);
- int ps_proto_update(
- PS_PROTO* proto, int ps_cnt, int pri_cnt, const SfIp* ip,
- u_short port, time_t pkt_time);
-
- int ps_tracker_update(
+ bool ps_tracker_update(
PS_PKT* ps_pkt, PS_TRACKER* scanner, PS_TRACKER* scanned);
- int ps_tracker_update_ip(
+ bool ps_tracker_alert(
PS_PKT* ps_pkt, PS_TRACKER* scanner, PS_TRACKER* scanned);
- int ps_tracker_update_tcp(
+ int ps_get_proto(PS_PKT* ps_pkt, int* proto);
+
+ void ps_proto_update_window(unsigned window, PS_PROTO* proto, time_t pkt_time);
+
+ int ps_proto_update(
+ PS_PROTO* proto, int ps_cnt, int pri_cnt, unsigned window, const SfIp* ip,
+ u_short port, time_t pkt_time);
+
+ void ps_tracker_update_ip(
PS_PKT* ps_pkt, PS_TRACKER* scanner, PS_TRACKER* scanned);
- int ps_tracker_update_udp(
+ void ps_tracker_update_tcp(
PS_PKT* ps_pkt, PS_TRACKER* scanner, PS_TRACKER* scanned);
- int ps_tracker_update_icmp(
+ void ps_tracker_update_udp(
PS_PKT* ps_pkt, PS_TRACKER* scanner, PS_TRACKER* scanned);
- int ps_tracker_alert(
+ void ps_tracker_update_icmp(
PS_PKT* ps_pkt, PS_TRACKER* scanner, PS_TRACKER* scanned);
- int ps_alert_tcp(PS_PROTO* scanner, PS_PROTO* scanned);
- int ps_alert_ip(PS_PROTO* scanner, PS_PROTO* scanned);
- int ps_alert_udp(PS_PROTO* scanner, PS_PROTO* scanned);
- int ps_alert_icmp(PS_PROTO* scanner, PS_PROTO* scanned);
+ void ps_alert_tcp(PS_PROTO* scanner, PS_PROTO* scanned);
+ void ps_alert_ip(PS_PROTO* scanner, PS_PROTO* scanned);
+ void ps_alert_udp(PS_PROTO* scanner, PS_PROTO* scanned);
+ void ps_alert_icmp(PS_PROTO* scanner, PS_PROTO* scanned);
int ps_detect(PS_PKT* ps_pkt);
#include <cassert>
//-------------------------------------------------------------------------
-// port_scan tables
+// port_scan params
//-------------------------------------------------------------------------
// order of protos and scans must match PS_* flags
#define protos \
"tcp | udp | icmp | ip | all"
-#define scans \
+#define scan_types \
"portscan | portsweep | decoy_portscan | distributed_portscan | all"
+static const Parameter scan_params[] =
+{
+ { "scans", Parameter::PT_INT, "0:", "100",
+ "scan attempts" },
+
+ { "rejects", Parameter::PT_INT, "0:", "15",
+ "scan attempts with negative response" },
+
+ { "nets", Parameter::PT_INT, "0:", "25",
+ "number of times address changed from prior attempt" },
+
+ { "ports", Parameter::PT_INT, "0:", "25",
+ "number of times port (or proto) changed from prior attempt" },
+
+ { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
static const Parameter ps_params[] =
{
{ "protos", Parameter::PT_MULTI, protos, "all",
"choose the protocols to monitor" },
- { "scan_types", Parameter::PT_MULTI, scans, "all",
+ { "scan_types", Parameter::PT_MULTI, scan_types, "all",
"choose type of scans to look for" },
- { "sense_level", Parameter::PT_ENUM, "low | medium | high", "medium",
- "choose the level of detection" },
-
{ "watch_ip", Parameter::PT_STRING, nullptr, nullptr,
"list of CIDRs with optional ports to watch" },
{ "logfile", Parameter::PT_BOOL, nullptr, "false",
"write scan events to file" },
+ { "tcp_ports", Parameter::PT_TABLE, scan_params, nullptr,
+ "tcp port scan configuration (one-to-one)" },
+
+ { "tcp_decoy", Parameter::PT_TABLE, scan_params, nullptr,
+ "tcp decoy scan configuration (one-to-one decoy)" },
+
+ { "tcp_sweep", Parameter::PT_TABLE, scan_params, nullptr,
+ "tcp sweep scan configuration (one-to-many)" },
+
+ { "tcp_dist", Parameter::PT_TABLE, scan_params, nullptr,
+ "tcp distributed scan configuration (many-to-one)" },
+
+ { "udp_ports", Parameter::PT_TABLE, scan_params, nullptr,
+ "udp port scan configuration (one-to-one)" },
+
+ { "udp_decoy", Parameter::PT_TABLE, scan_params, nullptr,
+ "udp decoy scan configuration (one-to-one)" },
+
+ { "udp_sweep", Parameter::PT_TABLE, scan_params, nullptr,
+ "udp sweep scan configuration (one-to-many)" },
+
+ { "udp_dist", Parameter::PT_TABLE, scan_params, nullptr,
+ "udp distributed scan configuration (many-to-one)" },
+
+ { "ip_proto", Parameter::PT_TABLE, scan_params, nullptr,
+ "ip protocol scan configuration (one-to-one)" },
+
+ { "ip_decoy", Parameter::PT_TABLE, scan_params, nullptr,
+ "ip decoy scan configuration (one-to-one decoy)" },
+
+ { "ip_sweep", Parameter::PT_TABLE, scan_params, nullptr,
+ "ip sweep scan configuration (one-to-many)" },
+
+ { "ip_dist", Parameter::PT_TABLE, scan_params, nullptr,
+ "ip distributed scan configuration (many-to-one)" },
+
+ { "icmp_sweep", Parameter::PT_TABLE, scan_params, nullptr,
+ "icmp sweep scan configuration (one-to-many)" },
+
+ { "tcp_window", Parameter::PT_INT, "0:", "0",
+ "detection interval for all tcp scans" },
+
+ { "udp_window", Parameter::PT_INT, "0:", "0",
+ "detection interval for all udp scans" },
+
+ { "ip_window", Parameter::PT_INT, "0:", "0",
+ "detection interval for all ip scans" },
+
+ { "icmp_window", Parameter::PT_INT, "0:", "0",
+ "detection interval for all icmp scans" },
+
{ nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
};
+//-------------------------------------------------------------------------
+// port_scan rules
+//-------------------------------------------------------------------------
+
static const RuleMap port_scan_rules[] =
{
{ PSNG_TCP_PORTSCAN, PSNG_TCP_PORTSCAN_STR },
// [ [ and ] ].
// consult RFC 5952 for ideas.
//-------------------------------------------------------------------------
-bool PortScanModule::set(const char*, Value& v, SnortConfig*)
+bool PortScanModule::set(const char* fqn, Value& v, SnortConfig*)
{
if ( v.is("protos") )
{
u = PS_TYPE_ALL;
config->detect_scan_type = u;
}
- else if ( v.is("sense_level") )
- config->sense_level = v.get_long() + 1;
-
else if ( v.is("include_midstream") )
config->include_midstream = v.get_bool();
else if ( v.is("logfile") )
config->logfile = v.get_bool();
+ else if ( v.is("scans") )
+ {
+ if ( auto p = get_alert_conf(fqn) )
+ p->connection_count = v.get_long();
+ else
+ return false;
+ }
+ else if ( v.is("rejects") )
+ {
+ if ( auto p = get_alert_conf(fqn) )
+ p->priority_count = v.get_long();
+ else
+ return false;
+ }
+ else if ( v.is("nets") )
+ {
+ if ( auto p = get_alert_conf(fqn) )
+ p->u_ip_count = v.get_long();
+ else
+ return false;
+ }
+ else if ( v.is("ports") )
+ {
+ if ( auto p = get_alert_conf(fqn) )
+ p->u_port_count = v.get_long();
+ else
+ return false;
+ }
+ else if ( v.is("tcp_window") )
+ config->tcp_window = v.get_long();
+
+ else if ( v.is("udp_window") )
+ config->udp_window = v.get_long();
+
+ else if ( v.is("ip_window") )
+ config->ip_window = v.get_long();
+
+ else if ( v.is("icmp_window") )
+ config->icmp_window = v.get_long();
+
else
return false;
return true;
}
-bool PortScanModule::begin(const char*, int, SnortConfig*)
+bool PortScanModule::begin(const char* fqn, int, SnortConfig*)
{
- assert(!config);
- config = new PortscanConfig;
+ if ( !config )
+ config = new PortscanConfig;
+
+ else if ( strcmp(fqn, "port_scan") )
+ return false;
+
return true;
}
+PS_ALERT_CONF* PortScanModule::get_alert_conf(const char* fqn)
+{
+ if ( !strncmp(fqn, "port_scan.tcp_ports", 19) )
+ return &config->tcp_ports;
+
+ else if ( !strncmp(fqn, "port_scan.tcp_decoy", 19) )
+ return &config->tcp_decoy;
+
+ else if ( !strncmp(fqn, "port_scan.tcp_sweep", 19) )
+ return &config->tcp_sweep;
+
+ else if ( !strncmp(fqn, "port_scan.tcp_dist", 18) )
+ return &config->tcp_dist;
+
+ else if ( !strncmp(fqn, "port_scan.udp_ports", 19) )
+ return &config->udp_ports;
+
+ else if ( !strncmp(fqn, "port_scan.udp_decoy", 19) )
+ return &config->udp_decoy;
+
+ else if ( !strncmp(fqn, "port_scan.udp_sweep", 19) )
+ return &config->udp_sweep;
+
+ else if ( !strncmp(fqn, "port_scan.udp_dist", 18) )
+ return &config->udp_dist;
+
+ else if ( !strncmp(fqn, "port_scan.ip_proto", 18) )
+ return &config->ip_proto;
+
+ else if ( !strncmp(fqn, "port_scan.ip_decoy", 18) )
+ return &config->ip_decoy;
+
+ else if ( !strncmp(fqn, "port_scan.ip_sweep", 18) )
+ return &config->ip_sweep;
+
+ else if ( !strncmp(fqn, "port_scan.ip_dist", 17) )
+ return &config->ip_dist;
+
+ else if ( !strncmp(fqn, "port_scan.icmp_sweep", 20) )
+ return &config->icmp_sweep;
+
+ return nullptr;
+}
+
PortscanConfig* PortScanModule::get_data()
{
PortscanConfig* tmp = config;
#define PSG_NAME "port_scan_global"
#define PSG_HELP "shared settings for port_scan inspectors for use with port_scan"
+//-------------------------------------------------------------------------
+// gid - sids
+//-------------------------------------------------------------------------
+
+#define GID_PORT_SCAN 122
+
+#define PSNG_TCP_PORTSCAN 1
+#define PSNG_TCP_DECOY_PORTSCAN 2
+#define PSNG_TCP_PORTSWEEP 3
+#define PSNG_TCP_DISTRIBUTED_PORTSCAN 4
+#define PSNG_TCP_FILTERED_PORTSCAN 5
+#define PSNG_TCP_FILTERED_DECOY_PORTSCAN 6
+#define PSNG_TCP_PORTSWEEP_FILTERED 7
+#define PSNG_TCP_FILTERED_DISTRIBUTED_PORTSCAN 8
+
+#define PSNG_IP_PORTSCAN 9
+#define PSNG_IP_DECOY_PORTSCAN 10
+#define PSNG_IP_PORTSWEEP 11
+#define PSNG_IP_DISTRIBUTED_PORTSCAN 12
+#define PSNG_IP_FILTERED_PORTSCAN 13
+#define PSNG_IP_FILTERED_DECOY_PORTSCAN 14
+#define PSNG_IP_PORTSWEEP_FILTERED 15
+#define PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN 16
+
+#define PSNG_UDP_PORTSCAN 17
+#define PSNG_UDP_DECOY_PORTSCAN 18
+#define PSNG_UDP_PORTSWEEP 19
+#define PSNG_UDP_DISTRIBUTED_PORTSCAN 20
+#define PSNG_UDP_FILTERED_PORTSCAN 21
+#define PSNG_UDP_FILTERED_DECOY_PORTSCAN 22
+#define PSNG_UDP_PORTSWEEP_FILTERED 23
+#define PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN 24
+
+#define PSNG_ICMP_PORTSWEEP 25
+#define PSNG_ICMP_PORTSWEEP_FILTERED 26
+
+#define PSNG_OPEN_PORT 27
+
+//-------------------------------------------------------------------------
+// rule msgs
+//-------------------------------------------------------------------------
+
+#define PSNG_TCP_PORTSCAN_STR \
+ "TCP portscan"
+#define PSNG_TCP_DECOY_PORTSCAN_STR \
+ "TCP decoy portscan"
+#define PSNG_TCP_PORTSWEEP_STR \
+ "TCP portsweep"
+#define PSNG_TCP_DISTRIBUTED_PORTSCAN_STR \
+ "TCP distributed portscan"
+#define PSNG_TCP_FILTERED_PORTSCAN_STR \
+ "TCP filtered portscan"
+#define PSNG_TCP_FILTERED_DECOY_PORTSCAN_STR \
+ "TCP filtered decoy portscan"
+#define PSNG_TCP_FILTERED_DISTRIBUTED_PORTSCAN_STR \
+ "TCP filtered distributed portscan"
+#define PSNG_TCP_PORTSWEEP_FILTERED_STR \
+ "TCP filtered portsweep"
+
+#define PSNG_IP_PORTSCAN_STR \
+ "IP protocol scan"
+#define PSNG_IP_DECOY_PORTSCAN_STR \
+ "IP decoy protocol scan"
+#define PSNG_IP_PORTSWEEP_STR \
+ "IP protocol sweep"
+#define PSNG_IP_DISTRIBUTED_PORTSCAN_STR \
+ "IP distributed protocol scan"
+#define PSNG_IP_FILTERED_PORTSCAN_STR \
+ "IP filtered protocol scan"
+#define PSNG_IP_FILTERED_DECOY_PORTSCAN_STR \
+ "IP filtered decoy protocol scan"
+#define PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN_STR \
+ "IP filtered distributed protocol scan"
+#define PSNG_IP_PORTSWEEP_FILTERED_STR \
+ "IP filtered protocol sweep"
+
+#define PSNG_UDP_PORTSCAN_STR \
+ "UDP portscan"
+#define PSNG_UDP_DECOY_PORTSCAN_STR \
+ "UDP decoy portscan"
+#define PSNG_UDP_PORTSWEEP_STR \
+ "UDP portsweep"
+#define PSNG_UDP_DISTRIBUTED_PORTSCAN_STR \
+ "UDP distributed portscan"
+#define PSNG_UDP_FILTERED_PORTSCAN_STR \
+ "UDP filtered portscan"
+#define PSNG_UDP_FILTERED_DECOY_PORTSCAN_STR \
+ "UDP filtered decoy portscan"
+#define PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN_STR \
+ "UDP filtered distributed portscan"
+#define PSNG_UDP_PORTSWEEP_FILTERED_STR \
+ "UDP filtered portsweep"
+
+#define PSNG_ICMP_PORTSWEEP_STR \
+ "ICMP sweep"
+#define PSNG_ICMP_PORTSWEEP_FILTERED_STR \
+ "ICMP filtered sweep"
+
+#define PSNG_OPEN_PORT_STR \
+ "open port"
+
+//-------------------------------------------------------------------------
+
extern THREAD_LOCAL SimpleStats spstats;
extern THREAD_LOCAL ProfileStats psPerfStats;
-//-------------------------------------------------------------------------
+struct PsCommon;
+struct PortscanConfig;
class PortScanGlobalModule : public Module
{
const PegInfo* get_pegs() const override;
PegCount* get_counts() const override;
ProfileStats* get_profile() const override;
+
PsCommon* get_data();
private:
PortscanConfig* get_data();
+private:
+ PS_ALERT_CONF* get_alert_conf(const char* fqn);
+
private:
PortscanConfig* config;
};
bool tmpval = true;
if (!keyword.compare("sense_level"))
- tmpval = parse_option("sense_level", data_stream);
-
+ {
+ table_api.add_deleted_comment("sense_level");
+ if (!util::get_string(data_stream, keyword, "}"))
+ tmpval = false;
+ }
else if (!keyword.compare("watch_ip"))
tmpval = parse_ip_list("watch_ip", data_stream);