Fuzzing: Avoid Zero-Day Attacks -- Build Security In, Don't Add it!
"Software development companies can no longer rely on user communities to find bugs, they need to find new ways to protect their products and services.”
- Ari Takanen
Zero-Day vulnerabilities are unknown bugs hidden in software code. In contrast to known disclosed flaws with available patches and updates, vendors are unaware of these unknown bugs, and therefore they are not prepared to provide fixes for them. Attackers need to find an unpatched bug in a system to exploit it. If a system gives an abnormal response to an input containing anomalies, then there is a bug in the system and the attackers will continue to edit their inputs until they get the system to behave the way they want. However, zero-day bugs do not always need to be exploited for criminal purposes to cause problems. Sometimes the bugs can be triggered by normal use or system maintenance. But one thing that ought to be realized is that a zero-day vulnerability is a ticking time bomb, it does not really matter what eventually sets it off. The important thing is to get rid of them.
It is generally acknowledged that the earlier a vulnerability is discovered, the easier and the cheaper it is to fix it, and the more comprehensive the fix is. Therefore, the best way to avoid vulnerabilities is to write good code, and testing is the easiest way to ensure the quality of your code. Fuzzing is a software testing technique, in which unexpected data is fed to the inputs of a system, and the behavior of the system is then monitored. If the system fails, e.g., by crashing or hanging, then there is a bug in the software. Fuzzing enables testers to accurately simulate potential attacks against their own code and to patch the found vulnerabilities before somebody else finds them and exploits them. Fuzzing is a risk-based approach: It does exactly what the attackers would do, but before them.
By integrating fuzz testing into your software development process, you can discover flaws at the earliest possible moment. By building security in, you can avoid external security features, which merely add to the complexity of your system by increasing its attack surface. The same applies to VPN systems, IDS/IPS, firewalls and anti-virus programs. Furthermore, application service providers, like online-banks and web stores, cannot build fortresses around their application, because their customers need to be able to use their services. Any system that is exposed to the Internet is also exposed to attacks, and should be fuzz-tested for security.
Most traditional vulnerability auditing solutions focus on scanning the systems for previously known bugs. The benefit of such testing methods is that they do not actually trigger any vulnerability, and therefore they are usually safe to use even in production networks. But their biggest weakness is that they cannot find previously unknown vulnerabilities. This is especially problematic with emerging technologies and proprietary protocol extensions: there are no ready bug lists, and thus it is impossible to find weaknesses using vulnerability or security scanners. In my opinion, the main strength of fuzzing is its ability to find completely new vulnerabilities.
In robustness testing, thousands and even millions of misuse-cases are created for each use-case, thus most robustness testing solution contain at least some degree of automation. The most comprehensive fuzzers, so called model-based fuzzers, utilize protocol specifications to intelligently target protocol areas most susceptible to vulnerabilities. Stateful model-based tests can also genuinely interoperate with the system under test and find vulnerabilities even in deeper protocol layers with high accuracy, making it possible to test complex protocols, like XML, accurately. Test targeting also significantly reduces the number of test cases needed and the test run times, making it possible to integrate tests into regression tests or to perform automated tests, for example, with every build. This creates an obvious advantage: If vulnerabilities are fixed early on during the software development process, there simply will not be any time for anyone to devise an attack.
With emerging technologies the specifications needed to create model-based tests are not always available: there might be no consensus or the specifications can be proprietary and not available to testers. In such cases traffic captures can be used to create mutation-based fuzzers. As these fuzzers are based on real traffic samples, no additional knowledge of the system under tested is needed. In addition, these test cases are quick to create and to execute, due to limited scope of the tests. But traffic captures are only samples of network traffic, and thus they only cover a limited selection of the implementation. For example, they completely ignore rarely used features, such as legacy technologies or other hidden features. Yet, if no model-based fuzzers are available, it is better to use some kind of traffic sample based robustness tests, than to not test the resilience of the system at all.
The costs of bad Quality of Service (QoS) and downtime can be considerable to your company reputation and sales, an important fact to consider especially when deploying new devices or technologies. By ensuring the quality of your software you can also avoid other liability problems. And, most importantly, by building the security into your system, you can be sure that it is really secure and not just coated with security. Remember, if it is a bug, fix it, do not try to protect it.