Evasion with OLE2 Fragmentation
Update: A bug was discovered in the public refragmenter script, after fixing this bug we updated the detection numbers to match the new results.
At BreakingPoint, we provide comprehensive coverage of Microsoft Tuesday patches. This Tuesday was no different and we released StrikePacks 45799 and 45800 to cover MS09-017 (the PowerPoint vulnerabilities). In addition to writing exploits for these flaws, we also research application-specific evasion methods. In the case of file format flaws, we support evasion at every level, including techniques like IP fragmentation, alternate MIME encodings, HTTP compression, and data randomization within the files themselves. While working on Strike coverage for MS09-017, we discovered a simple way to bypass mainstream anti-virus and IPS signatures for malicious Office documents. This post talks about the method we used and some of our test results against popular anti-virus products.
Microsoft Office documents have been abused by security researchers and malware writers for many years. In 1999, Melissa, one of the first email viruses, used Visual Basic macros to send itself to all addresses in the victim's address book. Since then, macro security has been greatly improved, and attackers have moved on to exploiting parsing flaws in the Office software itself. This month, Microsoft released patches to address 14 vulnerabilities in the PowerPoint document parsers. Unlike traditional network attacks, file format flaws are notoriously difficult for IPS vendors to identify accurately. To remedy this, the anti-virus industry has added file format exploit detection into both desktop and network gateway scanning products.
Office documents are some of the most convoluted file formats in wide-spread use. The basic structure of these files is based on the Compound Document Format (OLE2 Structured Storage). This format is essentially a block-based filesystem with specific files and directories for each type and version of Office document. The actual "file" entries within these documents are also proprietary and change based on the version and features of the Office software used to create them. In order to detect a file format exploit, the parsing software needs to understand OLE2, locate the correct entry containing the document contents, and parse through that content to locate the specific structure that triggers the exploit. This process is CPU intensive and requires the parsing software to have a deep understanding of the version-specific Office document data inside of the OLE2 container. Creating software to do this correctly is expensive and time consuming, so the easy solution is to ignore the document format entirely and just scan for exploit-specific signatures. This is what most anti-virus and IPS products do today.
Just like most block-based filesystems, the OLE2 format is susceptible to fragmentation. When the Office software wants to write data, it tries to consume any available free blocks before allocating new ones. The OLE2 format has two different block tables; one for small entries (normally set to be less than 4096 bytes), and another for larger contiguous segments. Although fragmentation can occur during normal editing of an Office document, it is rare for documents to be heavily fragmented.
It turns out that there is an excellent OLE library for Ruby, written by a developer who goes by aquasync. This library makes it easy to create and modify Compound Document files. With a little bit of scripting, we were able to create a tool (available below) to force heavy fragmentation of Office documents. Out first test of this tool used a Melissa variant as the base document. Uploading the raw Melissa Word document to VirusTotal.com resulted in 39 out of 40 AV products recognizing the document as malicious. After running this file through the refragmenter script, the results were 36 out of 40. This is pretty good, but keep in mind this malware was originally released in 1999.
Melissa may not be the best choice for testing modern anti-virus capabilities. Instead, lets look at a live sample of the Microsoft Word exploit for CVE-2007-0515 (MS07-014). The original, unmodified version of this document is detected by 25 out of 40 anti-virus products. Using the refragmenter script with 64 byte writes, only 4 out of 40 products detected the file as malicious.
IPS and IDS developers have a great excuse for poor Office document coverage - this type of analysis is difficult and processor intensive. However, this is precisely the area where anti-virus products are supposed to succeed. Its embarrassing that so many products fail to detect known threats that have the exact same byte stream, just reordered using a mechanism that occurs in real documents. In our testing, the only public tool that can accurately identify fragmented Office documents is Office Cat, written by Lurene Grenier of the Sourcefire VRT. This tool uses the Windows OLE API to parse each stream, regardless of fragmentation, and scans deep into the document format to detect individual exploits.
All BreakingPoint Strikes that target Office document flaws have been updated to support the OLE::RefragmentData option, which performs an operation similar to the refragmenter Ruby script below.
The refragmenter script can be downloaded here.
This script depends on the ruby-ole library, which can be found online at http://code.google.com/p/ruby-ole/
For more information about Office document flaws and exploitation methods, we recommend Bruce Dang's Black Hat USA 2008 presentation Methods for Understanding Targeted Attacks with Office Documents.
2009: A SMB Odyssey
This Black Tuesday (the 13th, no less), Microsoft released the first security patch of 2009. This patch addresses three vulnerabilities in the SRV.SYS driver of the Microsoft Windows operating system. The SRV.SYS driver implements the Server Service component of the SMB network service, exposed via ports 139 and 445. The first issue addressed in this patch (CVE-2008-4114) has been public since September 14th, 2008 and allows a remote user to crash a Windows-based system by sending a malformed WriteAndX request to a named pipe. This flaw is interesting because it is triggered by memory copy, but instead of an overflow, it is a miscalculation of the source pointer. When the target machine receives this write request, it attempts to read from a memory location that may not exist, causing the entire operating system to crash (and by default, reboot). Normally, Microsoft waits until the next service pack to address bugs that do not result in code execution, so having a fix for this before XP SP4 (assuming there is one) is a nice surprise.
The next two bugs (CVE-2008-4834 and CVE-2008-4835) are a little different. These bugs are triggered when the service attempts to zero out a memory buffer that is smaller than a static value. If the attacker sends a request with certain fields set to values smaller than the static buffer size, the resulting operation overwrites the memory after the buffer with NULL bytes. Since we are dealing with driver code and the first buffer is allocated in a kernel pool, the subsequent overwrite usually corrupts the following pool header with a series of NULL bytes. This is where things start to get interesting. The Microsoft bulletin rates this patch as Critical and these two flaws as Remote Code Execution, but in order to execute code, there needs to be a way to leverage a small NULL byte overwrite of a kernel pool header to somehow gain control of execution. While there has been some work in this area, it has focused on using controllable values to overwrite header entries. As far as I know, there is no easy way to leverage a NULL byte overwrite of a pool header into code execution. For this reason, I would agree that these bugs are Critical in the sense that they should be patched as soon as possible (to prevent an easy DoS if nothing else), but I do not believe they will result in code execution. Of course, I would love to be proven wrong :-)
Successful exploitation of the NULL byte overwrite bugs will result in an exception like the following:
BAD_POOL_HEADER (19)Arg1: 00000020, a pool block header size is corrupt.
Arg2: e2008540, The pool entry we were looking for within the page.
Arg3: e20089f0, The next pool entry. <-- OVERWRITTEN HEADER
Arg4: 0c96020e, (reserved)
BUGCHECK_STR: 0x19_20
f61bac30 80543e86 00000019 00000020 e2008540 nt!KeBugCheckEx+0x1b
f61bac80 f694fad1 e2008548 00000000 f695d2b9 nt!ExFreePoolWithTag+0x2a0
f61bac8c f695d2b9 00000021 e2008550 821e5bd0 srv!SrvFreePagedPool+0x2a
f61baca0 f695771c 820d1610 e2008550 821f1038 srv!SrvFreeTransaction+0x68
f61bacb4 f6958349 00000000 821f1038 e2008550 srv!SrvDereferenceTransaction+0x6b
f61bacec f695786b 00000000 0000001e 821f1038 srv!SrvCompleteExecuteTransaction+0xd0
f61bad04 f6958115 f694be34 821f1038 821f2058 srv!ExecuteTransaction+0x333
f61bad7c f693f836 821f1040 821f2020 f694fa98 srv!SrvSmbTransaction+0x7ac
f61bad88 f694fa98 00000000 8202e200 00000000 srv!SrvProcessSmb+0xb7
SYMBOL_NAME: srv!SrvFreePagedPool+2a
MODULE_NAME: srv
IMAGE_NAME: srv.sys
kd> dd e2008540 (current entry)
e2008540 0c96020e 7274534c 000004a0 00000000
e2008550 04a0030c 00000000 820d1610 821e5bd0
kd> dd e20089f0 (overwritten entry header)
e20089f0 00000000 00000000 00000000 00000000
e2008a00 00000000 00000000 00000000 82270000
PHP Safe Mode Considered Harmful
PHP web applications are one of the most commonly attacked pieces of software on the Internet today. Anyone who has looked at their web server logs can attest to the frequency of probes for vulnerable PHP applications. PHP's easy learning curve has lead to its popularity and breadth of applications, but not without some hard lessons on the way. The ability to treat a remote HTTP URL as a local file, the auto-instantiation of variables based on client input, and the prevalence of free-form SQL queries have opened up a wide range of attack vectors in PHP applications. Over the years, the interpreter has been improved, dangerous settings have been disabled by default, and a setting called "Safe Mode" has been introduced to limit the impact of a malicious or subverted web application.
The PHP Safe Mode setting is a blacklist approach that restricts certain functions when it is enabled. According to the PHP manual: "safe mode is an attempt to solve the shared-server security problem. It is architecturally incorrect to try to solve this problem at the PHP level, but since the alternatives at the web server and OS levels aren't very realistic, many people, especially ISP's, use safe mode for now". The next major version of PHP (6.0.0) removes Safe Mode completely, which should be a clear sign that it should not be relied upon for shared server security. The core problem with Safe Mode is its inconsistency; in many situations, it works great and limits access to dangerous functions, however, all it takes is one allowed dangerous function to negate it completely.
The current best practice is to combine Safe Mode with a long list of functions for the "disabled_functions" parameter in the php.ini configuration file. This approach applies the Safe Mode restrictions to PHP as a whole and then specifically limits functions that can be used to work around it. Again, the problem with this approach is inconsistency; if even a single dangerous function is missed, the entire process is moot. Depending on where you look on the Internet, the list of functions to disable is completely different. If you combine as many of these lists as possible, you end up with something like the following:
disable_functions = escapeshellarg, escapeshellcmd, exec, passthru, proc_close, proc_get_status, proc_open, proc_nice, proc_terminate, shell_exec, system, ini_restore, popen, dl, disk_free_space, diskfreespace, set_time_limit, tmpfile, fopen, readfile, fpassthru, fsockopen, mail, ini_alter, highlight_file, openlog, show_source, symlink, apache_child_terminate, apache_get_modules, apache_get_version, apache_getenv, apache_note, apache_setenv, parse_ini_file
This list blocks all of the "standard" methods of executing a command or loading arbitrary code. This list also prevents some resource attacks and the ability to open any arbitrary local file. However, if certain extensions are enabled, even this massive list is not enough. Take the Expect module as an example, the expect_popen() function can be used to execute arbitrary commands and is not affected by Safe Mode or the normal list of disabled functions. Other extensions also offer ways around Safe Mode and the function blacklist above. The Apache functions in the list above are rarely disabled; since many administrators either don't realize that the module is available, or underestimate the things that can be done with it. The sample PHP code below uses the apache_setenv() function to force an unrelated CGI script to execute arbitrary native code:
<php
apache_setenv("LD_PRELOAD", "/tmp/evil.so");
virtual("/cgi-bin/anyscript.cgi");
?>
Sometimes a function supports Safe Mode, but is implemented in a way that allows for the restrictions to be bypassed. For example, a vulnerability in the CURL extension (CVE-2007-4850) allowed a user to access any file on the file system by embedding a NULL byte into the URL passed to curl_init(). Over the years, a number of these bypass techniques have been published and subsequently fixed, but the end result is that Safe Mode has rarely been enforced correctly.
To make things even more interesting, the PHP filesystem API allows a handful of different protocols to be used in a path name. This allows the fopen() call to access files over HTTP, FTP, SSH2, stdin/stdout, compressed formats, and a even popen pipes (via Expect).
On Windows servers, the interpreter supports CIFS paths, which can leak authentication credentials and domain information to a third-party. These protocols can be chained together, so a path consisting of "compress.zlib://http://someurl/" would first download a file via HTTP, decompress it with ZLIB, and then return the decompressed content as a file stream. These protocol handlers can be used to evade the disabled function list and access files outside of the Safe Mode constraints.
Securing PHP from malicious and subverted scripts is not easy; even though Safe Mode and the disabled function blacklist can help in some cases, they should be not considered a replacement for OS-level security. Kernel solutions such as GRSecurity and SELinux can be used to isolate the PHP interpreter from other processes on the system and projects such as suPHP make it easy to isolate users from each other. A major benefit of using OS and web server hardening is that many common applications depend on being able to access potentially dangerous functions. Locking down PHP via a lengthy disable_function list will cause problems that may be easier to solve by limiting the privileges of the PHP interpreter through other means.
For these reasons, I believe Safe Mode is harmful, as it can lead to a false sense of security and rarely prevents access by a determined attacker. This will become a non-issue in PHP 6, but until then, any production use of Safe Mode should be considered a symptom of a larger problem with the web infrastructure.
Attacking Critical Internet Infrastructure
Update: The presentation went off without a hitch and the full paper describing the attack, including proof is now available.
Taking a page from L0pht Heavy Industries, Alexander Sotirov, Jacob Appelbaum, and a team of researchers whose identities have to remain secret for now are making the theoretical possible this Tuesday at the 25th Chaos Communication Congress in Berlin. The details of their presentation have been heavily censored leading up the event, with only a handful of security researchers, journalists, and collaborators given early access to the materials. Fortunately, I was one of them, and I wanted to take the opportunity to talk about their research, why it is important, and why the pre-conference secrecy is justified.
First things first; the reason for secrecy. Their research combined a known weakness in one area with a massive resource investment in another to show that a third party was vulnerable to a practical attack that affects the security of all Internet users. Security researchers often release code and technical documentation to demonstrate a flaw, but in this case, they went a step further and used the attack in the real world to obtain proof that it works. This process required interaction with a third party that will likely do whatever they can to save face once the details become public.
To prepare for the fallout, Alexander and Jacob have been working with a legal team to review their work and advise them on the best way to disclose the issue without finding themselves at the receiving end of a lawsuit. From my own conversations with Alexander, I don't believe they broke any laws, but in the past few years there have been multiple unjustified legal actions and threats against researchers who have tried to warn the public about serious security issues.
The last ten years have shown us that it is usually better to ask for forgiveness than permission when it comes to vulnerability disclosure. Vendors have a financial interest in protecting their reputation and this is apparent in the number of pre-disclosure threats they make; however, once the proverbial cat is out of the bag, it is cheaper to address the problem than to proceed with legal action, since that legal action will usually result in even worse publicity for the vendor. If your organization is withholding vulnerability information due to concerns over a legal reaction from the affected vendor, then you have already lost the game and are doing a disservice to every user that relies on that vendor's product or service.
Switching back to the actual presentation; there are three things that make their research impressive. First, their work involved serious collaboration between academia and independent security researchers. This type of coordination is tough to manage and nearly impossible to actually publish anything under terms everyone can agree to. Jacob's previous work on cold-boot memory attacks faced similar challenges and the end result was partial disclosure of the developed tools (the BitLocker code was never released). Second, their research required massive computational resources that had to be utilized within a specific window of time. Although computing costs have dropped significantly over the last few years, the researchers estimated that commercially available computation resources such as Amazon EC2 put the technique within the grasp of a profitable criminal organization, large botnet operator and certainly state sponsors. The attack only has to be performed once in order to reap rewards for a long time afterward (months, if not years). This one-time investment model could pay for itself many times over if it was used to provide services to criminal organizations. Finally, they actually did it. This isn't a pie-in-the-sky talk about what may happen or what someone might be able to do, this is a demonstration of what they actually did with the results to prove it.
Their live presentation will be available online via streaming video, it is scheduled for Saal 1 at 3:15pm (8:15am CST, 9:15am EST, 6:15am PST) on Tuesday, December 30th. Keep an eye on the schedule in case their timeslot is moved.
Fuzzing the Internet Printing Protocol (IPP)
The Internet Printing Protocol (IPP) was designed as a next-generation printing and print job management protocol. Unlike the older line printer protocol (LP), IPP supports a number of advanced features, including authentication and encryption. IPP is loosely based around HTTP 1.1 and takes advantage of many of HTTP's features and conventions. The amount of code required to implement IPP is helped by its similarity to normal HTTP traffic. Microsoft Windows, Mac OS X, and most Linux distributions all support client and server modes of IPP. On the Windows side, the IPP server is integrated into the Microsoft IIS web server (/printers/). On Mac OS X and most Unix flavors, IPP is implemented via the Common Unix Printing System (CUPS), an open source implementation that is current maintained by Apple. Most network printers also support IPP and enable this protocol by default, however they tend to use custom implementations that have less features (and as we will demonstrate, stability) than the IPP implementations available for consumer operating systems.
In this article, we will be launching the BreakingPoint IPP fuzzer against a HP LaserJet 4250 network printer as well as an Ubuntu Linux system running CUPS. To get started, we access the web interface of a BreakingPoint BPS 1K appliance running the latest StrikePack. This system has interface 3 connected to the network that our targets are on and interfaces 1, 2, and 4 unplugged. After authenticating, the first thing we need to do is create a new Attack Series containing the list of Strikes we want to run. To create the Attack Series, we need to access the Attack Manager from the Managers drop down menu at the top of the interface. Once the Attack Manager has loaded, click on the Create Attack Series button. When the system prompts for a name, enter “IPP Fuzzer”. After the Series has been created, click the Add Strikes button in the right-hand pane. This will load the Strike Browser interface. From this interface, select the “ipp” keyword from the Keywords list and click the Strikes radio button. The results should look like Figure 1.

