The blog post introduces a concept known as differential fuzzing. The idea is to generate input, process it through multiple pipelines and see if the output is the same. In blockchain protocols that must have the same data, such as consensus client protocols, this is a great way to find bugs. Asymmetric Research uses this for many things, like fuzzing the Solana validator client differences Agave and Firedancer.
The target for this demonstration is around JSON parsing. Their chosen fuzzer is AFL. The majority of fuzzing is the same as with a regular AFL fuzzer - input generation and such. The main difference is that we have two JSON parse calls to make. If the results are different, then this results in a "crash"!
While running the fuzzer, they ran into several bugs but they were unimportant for security. For instance, 222E2322 was an out of range number that was rejected for one parser but fine by another. Since this doesn't have security consequences, they patched out to accept this case as valid. This happened several times. It should be noted that using a fuzzer is an iterative process - it's not just letting it run once and forgetting about it.
Eventually, they get a legitimate parsing difference. serde_json gets a parsing error while json-rust parsers it. After looking at a hexdump, it becomes clear - the vertical control tab (^K) is causing the issue. json-rust has a goal of being less strict than the other JSON parser, since this can cause friction at times.
This bug is likely enough to cause a consensus divergence, which is pretty interesting. Many other parsing issues between implementations, like described by the Bishop Fox post, can lead to major security consequences by returning difference values.
There are many ways to make this fuzzer better. Using structured input on JSON data, parallelization and checks for equivalence on the data. Overall, a great post discussing automatic bug finding via differential fuzzing.