00001 //--------------------------------------------------------------------------
00002 // Copyright (C) 2014-2017 Cisco and/or its affiliates. All rights reserved.
00003 // Copyright (C) 2004-2013 Sourcefire, Inc.
00004 //
00005 // This program is free software; you can redistribute it and/or modify it
00006 // under the terms of the GNU General Public License Version 2 as published
00007 // by the Free Software Foundation. You may not use, modify or distribute
00008 // this program under any other version of the GNU General Public License.
00009 //
00010 // This program is distributed in the hope that it will be useful, but
00011 // WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00013 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License along
00016 // with this program; if not, write to the Free Software Foundation, Inc.,
00017 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018 //--------------------------------------------------------------------------
00019
00020 // sfportscan.c author Daniel Roelker <droelker@sourcefire.com>
00021 // port_scan.cc author Russ Combs <rucombs@cisco.com>
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include "config.h"
00025 #endif
00026
00027 #include "detection/detection_engine.h"
00028 #include "log/messages.h"
00029 #include "managers/inspector_manager.h"
00030 #include "profiler/profiler.h"
00031 #include "utils/util.h"
00032 #include "utils/util_cstring.h"
00033
00034 #include "main/snort_debug.h"
00035
00036 #include "ps_inspect.h"
00037 #include "ps_module.h"
00038
00039 THREAD_LOCAL SimpleStats spstats;
00040 THREAD_LOCAL ProfileStats psPerfStats;
00041
00042 static void make_port_scan_info(Packet* p, PS_PROTO* proto)
00043 {
00044 DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
00045
00046 SfIp* ip1 = &proto->low_ip;
00047 SfIp* ip2 = &proto->high_ip;
00048
00049 char a1[INET6_ADDRSTRLEN];
00050 char a2[INET6_ADDRSTRLEN];
00051
00052 ip1->ntop(a1, sizeof(a1));
00053 ip2->ntop(a2, sizeof(a2));
00054
00055 char type;
00056
00057 if ( proto->alerts == PS_ALERT_PORTSWEEP or proto->alerts == PS_ALERT_PORTSWEEP_FILTERED )
00058 type = 'd';
00059 else
00060 type = 'r';
00061
00062 buf.len = safe_snprintf((char*)buf.data, sizeof(buf.data),
00063 "Priority Count: %d\n"
00064 "Connection Count: %d\n"
00065 "IP Count: %d\n"
00066 "Scanne%c IP Range: %s:%s\n"
00067 "Port/Proto Count: %d\n"
00068 "Port/Proto Range: %d:%d\n",
00069 proto->priority_count,
00070 proto->connection_count,
00071 proto->u_ip_count,
00072 type, a1, a2,
00073 proto->u_port_count,
00074 proto->low_p, proto->high_p);
00075 }
00076
00077 static void make_open_port_info(Packet* p, PS_PROTO* proto)
00078 {
00079 DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
00080
00081 SfIp* ip1 = &proto->low_ip;
00082 char a1[INET6_ADDRSTRLEN];
00083 ip1->ntop(a1, sizeof(a1));
00084
00085 buf.len = safe_snprintf((char*)buf.data, sizeof(buf.data),
00086 "Scanned IP: %s\n"
00087 "Port Count: %d\n"
00088 "Ports:",
00089 a1,
00090 proto->open_ports_cnt);
00091
00092 for ( int i = 0; i < proto->open_ports_cnt; i++ )
00093 {
00094 buf.len += safe_snprintf(
00095 (char*)buf.data + buf.len, sizeof(buf.data) - buf.len, " %hu", proto->open_ports[i]);
00096 }
00097 buf.len += safe_snprintf((char*)buf.data + buf.len, sizeof(buf.data) - buf.len, "\n");
00098 }
00099
00100 static void make_open_port_info(Packet* p, uint16_t port)
00101 {
00102 DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
00103
00104 const char* addr = p->ptrs.ip_api.get_src()->ntoa();
00105
00106 buf.len = safe_snprintf((char*)buf.data, sizeof(buf.data),
00107 "Scanned IP: %s\n"
00108 "Open Port: %hu\n",
00109 addr, port);
00110 }
00111
00112 static void PortscanAlertTcp(Packet* p, PS_PROTO* proto)
00113 {
00114 assert(proto);
00115 bool portsweep = false;
00116
00117 switch (proto->alerts)
00118 {
00119 case PS_ALERT_ONE_TO_ONE:
00120 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_TCP_PORTSCAN);
00121 break;
00122
00123 case PS_ALERT_ONE_TO_ONE_DECOY:
00124 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_TCP_DECOY_PORTSCAN);
00125 break;
00126
00127 case PS_ALERT_PORTSWEEP:
00128 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_TCP_PORTSWEEP);
00129 portsweep = true;
00130 break;
00131
00132 case PS_ALERT_DISTRIBUTED:
00133 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_TCP_DISTRIBUTED_PORTSCAN);
00134 break;
00135
00136 case PS_ALERT_ONE_TO_ONE_FILTERED:
00137 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_TCP_FILTERED_PORTSCAN);
00138 break;
00139
00140 case PS_ALERT_ONE_TO_ONE_DECOY_FILTERED:
00141 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_TCP_FILTERED_DECOY_PORTSCAN);
00142 break;
00143
00144 case PS_ALERT_PORTSWEEP_FILTERED:
00145 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_TCP_PORTSWEEP_FILTERED);
00146 portsweep = true;
00147 break;
00148
00149 case PS_ALERT_DISTRIBUTED_FILTERED:
00150 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_TCP_FILTERED_DISTRIBUTED_PORTSCAN);
00151 break;
00152
00153 default:
00154 return;
00155 }
00156
00157 // Only log open ports for portsweeps after the alert has been generated.
00158 if (proto->open_ports_cnt and !portsweep)
00159 {
00160 make_open_port_info(p, proto);
00161 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_OPEN_PORT);
00162 }
00163 }
00164
00165 static void PortscanAlertUdp(Packet*, PS_PROTO* proto)
00166 {
00167 assert(proto);
00168
00169 switch (proto->alerts)
00170 {
00171 case PS_ALERT_ONE_TO_ONE:
00172 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_UDP_PORTSCAN);
00173 break;
00174
00175 case PS_ALERT_ONE_TO_ONE_DECOY:
00176 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_UDP_DECOY_PORTSCAN);
00177 break;
00178
00179 case PS_ALERT_PORTSWEEP:
00180 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_UDP_PORTSWEEP);
00181 break;
00182
00183 case PS_ALERT_DISTRIBUTED:
00184 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_UDP_DISTRIBUTED_PORTSCAN);
00185 break;
00186
00187 case PS_ALERT_ONE_TO_ONE_FILTERED:
00188 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_UDP_FILTERED_PORTSCAN);
00189 break;
00190
00191 case PS_ALERT_ONE_TO_ONE_DECOY_FILTERED:
00192 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_UDP_FILTERED_DECOY_PORTSCAN);
00193 break;
00194
00195 case PS_ALERT_PORTSWEEP_FILTERED:
00196 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_UDP_PORTSWEEP_FILTERED);
00197 break;
00198
00199 case PS_ALERT_DISTRIBUTED_FILTERED:
00200 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN);
00201 break;
00202
00203 default:
00204 break;
00205 }
00206 }
00207
00208 static void PortscanAlertIp(Packet*, PS_PROTO* proto)
00209 {
00210 assert(proto);
00211
00212 switch (proto->alerts)
00213 {
00214 case PS_ALERT_ONE_TO_ONE:
00215 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_IP_PORTSCAN);
00216 break;
00217
00218 case PS_ALERT_ONE_TO_ONE_DECOY:
00219 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_IP_DECOY_PORTSCAN);
00220 break;
00221
00222 case PS_ALERT_PORTSWEEP:
00223 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_IP_PORTSWEEP);
00224 break;
00225
00226 case PS_ALERT_DISTRIBUTED:
00227 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_IP_DISTRIBUTED_PORTSCAN);
00228 break;
00229
00230 case PS_ALERT_ONE_TO_ONE_FILTERED:
00231 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_IP_FILTERED_PORTSCAN);
00232 break;
00233
00234 case PS_ALERT_ONE_TO_ONE_DECOY_FILTERED:
00235 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_IP_FILTERED_DECOY_PORTSCAN);
00236 break;
00237
00238 case PS_ALERT_PORTSWEEP_FILTERED:
00239 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_IP_PORTSWEEP_FILTERED);
00240 break;
00241
00242 case PS_ALERT_DISTRIBUTED_FILTERED:
00243 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN);
00244 break;
00245
00246 default:
00247 break;
00248 }
00249 }
00250
00251 static void PortscanAlertIcmp(Packet*, PS_PROTO* proto)
00252 {
00253 assert(proto);
00254
00255 switch (proto->alerts)
00256 {
00257 case PS_ALERT_PORTSWEEP:
00258 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_ICMP_PORTSWEEP);
00259 break;
00260
00261 case PS_ALERT_PORTSWEEP_FILTERED:
00262 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_ICMP_PORTSWEEP_FILTERED);
00263 break;
00264
00265 default:
00266 break;
00267 }
00268 }
00269
00270 static void PortscanAlert(PS_PKT* ps_pkt, PS_PROTO* proto, int proto_type)
00271 {
00272 Packet* p = ps_pkt->pkt;
00273
00274 if (proto->alerts == PS_ALERT_OPEN_PORT)
00275 {
00276 make_open_port_info(p, p->ptrs.sp);
00277 DetectionEngine::queue_event(GID_PORT_SCAN, PSNG_OPEN_PORT);
00278 }
00279 else
00280 {
00281 make_port_scan_info(p, proto);
00282
00283 switch (proto_type)
00284 {
00285 case PS_PROTO_TCP:
00286 PortscanAlertTcp(p, proto);
00287 break;
00288
00289 case PS_PROTO_UDP:
00290 PortscanAlertUdp(p, proto);
00291 break;
00292
00293 case PS_PROTO_ICMP:
00294 PortscanAlertIcmp(p, proto);
00295 break;
00296
00297 case PS_PROTO_IP:
00298 PortscanAlertIp(p, proto);
00299 break;
00300 }
00301 }
00302 }
00303
00304 static void PrintIPPortSet(IP_PORT* p)
00305 {
00306 char ip_str[80], output_str[80];
00307
00308 SnortSnprintf(ip_str, sizeof(ip_str), "%s", p->ip.get_addr()->ntoa());
00309
00310 if (p->notflag)
00311 SnortSnprintf(output_str, sizeof(output_str), " !%s", ip_str);
00312 else
00313 SnortSnprintf(output_str, sizeof(output_str), " %s", ip_str);
00314
00315 if (((p->ip.get_family() == AF_INET6) and (p->ip.get_bits() != 128)) ||
00316 ((p->ip.get_family() == AF_INET ) and (p->ip.get_bits() != 32 )))
00317 SnortSnprintfAppend(output_str, sizeof(output_str), "/%d", p->ip.get_bits());
00318
00319 SF_LNODE* cursor;
00320 PORTRANGE* pr =(PORTRANGE*)sflist_first(&p->portset.port_list, &cursor);
00321
00322 if ( pr and pr->port_lo != 0 )
00323 SnortSnprintfAppend(output_str, sizeof(output_str), " : ");
00324
00325 for (; pr != nullptr;
00326 pr=(PORTRANGE*)sflist_next(&cursor) )
00327 {
00328 if ( pr->port_lo != 0)
00329 {
00330 SnortSnprintfAppend(output_str, sizeof(output_str), "%u", pr->port_lo);
00331 if ( pr->port_hi != pr->port_lo )
00332 {
00333 SnortSnprintfAppend(output_str, sizeof(output_str), "-%u", pr->port_hi);
00334 }
00335 SnortSnprintfAppend(output_str, sizeof(output_str), " ");
00336 }
00337 }
00338 LogMessage("%s\n", output_str);
00339 }
00340
00341 static void PrintPortscanConf(PortscanConfig* config)
00342 {
00343 char buf[STD_BUF + 1];
00344
00345 LogMessage("Portscan Detection Config:\n");
00346 SnortSnprintf(buf, sizeof(buf), " Detect Protocols: ");
00347
00348 if ( config->detect_scans & PS_PROTO_TCP )
00349 sfsnprintfappend(buf, sizeof(buf)-1, "TCP ");
00350
00351 if ( config->detect_scans & PS_PROTO_UDP )
00352 sfsnprintfappend(buf, sizeof(buf)-1, "UDP ");
00353
00354 if ( config->detect_scans & PS_PROTO_ICMP )
00355 sfsnprintfappend(buf, sizeof(buf)-1, "ICMP ");
00356
00357 if ( config->detect_scans & PS_PROTO_IP )
00358 sfsnprintfappend(buf, sizeof(buf)-1, "IP");
00359
00360 LogMessage("%s\n", buf);
00361 SnortSnprintf(buf, sizeof(buf), " Detect Scan Type: ");
00362
00363 if (config->detect_scan_type & PS_TYPE_PORTSCAN)
00364 sfsnprintfappend(buf, sizeof(buf)-1, "portscan ");
00365
00366 if (config->detect_scan_type & PS_TYPE_PORTSWEEP)
00367 sfsnprintfappend(buf, sizeof(buf)-1, "portsweep ");
00368
00369 if (config->detect_scan_type & PS_TYPE_DECOYSCAN)
00370 sfsnprintfappend(buf, sizeof(buf)-1, "decoy_portscan ");
00371
00372 if (config->detect_scan_type & PS_TYPE_DISTPORTSCAN)
00373 sfsnprintfappend(buf, sizeof(buf)-1, "distributed_portscan");
00374
00375 LogMessage("%s\n", buf);
00376 LogMessage(" Memcap (in bytes): %lu\n", config->memcap);
00377 LogMessage(" Number of Nodes: %ld\n", config->memcap / ps_node_size());
00378
00379 if ( config->logfile )
00380 LogMessage(" Logfile: %s\n", "yes");
00381
00382 if (config->ignore_scanners)
00383 {
00384 LogMessage(" Ignore Scanner IP List:\n");
00385 SF_LNODE* cursor;
00386
00387 IP_PORT* p = (IP_PORT*)sflist_first(&config->ignore_scanners->ip_list, &cursor);
00388
00389 for ( ; p; p = (IP_PORT*)sflist_next(&cursor) )
00390 PrintIPPortSet(p);
00391 }
00392
00393 if (config->ignore_scanned)
00394 {
00395 LogMessage(" Ignore Scanned IP List:\n");
00396 SF_LNODE* cursor;
00397
00398 IP_PORT* p = (IP_PORT*)sflist_first(&config->ignore_scanned->ip_list, &cursor);
00399
00400 for ( ; p; p = (IP_PORT*)sflist_next(&cursor) )
00401 PrintIPPortSet(p);
00402 }
00403
00404 if (config->watch_ip)
00405 {
00406 LogMessage(" Watch IP List:\n");
00407 SF_LNODE* cursor;
00408
00409 IP_PORT* p = (IP_PORT*)sflist_first(&config->watch_ip->ip_list, &cursor);
00410
00411 for ( ; p; p = (IP_PORT*)sflist_next(&cursor) )
00412 PrintIPPortSet(p);
00413 }
00414 }
00415
00416 //-------------------------------------------------------------------------
00417 // class stuff
00418 //-------------------------------------------------------------------------
00419
00420 PortScan::PortScan(PortScanModule* mod)
00421 {
00422 config = mod->get_data();
00423 }
00424
00425 PortScan::~PortScan()
00426 {
00427 if ( config )
00428 delete config;
00429 }
00430
00431 void PortScan::tinit()
00432 {
00433 ps_init_hash(config->memcap);
00434 }
00435
00436 void PortScan::tterm()
00437 {
00438 ps_cleanup();
00439 }
00440
00441 void PortScan::show(SnortConfig*)
00442 {
00443 PrintPortscanConf(config);
00444 }
00445
00446 void PortScan::eval(Packet* p)
00447 {
00448 Profile profile(psPerfStats);
00449
00450 new_invoked_inspector(7, p, 0);
00451
00452 assert(p->ptrs.ip_api.is_ip());
00453
00454 if ( p->packet_flags & PKT_REBUILT_STREAM )
00455 return;
00456
00457 ++spstats.total_packets;
00458
00459 PS_PKT ps_pkt;
00460 memset(&ps_pkt, 0x00, sizeof(PS_PKT));
00461 ps_pkt.pkt = p;
00462
00463 ps_detect(&ps_pkt);
00464
00465 if (ps_pkt.scanner and ps_pkt.scanner->proto.alerts and
00466 (ps_pkt.scanner->proto.alerts != PS_ALERT_GENERATED))
00467 {
00468 PortscanAlert(&ps_pkt, &ps_pkt.scanner->proto, ps_pkt.proto);
00469 }
00470
00471 if (ps_pkt.scanned and ps_pkt.scanned->proto.alerts and
00472 (ps_pkt.scanned->proto.alerts != PS_ALERT_GENERATED))
00473 {
00474 PortscanAlert(&ps_pkt, &ps_pkt.scanned->proto, ps_pkt.proto);
00475 }
00476 }
00477
00478 //-------------------------------------------------------------------------
00479 // api stuff
00480 //-------------------------------------------------------------------------
00481
00482 static Module* mod_ctor()
00483 { return new PortScanModule; }
00484
00485 static void mod_dtor(Module* m)
00486 { delete m; }
00487
00488 static Inspector* sp_ctor(Module* m)
00489 { return new PortScan((PortScanModule*)m); }
00490
00491 static void sp_dtor(Inspector* p)
00492 { delete p; }
00493
00494 static void sp_reset()
00495 { ps_reset(); }
00496
00497 static const InspectApi sp_api =
00498 {
00499 {
00500 PT_INSPECTOR,
00501 sizeof(InspectApi),
00502 INSAPI_VERSION,
00503 0,
00504 API_RESERVED,
00505 API_OPTIONS,
00506 PS_NAME,
00507 PS_HELP,
00508 mod_ctor,
00509 mod_dtor
00510 },
00511 IT_PROBE,
00512 (uint16_t)PktType::ANY_IP,
00513 nullptr, // buffers
00514 nullptr, // service
00515 nullptr, // pinit
00516 nullptr, // pterm
00517 nullptr, // tinit
00518 nullptr, // tterm
00519 sp_ctor,
00520 sp_dtor,
00521 nullptr, // ssn
00522 sp_reset // FIXIT-L only inspector using this, eliminate?
00523 };
00524
00525 #ifdef BUILDING_SO
00526 SO_PUBLIC const BaseApi* snort_plugins[] =
00527 #else
00528 const BaseApi* nin_port_scan[] =
00529 #endif
00530 {
00531 &sp_api.base,
00532 nullptr
00533 };
00534
END OF CODE