Figure
1: Searching for IPP strikes by keyword
Click the Search button to look for all individual Strikes which have the “ipp” keyword. The resulting list will contain a number of Strikes in the fuzzer category as well as an exploit. Since we are interested in fuzzing, we will select all of the fuzzer strikes and use the right-pointing arrow to add them to this test. The result should look like Figure 2.

Figure
2: Adding the IPP fuzzer Strikes to the Attack Group
Click the Add Strikes button to save this Attack Group and return to the main Attack Manager screen. The “IPP Fuzzer” Series should be selected and show the Strikes that were added to the list on the right-hand pane. This screen should look like Figure 3.

Figure
3: The configured Attack Series
The next thing we need to do is configure the IP address of the fuzzer and the target system. From the Control Center menu, select Network Neighborhood. Click the Create Neighborhood button and name the new setting “IPP Fuzzer Endpoint”. Once named, the right-hand pane will show a list of tabs for each interface and an additional interface labeled “External”. To configure the IP address used by the Fuzzer, select the tab for Interface 3. The network we are on is 10.10.10.0/23 and we want to confine the fuzzer to a single IP address, 10.10.11.165. Uncheck the “Use Address Range” box to ensure only a single IP address is used. Once configured, click the Apply Changes button. The result should look like Figure 4.

