GrammaTech brought unique binary code analysis to the market in 2013. Before then, the only option for binary analysis was to ship your code to specialists who would analyze it and send it back to you with a list of problems. Bringing a commercial binary analysis tool to the market enabled our customers to keep their code in-house and factor binary-only code (such as linked libraries and other third-party code) into safety and security from the beginning of development. Within CodeSonar, binary and source analysis can be done simultaneously on a development project, and the resulting hybrid mode analysis (we call it "mixed mode" at GrammaTech) has many advantages over source-only analysis. In this post, I look at how having both is a clear advantage in analyzing and remediating security vulnerabilities and software defects.
- Vulnerability Details : CVE-2010-2075
- Insider attacks and static analysis:How to spot the signs with three important new analyses
- Improving Quality and Security with Binary Analysis
An Insider Attack
In a previous post, our VP of Engineering Paul Anderson analyzed and explained an example of a code injection in Unreal IRCD. This exploit was reported as CVE-2010-2075. The post goes into detail on how external data is used unchecked to perform system commands – a textbook command injection vulnerability. Figure 1 and 2 illustrate the source code in question in the read_packet() function.
Figure 1: CodeSonar error report warning of a read from a connected socket and stored in readbuf.
Figure 2: CodeSonar warning of a command injection at this line. This is hidden by the macro DEBUG3_LOG. Initial review of this error might consider this a false positive since the code appears to be logging an error.
At first glance, this doesn’t look like a problem since all that appears to be happening is debug logging – a simple, detect an error dump the information to the application log. However, the DEBUG3_LOG macro is purposely obfuscated and requires further digging. In Figure 3, we can see the definition of DEBUG3_LOG is a call to system() which executes commands!
Figure 3: Expanding the macro DEBUG3_LOG reveals DEBUG_DOLOG_SYSTEM which in turn, translates into a direct call to system(x) - executing whatever command is passed to it.
Why does this look like an insider attack? This vulnerability was purposely written into the code and the macros have two levels of indirection in order to mask their real purpose. (A hacker group claimed responsibility for this exploit and injected this into the download archive for Unreal IRCD.)
Analyzing the Unreal IRCD vulnerability with Binary Analysis
Using CodeSonar’s binary analysis, it’s possible to detect security vulnerabilities from object, library, and executable code. The same exploit found by the source analysis is straightforward in the binary analysis. Figure 4 shows the warning from using a function known to read data from outside the process, and Figure 5 shows this data being used in a call to system(x). The compiler has completely stripped away any obfuscation in the source.
Figure 4: CodeSonar's binary analysis reveals the same vulnerability as the source analysis.
Figure 5: The command injection warning from calling system() with unchecked data read from a socket. In this case, the vulnerability is obvious due to compilation process - obfuscation via multiple macro definitions is removed.
Advantages of Hybrid Source and Binary Static Analysis
The Unreal IRCD vulnerability is a clear example of how static analysis in general (both source and binary) can detect such vulnerabilities, and also a great example of how binary analysis can detect errors that might be obfuscated in source or added maliciously after compilation.
Here are some of the benefits of hybrid static analysis:
- Learn from two views of the same vulnerability/defect: Once the compiler has optimized the source code, the resulting binary code can reveal a different view of the detected errors. Analyzing binaries as well as source is beneficial to fully understand these errors.
- Detect injected code, modified binaries, and insider attacks: A program’s source isn’t its final state. Binary analysis can detect unwanted changes in the final executable. Code injected into executables or download payloads can be analyzed for defects and vulnerabilities. Malicious code added by inside attackers, possibly hidden in source, can be detected before shipping to customers.
- Continue call graph into libraries and other binaries without source: CodeSonar can analyze standard C/C++ libraries and any other third-party library or executable. When code makes calls to these libraries, the analysis continues in the binary realm. Extending the analysis means better detection and less false positives.
The Unreal RCD exploit is a good example of how binary analysis can support source-based static analysis. Having the option to use hybrid analysis provides better detection of errors and security vulnerabilities, and helps defend against malicious code added by insiders -- a difficult attack vector to address.