вт, 21 апр. 2020 г. в 20:24, Tim Düsterhus <t...@bastelstu.be>:
> Ilya, > > Am 21.04.20 um 17:02 schrieb Илья Шипицин: > >> The two CVEs I mentioned were bugs *I* found using afl-fuzz. The biggest > >> hurdle back when I attempted fuzzing was not getting an appropriate > >> workload (I've just created a few basic requests using nghttp), but > >> instead getting the requests into HAProxy in a way so that afl is able > >> to detect branches that change based on input changes. This branch > >> detection is *the* main selling point of afl. Just sending random > >> garbage is not going to turn up interesting stuff, if anything. > >> > > > > > > I really beleive that people who can perform fuzzing are smarter than me. > > But I hope > > to be able to run fuzzing some day :) > > > > what are "branches" ? are them git branches ? do you have any setup > > step-by-step > > Branches refer to branches within the generated machine code (i.e. > conditional jumps). AFL works similarly to ASAN in that it adds some > additional code to the executable to detect whether a branch was taken > (i.e. a jump happened) or not. > > As a super simplified example consider the following code: > > if (buf[0] == 'b') { > if (buf[1] == '1') { > crash(); > } > // do something (1) > } > else { > // do something (2) > } > > I would then use the following as the initial payload: > > buf = "a0" > > AFL would then execute the "(2)" line. Afterwards it might try the > following (increase the first byte by 1): > > buf = "b0" > I thought of some more high level fuzzing without intercepting code path. for example, we know about range queries Range: bytes=0-1023 i.e. bytes=(integer)-(integer) what if we send Range: bytes=1023-0 or Range: bytes=1023 or Range: bytes=abc-def and so on. it does not require any code modification. but proper workload generator should be chosen > AFL would then detect that something changed: Instead of jumping to the > 'else' it would continue executing the second 'if'. Now AFL knows that > the first byte being 'b' is special (or at least different to 'a'). > Instead of attempting 'c' it might then proceed to modify the second > byte. By incrementing it from '0' to '1' it notices that again something > changed: The program crashes. > > This "intelligent" processing could find the bug with just 3 inputs > instead of having to randomly test 256*256 combinations for the two > bytes. In reality the results are even more impressive: AFL was able to > generate a valid JPG image based on the starting input 'hello'. > > See this blog post: > https://lcamtuf.blogspot.com/2014/11/pulling-jpegs-out-of-thin-air.html > > > described how those CVE were detected ? > > > > I intended to write up a blog post after my initial find, but never got > around to it. For the first one it basically went like this: > > 1. Compile the standalone hpack decoder. > 2. Start afl-fuzz with a single input on the decoder. > 3. Wait 2 minutes. > 4. Report security issue. > > Not joking, it literally took 2 minutes of throwing data at the decoder > to find the issue on a single core cloud server. I believe you'll be > able to figure it out yourself. To reproduce the bug you need to check > out commit f7db9305aa8642cb5145bba6f8948400c52396af (that's one before > the fix). > > The second one was more involved and less reliable. I used desock.so > from https://github.com/zardus/preeny to receive "network" input from > stdin and patched HAProxy to exit after serving a single request. Then I > used a simplistic configuration pointing to an nginx and seeded AFL > using some HTTP/2 requests I generated using nghttp against `nc -l > > request`. However that dirty hackery resulted in AFL not reliably > detecting whether something changed because the input changed or whether > it just randomly changed. > thank you, I'll try next weekend > > Best regards > Tim Düsterhus >