zmap/zmap — pull request #160 by hmoore-r7 (2014-05-23 17:27:22+00:00)
Title: Introduce UDP payload templates (feedback only)

This patch adds support for payload "templates" . This feature is activated with the following parameters:
```
-M udp --probe-args=template:/payload.tpl
```
Templates are essentially just packet payloads with inline variables expanded through the ${TYPE=PARAM} syntax. For example, the following template will generate a UDP packet that sends its source IP, source port, destination IP, destination port, and a random alphanumeric string.
```
Hello ${DADDR}:${DPORT},
My name is ${SADDR}:${SPORT} and I would like to tell you about ${RAND_ALPHANUM=32}!
```
This would generate a unique payload per sent packet (assuming no retries). This feature is required to implement a number of UDP protocol probes. For example, this allows a random DNS XID to be embedded into each request by using ${RAND_BYTES=2}. The template below is used to generate a SIP OPTIONS request with both the source, destination, and identify fields set:

```
OPTIONS sip:${RAND_ALPHA=8}@${DADDR} SIP/2.0
Via: SIP/2.0/UDP ${SADDR}:${SPORT};branch=${RAND_ALPHA=6}.${RAND_DIGIT=10};rport;alias
From: sip:${RAND_ALPHA=8}@${SADDR}:${SPORT};tag=${RAND_DIGIT=8}
To: sip:${RAND_ALPHA=8}@${DADDR}
Call-ID: ${RAND_DIGIT=10}@${SADDR}
CSeq: 1 OPTIONS
Contact: sip:${RAND_ALPHA=8}@${SADDR}:${SPORT}
Content-Length: 0
Max-Forwards: 20
User-Agent: ${RAND_ALPHA=8}
Accept: text/plain
```
Future work would include extending the number of field types, allowing random-length outputs (${RAND_BYTES=1-100}), and generally making the entire process more efficient. I would also like to add some sample templates for various protocols that require this kind of dynamic output.

The template parser is treats the input as a raw binary file and simply expands the fields as they are found. This could be improved by adding escape sequences and allowing some form of hex-escape. The example above requires CRLF line endings, which is not intuitive when using a normal text editor.

The generator is called for every packet and overwrites the existing payload and then adjusts the IP and UDP headers to match the new result. This could be obviously be more efficient. A better approach may be for the plugin to change its registered make_packet dispatch function if a template is specified, which would leave the original mode unaffected, performance-wise (no conditional branch in the middle of make_packet). It wasn't clear whether a plugin should be able to change its registered functions in the module_udp structure at runtime.

The performance of the generator could be improved and the giant select statement for field types could be made less redundant by combining source and destination operators.

The use of aesrand_getword() in the random byte generators may change the expected sequence of a scan with a given seed when templates are enabled. This seems moderately OK, but I may be missing something about how this function is used.

If anyone has feedback, please let me know. I have a handful of other minor fixes and improvements in the queue, but wanted to get an initial PR going before piling on additional changes.