Figure
4: Configuring the fuzzer source IP address
Now that the source address has been configured, select the tab labeled “External”. This screen is used to configure the target IP address. First we need to select the preset range and use the delete button to remove it. Next we enter the target address into the Minimum Address field, uncheck the “Use Address Range” box, and click Add Range. The address we chose (10.10.10.251) points to the HP LaserJet printer that we want to test. Finally, click the Apply Changes button to save these settings. The result should look like Figure 5.

Figure
5: Configuring the target IP address
At this point, our Attack Series and Network Neighborhood is configured. The next step is to create a new test using these settings. From the Test menu at the top of the screen, select the New Test option. On the left hand side of the new test screen is a link for selecting the DUT and Network Neighborhood. Click this link, select the newly created “IPP Fuzzer Endpoint” option from the list of neighborhoods, and click the Accept button.
Once the interface has returned to the New Test screen, select the link labeled “Add a Test Component”. This will display a screen of 7 test components. Choose the component labeled Security from the bottom left of this screen. Once the Security component has been added, select the Interfaces tab, uncheck the presets, and use the checkboxes to select Interface 3 as the Client and the External interface as the Server. Click the Apply Changes button. The result should look like Figure 6.

Figure
6: Configuring the Security component interfaces
Select the Parameters tab of the Security component. Click the Attack Series option in the list of parameters and choose the IPP Fuzzer option that was created in the previous steps. Click the Apply Changes button. The result should look like Figure 7.

