This commit introduces pcapng awareness into Radamsa.
we spoke a few months ago about extending Radamsa with PCAPNG fuzzying awareness. Briefly, we wanted Radamsa to mutate PCAPNG files in a way that guarantees valid PCAPNG files as output.
As part of our work at Nozomi Networks, Guglielmo Fachini and I have experimented a bit and finally obtained a working prototype. This MR is thus meant to be a starting point for discussing what we have done so far and what we could do from now on. In particular, we are eager to hear your feedback because, if the work we are doing is of interest to you, we would be glad to improve it and do what's needed in order to eventually merge the feature (or a variant of it) into Radamsa itself.
To give some context, a PCAPNG file is just a sequence of blocks. There are several kind of blocks, Ehnanced Packet Block being the most interesting one for us due to the fact that it is generally used to store network packets. A block always has some metadata associated to it (e.g. type, length, capture time, etc) and it can use either the little-endian or big-endian format depending on the machine that created the file. Currently we should be able to parse all PCAPNG files containing metadata in the little-endian format, but in the future we could extend the support to the big-endian format too. For more information you can consult the PCAPNG specification .
Now, on the technical side, our solution consists mainly of three parts:
- a generator that parses PCAPNG files and produces a stream of PCAPNG blocks
- an instrumentation applied to all mutations that takes care of unpacking and packing blocks before and after mutating them (e.g. extract the payload, mutate, rebuild the block by updating metadata such as payload size)
- a mutation predicate that determines whether a block has to be mutated or not (e.g. we don't want to mutate PCAPNG blocks containing information about the capture)
This last point is particularly invasive with respect to Radamsa, however it is of fundamental importance in that it prevents Radamsa from going into an infinite loop when blocks that must not be mutated are encountered and multiple unique output files are requested.
To test our changes we have used two scripts that you can also run against a directory containing PCAPNG files:
pcapng_identity_test.sh It checks that running Radamsa with the NOP mutation applied at most once produces an output file that is an exact copy of the input file.
$ ./pcapng_identity_test.sh pcapng
pcapng_well_formedness_test.sh It checks that running Radamsa with its default parameters produces N output files that are valid PCAPNG. Specifically, we check that tcpdump is able to parse those files without exiting with a non-zero value, that is, with no errors.
$ ./pcapng_well_formedness_test.sh pcapng 3
We used both tests extensively on all our internal traffic which, unfortunately, we cannot share. You can find some public traffic on the Wireshark website .
Our code is probably not very idiomatic and we didn't invest too much time in safety checks (e.g. packing/upacking) since this is a just a proof of concept. If you have any suggestion or if you notice some misunderstanding of Radamsa on our side, please don't hesitate to tell us. We would really appreciate it!
To conclude, we were also wondering whether our changes could be made more generic, effectively allowing our work on PCAPNG (and possibly many others) to be just a sort of plugin.
Thank you very much for your time!
Alberto Zaccagni, Guglielmo Fachini