Hi,
I recently stumbled upon results of running afl-tmin that I did not expect, I've
had ~1,5KB crashing input that got minimized (quiet fast I may add) to 10B, in
addition to minimization, tmining totally changed the execution path of that
input.
Instrumented binary was compiled with Clang and ASAN, before minimization it
ended on bad-free and after tmin it was global-buffer-overflow, also point of
crash, and trace where totally different
I mean, it's nice to have extra crash for free :) but still I decided to ping
you and share that effect, and ask if there is a way to run tmin in crash mode
so it would use instrumentation to preserve point of crash and maybe path
As I think about it it was predictable, as app has lot of crash points and tmin
crashing mode don't care about instrumentation and I know I can edit the app and
make it exit just before that bad-free if pointer is wild and use non-crashing
mode... but I suppose it would be helpful not only to me to be able to minimize
different crashes on target that has them in different places out of the box.
FZ
PS:
Logs, if you care:
$ afl-tmin -t 10000 -m none -i ./bad_free -o bad_free_smaller ./app @@
afl-tmin 2.49b by <
lca...@google.com>
[+] Read 1449 bytes from './bad_free'.
[*] Performing dry run (mem limit = 0 MB, timeout = 10000 ms)...
[+] Program exits with a signal, minimizing in crash mode.
[*] Stage #0: One-time block normalization...
[+] Block normalization complete, 1353 bytes replaced.
[*] --- Pass #1 ---
[*] Stage #1: Removing blocks of data...
Block length = 128, remaining size = 1449
Block length = 64, remaining size = 512
Block length = 32, remaining size = 256
Block length = 16, remaining size = 160
Block length = 8, remaining size = 96
Block length = 4, remaining size = 56
Block length = 2, remaining size = 36
Block length = 1, remaining size = 32
[+] Block removal complete, 1421 bytes deleted.
[*] Stage #2: Minimizing symbols (16 code points)...
[+] Symbol minimization finished, 4 symbols (4 bytes) replaced.
[*] Stage #3: Character minimization...
[+] Character minimization done, 1 byte replaced.
[*] --- Pass #2 ---
[*] Stage #1: Removing blocks of data...
Block length = 1, remaining size = 28
[+] Block removal complete, 18 bytes deleted.
[*] Stage #2: Minimizing symbols (5 code points)...
[+] Symbol minimization finished, 0 symbols (0 bytes) replaced.
[*] Stage #3: Character minimization...
[+] Character minimization done, 0 bytes replaced.
[*] --- Pass #3 ---
[*] Stage #1: Removing blocks of data...
Block length = 1, remaining size = 10
[+] Block removal complete, 0 bytes deleted.
File size reduced by : 99.31% (to 10 bytes)
Characters simplified : 13580.00%
Number of execs done : 281
Fruitless execs : path=137 crash=0 hang=0
[*] Writing output to 'bad_free_smaller'...
[+] We're done here. Have a nice day!
$ app ./bad_free
==18919==ERROR: AddressSanitizer: attempting free on address which was not
malloc()-ed: 0x00490000f100 in thread T0
[...]
Address 0x00490000f100 is a wild pointer.
SUMMARY: AddressSanitizer: bad-free (app+0x4dead)
==18919==ABORTING
Aborted
$ app ./bad_free_smaller
==18920==ERROR: AddressSanitizer: global-buffer-overflow on address
0x000000504657 at pc [...]
READ of size 1 at 0x000000504657 thread T0
[...]
0x000000504657 is located 9 bytes to the left of global variable [...] of size 16
0x000000504657 is located 119 bytes to the right of global variable[...] of size 512
SUMMARY: AddressSanitizer: global-buffer-overflow (app+0x4beaf)
[...]
==18920==ABORTING
Aborted
sorry for log obfuscation and not giving a sample but I work on closed-source ;/
FZ
--
- Filip Zarzyński