1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 04:31:29 +00:00

Allow multiple UDP payloads per port. Closes #1859 (payloads to be committed later)

This commit is contained in:
dmiller
2020-09-01 17:09:46 +00:00
parent 083475eb6f
commit 9c83be3833
5 changed files with 70 additions and 19 deletions

View File

@@ -1,8 +1,12 @@
#Nmap Changelog ($Id$); -*-text-*-
o [GH#1859] Allow multiple UDP payloads to be specified for a port in
nmap-payloads. If the first payload does not get a response, the remaining
payloads are tried round-robin. [Paul Miseiko, Rapid7]
o [GH#1616] New option --discovery-ignore-rst tells Nmap to ignore TCP RST
responses when determining if a target is up. Useful when firewalls are
spoofing RST packets. [Tom Sellers]
spoofing RST packets. [Tom Sellers, Rapid7]
o [Ncat][GH#2087][GH#1927][GH#1928][GH#1974] It is now possible to override
the value of TLS SNI via --ssl-servername [Hank Leininger, nnposter]

View File

@@ -171,7 +171,7 @@ struct proto_dport {
}
};
static std::map<struct proto_dport, struct payload> payloads;
static std::map<struct proto_dport, std::vector<struct payload> > portPayloads;
/* Newlines are significant because keyword directives (like "source") that
follow the payload string are significant to the end of the line. */
@@ -307,11 +307,35 @@ static int load_payloads_from_file(FILE *fp) {
}
for (int p = 0; p < count; p++) {
std::map<struct proto_dport, std::vector<struct payload> >::iterator portPayloadIterator;
std::vector<struct payload> portPayloadVector;
std::vector<struct payload>::iterator portPayloadVectorIterator;
struct proto_dport key(IPPROTO_UDP, ports[p]);
struct payload payload;
struct payload portPayload;
bool duplicate = false;
payload.data = payload_data;
payloads[key] = payload;
portPayloadIterator = portPayloads.find(key);
if (portPayloadIterator != portPayloads.end()) {
portPayloadVector = portPayloadIterator->second;
portPayloadVectorIterator = portPayloadVector.begin();
while (portPayloadVectorIterator != portPayloadVector.end()) {
if (portPayloadVectorIterator->data == payload_data) {
log_write(LOG_STDERR, "UDP port payload duplication found on port: %u\n", ports[p]);
duplicate = true;
break;
}
portPayloadVectorIterator++;
}
}
if (!duplicate) {
portPayload.data = payload_data;
portPayloadVector.push_back(portPayload);
portPayloads[key] = portPayloadVector;
}
}
free(ports);
@@ -356,15 +380,39 @@ int init_payloads(void) {
/* Get a payload appropriate for the given UDP port. For certain selected ports
a payload is returned, and for others a zero-length payload is returned. The
length is returned through the length pointer. */
const char *udp_port2payload(u16 dport, size_t *length) {
const char *udp_port2payload(u16 dport, size_t *length, u8 tryno) {
static const char *payload_null = "";
std::map<struct proto_dport, struct payload>::iterator it;
proto_dport pp(IPPROTO_UDP, dport);
std::map<struct proto_dport, std::vector<struct payload> >::iterator portPayloadIterator;
std::vector<struct payload> portPayloadVector;
std::vector<struct payload>::iterator portPayloadVectorIterator;
proto_dport key(IPPROTO_UDP, dport);
int portPayloadVectorSize;
it = payloads.find(pp);
if (it != payloads.end()) {
*length = it->second.data.size();
return it->second.data.data();
portPayloadIterator = portPayloads.find(key);
if (portPayloadIterator != portPayloads.end()) {
portPayloadVector = portPayloads.find(key)->second;
portPayloadVectorSize = portPayloadVector.size();
tryno %= portPayloadVectorSize;
if (portPayloadVectorSize > 0) {
portPayloadVectorIterator = portPayloadVector.begin();
while (tryno > 0 && portPayloadVectorIterator != portPayloadVector.end()) {
tryno--;
portPayloadVectorIterator++;
}
assert (tryno == 0);
assert (portPayloadVectorIterator != portPayloadVector.end());
*length = portPayloadVectorIterator->data.size();
return portPayloadVectorIterator->data.data();
} else {
*length = 0;
return payload_null;
}
} else {
*length = 0;
return payload_null;
@@ -375,11 +423,11 @@ const char *udp_port2payload(u16 dport, size_t *length) {
returns the global random payload. Otherwise, for certain selected ports a
payload is returned, and for others a zero-length payload is returned. The
length is returned through the length pointer. */
const char *get_udp_payload(u16 dport, size_t *length) {
const char *get_udp_payload(u16 dport, size_t *length, u8 tryno) {
if (o.extra_payload != NULL) {
*length = o.extra_payload_length;
return o.extra_payload;
} else {
return udp_port2payload(dport, length);
return udp_port2payload(dport, length, tryno);
}
}

View File

@@ -134,9 +134,8 @@
#define PAYLOAD_FILENAME "nmap-payloads"
const char *get_udp_payload(u16 dport, size_t *length);
const char *udp_port2payload(u16 dport, size_t *length);
const char *get_udp_payload(u16 dport, size_t *length, u8 tryno);
const char *udp_port2payload(u16 dport, size_t *length, u8 tryno);
int init_payloads(void);
#endif /* PAYLOAD_H */

View File

@@ -1393,7 +1393,7 @@ UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss,
const char *payload;
size_t payload_length;
payload = get_udp_payload(pspec->pd.udp.dport, &payload_length);
payload = get_udp_payload(pspec->pd.udp.dport, &payload_length, tryno);
if (hss->target->af() == AF_INET) {
for (decoy = 0; decoy < o.numdecoys; decoy++) {

View File

@@ -785,7 +785,7 @@ public:
const char *payload;
size_t payload_length;
payload = get_udp_payload(pspec.pd.udp.dport, &payload_length);
payload = get_udp_payload(pspec.pd.udp.dport, &payload_length, 0);
/* For UDP we encode the token in the source port. */
if (source->ss_family == AF_INET) {