From c4bdee677c6f16aa33a37a28af695622bf8378b7 Mon Sep 17 00:00:00 2001 From: Slava Bacherikov Date: Sun, 11 Jan 2026 11:11:08 +0200 Subject: [PATCH 1/2] nping: Add --badsum option for ICMP mode This adds support for --badsum flag that already exists and used for TCP/UDP modes to work for ICMP packets as well. --- libnetutil/ICMPv4Header.cc | 11 +++++++++++ libnetutil/ICMPv4Header.h | 1 + libnetutil/ICMPv6Header.cc | 8 ++++++++ nping/ArgParser.cc | 3 +++ nping/NpingOps.cc | 37 ------------------------------------- nping/NpingOps.h | 4 +--- nping/ProbeMode.cc | 10 ++++++++-- 7 files changed, 32 insertions(+), 42 deletions(-) diff --git a/libnetutil/ICMPv4Header.cc b/libnetutil/ICMPv4Header.cc index b66fbec48..d47457981 100644 --- a/libnetutil/ICMPv4Header.cc +++ b/libnetutil/ICMPv4Header.cc @@ -453,6 +453,17 @@ int ICMPv4Header::setSum(u16 s){ } /* End of setSum() */ +/** Set the ICMP checksum field to a random value that will never + * match the correct checksum. This is achieved by computing the correct + * checksum first and then XORing it with a random value that can + * never be zero. */ +int ICMPv4Header::setSumRandom(){ + this->setSum(); + this->h.checksum = this->getSum() ^ (1 + (get_random_u16() % (65535-1))); + return OP_SUCCESS; +} /* End of setSumRandom() */ + + /** Returns the value of the checksum field. * @warning The returned value is in NETWORK byte order, no conversion is * performed */ diff --git a/libnetutil/ICMPv4Header.h b/libnetutil/ICMPv4Header.h index 389e3d71e..c3928fd3f 100644 --- a/libnetutil/ICMPv4Header.h +++ b/libnetutil/ICMPv4Header.h @@ -459,6 +459,7 @@ class ICMPv4Header : public ICMPHeader { /* Checksum */ int setSum(); int setSum(u16 s); + int setSumRandom(); u16 getSum() const; /* Unused and reserved fields */ diff --git a/libnetutil/ICMPv6Header.cc b/libnetutil/ICMPv6Header.cc index e31fceedf..abdadcb36 100644 --- a/libnetutil/ICMPv6Header.cc +++ b/libnetutil/ICMPv6Header.cc @@ -424,6 +424,14 @@ u16 ICMPv6Header::getSum() const{ } /* End of getSum() */ +/** Set the ICMP checksum field to a random value that will never + * match the correct checksum */ +int ICMPv6Header::setSumRandom(){ + this->setSum(); + this->h.checksum = this->getSum() ^ (1 + (get_random_u16() % (65535-1))); + return OP_SUCCESS; +} /* End of setSumRandom() */ + /** @warning Supplied value MUST be in host byte order because it will get * converted by this method using htonl() */ int ICMPv6Header::setReserved(u32 val){ diff --git a/nping/ArgParser.cc b/nping/ArgParser.cc index 76787840c..7abff8b89 100644 --- a/nping/ArgParser.cc +++ b/nping/ArgParser.cc @@ -135,6 +135,8 @@ int ArgParser::parseArguments(int argc, char *argv[]) { {"flags", required_argument, 0, 0}, {"ack", required_argument, 0, 0}, {"win", required_argument, 0, 0}, + + /* TCP/UDP/ICMP */ {"badsum", no_argument, 0, 0}, /* ICMP */ @@ -1180,6 +1182,7 @@ void ArgParser::printUsage(void){ " --icmp-orig-time : Set originate timestamp.\n" " --icmp-recv-time : Set receive timestamp.\n" " --icmp-trans-time : Set transmit timestamp.\n" +" --badsum : Use a random invalid checksum. \n" "ARP/RARP PROBE MODE:\n" " --arp-type : Type: ARP, ARP-reply, RARP, RARP-reply.\n" " --arp-sender-mac : Set sender MAC address.\n" diff --git a/nping/NpingOps.cc b/nping/NpingOps.cc index 0a1988dae..9ddbef6b2 100644 --- a/nping/NpingOps.cc +++ b/nping/NpingOps.cc @@ -225,9 +225,6 @@ NpingOps::NpingOps() { icmp_code=0; icmp_code_set=false; - badsum_icmp=false; - badsum_icmp_set=false; - icmp_redir_addr.s_addr=0; icmp_redir_addr_set=false; @@ -1672,40 +1669,6 @@ bool NpingOps::issetICMPCode(){ } /* End of issetICMPCode() */ -/** Sets attribute badsum_icmp to "true". (Generate invalid checksums in ICMP - * packets) - * @return previous value of the attribute. */ -bool NpingOps::enableBadsumICMP() { - bool prev = this->badsum_icmp; - this->badsum_icmp=true; - this->badsum_icmp_set=true; - return prev; -} /* End of enableBadsumICMPTCP() */ - - -/** Sets attribute traceroute to "false". (Do NOT Generate invalid checksums - * in UDP / TCP packets) - * @return previous value of the attribute. */ -bool NpingOps::disableBadsumICMP() { - bool prev = this->badsum_icmp; - this->badsum_icmp=false; - this->badsum_icmp_set=true; - return prev; -} /* End of disableBadsumICMP() */ - - -/** Returns value of attribute badsum_icmp */ -bool NpingOps::getBadsumICMP() { - return this->badsum_icmp; -} /* End of getBadsumICMP() */ - - -/* Returns true if option has been set */ -bool NpingOps::issetBadsumICMP(){ - return this->badsum_icmp_set; -} /* End of issetBadsumICMP() */ - - /** Sets ICMPRedirectAddress. * @return OP_SUCCESS on success and OP_FAILURE in case of error. */ int NpingOps::setICMPRedirectAddress(struct in_addr val){ diff --git a/nping/NpingOps.h b/nping/NpingOps.h index f9ce6440b..3885642f5 100644 --- a/nping/NpingOps.h +++ b/nping/NpingOps.h @@ -210,7 +210,7 @@ class NpingOps { bool tcpflags_set; u16 tcpwin; /* TCP Window */ bool tcpwin_set; - bool badsum; /* Generate invalid TCP/UDP checksums? */ + bool badsum; /* Generate invalid TCP/UDP/ICMP checksums? */ bool badsum_set; /* ICMP */ @@ -218,8 +218,6 @@ class NpingOps { bool icmp_type_set; u8 icmp_code; /* ICMP Code */ bool icmp_code_set; - bool badsum_icmp; /* Generate invalid ICMP checksums? */ - bool badsum_icmp_set; struct in_addr icmp_redir_addr; /* ICMP Redirect Address */ /* ##TODO## Turn this into an IPAddress object */ bool icmp_redir_addr_set; u8 icmp_paramprob_pnt; /* ICMP Parameter Problem pointer */ diff --git a/nping/ProbeMode.cc b/nping/ProbeMode.cc index 7ad6971a5..ea965fec8 100644 --- a/nping/ProbeMode.cc +++ b/nping/ProbeMode.cc @@ -1082,7 +1082,10 @@ int ProbeMode::fillPacketICMP(NpingTarget *target, u8 *buff, int bufflen, int *f } /* Compute checksum */ - c4.setSum(); /* TODO: Do we want to implement --badsum-icmp? */ + if( o.getBadsum() == true ) + c4.setSumRandom(); + else + c4.setSum(); /* Fill the IPv4Header object with the info from NpingOps */ createIPv4(&i, &c4, "ICMP", target); @@ -1122,7 +1125,10 @@ int ProbeMode::fillPacketICMP(NpingTarget *target, u8 *buff, int bufflen, int *f createIPv6(&i6, &c6, "ICMPv6", target); /* Compute checksum */ - c6.setSum(); + if( o.getBadsum() == true ) + c6.setSumRandom(); + else + c6.setSum(); /* Store result in user supplied buffer */ *filledlen = i6.dumpToBinaryBuffer(buff, bufflen); From 28a64a848f378369f4f1cf30775d4eec444771ca Mon Sep 17 00:00:00 2001 From: Slava Bacherikov Date: Sun, 11 Jan 2026 11:29:52 +0200 Subject: [PATCH 2/2] nping: add docs about --badsum for ICMP --- nping/docs/nping-man.xml | 17 +++++++++++++++++ nping/docs/nping-usage.txt | 1 + nping/docs/nping.1 | 7 +++++++ 3 files changed, 25 insertions(+) diff --git a/nping/docs/nping-man.xml b/nping/docs/nping-man.xml index 2f1d73c66..9aa0c4b9c 100644 --- a/nping/docs/nping-man.xml +++ b/nping/docs/nping-man.xml @@ -1049,6 +1049,23 @@ SENT (4.0330s) TCP 192.168.0.21 > 3.3.3.3:139 + + + (Invalid Checksum) + (Nping option) + + + + Asks Nping to use an invalid ICMP checksum for the packets sent to + target hosts. Since virtually all host IP stacks properly drop these + packets, any responses received are likely coming from a firewall or + an IDS that didn't bother to verify the checksum. For more + details on this technique, see + . + + + + diff --git a/nping/docs/nping-usage.txt b/nping/docs/nping-usage.txt index 3e0cfca29..f621829c8 100644 --- a/nping/docs/nping-usage.txt +++ b/nping/docs/nping-usage.txt @@ -39,6 +39,7 @@ ICMP PROBE MODE: --icmp-orig-time : Set originate timestamp. --icmp-recv-time : Set receive timestamp. --icmp-trans-time : Set transmit timestamp. + --badsum : Use a random invalid checksum. ARP/RARP PROBE MODE: --arp-type : Type: ARP, ARP-reply, RARP, RARP-reply. --arp-sender-mac : Set sender MAC address. diff --git a/nping/docs/nping.1 b/nping/docs/nping.1 index dbb75605b..31af3a817 100644 --- a/nping/docs/nping.1 +++ b/nping/docs/nping.1 @@ -131,6 +131,7 @@ ICMP PROBE MODE: \-\-icmp\-orig\-time : Set originate timestamp\&. \-\-icmp\-recv\-time : Set receive timestamp\&. \-\-icmp\-trans\-time : Set transmit timestamp\&. + \-\-badsum : Use a random invalid checksum\&. ARP/RARP PROBE MODE: \-\-arp\-type : Type: ARP, ARP\-reply, RARP, RARP\-reply\&. \-\-arp\-sender\-mac : Set sender MAC address\&. @@ -678,6 +679,12 @@ This option sets the Transmit Timestamp in ICMP Timestamp messages\&. The Transm is as with \fB\-\-icmp\-orig\-time\fR\&. .RE +.PP +\fB\-\-badsum\fR (Invalid Checksum) +.RS 4 +Asks Nping to use an invalid ICMP checksum for the packets sent to target hosts\&. Since virtually all host IP stacks properly drop these packets, any responses received are likely coming from a firewall or an IDS that didn\*(Aqt bother to verify the checksum\&. For more details on this technique, see +\m[blue]\fB\%https://nmap.org/p60-12.html\fR\m[]\&. +.RE .SS "ICMP Types" .PP These identifiers may be used as mnemonics for the ICMP type numbers given to the