From 50830f7488b8aecd5d99b2908c99c19d5b6c6d91 Mon Sep 17 00:00:00 2001 From: daniel Date: Wed, 3 Jun 2009 23:15:45 +0000 Subject: [PATCH] o Added initial SCTP port scanning support to Nmap. SCTP is a layer 4 protocol used mostly for telephony related applications. This brings the following new features: o SCTP INIT chunk port scan (-sY): open ports return an INIT-ACK chunk, closed ones an ABORT chunk. This is the SCTP equivalent of a TCP SYN stealth scan. o SCTP COOKIE-ECHO chunk port scan (-sZ): open ports are silent, closed ports return an ABORT chunk. o SCTP INIT chunk ping probes (-PY): host discovery using SCTP INIT chunk packets. o SCTP-specific IP protocol scan (-sO -p sctp). o SCTP-specific traceroute support (--traceroute). o The ability to use the deprecated Adler32 algorithm as specified in RFC 2960 instead of CRC32C from RFC 4960 (--adler32). o 42 well-known SCTP ports were added to the nmap-services file. Part of the work on SCTP support was kindly sponsored by Compass Security AG, Switzerland. [Daniel Roethlisberger] --- CHANGELOG | 18 + NmapOps.cc | 28 +- NmapOps.h | 7 + docs/nmap.dtd | 4 +- docs/refguide.xml | 198 ++++++++-- global_structures.h | 10 +- libdnet-stripped/NMAP_MODIFICATIONS | 9 +- libdnet-stripped/include/dnet.h | 1 + libdnet-stripped/include/dnet/Makefile.am | 2 +- libdnet-stripped/include/dnet/sctp.h | 168 +++++++++ libdnet-stripped/libdnet-stripped.vcproj | 4 + libdnet-stripped/src/crc32ct.h | 83 +++++ libdnet-stripped/src/ip-util.c | 31 ++ nmap-services | 70 +++- nmap.cc | 78 +++- nmap.h | 13 + nse_main.cc | 3 +- nse_nmaplib.cc | 6 +- nse_nsock.cc | 5 +- output.cc | 18 +- output.h | 2 +- portlist.cc | 34 +- portlist.h | 20 +- portreasons.cc | 8 +- portreasons.h | 3 +- protocols.h | 12 + scan_engine.cc | 422 ++++++++++++++++++++-- scan_engine.h | 7 + service_scan.cc | 11 +- services.cc | 36 +- services.h | 3 +- targets.cc | 2 +- targets.h | 1 + tcpip.cc | 77 ++++ tcpip.h | 14 + traceroute.cc | 77 +++- 36 files changed, 1333 insertions(+), 152 deletions(-) create mode 100644 libdnet-stripped/include/dnet/sctp.h create mode 100644 libdnet-stripped/src/crc32ct.h diff --git a/CHANGELOG b/CHANGELOG index 8791d760b..da8be426c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,23 @@ # Nmap Changelog ($Id$); -*-text-*- +o Added initial SCTP port scanning support to Nmap. SCTP is + a layer 4 protocol used mostly for telephony related applications. + This brings the following new features: + o SCTP INIT chunk port scan (-sY): open ports return an INIT-ACK + chunk, closed ones an ABORT chunk. This is the SCTP equivalent + of a TCP SYN stealth scan. + o SCTP COOKIE-ECHO chunk port scan (-sZ): open ports are silent, + closed ports return an ABORT chunk. + o SCTP INIT chunk ping probes (-PY): host discovery using SCTP + INIT chunk packets. + o SCTP-specific IP protocol scan (-sO -p sctp). + o SCTP-specific traceroute support (--traceroute). + o The ability to use the deprecated Adler32 algorithm as specified + in RFC 2960 instead of CRC32C from RFC 4960 (--adler32). + o 42 well-known SCTP ports were added to the nmap-services file. + Part of the work on SCTP support was kindly sponsored by + Compass Security AG, Switzerland. [Daniel Roethlisberger] + o [Zenmap] The Topology tab now has a "Save Snapshot" button that allows saving the current topology display as PNG, PostScript, PDF, and SVG. [Joao Medeiros] diff --git a/NmapOps.cc b/NmapOps.cc index 8da7522a4..59bff557b 100644 --- a/NmapOps.cc +++ b/NmapOps.cc @@ -238,6 +238,7 @@ void NmapOps::Initialize() { max_host_group_sz = 100000; // don't want to be restrictive unless user sets max_tcp_scan_delay = MAX_TCP_SCAN_DELAY; max_udp_scan_delay = MAX_UDP_SCAN_DELAY; + max_sctp_scan_delay = MAX_SCTP_SCAN_DELAY; max_ips_to_scan = 0; extra_payload_length = 0; extra_payload = NULL; @@ -258,6 +259,8 @@ void NmapOps::Initialize() { listscan = pingscan = allowall = ackscan = bouncescan = connectscan = 0; rpcscan = nullscan = xmasscan = fragscan = synscan = windowscan = 0; maimonscan = idlescan = finscan = udpscan = ipprotscan = noresolve = 0; + sctpinitscan = 0; + sctpcookieechoscan = 0; append_output = 0; memset(logfd, 0, sizeof(FILE *) * LOG_NUM_FILES); ttl = -1; @@ -266,6 +269,7 @@ void NmapOps::Initialize() { gettimeofday(&start_time, NULL); pTrace = vTrace = false; reason = false; + adler32 = false; if (datadir) free(datadir); datadir = NULL; if (xsl_stylesheet) free(xsl_stylesheet); @@ -305,6 +309,10 @@ void NmapOps::Initialize() { sourcesocklen = 0; } +bool NmapOps::SCTPScan() { + return sctpinitscan|sctpcookieechoscan; +} + bool NmapOps::TCPScan() { return ackscan|bouncescan|connectscan|finscan|idlescan|maimonscan|nullscan|synscan|windowscan|xmasscan; } @@ -318,9 +326,9 @@ bool NmapOps::UDPScan() { IPv6 is being used. It will return false in those cases where a RawScan is not neccessarily used. */ bool NmapOps::RawScan() { - if (ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|osscan|synscan|udpscan|windowscan|xmasscan) + if (ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|osscan|synscan|udpscan|windowscan|xmasscan|sctpinitscan|sctpcookieechoscan) return true; - if (pingtype & (PINGTYPE_ICMP_PING|PINGTYPE_ICMP_MASK|PINGTYPE_ICMP_TS|PINGTYPE_TCP_USE_ACK|PINGTYPE_UDP)) + if (pingtype & (PINGTYPE_ICMP_PING|PINGTYPE_ICMP_MASK|PINGTYPE_ICMP_TS|PINGTYPE_TCP_USE_ACK|PINGTYPE_UDP|PINGTYPE_SCTP_INIT)) return true; return false; @@ -336,11 +344,11 @@ void NmapOps::ValidateOptions() { /* Insure that at least one scantype is selected */ - if (TCPScan() + UDPScan() + ipprotscan + listscan + pingscan == 0) { + if (TCPScan() + UDPScan() + SCTPScan() + ipprotscan + listscan + pingscan == 0) { if (isr00t && af() == AF_INET) synscan++; else connectscan++; - // if (verbose) error("No tcp, udp, or ICMP scantype specified, assuming %s scan. Use -sP if you really don't want to portscan (and just want to see what hosts are up).", synscan? "SYN Stealth" : "vanilla tcp connect()"); + // if (verbose) error("No TCP, UDP, SCTP or ICMP scantype specified, assuming %s scan. Use -sP if you really don't want to portscan (and just want to see what hosts are up).", synscan? "SYN Stealth" : "vanilla tcp connect()"); } if (pingtype != PINGTYPE_NONE && spoofsource) { @@ -364,11 +372,15 @@ void NmapOps::ValidateOptions() { fatal("Sorry, UDP Ping (-PU) only works if you are root (because we need to read raw responses off the wire) and only for IPv4 (cause fyodor is too lazy right now to add IPv6 support and nobody has sent a patch)"); } + if ((pingtype & PINGTYPE_SCTP_INIT) && (!isr00t || af() != AF_INET)) { + fatal("Sorry, SCTP INIT Ping (-PY) only works if you are root (because we need to read raw responses off the wire) and only for IPv4 (cause fyodor is too lazy right now to add IPv6 support and nobody has sent a patch)"); + } + if ((pingtype & PINGTYPE_PROTO) && (!isr00t || af() != AF_INET)) { fatal("Sorry, IPProto Ping (-PO) only works if you are root (because we need to read raw responses off the wire) and only for IPv4"); } - if (ipprotscan + (TCPScan() || UDPScan()) + listscan + pingscan > 1) { + if (ipprotscan + (TCPScan() || UDPScan() || SCTPScan()) + listscan + pingscan > 1) { fatal("Sorry, the IPProtoscan, Listscan, and Pingscan (-sO, -sL, -sP) must currently be used alone rather than combined with other scan types."); } @@ -376,7 +388,7 @@ void NmapOps::ValidateOptions() { fatal("-PN (skip ping) is incompatable with -sP (ping scan). If you only want to enumerate hosts, try list scan (-sL)"); } - if (pingscan && (TCPScan() || UDPScan() || ipprotscan || listscan)) { + if (pingscan && (TCPScan() || UDPScan() || SCTPScan() || ipprotscan || listscan)) { fatal("Ping scan is not valid with any other scan types (the other ones all include a ping scan"); } @@ -394,7 +406,7 @@ void NmapOps::ValidateOptions() { /* We start with stuff users should not do if they are not root */ if (!isr00t) { - if (ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|synscan|udpscan|windowscan|xmasscan) { + if (ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|synscan|udpscan|windowscan|xmasscan|sctpinitscan|sctpcookieechoscan) { fatal("You requested a scan type which requires %s.", privreq); } @@ -477,7 +489,7 @@ void NmapOps::ValidateOptions() { fatal("--min-rate=%g must be less than or equal to --max-rate=%g", min_packet_send_rate, max_packet_send_rate); } - if (af() == AF_INET6 && (generate_random_ips|numdecoys|osscan|bouncescan|fragscan|ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|synscan|udpscan|windowscan|xmasscan)) { + if (af() == AF_INET6 && (generate_random_ips|numdecoys|osscan|bouncescan|fragscan|ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|synscan|udpscan|windowscan|xmasscan|sctpinitscan|sctpcookieechoscan)) { fatal("Sorry -- IPv6 support is currently only available for connect() scan (-sT), ping scan (-sP), and list scan (-sL). OS detection, random targets and decoys are also not supported with IPv6. Further support is under consideration."); } diff --git a/NmapOps.h b/NmapOps.h index 9e338017c..db7170ebe 100644 --- a/NmapOps.h +++ b/NmapOps.h @@ -123,6 +123,7 @@ class NmapOps { bool TCPScan(); /* Returns true if at least one chosen scan type is TCP */ bool UDPScan(); /* Returns true if at least one chosen scan type is UDP */ + bool SCTPScan(); /* Returns true if at least one chosen scan type is SCTP */ /* Returns true if at least one chosen scan type uses raw packets. It does not currently cover cases such as TCP SYN ping scan which @@ -222,8 +223,10 @@ class NmapOps { void setMaxHostGroupSz(unsigned int sz); unsigned int maxTCPScanDelay() { return max_tcp_scan_delay; } unsigned int maxUDPScanDelay() { return max_udp_scan_delay; } + unsigned int maxSCTPScanDelay() { return max_sctp_scan_delay; } void setMaxTCPScanDelay(unsigned int delayMS) { max_tcp_scan_delay = delayMS; } void setMaxUDPScanDelay(unsigned int delayMS) { max_udp_scan_delay = delayMS; } + void setMaxSCTPScanDelay(unsigned int delayMS) { max_sctp_scan_delay = delayMS; } /* Sets the Name of the XML stylesheet to be printed in XML output. If this is never called, a default stylesheet distributed with @@ -291,6 +294,8 @@ class NmapOps { int rpcscan; int synscan; int udpscan; + int sctpinitscan; + int sctpcookieechoscan; int windowscan; int xmasscan; int noresolve; @@ -314,6 +319,7 @@ class NmapOps { bool log_errors; bool traceroute; bool reason; + bool adler32; #ifndef NOLUA int script; @@ -347,6 +353,7 @@ class NmapOps { int max_retransmissions; unsigned int max_tcp_scan_delay; unsigned int max_udp_scan_delay; + unsigned int max_sctp_scan_delay; unsigned int min_host_group_sz; unsigned int max_host_group_sz; void Initialize(); diff --git a/docs/nmap.dtd b/docs/nmap.dtd index 3a475f0d3..5c97bd9a8 100644 --- a/docs/nmap.dtd +++ b/docs/nmap.dtd @@ -58,11 +58,11 @@ - + - +