Fuzzification: Anti-Fuzzing Techniques [pdf]
usenix.org
usenix.org
Regardless of this specific paper, assuming all bugs can be found and fixed is not a sound assumption. I'm happy to see techniques that correctly assume undetected bugs exist, and propose solutions to that problem. (Other than asking developers to just find and fix all the bugs, which again, is not possible)
> Unfortunately, advanced fuzzing techniques can also be used by malicious attackers
So the solution is to make it harder to find bugs instead of finding and fixing them, which affects everybody, not just "attackers". This is like the companies who'll sue or ban researchers for finding bugs in their stuff. Or programmers on HN who criticize researchers for publicizing vulnerabilities when companies refuse to fix them and give them the runaround.
I can already see companies like Apple implementing something like this instead of putting in the required time, effort and money to fix issues, while simultaneously villifying legitimate security researchers who look for vulnerabilities in their products.
In many cases vulnerabilities come from complex, messy, disorganized, or just poorly written code. Assuming that the "fuzzification" techniques are implemented by the same developer who wrote the original vulnerable code; how can we be sure that he isn't introducing MORE bugs in his fuzzified version?
For example, if you have a product which is NOT currently vulnerable and add BranchTrap to it the likelihood that you're creating a vulnerability where one never existed before is insanely high.
So you essentially created a code path for the fuzzer that never would have existed if you never tried to fool the fuzzer in the first place.
Assuming two binaries, an original and a "fuzzified" version and an unlimited amount of time: Which version would have overall More vulnerable code paths? Probably the fuzzified version simply because it has more code. The point of producing two binaries is that one can be analyzed quickly and one slowly. But if your original code doesn't contain a vulnerability and the fuzzed version does your trusted party doesn't mean anything.
This is not insignificant either. Time to fuzz an application no longer matters for the attacker. If he grinds on it long enough he will have a vuln that the authors aren't aware of (and can't/won't even find now). It doesn't matter if it takes 2 years to find a vuln in your code... Someone will do it.
Note that whether or not that behaviour happens to be undefined in the source language is irrelevant. Undefined behaviour still tends to manifest in a few recognisable ways, which this would then obfuscate.
While an interesting academic exercise, this has negative value to the software industry. I bet it'll still see a lot of use though.
Reminds me a bit of people trying to 'fix' errors with an empty `catch` block...
From my own skimming of the paper, the discussion of 'why?' boils down roughly to 'exploits are sometimes used for bad things'.
Do you believe your approach will actually improve the security of any systems, or will it just allow lazy vendors to hide their shallow bugs - leaving them to the most motivated (e.g. nation-state) adversaries?
If you or anyone else is interested, the strongest approaches when I last looked at everything tried to create full memory safety or do properties like CFI with strong assurance. Softbound+CETS, SafeCODE, and Data-Flow Integrity focused on memory safety with less performance hit. Code-Pointer Integrity with segments had low overhead. Some people were talking about S+C combined with DFI but overhead was crazy. I encourage folks to look at that kind of work, look at whatever [fast] mechanisms are in modern hardware, look at any software improvements in literature, and try to reduce the overhead of techniques like that (esp in combination).
Similar to you, I proposed we use techniques like Softbound+CETS on proprietary, closed applications to increase their security at a performance loss that can be made up for with cheap hardware. And then sell them on that saying security personnel cost way more than a few more rack servers.
1. An attacker skilled enough to perform black box binary fuzzing, and create a testing harnass. Will only be minimally hindered by anything less than full blown obfuscation.
2. This approach aims to 'fix' the problem of someone looking and testing your code, it's hiding (not fixing!) a symptom of the problem: you wrote vulnerable code. Why not spend this effort on improving existing and actually helpfull mitigations such as dep, aslr, re-linking and pledge systems? Even better, why not re-write error prone or complex code in a safe language?!
2.1. This is security through obscurity, the vulnerable code is still there, someone will find it.
3. End users will be inconvenienced because obfuscation implies inefficient code.
4. This widens the gap between white hat research (not funded, often done for reputation) and black hat research which is worth good money for a quality exploit and therefore more sustainable for researchers making it their day job.
2. Well yeah! If I write vulnerable code I would want to make sure it was as difficult as possible to discover. Who wants easy to discover vulnerabilities? Anyone who I want looking at my code will have the source and can build without obfuscation and fuzzing protection.
2.1 If I'm a big enough target sure, but if I make it as annoying and difficult to work with my software as possible the hope is that you'll go somewhere else.
3. The performance impact is super mild and completely unnoticeable on anything that works in human time. The slight performance hit to protect your IP is a no brainier calculation. Nvidia famously implores absolutely crazy obfuscation on their chips and they're still the market leader on speed.
4. Companies that use these kinds of techniques don't recognize a difference between the two. If you're not employed or contracted by them and you're looking at their code you are the adversary.
I think it's funny that when we talk about encryption we talk about its strength like "an attacker with a supercomputer X years to brute-force it" but when it comes to things like this we say "security through obscurity! Worthless!" instead of "the total population of people with the skills to even begin to find vulnerabilities is professional security researches and could all fit comfortably in a mid-sized event venue."
And yet, Oracle still has some market share.
There is a specific program path, or "key", that leads to a crash. Fuzzers attempt to search all paths in a somewhat intelligent manner to find the "key" path that leads to a crash.
We can inhibit the fuzzers ability to find the key by increasing the search space by adding more paths. The way in which this paper adds paths takes advantages of the way intelligent fuzzers explore the path space to make it even more difficult to search the entire path space.
What fuzzification actually enables is to hide more keys (crashes) from a constant amount of (current) effort. Those crashes are still there and now there are more of them, waiting for someone to find them with an alternative method or simply by buying more fuzzing equipment to scale horizontally.
3. Software is layered, if every layer of your electron app starts using this type of obfuscation you will notice the slowdown.
1. I think there's an underlying assumption we both make about this research: it will increase the costs of finding exploits, but it will definitively not prevent a skilled attacker.
I also don't think it absolutely disqualifies anyone who's already able to craft an exploit, perhaps it will take them longer but anyone with the reversing chops to abuse an aslr weakness can figure out how to patch out or reverse the jumptables.
With that in mind, it comes back at the question:
Is it worth it? Increase the costs for an attacker but simultaneously adding an incentive for vendors to be lazy, an chose a cheap band-aid bolted-on-security approach as opposed to what we all know is the eventual (expensive) fix for memory related security problems?
I still think: hell no, don't make this stuff available, invest resources in alternative mitigations if not in outright solving the issue.
Nothing that they're doing would be a "minimal" hindrance to people employing fuzzers. Rather, it all seems like an extreme pain in the ass, and it would doubtlessly deter people from fuzzing.
My guess is that the authors likely share your opinion of the utility of anti-fuzzing. This is (literally) a science project, not an advertisement for a product. In the scientific context, that the most popular current-generation fuzzing tools can be straightforwardly retarded through these techniques is an important observation.
I can send a malicious individual a link to this paper saying I used these techniques on my binary but fuzzing will still be more difficult.
Just like encryption takes my message and jumbles it up to "obscure it", this technique is adding slowdowns and false paths to hinder the fuzzer.
Knowing my message is encrypted doesn't make it any easier to read, just like knowing my binary has been fuzzification-ified doesn't make it any easier to fuzz. The only thing that would help is giving you the key to my message, or program paths with added complexity to throw off the fuzzer.
0: Note that obfuscator output is not source code.