A Strategic Guide To Discovering Software Vulnerabilities
Many people have expressed an interest in how eEye goes about discovering vulnerabilities in software. Because of the interest, this article is an overview of the basic process from a researcher's perspective.
To begin the search for a vulnerability, the first priority is to identify a piece of mission-critical software that warrants vulnerability research. After identifying a product, we need to understand the software product inside and out, including the features it provides as well as the internal processing component. The degree of information that can be acquired from existing sources depends largely on the software.
For commercial software products that are widely used and easily attainable, there is typically a wealth of information on how the product works, the protocols it uses, and how each protocol functions.
For custom programs, and software with a limited installation base, the project requires much more intensive research. Not having access to the software, binaries, or source makes the effort even tougher but certainly not impossible. In this case, we exhaust all available resources in an effort to obtain an understanding of how the software communicates and works. If the product being researched communicates using an undocumented protocol, then a considerable amount of reverse engineering may be needed in order to understand how the product communicates. This knowledge leads to an understanding of the areas where the product could possibly be vulnerable. In most cases, there is ample information to facilitate looking for vulnerabilities.
As an example, a web server product provides considerable information to jump-start vulnerability research. Since the web server is going to be using the HTTP protocol for its communication, one can begin by reviewing the many existing documents on how the HTTP protocol functions.
After going through the documented functionality of a product or protocol, reverse engineering will be required to search out undocumented (or poorly documented) functionality that may exist within the product. Some of the better reverse engineering tools for Windows would be IDA (Interactive Disassembler) (http://www.datarescue.com/) and Softice (http://www.numega.com). Some people prefer to use only a Strings program to search the software for hidden commands and other elements, but I strongly suggest learning some ASM and using tools like IDA and Softice to compliment a Strings tool.
Obviously, knowledge of past vulnerabilities can also provide valuable insight as to which processes of software products are most vulnerable, and which type of vulnerability tends to appear depending on the type of process. Most software vulnerabilities share a set of common characteristics as to how they are exploited and nearly all of today's software vulnerabilities are due to an error in how the program handles user-supplied data.
User-supplied data refers to the input that the software user provides as opposed to the data that the software program generates for its own internal processing. User-supplied data can be processed directly by the target program (e.g. overflowing the user command on a FTP server) or else the data can be passed through secondary software, eventually reaching your target program (e.g. a SQL attack via a web-based application).
The main goal of researching the target software is twofold: identifying all of the possible ways to supply data that is processed by the application and identifying possible flaws within the software program. If a match can be found between a data entry point and a piece of vulnerable code (i.e. if the user-supplied data deals with the vulnerable code at any point during processing) then a software vulnerability exists.
Although performing external research on a software product can provide insight into where you can find flaws, actually examining the program's code can reveal many vulnerabilities as well. A binary auditing tool allows researchers with strong Assembly and engineering backgrounds to proficiently step through the source of a software program. Finding a piece of vulnerable code during binary auditing does not always equate to an exploitable vulnerability. For instance, once the vulnerable code is identified, we must determine if and where a piece of user data can be supplied so that it works into the vulnerable code. This step is not always easy, but advancements in tools that assist in this process have made scanning through binary data for exploitable vulnerabilities much less daunting.
Another way to search out potentially exploitable flaws in a target program is to utilize the knowledge gained regarding the network/protocol workings within the software. This knowledge allows the building of customized tools (in Perl, C, C++, etc.) that automate the testing of the software in order to find vulnerabilities by "brute force".
A basic program can be written that tests specific functionalities of the software, such as a web server testing tool that iterates through all possible HTTP headers and tries to overflow them by incrementing buffers. However, once research has been conducted on the target software, a more sophisticated testing system can be built that reflects a deeper understanding of the product's functionality and interdependencies. In addition, an understanding of vulnerability classes and how they relate to specific product functionality is useful in creating an efficient testing system that eliminates implausible testing scenarios.
The end result of a testing system will yield many different "attacks" based on comprehensive knowledge of what user-supplied data a program is manipulating in conjunction with knowledge of the types of vulnerabilities that can potentially be passed via this user-supplied data. If built correctly, this testing system will begin to find areas of the software program that fail when tested; thus, pointing out vulnerable code.
In conclusion, a thorough understanding of the software, comprehensive research, an understanding of potential vulnerabilities associated with a programs internal components, and lots of practice enables eEye to discover software vulnerabilities. Since training on this subject is hard to come by, I hope this overview was helpful in providing you with a little background on what it takes to find vulnerabilities.
Marc Maiffret Chief Hacking Officer eEye Digital Security
P.S. If you are interested in reading a bit more about reverse engineering and binary auditing from a security perspective, be sure to check out the link to "Auditing Closed-Source Applications" in our Etcetera section below. |