...
When the above two options are both used, BFF is put into a mode where it becomes more obvious which crashes have an EFA that is directly influenced by the bytes in the fuzzed file. By looking for EFA patterns that have 0x78
in them, you can find crashes where you may be able to influence the code being executed. For example:
Here are multiple crashes where the faulting address appear to be influenced by the 'x' bytes in our fuzzed file. Again, to put BFF into this mode, use the following two options:
...
Assuming that immunitydebugger.exe
is in our PATH, this will reproduce the newly-string-minimized crash in Immunity Debugger:
Here we see that we have control of the instruction pointer, and we have some Metasploit pattern bytes at our disposal on the stack. If we open our newly-created file in a hex editor, we can see the bytes that control the instruction pointer. Many of the other bytes are the Metasploit pattern.
We now take those bytes and set them to a pattern that we recognize. I use 0x44434241
, which is ASCII ABCD
in little-endian format, and save the file as abcd.wpg
.
Finally, we run tools\repro.py
on minimizer_out\abcd.wpg
:
Here we have demonstrated control of the instruction pointer, and we have some stack space at our disposal. It is pretty easy to go from here to something that launches calc.exe
when the image is opened, for example. By default, there is no DEP, ASLR, SafeSEH, or any of the other exploit mitigations at play with this application, since the target application is so old.
...
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:
Here we can see that MaxView is attempting to write the value in EAX
into the location designated by ECX+4
. By looking at the registers EAX
and ECX
, we can see that we control both of them. This is a clear indication that we can write an arbitrary dword to an arbitrary location. This is known as an exploitable write-what-where vulnerability, or a "Write4."
...
Here we are reproducing a crash in the default UbuFuzz campaign of ImageMagick that indicates control of the EFA. Using tools/repro.py -e
, which uses the edb debugger, we get:
Here we can see that the faulting instruction is dereferencing EAX
to load a qword of data into XMM0
. XMM1
is also populated with the bytes at EAX + 8
. The instruction immediately following is:
...
Using the above technique of enabling in-campaign string minimization along with considering the EFA as part of the crash hash, we find an UNKNOWN
crash in Microsoft Office 2003 Excel:
Why does Microsoft !exploitable treat this as an UNKNOWN
? Remember that the !exploitable visibility is limited to the current basic block. Specifically:
...
If we're not using something like a symbolic execution engine, the experimentation of what happens after the original fault can take a bit of trial-and-error testing. First we simply take a memory address that can be dereferenced, and change the 0x78787878
pattern in our fuzzed file to this address. Reproducing the crash in Immunity Debugger gives us:
Well now this is interesting! We have an access violation on a CALL
instruction. This is reported as PROBABLY_EXPLOITABLE
by !exploitable:
...
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:
...