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:
@@ -1,8 +1,12 @@
|
|||||||
#Nmap Changelog ($Id$); -*-text-*-
|
#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
|
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
|
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
|
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]
|
the value of TLS SNI via --ssl-servername [Hank Leininger, nnposter]
|
||||||
|
|||||||
74
payload.cc
74
payload.cc
@@ -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
|
/* Newlines are significant because keyword directives (like "source") that
|
||||||
follow the payload string are significant to the end of the line. */
|
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++) {
|
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 proto_dport key(IPPROTO_UDP, ports[p]);
|
||||||
struct payload payload;
|
struct payload portPayload;
|
||||||
|
bool duplicate = false;
|
||||||
|
|
||||||
payload.data = payload_data;
|
portPayloadIterator = portPayloads.find(key);
|
||||||
payloads[key] = payload;
|
|
||||||
|
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);
|
free(ports);
|
||||||
@@ -356,15 +380,39 @@ int init_payloads(void) {
|
|||||||
/* Get a payload appropriate for the given UDP port. For certain selected ports
|
/* 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
|
a payload is returned, and for others a zero-length payload is returned. The
|
||||||
length is returned through the length pointer. */
|
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 = "";
|
static const char *payload_null = "";
|
||||||
std::map<struct proto_dport, struct payload>::iterator it;
|
std::map<struct proto_dport, std::vector<struct payload> >::iterator portPayloadIterator;
|
||||||
proto_dport pp(IPPROTO_UDP, dport);
|
std::vector<struct payload> portPayloadVector;
|
||||||
|
std::vector<struct payload>::iterator portPayloadVectorIterator;
|
||||||
|
proto_dport key(IPPROTO_UDP, dport);
|
||||||
|
int portPayloadVectorSize;
|
||||||
|
|
||||||
it = payloads.find(pp);
|
portPayloadIterator = portPayloads.find(key);
|
||||||
if (it != payloads.end()) {
|
|
||||||
*length = it->second.data.size();
|
if (portPayloadIterator != portPayloads.end()) {
|
||||||
return it->second.data.data();
|
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 {
|
} else {
|
||||||
*length = 0;
|
*length = 0;
|
||||||
return payload_null;
|
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
|
returns the global random payload. Otherwise, for certain selected ports a
|
||||||
payload is returned, and for others a zero-length payload is returned. The
|
payload is returned, and for others a zero-length payload is returned. The
|
||||||
length is returned through the length pointer. */
|
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) {
|
if (o.extra_payload != NULL) {
|
||||||
*length = o.extra_payload_length;
|
*length = o.extra_payload_length;
|
||||||
return o.extra_payload;
|
return o.extra_payload;
|
||||||
} else {
|
} else {
|
||||||
return udp_port2payload(dport, length);
|
return udp_port2payload(dport, length, tryno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,9 +134,8 @@
|
|||||||
|
|
||||||
#define PAYLOAD_FILENAME "nmap-payloads"
|
#define PAYLOAD_FILENAME "nmap-payloads"
|
||||||
|
|
||||||
const char *get_udp_payload(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);
|
const char *udp_port2payload(u16 dport, size_t *length, u8 tryno);
|
||||||
int init_payloads(void);
|
int init_payloads(void);
|
||||||
|
|
||||||
#endif /* PAYLOAD_H */
|
#endif /* PAYLOAD_H */
|
||||||
|
|
||||||
|
|||||||
@@ -1393,7 +1393,7 @@ UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss,
|
|||||||
const char *payload;
|
const char *payload;
|
||||||
size_t payload_length;
|
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) {
|
if (hss->target->af() == AF_INET) {
|
||||||
for (decoy = 0; decoy < o.numdecoys; decoy++) {
|
for (decoy = 0; decoy < o.numdecoys; decoy++) {
|
||||||
|
|||||||
@@ -785,7 +785,7 @@ public:
|
|||||||
const char *payload;
|
const char *payload;
|
||||||
size_t payload_length;
|
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. */
|
/* For UDP we encode the token in the source port. */
|
||||||
if (source->ss_family == AF_INET) {
|
if (source->ss_family == AF_INET) {
|
||||||
|
|||||||
Reference in New Issue
Block a user