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

@@ -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);
}
}