Nmap Development mailing list archives

[RFC PATCH] Add --win option to set receive window size in TCP SYN Scan


From: Bernhard Thaler <bernhard.thaler () r-it at>
Date: Wed, 8 Jul 2015 16:07:44 +0200

Some IPS seem to detect and block nmap probes due to hard-coded TCP receive
window size of 1024.

Add --win option to set any receive window size 0 < win < 65535 to avoid being
detected by hard-coded window size 1024.
---
 NmapOps.cc         |    1 +
 NmapOps.h          |    1 +
 nmap.cc            |    7 +++++++
 scan_engine_raw.cc |    8 ++++----
 4 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/NmapOps.cc b/NmapOps.cc
index b6ff244..776cf74 100644
--- a/NmapOps.cc
+++ b/NmapOps.cc
@@ -342,6 +342,7 @@ void NmapOps::Initialize() {
   append_output = 0;
   memset(logfd, 0, sizeof(FILE *) * LOG_NUM_FILES);
   ttl = -1;
+  win = 0;
   badsum = 0;
   nmap_stdout = stdout;
   gettimeofday(&start_time, NULL);
diff --git a/NmapOps.h b/NmapOps.h
index 5728a50..dcbbda6 100644
--- a/NmapOps.h
+++ b/NmapOps.h
@@ -344,6 +344,7 @@ class NmapOps {
   FILE *logfd[LOG_NUM_FILES];
   FILE *nmap_stdout; /* Nmap standard output */
   int ttl; // Time to live
+  int win; // TCP Receive Window Size
   int badsum;
   char *datadir;
   /* A map from abstract data file names like "nmap-services" and "nmap-os-db"
diff --git a/nmap.cc b/nmap.cc
index 97f85f1..e4b3634 100644
--- a/nmap.cc
+++ b/nmap.cc
@@ -321,6 +321,7 @@ static void printusage(int rc) {
          "  --data-length <num>: Append random data to sent packets\n"
          "  --ip-options <options>: Send packets with specified ip options\n"
          "  --ttl <val>: Set IP time-to-live field\n"
+         "  --win <val>: Set TCP receive window size field\n"
          "  --spoof-mac <mac address/prefix/vendor name>: Spoof your MAC address\n"
          "  --badsum: Send packets with a bogus TCP/UDP/SCTP checksum\n"
          "OUTPUT:\n"
@@ -632,6 +633,7 @@ void parse_options(int argc, char **argv) {
     {"thc", no_argument, 0, 0},
     {"badsum", no_argument, 0, 0},
     {"ttl", required_argument, 0, 0}, /* Time to live */
+    {"win", required_argument, 0, 0}, /* TCP Receive Window Size */
     {"traceroute", no_argument, 0, 0},
     {"reason", no_argument, 0, 0},
     {"allports", no_argument, 0, 0},
@@ -776,6 +778,11 @@ void parse_options(int argc, char **argv) {
           if (o.ttl < 0 || o.ttl > 255) {
             fatal("ttl option must be a number between 0 and 255 (inclusive)");
           }
+        } else if (strcmp(long_options[option_index].name, "win") == 0) {
+          o.win = atoi(optarg);
+          if (o.win < 0 || o.win > 65535) {
+            fatal("win option must be a number between 0 and 65535 (inclusive)");
+          }
         } else if (strcmp(long_options[option_index].name, "datadir") == 0) {
           o.datadir = strdup(optarg);
         } else if (strcmp(long_options[option_index].name, "servicedb") == 0) {
diff --git a/scan_engine_raw.cc b/scan_engine_raw.cc
index 54f258a..e1c8eda 100644
--- a/scan_engine_raw.cc
+++ b/scan_engine_raw.cc
@@ -1166,7 +1166,7 @@ static u8 *build_protoscan_packet(const struct sockaddr_storage *src,
     case IPPROTO_TCP:
       packet = build_tcp_raw(&src_in->sin_addr, &dst_in->sin_addr,
                              o.ttl, ipid, IP_TOS_DEFAULT, false, o.ipoptions, o.ipoptionslen,
-                             sport, DEFAULT_TCP_PROBE_PORT, get_random_u32(), get_random_u32(), 0, TH_ACK, 0, 0, NULL, 
0,
+                             sport, DEFAULT_TCP_PROBE_PORT, get_random_u32(), get_random_u32(), 0, TH_ACK, o.win, 0, 
NULL, 0,
                              o.extra_payload, o.extra_payload_length, packetlen);
       break;
     case IPPROTO_ICMP:
@@ -1215,7 +1215,7 @@ static u8 *build_protoscan_packet(const struct sockaddr_storage *src,
     case IPPROTO_TCP:
       packet = build_tcp_raw_ipv6(&src_in6->sin6_addr, &dst_in6->sin6_addr,
                                   0, ipid, o.ttl,
-                                  sport, DEFAULT_TCP_PROBE_PORT, get_random_u32(), get_random_u32(), 0, TH_ACK, 0, 0, 
NULL, 0,
+                                  sport, DEFAULT_TCP_PROBE_PORT, get_random_u32(), get_random_u32(), 0, TH_ACK, o.win, 
0, NULL, 0,
                                   o.extra_payload, o.extra_payload_length, packetlen);
       break;
     case IPPROTO_ICMPV6:
@@ -1317,7 +1317,7 @@ UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss,
                                o.ttl, ipid, IP_TOS_DEFAULT, false,
                                o.ipoptions, o.ipoptionslen,
                                sport, pspec->pd.tcp.dport,
-                               seq, ack, 0, pspec->pd.tcp.flags, 0, 0,
+                               seq, ack, 0, pspec->pd.tcp.flags, o.win, 0,
                                tcpops, tcpopslen,
                                o.extra_payload, o.extra_payload_length,
                                &packetlen);
@@ -1339,7 +1339,7 @@ UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss,
       sin6 = (struct sockaddr_in6 *) &source;
       packet = build_tcp_raw_ipv6(&sin6->sin6_addr, hss->target->v6hostip(),
                                   0, 0, o.ttl, sport, pspec->pd.tcp.dport,
-                                  seq, ack, 0, pspec->pd.tcp.flags, 0, 0,
+                                  seq, ack, 0, pspec->pd.tcp.flags, o.win, 0,
                                   tcpops, tcpopslen,
                                   o.extra_payload, o.extra_payload_length,
                                   &packetlen);
-- 
1.7.10.4

_______________________________________________
Sent through the dev mailing list
https://nmap.org/mailman/listinfo/dev
Archived at http://seclists.org/nmap-dev/


Current thread: