From: Russ Combs (rucombs) Date: Fri, 16 Jun 2017 17:07:20 +0000 (-0400) Subject: Merge pull request #928 in SNORT/snort3 from ps_events to master X-Git-Tag: 3.0.0-239~46 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=91b2edaba3175f0f9122c2d01123ecf4c6016992;p=thirdparty%2Fsnort3.git Merge pull request #928 in SNORT/snort3 from ps_events to master Squashed commit of the following: commit 3877ccf2211f0341b0cdd6d59c7ef9b41023955f Author: Russ Combs Date: Fri Jun 16 08:43:10 2017 -0400 port_scan: execute probes after detection and log the alt buffer if set commit 2965452abf7ed909be0cfcb76b645f1439022c8d Author: Russ Combs Date: Thu Jun 15 13:01:09 2017 -0400 port_scan: cleanup headers commit 25c305b763019b77823bc3de0ad78c972168d72b Author: Russ Combs Date: Thu Jun 15 11:51:59 2017 -0400 port_scan: refactor alerting commit 2c9380e50066da9b7319f134202d737e3acad7d9 Author: Russ Combs Date: Thu Jun 15 10:58:18 2017 -0400 port_scan: just use normal log files commit 5786467d359d8c59523a060a9ddee29a1963cf99 Author: Russ Combs Date: Thu Jun 15 10:54:23 2017 -0400 port_scan: eliminate use of pseudo packet for events --- diff --git a/src/detection/detection_engine.cc b/src/detection/detection_engine.cc index d125ad949..0ca998915 100644 --- a/src/detection/detection_engine.cc +++ b/src/detection/detection_engine.cc @@ -362,6 +362,8 @@ void DetectionEngine::inspect(Packet* p) if ( p->has_ip() ) check_tags(p); + + InspectorManager::probe(p); } Profile profile(eventqPerfStats); diff --git a/src/loggers/alert_fast.cc b/src/loggers/alert_fast.cc index 225ce89aa..c672154f7 100644 --- a/src/loggers/alert_fast.cc +++ b/src/loggers/alert_fast.cc @@ -39,6 +39,7 @@ #include +#include "detection/detection_engine.h" #include "detection/signature.h" #include "events/event.h" #include "framework/logger.h" @@ -300,6 +301,11 @@ void FastLogger::alert(Packet* p, const char* msg, Event* event) } else if ( log_pkt ) LogNetData(fast_log, p->data, p->dsize, p); + + DataBuffer& buf = DetectionEngine::get_alt_buffer(p); + + if ( buf.len and event->sig_info->gid != 116 ) + LogNetData(fast_log, buf.data, buf.len, p, "alt"); } TextLog_NewLine(fast_log); TextLog_Flush(fast_log); diff --git a/src/loggers/unified2.cc b/src/loggers/unified2.cc index d61b9e3dd..7f905dff1 100644 --- a/src/loggers/unified2.cc +++ b/src/loggers/unified2.cc @@ -260,24 +260,17 @@ static void _AlertIP4_v2(Packet* p, const char*, Unified2Config* config, Event* } } - if (p->is_portscan()) + alertdata.ip_proto = p->get_ip_proto_next(); + + if ( p->type() == PktType::ICMP) { - alertdata.ip_proto = p->ps_proto; + // If PktType == ICMP, icmph is set + alertdata.sport_itype = htons(p->ptrs.icmph->type); + alertdata.dport_icode = htons(p->ptrs.icmph->code); } - else - { - alertdata.ip_proto = p->get_ip_proto_next(); - if ( p->type() == PktType::ICMP) - { - // If PktType == ICMP, icmph is set - alertdata.sport_itype = htons(p->ptrs.icmph->type); - alertdata.dport_icode = htons(p->ptrs.icmph->code); - } - - alertdata.sport_itype = htons(p->ptrs.sp); - alertdata.dport_icode = htons(p->ptrs.dp); - } + alertdata.sport_itype = htons(p->ptrs.sp); + alertdata.dport_icode = htons(p->ptrs.dp); if ((p->proto_bits & PROTO_BIT__MPLS) && (config->mpls_event_types)) { @@ -352,24 +345,17 @@ static void _AlertIP6_v2(Packet* p, const char*, Unified2Config* config, Event* } } - if (p->is_portscan()) + alertdata.ip_proto = p->get_ip_proto_next(); + + if ( p->type() == PktType::ICMP) { - alertdata.ip_proto = p->ps_proto; + // If PktType == ICMP, icmph is set + alertdata.sport_itype = htons(p->ptrs.icmph->type); + alertdata.dport_icode = htons(p->ptrs.icmph->code); } - else - { - alertdata.ip_proto = p->get_ip_proto_next(); - if ( p->type() == PktType::ICMP) - { - // If PktType == ICMP, icmph is set - alertdata.sport_itype = htons(p->ptrs.icmph->type); - alertdata.dport_icode = htons(p->ptrs.icmph->code); - } - - alertdata.sport_itype = htons(p->ptrs.sp); - alertdata.dport_icode = htons(p->ptrs.dp); - } + alertdata.sport_itype = htons(p->ptrs.sp); + alertdata.dport_icode = htons(p->ptrs.dp); if ((p->proto_bits & PROTO_BIT__MPLS) && (config->mpls_event_types)) { diff --git a/src/managers/inspector_manager.cc b/src/managers/inspector_manager.cc index fd16afc3e..83b02a654 100644 --- a/src/managers/inspector_manager.cc +++ b/src/managers/inspector_manager.cc @@ -818,7 +818,11 @@ void InspectorManager::execute(Packet* p) if(!full_inspection(fp, p)) return; } +} +void InspectorManager::probe(Packet* p) +{ + FrameworkPolicy* fp = get_inspection_policy()->framework_policy; ::execute(p, fp->probe.vec, fp->probe.num); } diff --git a/src/managers/inspector_manager.h b/src/managers/inspector_manager.h index 540aa19c3..e726a6b42 100644 --- a/src/managers/inspector_manager.h +++ b/src/managers/inspector_manager.h @@ -76,6 +76,8 @@ public: static void dispatch_meta(FrameworkPolicy*, int type, const uint8_t* data); static void execute(Packet*); + static void probe(Packet*); + static void clear(Packet*); static void empty_trash(); diff --git a/src/network_inspectors/port_scan/port_scan.cc b/src/network_inspectors/port_scan/port_scan.cc index 383c1777b..1ac96113a 100644 --- a/src/network_inspectors/port_scan/port_scan.cc +++ b/src/network_inspectors/port_scan/port_scan.cc @@ -17,443 +17,184 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** @file sfportscan.c -** @author Daniel Roelker -*/ +// sfportscan.c author Daniel Roelker +// port_scan.cc author Russ Combs #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include "detection/detect.h" #include "detection/detection_engine.h" -#include "detection/signature.h" -#include "events/event.h" -#include "filters/sfthreshold.h" #include "log/messages.h" #include "managers/inspector_manager.h" #include "profiler/profiler.h" -#include "protocols/packet_manager.h" #include "utils/util.h" #include "utils/util_cstring.h" #include "ps_inspect.h" #include "ps_module.h" -#define PROTO_BUFFER_SIZE 256 - -static THREAD_LOCAL Packet* g_tmp_pkt = nullptr; -static THREAD_LOCAL FILE* g_logfile = nullptr; - THREAD_LOCAL SimpleStats spstats; THREAD_LOCAL ProfileStats psPerfStats; -/** -** This routine makes the portscan payload for the events. The listed -** info is: -** - priority count (number of error transmissions RST/ICMP UNREACH) -** - connection count (number of protocol connections SYN) -** - ip count (number of IPs that communicated with host) -** - 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) -*/ -static bool MakeProtoInfo(PS_PROTO* proto, const uint8_t* buffer, unsigned& total_size) +static void make_port_scan_info(Packet* p, PS_PROTO* proto) { - assert(buffer); + DataBuffer& buf = DetectionEngine::get_alt_buffer(p); - int dsize = (g_tmp_pkt->max_dsize - total_size); + SfIp* ip1 = &proto->low_ip; + SfIp* ip2 = &proto->high_ip; - if (dsize < PROTO_BUFFER_SIZE) - return false; + char a1[INET6_ADDRSTRLEN]; + char a2[INET6_ADDRSTRLEN]; - SfIp* ip1, * ip2; - ip1 = &proto->low_ip; - ip2 = &proto->high_ip; + ip1->ntop(a1, sizeof(a1)); + ip2->ntop(a2, sizeof(a2)); - if (proto->alerts == PS_ALERT_PORTSWEEP || - proto->alerts == PS_ALERT_PORTSWEEP_FILTERED) - { - SnortSnprintf((char*)buffer, PROTO_BUFFER_SIZE, - "Priority Count: %d\n" - "Connection Count: %d\n" - "IP Count: %d\n" - "Scanned IP Range: %s:", - proto->priority_count, - proto->connection_count, - proto->u_ip_count, - ip1->ntoa()); - - /* Now print the high ip into the buffer. This saves us - * from having to copy the results of SfIp::ntoa (which is - * a static buffer) to avoid the reuse of that buffer when - * more than one use of SfIp::ntoa is within the same printf. - */ - SnortSnprintfAppend((char*)buffer, PROTO_BUFFER_SIZE, - "%s\n" - "Port/Proto Count: %d\n" - "Port/Proto Range: %d:%d\n", - ip2->ntoa(), - proto->u_port_count, - proto->low_p, - proto->high_p); - } - else - { - SnortSnprintf((char*)buffer, PROTO_BUFFER_SIZE, - "Priority Count: %d\n" - "Connection Count: %d\n" - "IP Count: %d\n" - "Scanner IP Range: %s:", - proto->priority_count, - proto->connection_count, - proto->u_ip_count, - ip1->ntoa() - ); - - /* Now print the high ip into the buffer. This saves us - * from having to copy the results of SfIp::ntoa (which is - * a static buffer) to avoid the reuse of that buffer when - * more than one use of SfIp::ntoa is within the same printf. - */ - SnortSnprintfAppend((char*)buffer, PROTO_BUFFER_SIZE, - "%s\n" - "Port/Proto Count: %d\n" - "Port/Proto Range: %d:%d\n", - ip2->ntoa(), - proto->u_port_count, - proto->low_p, - proto->high_p); - } + char type; - dsize = SnortStrnlen((const char*)buffer, PROTO_BUFFER_SIZE); - total_size += dsize; - - // Set the payload size. This is protocol independent. - g_tmp_pkt->dsize = dsize; - - return true; -} - -static void LogPortscanAlert(Packet* p, uint32_t event_id, - uint32_t event_ref, uint32_t gid, uint32_t sid) -{ - if(!p->ptrs.ip_api.is_ip()) - return; - - /* Do not log if being suppressed */ - const SfIp* src_addr = p->ptrs.ip_api.get_src(); - const SfIp* dst_addr = p->ptrs.ip_api.get_dst(); - - if ( sfthreshold_test(gid, sid, src_addr, dst_addr, p->pkth->ts.tv_sec) ) - { - 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, "event_id: %u\n", event_id); + if ( proto->alerts == PS_ALERT_PORTSWEEP or proto->alerts == PS_ALERT_PORTSWEEP_FILTERED ) + type = 'd'; else - fprintf(g_logfile, "event_ref: %u\n", event_ref); - - fprintf(g_logfile, "%s ", p->ptrs.ip_api.get_src()->ntoa()); - fprintf(g_logfile, "-> %s\n", p->ptrs.ip_api.get_dst()->ntoa()); - fprintf(g_logfile, "%.*s\n", p->dsize, p->data); - - fflush(g_logfile); + type = 'r'; + + buf.len = snprintf((char*)buf.data, sizeof(buf.data), + "Priority Count: %d\n" + "Connection Count: %d\n" + "IP Count: %d\n" + "Scanne%c IP Range: %s:%s\n" + "Port/Proto Count: %d\n" + "Port/Proto Range: %d:%d\n", + proto->priority_count, + proto->connection_count, + proto->u_ip_count, + type, a1, a2, + proto->u_port_count, + proto->low_p, proto->high_p); } -static int GeneratePSSnortEvent(Packet* p, uint32_t gid, uint32_t sid) +static void make_open_port_info(Packet* p, PS_PROTO* proto) { - unsigned int event_id = 0; // FIXIT-H eliminate this - - DetectionEngine de; - de.queue_event(gid, sid); + DataBuffer& buf = DetectionEngine::get_alt_buffer(p); - if (g_logfile) - LogPortscanAlert(p, event_id, 0, gid, sid); + SfIp* ip1 = &proto->low_ip; + char a1[INET6_ADDRSTRLEN]; + ip1->ntop(a1, sizeof(a1)); - return event_id; -} + buf.len = snprintf((char*)buf.data, sizeof(buf.data), + "Scanned IP: %s\n" + "Port Count: %d\n" + "Ports: ", + a1, + proto->open_ports_cnt); -/** -** We have to generate open port events differently because we tag these -** to the original portscan event. -** -** @retval 0 success -*/ -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 - ** reference for it, so we don't log a snort event. We still keep - ** track of it though. - */ - if (!event_ref) - return 0; - - /* reset the thresholding subsystem checks for this packet */ - sfthreshold_reset(); - - SigInfo info; - Event event(info); - - 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; - - if (p) - { - /* - * Do threshold test for suppression and thresholding. We have to do it - * 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(gid, sid, p->ptrs.ip_api.get_src(), - p->ptrs.ip_api.get_dst(), p->pkth->ts.tv_sec) ) - { - return 0; - } - - CallLogFuncs(p, nullptr, &event, msg); - } - else + for ( int i = 0; i < proto->open_ports_cnt; i++ ) { - return -1; + buf.len += snprintf( + (char*)buf.data, sizeof(buf.data) - buf.len, "%hu ", proto->open_ports[i]); } - - if (g_logfile) - LogPortscanAlert(p, 0, event_ref, gid, sid); - - return event.event_id; } -// Write out the open ports info for open port alerts. -static bool MakeOpenPortInfo( - PS_PROTO*, const uint8_t* buffer, unsigned& total_size, void* user) +static void make_open_port_info(Packet* p, uint16_t port) { - assert(buffer); - - if ( !user ) - return false; - - int dsize = (g_tmp_pkt->max_dsize - total_size); - - if (dsize < PROTO_BUFFER_SIZE) - return false; - - SnortSnprintf((char*)buffer, PROTO_BUFFER_SIZE, - "Open Port: %hu\n", *((unsigned short*)user)); + DataBuffer& buf = DetectionEngine::get_alt_buffer(p); - dsize = SnortStrnlen((const char*)buffer, PROTO_BUFFER_SIZE); - total_size += dsize; + const char* addr = p->ptrs.ip_api.get_src()->ntoa(); - // Set the payload size. This is protocol independent. - g_tmp_pkt->dsize = dsize; - - return true; + buf.len = snprintf((char*)buf.data, sizeof(buf.data), + "Scanned IP: %s\n" + "Open Port: %hu\n", + addr, port); } -/* -** 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 bool MakePortscanPkt(PS_PKT* ps_pkt, PS_PROTO* proto, int proto_type, void* user) -{ - Packet* p = (Packet*)ps_pkt->pkt; - - if (!p->has_ip()) - return false; - - EncodeFlags flags = ENC_FLAG_NET; - - if ( !ps_pkt->reverse_pkt ) - flags |= ENC_FLAG_FWD; - - PacketManager::encode_format(flags, p, g_tmp_pkt, PSEUDO_PKT_PS); - - switch (proto_type) - { - case PS_PROTO_TCP: - g_tmp_pkt->ps_proto = IpProtocol::TCP; - break; - case PS_PROTO_UDP: - g_tmp_pkt->ps_proto = IpProtocol::UDP; - break; - case PS_PROTO_ICMP: - g_tmp_pkt->ps_proto = IpProtocol::ICMPV4; - break; - case PS_PROTO_IP: - g_tmp_pkt->ps_proto = IpProtocol::IP; - break; - case PS_PROTO_OPEN_PORT: - g_tmp_pkt->ps_proto = p->get_ip_proto_next(); - break; - default: - return false; - } - - if (g_tmp_pkt->is_ip4()) - ((IP4Hdr*)g_tmp_pkt->ptrs.ip_api.get_ip4h())->set_proto(IpProtocol::PORT_SCAN); - - 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_TCP: - case PS_PROTO_UDP: - case PS_PROTO_ICMP: - case PS_PROTO_IP: - 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 false; - - break; - - default: - return false; - } - - // Let's finish up the IP header and checksum. - PacketManager::encode_update(g_tmp_pkt); - - 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 true; -} - -static void PortscanAlertTcp(Packet* p, PS_PROTO* proto, int) +static void PortscanAlertTcp(Packet* p, PS_PROTO* proto) { assert(proto); - - unsigned int event_ref; bool portsweep = false; switch (proto->alerts) { case PS_ALERT_ONE_TO_ONE: - event_ref = GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_TCP_PORTSCAN); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_TCP_PORTSCAN); break; case PS_ALERT_ONE_TO_ONE_DECOY: - event_ref = GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_TCP_DECOY_PORTSCAN); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_TCP_DECOY_PORTSCAN); break; case PS_ALERT_PORTSWEEP: - event_ref = GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_TCP_PORTSWEEP); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_TCP_PORTSWEEP); portsweep = true; break; case PS_ALERT_DISTRIBUTED: - event_ref = GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_TCP_DISTRIBUTED_PORTSCAN); + DetectionEngine::queue_event(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); + DetectionEngine::queue_event(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); + DetectionEngine::queue_event(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); + DetectionEngine::queue_event(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); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_TCP_FILTERED_DISTRIBUTED_PORTSCAN); break; default: return; } - // 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 and !portsweep) { - 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; - - 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); - } + make_open_port_info(p, proto); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_OPEN_PORT); } } -static void PortscanAlertUdp(Packet* p, PS_PROTO* proto, int) +static void PortscanAlertUdp(Packet*, PS_PROTO* proto) { assert(proto); switch (proto->alerts) { case PS_ALERT_ONE_TO_ONE: - GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_UDP_PORTSCAN); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_UDP_PORTSCAN); break; case PS_ALERT_ONE_TO_ONE_DECOY: - GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_UDP_DECOY_PORTSCAN); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_UDP_DECOY_PORTSCAN); break; case PS_ALERT_PORTSWEEP: - GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_UDP_PORTSWEEP); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_UDP_PORTSWEEP); break; case PS_ALERT_DISTRIBUTED: - GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_UDP_DISTRIBUTED_PORTSCAN); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_UDP_DISTRIBUTED_PORTSCAN); break; case PS_ALERT_ONE_TO_ONE_FILTERED: - GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_UDP_FILTERED_PORTSCAN); + DetectionEngine::queue_event(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); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_UDP_FILTERED_DECOY_PORTSCAN); break; case PS_ALERT_PORTSWEEP_FILTERED: - GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_UDP_PORTSWEEP_FILTERED); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_UDP_PORTSWEEP_FILTERED); break; case PS_ALERT_DISTRIBUTED_FILTERED: - GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN); break; default: @@ -461,42 +202,42 @@ static void PortscanAlertUdp(Packet* p, PS_PROTO* proto, int) } } -static void PortscanAlertIp(Packet* p, PS_PROTO* proto, int) +static void PortscanAlertIp(Packet*, PS_PROTO* proto) { assert(proto); switch (proto->alerts) { case PS_ALERT_ONE_TO_ONE: - GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_IP_PORTSCAN); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_IP_PORTSCAN); break; case PS_ALERT_ONE_TO_ONE_DECOY: - GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_IP_DECOY_PORTSCAN); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_IP_DECOY_PORTSCAN); break; case PS_ALERT_PORTSWEEP: - GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_IP_PORTSWEEP); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_IP_PORTSWEEP); break; case PS_ALERT_DISTRIBUTED: - GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_IP_DISTRIBUTED_PORTSCAN); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_IP_DISTRIBUTED_PORTSCAN); break; case PS_ALERT_ONE_TO_ONE_FILTERED: - GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_IP_FILTERED_PORTSCAN); + DetectionEngine::queue_event(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); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_IP_FILTERED_DECOY_PORTSCAN); break; case PS_ALERT_PORTSWEEP_FILTERED: - GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_IP_PORTSWEEP_FILTERED); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_IP_PORTSWEEP_FILTERED); break; case PS_ALERT_DISTRIBUTED_FILTERED: - GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN); break; default: @@ -504,18 +245,18 @@ static void PortscanAlertIp(Packet* p, PS_PROTO* proto, int) } } -static void PortscanAlertIcmp(Packet* p, PS_PROTO* proto, int) +static void PortscanAlertIcmp(Packet*, PS_PROTO* proto) { assert(proto); switch (proto->alerts) { case PS_ALERT_PORTSWEEP: - GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_ICMP_PORTSWEEP); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_ICMP_PORTSWEEP); break; case PS_ALERT_PORTSWEEP_FILTERED: - GeneratePSSnortEvent(p, GID_PORT_SCAN, PSNG_ICMP_PORTSWEEP_FILTERED); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_ICMP_PORTSWEEP_FILTERED); break; default: @@ -525,44 +266,36 @@ static void PortscanAlertIcmp(Packet* p, PS_PROTO* proto, int) static void PortscanAlert(PS_PKT* ps_pkt, PS_PROTO* proto, int proto_type) { - Packet* p = (Packet*)ps_pkt->pkt; - g_tmp_pkt = DetectionEngine::set_next_packet(); + Packet* p = ps_pkt->pkt; if (proto->alerts == PS_ALERT_OPEN_PORT) { - 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); + make_open_port_info(p, p->ptrs.sp); + DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_OPEN_PORT); } else { - if ( !MakePortscanPkt(ps_pkt, proto, proto_type, nullptr) ) - return; + make_port_scan_info(p, proto); switch (proto_type) { case PS_PROTO_TCP: - PortscanAlertTcp(g_tmp_pkt, proto, proto_type); + PortscanAlertTcp(p, proto); break; case PS_PROTO_UDP: - PortscanAlertUdp(g_tmp_pkt, proto, proto_type); + PortscanAlertUdp(p, proto); break; case PS_PROTO_ICMP: - PortscanAlertIcmp(g_tmp_pkt, proto, proto_type); + PortscanAlertIcmp(p, proto); break; case PS_PROTO_IP: - PortscanAlertIp(g_tmp_pkt, proto, proto_type); + PortscanAlertIp(p, proto); break; } } - - sfthreshold_reset(); - g_tmp_pkt = nullptr; } static void PrintIPPortSet(IP_PORT* p) @@ -713,28 +446,10 @@ bool PortScan::configure(SnortConfig* sc) void PortScan::tinit() { ps_init_hash(config->common->memcap); - - if ( !config->logfile ) - return; - - std::string name; - get_instance_file(name, "portscan.log"); - g_logfile = fopen(name.c_str(), "a+"); - - if ( !g_logfile ) - { - FatalError("Portscan log file '%s' could not be opened: %s.\n", - name.c_str(), get_error(errno)); - } } void PortScan::tterm() { - if ( g_logfile ) - { - fclose(g_logfile); - g_logfile = nullptr; - } ps_cleanup(); } @@ -755,7 +470,7 @@ void PortScan::eval(Packet* p) PS_PKT ps_pkt; memset(&ps_pkt, 0x00, sizeof(PS_PKT)); - ps_pkt.pkt = (void*)p; + ps_pkt.pkt = p; ps_detect(&ps_pkt); diff --git a/src/network_inspectors/port_scan/ps_detect.cc b/src/network_inspectors/port_scan/ps_detect.cc index af602c67e..0d6033a32 100644 --- a/src/network_inspectors/port_scan/ps_detect.cc +++ b/src/network_inspectors/port_scan/ps_detect.cc @@ -17,19 +17,15 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- +// portscan.c author Daniel Roelker +// ps_detect.cc author Russ Combs + /* -** @file portscan.c -** -** @author Daniel Roelker -** -** @brief Detect portscans -** -** NOTES -** - Marc Norton and Jeremy Hewlett were involved in the requirements and -** design of this portscan detection engine. -** - Thanks to Judy Novak for her suggestion to log open ports -** on hosts that are portscanned. This idea makes portscan a lot more -** useful for analysts. +** - Marc Norton and Jeremy Hewlett were involved in the requirements and +** design of this portscan detection engine. +** - Thanks to Judy Novak for her suggestion to log open ports on hosts +** that are portscanned. This idea makes portscan a lot more useful for +** analysts. */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/network_inspectors/port_scan/ps_detect.h b/src/network_inspectors/port_scan/ps_detect.h index b5c0fb0e2..a7a062867 100644 --- a/src/network_inspectors/port_scan/ps_detect.h +++ b/src/network_inspectors/port_scan/ps_detect.h @@ -28,6 +28,39 @@ #define PS_OPEN_PORTS 8 +#define PS_PROTO_NONE 0x00 +#define PS_PROTO_TCP 0x01 +#define PS_PROTO_UDP 0x02 +#define PS_PROTO_ICMP 0x04 +#define PS_PROTO_IP 0x08 +#define PS_PROTO_ALL 0x0f + +#define PS_PROTO_OPEN_PORT 0x80 + +#define PS_TYPE_PORTSCAN 0x01 +#define PS_TYPE_PORTSWEEP 0x02 +#define PS_TYPE_DECOYSCAN 0x04 +#define PS_TYPE_DISTPORTSCAN 0x08 +#define PS_TYPE_ALL 0x0f + +#define PS_SENSE_HIGH 3 +#define PS_SENSE_MEDIUM 2 +#define PS_SENSE_LOW 1 + +#define PS_ALERT_ONE_TO_ONE 1 +#define PS_ALERT_ONE_TO_ONE_DECOY 2 +#define PS_ALERT_PORTSWEEP 3 +#define PS_ALERT_DISTRIBUTED 4 +#define PS_ALERT_ONE_TO_ONE_FILTERED 5 +#define PS_ALERT_ONE_TO_ONE_DECOY_FILTERED 6 +#define PS_ALERT_DISTRIBUTED_FILTERED 7 +#define PS_ALERT_PORTSWEEP_FILTERED 8 +#define PS_ALERT_OPEN_PORT 9 + +#define PS_ALERT_GENERATED 255 + +//------------------------------------------------------------------------- + struct PsCommon { unsigned long memcap; @@ -103,9 +136,6 @@ struct PS_PROTO unsigned short open_ports[PS_OPEN_PORTS]; unsigned char open_ports_cnt; - struct timeval event_time; - unsigned int event_ref; - unsigned char alerts; time_t window; @@ -120,7 +150,7 @@ struct PS_TRACKER struct PS_PKT { - void* pkt; + struct Packet* pkt; PS_TRACKER* scanner; PS_TRACKER* scanned; @@ -129,38 +159,11 @@ struct PS_PKT int reverse_pkt; }; -//------------------------------------------------------------------------- - -#define PS_PROTO_NONE 0x00 -#define PS_PROTO_TCP 0x01 -#define PS_PROTO_UDP 0x02 -#define PS_PROTO_ICMP 0x04 -#define PS_PROTO_IP 0x08 -#define PS_PROTO_ALL 0x0f - -#define PS_PROTO_OPEN_PORT 0x80 - -#define PS_TYPE_PORTSCAN 0x01 -#define PS_TYPE_PORTSWEEP 0x02 -#define PS_TYPE_DECOYSCAN 0x04 -#define PS_TYPE_DISTPORTSCAN 0x08 -#define PS_TYPE_ALL 0x0f - -#define PS_SENSE_HIGH 3 -#define PS_SENSE_MEDIUM 2 -#define PS_SENSE_LOW 1 - -#define PS_ALERT_ONE_TO_ONE 1 -#define PS_ALERT_ONE_TO_ONE_DECOY 2 -#define PS_ALERT_PORTSWEEP 3 -#define PS_ALERT_DISTRIBUTED 4 -#define PS_ALERT_ONE_TO_ONE_FILTERED 5 -#define PS_ALERT_ONE_TO_ONE_DECOY_FILTERED 6 -#define PS_ALERT_DISTRIBUTED_FILTERED 7 -#define PS_ALERT_PORTSWEEP_FILTERED 8 -#define PS_ALERT_OPEN_PORT 9 +void ps_cleanup(); +void ps_reset(); -#define PS_ALERT_GENERATED 255 +void ps_init_hash(unsigned long); +int ps_detect(PS_PKT*); #endif diff --git a/src/network_inspectors/port_scan/ps_inspect.h b/src/network_inspectors/port_scan/ps_inspect.h index 89f75b839..dc167ff52 100644 --- a/src/network_inspectors/port_scan/ps_inspect.h +++ b/src/network_inspectors/port_scan/ps_inspect.h @@ -21,6 +21,10 @@ #ifndef PS_INSPECT_H #define PS_INSPECT_H +// The PortScan inspector is declared here. The public methods and +// alerting methods are defined in port_scan.cc and the detection methods +// are in ps_detect.cc. + #include "framework/inspector.h" #include "ps_detect.h" @@ -51,56 +55,34 @@ private: const SfIp* scanner, uint16_t scanner_port, const SfIp* scanned, uint16_t scanned_port); - bool ps_tracker_lookup( - PS_PKT* ps_pkt, PS_TRACKER** scanner, PS_TRACKER** scanned); - - bool ps_filter_ignore(PS_PKT* ps_pkt); - - bool ps_tracker_update( - PS_PKT* ps_pkt, PS_TRACKER* scanner, PS_TRACKER* scanned); - - bool ps_tracker_alert( - PS_PKT* ps_pkt, PS_TRACKER* scanner, PS_TRACKER* scanned); + bool ps_filter_ignore(PS_PKT*); + int ps_get_proto(PS_PKT*, int* proto); + int ps_detect(PS_PKT*); - int ps_get_proto(PS_PKT* ps_pkt, int* proto); + bool ps_tracker_lookup(PS_PKT*, PS_TRACKER** scanner, PS_TRACKER** scanned); + bool ps_tracker_update(PS_PKT*, PS_TRACKER* scanner, PS_TRACKER* scanned); + bool ps_tracker_alert(PS_PKT*, PS_TRACKER* scanner, PS_TRACKER* scanned); - void ps_proto_update_window(unsigned window, PS_PROTO* proto, time_t pkt_time); + void ps_proto_update_window(unsigned window, PS_PROTO*, time_t pkt_time); int ps_proto_update( - PS_PROTO* proto, int ps_cnt, int pri_cnt, unsigned window, const SfIp* ip, + PS_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); - - void ps_tracker_update_tcp( - PS_PKT* ps_pkt, PS_TRACKER* scanner, PS_TRACKER* scanned); - - void ps_tracker_update_udp( - PS_PKT* ps_pkt, PS_TRACKER* scanner, PS_TRACKER* scanned); - - void ps_tracker_update_icmp( - PS_PKT* ps_pkt, PS_TRACKER* scanner, PS_TRACKER* scanned); + void ps_tracker_update_ip(PS_PKT*, PS_TRACKER* scanner, PS_TRACKER* scanned); + void ps_tracker_update_tcp(PS_PKT*, PS_TRACKER* scanner, PS_TRACKER* scanned); + void ps_tracker_update_udp(PS_PKT*, PS_TRACKER* scanner, PS_TRACKER* scanned); + void ps_tracker_update_icmp(PS_PKT*, PS_TRACKER* scanner, PS_TRACKER* scanned); - void ps_alert_tcp(PS_PROTO* scanner, PS_PROTO* scanned); void ps_alert_ip(PS_PROTO* scanner, PS_PROTO* scanned); + void ps_alert_tcp(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); - private: PortscanConfig* config; PsData* global; }; -void ps_cleanup(); -void ps_reset(); - -int ps_detect(PS_PKT* p); -void ps_tracker_print(PS_TRACKER* tracker); - -void ps_init_hash(unsigned long); - #endif diff --git a/src/network_inspectors/port_scan/ps_module.cc b/src/network_inspectors/port_scan/ps_module.cc index d36899fcf..f7b21cf04 100644 --- a/src/network_inspectors/port_scan/ps_module.cc +++ b/src/network_inspectors/port_scan/ps_module.cc @@ -74,9 +74,6 @@ static const Parameter ps_params[] = { "include_midstream", Parameter::PT_BOOL, nullptr, "false", "list of CIDRs with optional ports" }, - { "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)" }, @@ -247,9 +244,6 @@ bool PortScanModule::set(const char* fqn, Value& v, SnortConfig*) if ( !ips || ipset_parse(ips, v.get_string()) ) return false; } - else if ( v.is("logfile") ) - config->logfile = v.get_bool(); - else if ( v.is("scans") ) { if ( auto p = get_alert_conf(fqn) ) diff --git a/src/piglet_plugins/pp_packet_iface.cc b/src/piglet_plugins/pp_packet_iface.cc index 544cbb827..7259a380d 100644 --- a/src/piglet_plugins/pp_packet_iface.cc +++ b/src/piglet_plugins/pp_packet_iface.cc @@ -42,7 +42,6 @@ static void set_fields(lua_State* L, int tindex, Packet& self) table.get_field("num_layers", self.num_layers); table.get_field("iplist_id", self.iplist_id); table.get_field("user_policy_id", self.user_policy_id); - table.get_field("ps_proto", reinterpret_cast(self.ps_proto)); } static void get_fields(lua_State* L, int tindex, Packet& self) @@ -56,7 +55,6 @@ static void get_fields(lua_State* L, int tindex, Packet& self) table.set_field("num_layers", self.num_layers); table.set_field("iplist_id", self.iplist_id); table.set_field("user_policy_id", self.user_policy_id); - table.set_field("ps_proto", static_cast(self.ps_proto)); } static void set(lua_State* L, Packet& self, Lua::Args& args, int start) diff --git a/src/protocols/packet.cc b/src/protocols/packet.cc index e923792cf..3139265e7 100644 --- a/src/protocols/packet.cc +++ b/src/protocols/packet.cc @@ -179,9 +179,6 @@ const char* Packet::get_pseudo_type() const case PSEUDO_PKT_USER: return "stream_user"; - case PSEUDO_PKT_DCE_RPKT: - return "dce2_rpc_reass"; - case PSEUDO_PKT_DCE_SEG: return "dce2_rpc_deseg"; @@ -194,12 +191,6 @@ const char* Packet::get_pseudo_type() const case PSEUDO_PKT_SMB_TRANS: return "dce2_smb_transact"; - case PSEUDO_PKT_PS: - return "port_scan"; - - case PSEUDO_PKT_SDF: - return "sdf"; - default: break; } return "other"; diff --git a/src/protocols/packet.h b/src/protocols/packet.h index 1c064c02d..51dbf634d 100644 --- a/src/protocols/packet.h +++ b/src/protocols/packet.h @@ -75,13 +75,10 @@ enum PseudoPacketType PSEUDO_PKT_IP, PSEUDO_PKT_TCP, PSEUDO_PKT_USER, - PSEUDO_PKT_DCE_RPKT, PSEUDO_PKT_DCE_SEG, PSEUDO_PKT_DCE_FRAG, PSEUDO_PKT_SMB_SEG, PSEUDO_PKT_SMB_TRANS, - PSEUDO_PKT_PS, - PSEUDO_PKT_SDF, PSEUDO_PKT_MAX }; @@ -137,8 +134,6 @@ struct SO_PUBLIC Packet // for correlating configuration with event output uint16_t user_policy_id; - IpProtocol ps_proto; // Used for portscan and unified2 logging - // IP_MAXPACKET is the minimum allowable max_dsize // there is no requirement that all data fit into an IP datagram // but we do require that an IP datagram fit into Packet space @@ -231,9 +226,6 @@ struct SO_PUBLIC Packet bool is_from_server() const { return (packet_flags & PKT_FROM_SERVER) != 0; } - bool is_portscan() const - { return is_cooked() and (pseudo_type == PSEUDO_PKT_PS); } - bool is_full_pdu() const { return (packet_flags & PKT_PDU_FULL) == PKT_PDU_FULL; } diff --git a/src/sfip/sf_ip.h b/src/sfip/sf_ip.h index 5163b52a2..dac4eacde 100644 --- a/src/sfip/sf_ip.h +++ b/src/sfip/sf_ip.h @@ -449,8 +449,6 @@ inline bool SfIp::fast_equals_raw(const SfIp& ip2) const /* End of member function definitions */ - -/* Uses a static buffer to return a string representation of the IP */ SO_PUBLIC void sfip_ntop(const SfIp* ip, char* buf, int bufsize); inline std::ostream& operator<<(std::ostream& os, const SfIp* addr) @@ -461,7 +459,6 @@ inline std::ostream& operator<<(std::ostream& os, const SfIp* addr) return os; } - // FIXIT-L X This should be in utils_net if anywhere, but that makes it way harder to link into unit tests SO_PUBLIC void snort_inet_ntop(int family, const void* ip_raw, char* buf, int bufsize);