diff --git a/libnetutil/ICMPv4Header.cc b/libnetutil/ICMPv4Header.cc index 384cd4618..85497ab1b 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 3158fe36a..49c6f3c47 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 71525501d..bc48f0e53 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 20ed9991a..3791e1ffa 100644 --- a/nping/ArgParser.cc +++ b/nping/ArgParser.cc @@ -134,6 +134,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 */ @@ -1182,6 +1184,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 07bbc7274..4de61b318 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; @@ -1656,40 +1653,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 91a850f23..2e16b5ea1 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 43fa3c939..768631fc5 100644 --- a/nping/ProbeMode.cc +++ b/nping/ProbeMode.cc @@ -968,7 +968,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); @@ -1008,7 +1011,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); 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 e60c1365f..d9dac2402 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