On Monday, I presented Flayer: Exposing Application Internals at the First USENIX Workshop on
Offensive Technologies (WOOT’07).
Flayer is a tool that I wrote for use in my everyday work. It allows me to
trace input through an application extracting the locations where that data
traverses conditional branches (
ifs) and where it is used in system
calls. (It traces this data with bit-precision.) Armed with the locations
where the data is used, Flayer can force the tainted code path to behave
differently by changing the outcome of conditional jumps and stepping over
function calls. I use this functionality to bypass banner checks, version
checks, magic checks, etc in applications when I need to test them. Once
the outer layer of an application has been removed (flayed), I use classic
fuzz testing techniques against the exposed code without needing full
protocol awareness or other large initial investments other testing approaches
To speed testing up, I wrote a helper program, named MKF, that uses ptrace to perform the same check-bypassing modifications on binaries at runtime without relying on Flayer (which has all the overhead of Valgrind/MemCheck). This gives me the best of both worlds: high speed fuzzing with the targeting of Flayer.
In addition to testing, I find that tracing input and modifying execution behavior on-the-fly is excellent for learning about an application quickly. This approach allows me to determine attack surfaces based on what functions are traversed without digging around the code for a while first. In a similar vein, I’ve also used Flayer to compare code paths that are followed in patched versus unpatched applications with the included interactive shell, flayersh.
Of course, the best part is that I was able to release Flayer publicly. This makes it available to everyone to try out and change. I hope that this turns out to be as useful for other people as has been for me.
That aside, the workshop itself was well-sized at around thirty people with several interesting talks. In particular, I enjoyed Robert Watson’s “Exploiting Concurrency Vulnerabilities in System Call Wrappers”. While time-of-check-time-of-use problems with system call wrappers have been discussed before, it was great to see some code for exploiting these problems across operating systems.