...
After configuring BFF to correctly (and effectively) run your target application, you should eventually see some crashing test cases. For example, here is drillresults.py
output from a brief fuzzing campaign against a target application:
Code Block | ||||
---|---|---|---|---|
| ||||
0x2cb0f334.0x4bb3d30a - Exploitability rank: 10 Fuzzed file: results\TARGET\crashers\EXPLOITABLE\0x2cb0f334.0x4bb3d30a\sf_7d7bb89974213e3de4d2b9289fa0caba-4257-0x00130000-minimized.EXT exception 0: ExceptionHandlerCorrupted accessing 0x00130000 0040eaec f3a5 rep movs dword ptr es:[edi],dword ptr [esi] Code executing in: image00400000 exception 1: ReadAVonIP accessing 0x6e4e99dd *** Byte pattern is in fuzzed file! *** 6e4e99dd ?? ??? Instruction pointer is not in a loaded module! exception 2: ReadAVonIP accessing 0x6e4e99dd *** Byte pattern is in fuzzed file! *** 6e4e99dd ?? ??? Instruction pointer is not in a loaded module! exception 3: ReadAVonIP accessing 0x6e4e99dd *** Byte pattern is in fuzzed file! *** 6e4e99dd ?? ??? Instruction pointer is not in a loaded module! exception 4: ReadAVonIP accessing 0x6e4e99dd *** Byte pattern is in fuzzed file! *** 6e4e99dd ?? ??? Instruction pointer is not in a loaded module! exception 5: ReadAVonIP accessing 0x6e4e99dd *** Byte pattern is in fuzzed file! *** 6e4e99dd ?? ??? Instruction pointer is not in a loaded module! exception 6: ReadAVonIP accessing 0x6e4e99dd *** Byte pattern is in fuzzed file! *** 6e4e99dd ?? ??? Instruction pointer is not in a loaded module! |
...
BFF includes the ability to perform string minimization during fuzzing. For every unique crash encountered, instead of minimizing the crashing testcase to the seed file, BFF will minimize the crashing testcase to a string of ASCII 'x' characters. The option is enabled with the following configuration item in bff.yaml
:
Code Block | ||||
---|---|---|---|---|
| ||||
runoptions: minimize: string |
...
BFF also has an option to treat unique EFAs as unique crashes. On the Windows platform, this is done by simply appending the EFA pattern onto the !exploitable
crash hash. For example, in the crash at the beginning of this page, the crash hash of 0x2cb0f334.0x4bb3d30a
will be reported as 0x2cb0f334.0x4bb3d30a.6e4e99dd
if the following option is set:
Code Block | ||||
---|---|---|---|---|
| ||||
runoptions: keep_unique_faddr: True |
...
When testing out fuzzing strategies, it can be effective to target old software. The assumption here is that older software is more likely to crash when fuzzed. This assumption turns out to be quite true:
Code Block | ||||
---|---|---|---|---|
| ||||
0x2cb0f334.0x4bb3d30a - Exploitability rank: 10 Fuzzed file: results\TARGET\crashers\EXPLOITABLE\0x2cb0f334.0x4bb3d30a\sf_7d7bb89974213e3de4d2b9289fa0caba-4257-0x00130000-minimized.EXT exception 0: ExceptionHandlerCorrupted accessing 0x00130000 0040eaec f3a5 rep movs dword ptr es:[edi],dword ptr [esi] Code executing in: image00400000 exception 1: ReadAVonIP accessing 0x6e4e99dd *** Byte pattern is in fuzzed file! *** 6e4e99dd ?? ??? Instruction pointer is not in a loaded module! exception 2: ReadAVonIP accessing 0x6e4e99dd *** Byte pattern is in fuzzed file! *** 6e4e99dd ?? ??? Instruction pointer is not in a loaded module! exception 3: ReadAVonIP accessing 0x6e4e99dd *** Byte pattern is in fuzzed file! *** 6e4e99dd ?? ??? Instruction pointer is not in a loaded module! exception 4: ReadAVonIP accessing 0x6e4e99dd *** Byte pattern is in fuzzed file! *** 6e4e99dd ?? ??? Instruction pointer is not in a loaded module! exception 5: ReadAVonIP accessing 0x6e4e99dd *** Byte pattern is in fuzzed file! *** 6e4e99dd ?? ??? Instruction pointer is not in a loaded module! exception 6: ReadAVonIP accessing 0x6e4e99dd *** Byte pattern is in fuzzed file! *** 6e4e99dd ?? ??? Instruction pointer is not in a loaded module! |
This looks quite promising! The first thing we will do is take this crash and do a Metasploit string minimization on it:
Code Block | ||||
---|---|---|---|---|
| ||||
C:\BFF>tools\minimize.py -s -k -f results\psp501-x\crashers\EXPLOITABLE\0x5b334a69.0xae9fae70.0x58787878_0xe6b39f75.0x28e42113.0x7878787c\sf_1f25044e863e7b1bef5ae42d968fe27f-siv0qq-0x58787878.wpg |
After this is done, we will have a number of files in the minimizer_out
directory. The one I'm interested in has -min-mtsp
appended to the file name. We can run tools\repro.py
to reproduce the crash:
Code Block | ||||
---|---|---|---|---|
| ||||
C:\BFF>tools\repro.py
minimizer_out\sf_1f25044e863e7b1bef5ae42d968fe27f-siv0qq-0x58787878-0x58787878-min-mtsp.wpg
-p immunitydebugger |
Assuming that immunitydebugger.exe
is in our PATH, this will reproduce the newly-string-minimized crash in Immunity Debugger:
...
Other old target that I looked at was FastStone MaxView 1.6. After a short amount of fuzzing, this crash came up:
Code Block | ||||
---|---|---|---|---|
| ||||
0x3eda38dc.0x5ce6d1f9.0x00cc0000_0x3eda38dc.0x3e7d918a.0x7878787c_0x3eda38dc.0x7095d__ - Exploitability rank: 50
Fuzzed
file:
results\maxview-x\crashers\EXPLOITABLE\0x3eda38dc.0x5ce6d1f9.0x00cc0000_0x3eda38dc.0x3e7d918a.0x7878787c_0x3eda38dc.0x7095d__\sf_540cee04253030f363f7902b6edc732d-aikdpf-0x00cc0000.tga
exception 0: WriteAV accessing 0x00cc0000
004fd19c 880416 mov byte ptr [esi+edx],al ds:0023:00cc0000=??
Code executing in: image00400000
exception 1: WriteAV accessing 0x7878787c *** Byte pattern is in fuzzed file! ***
004022c2 894104 mov dword ptr [ecx+4],eax ds:0023:7878787c=????????
|
Here we have a crash that is ranked as a 50
. What makes this crash interesting is that we have a WriteAV
exception, and the faulting address looks to be under our control (due to the 78
's). Let's look in Immunity Debugger:
...
Why does Microsoft !exploitable treat this as an UNKNOWN
? Remember that the !exploitable visibility is limited to the current basic block. Specifically:
Code Block | ||||
---|---|---|---|---|
| ||||
300F57FD . F646 06 04 TEST BYTE PTR DS:[ESI+6],4 300F5801 . 8B45 10 MOV EAX,DWORD PTR SS:[EBP+10] 300F5804 . 8975 F0 MOV DWORD PTR SS:[EBP-10],ESI 300F5807 . 8945 F4 MOV DWORD PTR SS:[EBP-C],EAX 300F580A . 75 10 JNZ SHORT EXCEL.300F581C |
...
Well now this is interesting! We have an access violation on a CALL
instruction. This is reported as PROBABLY_EXPLOITABLE
by !exploitable:
Code Block | ||||
---|---|---|---|---|
| ||||
30ea6b1a ff10 call dword ptr [eax] ds:0023:00000000=???????? 0:000> !exploitable !exploitable 1.6.0.0 *** ERROR: Symbol file could not be found. Defaulted to export symbols for Excel.EXE - Exploitability Classification: PROBABLY_EXPLOITABLE Recommended Bug Title: Probably Exploitable - Read Access Violation on Control Flow starting at mso!Ordinal6543+0x0000000000001eda (Hash=0x3d855f61.0xa61eef28) Access violations near null in control flow instructions are considered probably exploitable. 0:000> |
We'd like to do better than that, though. Use your favorite tracing techniques and determine how the EAX
register is set before the CALL
. Looking at the Excel code, we determine that EAX
is populated by dereferencing the pointer specified by our original exception twice. By using a pointer-to-a-pointer memory location as our address, we can now demonstrate full control of the CALL
instruction:
...
Jackpot! We've started with an UNKNOWN
crash, and we now have a demonstrably EXPLOITABLE
crash. All of this was made possible with the following two BFF options use together:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
runoptions: minimize: string keep_unique_faddr: True |
...