Figure
7: Selecting the IPP Fuzzer Attack Series
Finally, click the Save and Run button from the left side of the screen. The interface will prompt for a name for the test and start running the IPP Fuzzer Strikes against the target device. Once the test starts running, we will see a progress screen like the one shown in Figure 8.

Figure
8: Running the IPP Fuzzer Attack Series
In the graph above, we see a short spike of packets, followed by a long series of almost no traffic. Once the test completes, we can look at the report and determine what happened. Figure 9 shows a sample report for this test.

Figure
9: IPP Fuzzer vs HP LaserJet
In the Strike Detail section of the report, we see that the “IPP Print Operation Long Job Name” Strike reported a maximum job size of 64 bytes (of a maximum tested size of 65528). All of the following Strikes reported a maximum length of zero while the last Strike indicates that zero operations were accepted. If we try to telnet to the IPP port of the target device, we can see that the service is down and is no longer accepting requests. It appears that an IPP Job Name that is 65 bytes long will crash the HP LaserJet IPP service. The bandwidth graph showed a quick spike as the first 64 requests were sent to the IPP service, but after the 65th test, the IPP service stopped responding and the subsequent Strikes quickly gave up after not being able to connect.
The second target we want to test is a Ubuntu Linux system running CUPS, which happens to expose an IPP service as well. To change the target IP address, we access the Network Neighborhood we created, click on the External tab, change the IP address, and click Apply Changes. The next time we run this test, the fuzzer will target the Ubuntu system instead. Figure 10 shows a sample run of the exact same test against a CUPS IPP server.

Figure
10: IPP Fuzzer vs CUPS
In this test, we see that the service refused requests with field lengths over a threshold (~14100), but did not crash. At the end of the test, the IPP service was still online and functional, and the logs of the CUPS server did not show any fatal errors. Since the IPP service did not crash during this test, all six Strikes were able to run to completion, extending the test time to about one hour.
The BreakingPoint architecture makes it easy to integrate fuzzing with performance, application, and live exploit testing. This combination provides a way to flush out bugs that only trigger when the device is under a heavy load, something that is difficult to do with other products on the market. While IPP is a simple example, the same technique applies to all of our fuzzers. We design them to test live services as well as content-inspection devices that route traffic. The reports make it possible to determine exactly what requests can break a service and allow our users to reverse-engineer a content-filter's traffic normalization rules.
