Security Research & Defense

Information from Microsoft about vulnerabilities, mitigations and workarounds, active attacks, security research, tools and guidance

Posts
  • Security Research & Defense

    MS08-026: How to prevent Word from loading RTF files

    This month we released an update for Microsoft Word that fixed issues relating to loading RTF files (CVE-2008-1091) and HTML files (CVE-2008-1434).  Office applications like Microsoft Word can load a large variety of different file formats, and some people may want to reduce their attack surface by disabling the formats they don’t typically use.  As of May 2007, Office 2003 and 2007 have had a feature in place called File Block which allows you to do exactly that via the registry. 

    It’s important to note that the file extension doesn’t tell you what format a file is.  For example, you can rename an .RTF or .HTM file to .DOC, and Microsoft Word will load it.  File Block doesn’t key off the file extensions; these format “kill switches” are actually checked in each of the file format parsers, so the restriction can’t be bypassed by simply changing a file’s extension.  That means that simply disabling the file association between .RTF and Microsoft Word will not prevent Word from loading potentially malicious RTF files, since they can end with a .DOC extension.

    Microsoft Word, Excel, and PowerPoint can each load a number of different formats which you can individually disable with File Block.  You can also specify a trusted (Office 2007) or exempt (Office 2003) folder, so that files loaded from that location are always allowed through. 

    Here are some links that explain how to enable File Block and also how to configure trusted/exempt folders:

    For general information about File Block and MOICE see this advisory: http://www.microsoft.com/technet/security/advisory/937696.mspx

    We talk about File Block and MOICE with customers as often as we can.  Our team has presented this information at FIRST 2007, BlueHat 2007, CanSecWest 2008, and on several customer visits.  We are hoping the Black Hat selection committee will accept our talk for the 2008 Vegas conference.  Let us know (switech@microsoft.com) if you have questions about File Block or MOICE, and we can either answer them or put you in touch with someone who will have the answer.

    - Security Vulnerability Research & Defense Bloggers

    *Postings are provided "AS IS" with no warranties, and confers no rights.*

  • Security Research & Defense

    MS08-025: Win32k vulnerabilities

    MS08-025 addresses several vulnerabilities in win32k.sys where you can execute arbitrary code in kernel mode. These bugs can only be exploited locally and there is no remote vector we are aware of.

    One of these vulnerabilities deals on how we can bypass some of the ProbeForWrite and ProbeForRead checks when using user supplied memory pointers.

    ProbeForWrite/Read are functions that will check if a provided address range (base + length) has the following properties (throwing an exception in case it fails):

    ·         The range is inside the user mode virtual memory space.

    ·         ProbeForWrite will check if the range is writable.

    ·         By design, if the length of the range equals to zero, ProbeForRead and ProbeForWrite will not throw an exception and the normal flow of this request will be taken (the range will be validated).

    Find out more information about these functions at: http://msdn2.microsoft.com/en-us/library/ms809962.aspx and http://msdn2.microsoft.com/en-us/library/ms790786.aspx

    In the case of this bulletin, using a specially crafted request to win32k from user mode we can overflow the length variable, which can then take the erroneous value of zero, leading to the probing function being bypassed.

    One of the approaches that we could have taken was to fix these functions and throw an exception when we receive a zero length. This was not a good approach since it will break lots of interfaces. On win32k there are some functions that upon receiving a zero length they will return with the needed length for a correct request. Updating the probe functions to blindly reject zero length values would break these usages.

    Instead we decided to check each of the probes looking for integer overflows that will lead to length zero. These are the cases we and drivers developers need to take care of:

    // lParam and wParam are untrusted DWORDs since they come from user mode
    
    try {
            str.bAnsi = bAnsi;
            str.MaximumLength = (ULONG)wParam;
            if (!bAnsi) {
                str.MaximumLength *= sizeof(WCHAR);   // we can overflow this max length and lead to zero
            }
    
            str.Length = 0;
            str.Buffer = (LPBYTE)lParam;
    
            ProbeForWrite((PVOID)str.Buffer, str.MaximumLength, sizeof(BYTE));
        
        } except (StubExceptionHandler(FALSE)) {
              MSGERROR(0);
        }
    
     [... later write into str.Buffer pointer based on wParam ...]
    

    As you can see we bypass the ProbeForWrite check with the overflow (wParam = 0x80000000 that leads to str.MaximumLength = 0). Once this check has been passed, it depends on the function we are targeting but a ProbeForWrite seems like later we are going to write to the supplied pointer (lPram).

    And these are the cases where we can have a legitimate use of zero length on the probe:

    // lParam and wParam are untrusted DWORDs since they come from user mode
    
    try {
            str.bAnsi = bAnsi;
            str.MaximumLength = (ULONG)wParam;
    
            str.Length = 0;
            str.Buffer = (LPBYTE)lParam;
    
            ProbeForWrite((PVOID)str.Buffer, str.MaximumLength, sizeof(BYTE));
        
        } except (StubExceptionHandler(FALSE)) {
              MSGERROR(0);
        }
    
        if (str.MaximumLength==0) {
                   retval = STATUS_BUFFER_TOO_SMALL;
                  *size_needed= sizeof(struct_to_copy_from);
                  return retval:
        }
    
    [... later checks for the size needed may apply ...]
    

    In this case it is by design on some API that if you pass a zero length the call will fail and you will get back the needed size for this particular API call.

    - Security Vulnerability Research & Defense Bloggers

    *Postings are provided "AS IS" with no warranties, and confers no rights.*

  • Security Research & Defense

    MS08-023: Same bug, four different security bulletin ratings

    Security bulletin MS08-023 addressed two ActiveX control vulnerabilities, one in a Visual Studio ActiveX control and another in a Yahoo!’s Music Jukebox ActiveX control.  The security update sets the killbit for both controls.  For more about how the killbit works, see the excellent three-part series (1, 2, 3) from early February in this blog.

    One interesting thing you might notice about this bulletin is the diversity of severity ratings between different platforms.  Windows 2000 and XP are rated Critical.  Windows Vista is rated Important.  Windows Server 2003 is rated Moderate.  And Windows Server 2008 is rated Low.  The same bug on different platforms got four different security bulletin ratings!  We thought this might raise some questions so we decided to explain a little more about how the rating system works for browser-based vulnerabilities.

    We rate browser-based vulnerabilities Critical when they allow drive-by code execution.  Internally, we refer to them as “browse-and-you’re-owned”.  Simply browsing to the website (or being redirected there via iframe) is enough to trigger the vulnerability – no prompts, no gold bar, nothing but browsing is necessary.  In this specific case of MS08-023 on Windows XP SP2, users who have the ActiveX control installed are vulnerable to drive-by attack.  And even if the ActiveX control is not already installed, an attacker can serve it to the browsing user.  Because this control was signed by Microsoft, if a user had previously chosen to always install software from Microsoft, they will not be prompted.  The security warning dialog below shows how a user could choose to always install software from Microsoft.

    IE7 on Vista requires a user to “opt-in” to ActiveX controls they want to run.  If an ActiveX control is not included on the opted-in list, it will not run.  We do not expect users will have opted-in to use this Visual Studio ActiveX control (most of you probably have never even heard of it), so the Vista MS08-023 rating is Important.  You can see what the ActiveX opt-in gold bar looks like below.

    Windows Server 2003 ships with the Enhanced Security Configuration (ESC) enabled. Browsing with the ESC enabled prevents any scripting or ActiveX controls from being run (and also enables other browser hardening suitable on a server).  With the ESC enabled, the MS08-023 vulnerabilities are not reachable.  You’d have to explicitly turn this security setting off, and so we’ve rated this issue Moderate. You can see the Enhanced Security Configuration dialog below.

    Windows Server 2008 includes both the above mitigations.  It ships with IE7 so it gets the IE7 ActiveX opt-in by default.  And it also ships with the Enhanced Security Configuration feature enabled.  The ESC drops the rating from Critical to Moderate.  The IE7 ActiveX opt-in drops it one more notch from Moderate to Low.    

    - Security Vulnerability Research & Defense Bloggers

    *Postings are provided "AS IS" with no warranties, and confers no rights.*

  • Security Research & Defense

    MS08-020 : How predictable is the DNS transaction ID?

    Today we released MS08-020 to address a weakness in the Transaction ID (TXID) generation algorithm in the DNS client resolver.  The TXID is a 16-bit entity that is primarily used as a synchronization mechanism between DNS servers/clients; in fact, you can think of it as an Initial Sequence Number (ISN) for DNS query/response exchanges.  Consequently, the TXID is intended to be somewhat random and difficult to predict.  If both the TXID and hostname are predictable, an attacker can forge malicious DNS replies which the DNS client resolver will believe to be from the legitimate DNS server.  The client would then use the spoofed information to make an outbound connection to a (potentially) attacker-controlled IP.

    We wanted to explain a little more about the weakness to help you recognize potential attacks on the wire.  Remember that an attacker needs to match the request TXID exactly in the spoofed response before the legitimate DNS server replies with a valid response.  This was facilitated by our previous implementation of this PRNG algorithm being weak and hence vulnerable to prediction attacks.  Given the previous consecutive TIDs, x_n, x_{n+1}, x_{n+2}, the attacker may be able to determine the PRNG state and predict x_{n+3}, x_{n+4}, … with a high degree of confidence.  The old TXID generation algorithm was as follows (revised pseudo-code for technical accuracy):

          GlobalSeed++;
    SomeNumber = (WORD)GetTickCount()+(SomeRandomAddress>>6)+GlobalSeed;
    SomeNumber = (SomeNumber%487)+1+GlobalLastTXID);
    GlobalLastTXID = SomeNumber;
    XID = SomeNumber^XIDMask;

    Below is a log of sequential TXID’s sent from the old client resolver.  Notice the predictable patterns that develop in bit positions 4,5,6,7 and 8.

    As you can see, attackers cannot predict a guaranteed, known-next TXID exactly even with this weakness.  But limited entropy in those middle bits does cut down the search space substantially to predict the next TXID.  If you are watching for attacks on the wire, continue to look for the same pattern as previous DNS spoofing attacks: a steady flood of DNS “replies” with thousands of different TXID’s targeting a client lookup for a single host. 

    To address this weakness, we simply replaced the algorithm with a cryptographically secure PRNG: CryptGenRandom().  You can read about how it works at http://msdn2.microsoft.com/en-us/library/aa379942(VS.85).aspx.

    Blog Update - April 29: Revised pseudo code above for technical accuracy.

    - Security Vulnerability Research & Defense Bloggers

    *Postings are provided "AS IS" with no warranties, and confers no rights.*

  • Security Research & Defense

    MS08-015: Protocol Handler and its Default Security Zone

    MS08-015, CVE-2008-0110, addresses a vulnerability in Microsoft Outlook’s implementation of “mailto” URI handling. The attack can be launched via IE or other applications which invoke the “mailto” protocol.

    Applications can register pluggable protocol handlers to handle a custom Uniform Resource Locator (URL) protocol scheme. Here “mailto” is one example of the various protocol handles that can be registered.  The “pluggable” model allows new or custom protocol schemes to be flexibly implemented and added. For a detailed description about “asynchronous pluggable protocols”, please refer to http://msdn2.microsoft.com/en-us/library/aa767916(VS.85).aspx.

    The registration of the application protocol handler is controlled by the registry key: HKEY_CLASSES_ROOT\<protocol scheme>. For example, the registry key for the “mailto” protocol is: HKEY_CLASSES_ROOT\mailto

    [HKEY_CLASSES_ROOT\mailto]
    "EditFlags"=hex:02,00,00,00
    "URL Protocol"=""
    @="URL:MailTo Protocol"
    
    [HKEY_CLASSES_ROOT\mailto\DefaultIcon]
    @="\"C:\\PROGRA~1\\MICROS~2\\OFFICE11\\OUTLOOK.EXE\",7"
    
    [HKEY_CLASSES_ROOT\mailto\shell]
    
    [HKEY_CLASSES_ROOT\mailto\shell\open]
    
    [HKEY_CLASSES_ROOT\mailto\shell\open\command]
    @="\"C:\\PROGRA~1\\MICROS~2\\OFFICE11\\OUTLOOK.EXE\" -c IPM.Note /m \"%1\""
    

    As shown above, “outlook.exe” is the application that will be launched to process the “mailto” protocol. You could change the shell open command to use another mail client to handle the protocol, or you could remove HKEY_CLASSES_ROOT\mailto to disable the “mailto” protocol totally, as does the work around in the bulletin. Once this key is removed, the following dialogue will pop up when IE handles the “mailto” protocol.

    clip_image001[6]

    The second part we would like to talk about here is a specific registry key which impacts IE behavior. The key is:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\ProtocolDefaults

    The ProtocolDefaults key specifies the default security zone that is used for a particular protocol (ftp, http, https, etc). For a DWORD value under this key, the name of the DWORD value is the protocol name, and the value specifies the default security zone.

    Back to our “mailto” example, if we add the following value under ProtocolDefaults:

    Name: mailto
    Type: REG_DWORD
    Data: 0
    

    This setting would put “mailto” in the local machine zone. Then if a page attempts to browse from internet or intranet to “mailto”, zone elevation occurs, and IE would block it. Therefore, it mitigates the attack launched via IE from internet/intranet. For more details about IE’s zone elevation feature, please refer to http://msdn2.microsoft.com/en-us/library/ms537185(VS.85).aspx.

    The value for the Zones are:

       Value    Setting
       ------------------------------
       0        Local Machine Zone
       1        Local Intranet Zone
       2        Trusted sites Zone
       3        Internet Zone
       4        Restricted Sites Zone
    

    More details about the ProtocolDefaults key can be found in http://support.microsoft.com/kb/182569.

    The reason we did not list this approach in the bulletin is that this is for IE only. The above setting won’t prevent another app from invoking the “mailto” protocol.

    In general, if you feel a particular protocol is not safe (we won’t name one here J), removing the HKEY_CLASSES_ROOT\<protocol scheme> registry key can be an option, or you may consider locking down its default security zone in IE via the ProtocolDefaults setting.

    - Security Vulnerability Research & Defense Bloggers

    *Postings are provided "AS IS" with no warranties, and confers no rights.*

  • Security Research & Defense

    MS08-014 : The Case of the Uninitialized Stack Variable Vulnerability

    MS08-014, CVE 2008-0081, addresses a vulnerability in Excel whose root cause is an uninitialized stack variable.  You probably have seen these types of compiler warnings before:

    C:\temp>cl stack.cpp
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86 Copyright (C) Microsoft Corporation.  All rights reserved.
    
    stack.cpp
    c:\temp\stack.cpp(49) : warning C4700: uninitialized local variable 'pNoInit' used ...
    

    The code still compiles and links fine so maybe you have even ignored this warning in the past.  This type of code defect is not discussed as widely as buffer overruns but MS08-014 is a good example of why using uninitialized variables is potentially dangerous.  We'll use the following PoC code to illustrate the vulnerability, show how it is vulnerable to attack, and then give more detail about these compiler warnings:

    // stack.cpp
    unsigned char scode[] = "shell code";
    
    void parse();
    
    void p1();
    void p2();
    
    int main(int argc, char* argv[])
    {
        parse();
        return 0;
    }
    
    void parse()
    {
        p1();
        p2();
    }
    
    void p1()
    {
        // Assume p1 is reading data from the file to s
        // Content of s could be controlled by the attacker.
    
        // For simplicity, assign s to 0x0013fee8, location of return address to stack!main+0x8
    
        int s[64];
        for (int i=0; i<64; i++)
        {
            s[i] = 0x0013fee8;                 // spray the stack buffer
        }
    }
    
    void p2()
    {
        // Assume p2 is the next parsing function to read data.
        // For example, it tries to load an image from the file, and assign to its field.
        // If the content image is the shellcode, by modifying the return address in the
        // stack, the shell code runs.
    
        struct {
            char * pImage;
    } *pNoInit;
    
        // This is to align the stack layout to demonstrate the attack
        char s[100];
    
        pNoInit->pImage = (char *) scode;
    }
    

    pNoInit is not initialized before it is used in function p2().  Is this a programming mistake that could lead to code execution?  The answer lies in whether the attacker can prepare the stack right before p2() is called.  If so, the value of pNoInit would be controlled by the attacker.

    In our example, function p1() is called right before p2(). In function p1(), we tried to set values in specific location in the stack. These values would still be kept in the stack, even when p1 returns. Therefore, when p2 enters, the attacker controls the value of pNoInit. In this case, it points to the return address of the main(), and off we go.

    Here's what it looks like in the debugger:

    stack!p2:
    00401090 55              push    ebp
    0:000> k
    ChildEBP RetAddr
    0013fed4 0040101d stack!p2 [h:\work\stack\stack\stack.cpp @ 57] 0013fedc 00401008 stack!parse+0xd [h:\work\stack\stack\stack.cpp @ 33]
    0013fee4 004012ae stack!main+0x8 [h:\work\stack\stack\stack.cpp @ 26] 0013ffc0 7c816fd7 stack!mainCRTStartup+0x173 [f:\vs70builds\3077\vc\crtbld\crt\src\crt0.c @ 259]
    WARNING: Stack unwind information not available. Following frames may be wrong.
    0013fff0 00000000 kernel32!RegisterWaitForInputIdle+0x49
    
    0:000> dv
            pNoInit = 0x0013fee8
                  s = char [100] "???"
    
    stack!p2+0x32:
    004010c2 8b458c          mov     eax,dword ptr [ebp-74h] ss:0023:0013fe60=0013fee8
    
    0:000> t
    eax=0013fee8 ebx=7ffdf000 ecx=00000063 edx=7c90eb63 esi=00000a28 edi=00000000
    eip=004010c5 esp=0013fe5c ebp=0013fed4 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    stack!p2+0x35:
    004010c5 c70030704000    mov     dword ptr [eax],offset stack!scode (00407030) ds:0023:0013fee8=004012ae
    
    0:000> k
    ChildEBP RetAddr
    0013fed4 0040101d stack!p2+0x3b [h:\work\stack\stack\stack.cpp @ 79] 0013fedc 00401008 stack!parse+0xd [h:\work\stack\stack\stack.cpp @ 33]
    0013fee4 00407030 stack!main+0x8 [h:\work\stack\stack\stack.cpp @ 26] 0013ffc0 7c816fd7 stack!scode
    WARNING: Stack unwind information not available. Following frames may be wrong.
    

    When the compiler warned us about the uninitialized variable above, it was attempting to save us from a real vulnerability!

    You can also get more help from the compiler by using the /W4 switch. Check the following test.cpp:

    int main(int argc, char *argv[])
    {
            int *pNoInit ;
            int *pMaynotInit;
    
            if (argc < 3)
            {
                pMaynotInit = 0;
            }
    
            return *pNoInit + *pMaynotInit;
    }
    
    C:\test>cl /W4 test.cpp
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
    Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
    
    test.cpp
    c:\test\test.cpp(11) : warning C4700: local variable 'pNoInit' used without having been initialized
    c:\test\test.cpp(11) : warning C4701: local variable 'pMaynotInit' may be used without having been initialized
    

    Now we see the C4700 warning, same as before, and also a C4701 warning, "potentially" uninitialized local variable.  /W4 will generate a large number of warnings (which is why most people don't compile with /W4) however most 4701 warnings are trivially fixed. Those additional warnings may be noise or they might be an indicator of a subtle bug.

    For example, the following code will be flagged as a potential use of an uninitialized variable:

    MYOBJECT *p;
    HRESULT hr = S_OK;
              
    if(SUCCEEDED(hr))    
    { 
         hr = MyInitializationFunction(&p);     
    } 
    
    if(SUCCEEDED(hr))    
    { 
         p->DoSomething();    /*flagged as potential uninitialized use*/    
    }
    

    The compiler doesn’t know that MyInitializationFunction() will initialize *p on success. However initializing p to NULL on declaration avoids any ambiguity – and is good practice just in case there is a bug in MyInitializationFunction leading to it returning success without initializing its parameter!

    The other common source of noise from the 4701 warning is:

    foo(BYTE packet_type)
    {
    MYOBJECT *p;
    switch(packet_type)
    {
           case REQUEST:
                  p= new MYOBJECT ...;
    
           case RESPONSE:
                  p= new MYOBJECT ...;
    
    }
    p->DoSomething();    <- flagged as potential uninitialized use
    ...
    

    The compiler is picking up on the theoretical code path where packet_type is neither REQUEST nor RESPONSE. The implicit ‘default’ case of the switch statement does not initialize p - hence the warning. Maybe there really are only two packet types that can reach this code (eg because validation of packet_type happens before this function is ever called). If so then one of the switch statements will always be executed and p will always be initialized. Once again however the warning is easily fixed by initializing p to null on declaration – and in the event that the code above can be reached (e.g. via a malicious attacker crafting a network packet with a bogus type field) then we’ve reduced an almost certain code execution vulnerability to a null dereference. Of course the better way to fix this is to add an explicit default statement that returns an error code when it finds an unexpected packet_type value.

    We hope the above discussion shows that these compiler warnings should be treated seriously.  In fact, we're hoping to get them added as a banned warning type in the next version of the SDL.

    April 16, 2008 Update: Revised code to be more accurate.

    - Security Vulnerability Research & Defense Bloggers

    *Postings are provided "AS IS" with no warranties, and confers no rights.*

  • Security Research & Defense

    The Kill-Bit FAQ: Part 3 of 3

    It is very common for Microsoft security bulletins to include “Kill-Bits” to disable individual ActiveX controls / COM objects. Here is the final part of our three-part Kill-Bit FAQ.

    The Kill-Bit FAQ – Part 3 of 3

    Are there issues that could complicate the implementation of a Kill-Bit based fix?

    Yes. Here’s one interesting example: if the vulnerable code is in a separate binary from the one that implements the ActiveX control (the one referenced by the registered CLSID for the control) then the Kill-Bit may not have the intended effect.

    Per the top portion of Figure 1 below, imagine Control AX.1 references some vulnerable code in DLL.1. The proposed fix plan is as follows:

    • The code in DLL.1 will be fixed and released as DLL.2.
    • A Kill-Bit / Phoenix-Bit will be released for AX.1 to redirect to AX.2 which has a brand new CLSID.
    • The new binaries, DLL.2 and AX.2, will be bundled together in one fix package.

    Now imagine that the old DLL B.1 binary is dropped onto the system and registered. The system is now in a “downgraded” and vulnerable state, as depicted in Figure 1. The Kill-Bit does not automatically address this problem because even the new “fixed” AX.2 can still reference the old vulnerable DLL.1.

     

    image

    Figure 1

    Consequently, in the event that you need to fix a vulnerable control and the vulnerable code is actually in a separate binary, make sure that the new control is not able to use the old / vulnerable binary even if that binary is reintroduced onto the system. You can achieve this by performing a handshake or version check between the new control and the new / fixed binary.

    You should always carefully consider the applicability of the Kill-Bit before deciding to use it. For example, if an attack vector exists through a non-Kill-Bit-aware application then a Kill-Bit obviously will not be effective. See “If I Kill-Bit my vulnerable object / control, should I still release a fixed version?” in part 2.

    Thanks to Matt Thomlinson for providing Figure 1 above!

    Can I lock my ActiveX control down to a specific web site as an additional security measure?

    Yes, use SiteLock. Try to avoid implementing this functionality from scratch – there are many ways to get this wrong.

    SWI recommends using SiteLock only as “defense-in-depth” as it is not bulletproof. (For example, if a Cross-Site Scripting flaw exists anywhere on the domain it can potentially be abused to bypass this restriction.)

    Where are some additional resources on ActiveX Controls?

    Most relevant to this FAQ:

    Other good stuff:

    - Security Vulnerability Research & Defense Bloggers

    *Postings are provided "AS IS" with no warranties, and confers no rights.*

  • Security Research & Defense

    The Kill-Bit FAQ: Part 2 of 3

    It is very common for Microsoft security bulletins to include “Kill-Bits” to disable individual ActiveX controls / COM objects. Here is the second part of our three-part Kill-Bit FAQ.

    The Kill-Bit FAQ – Part 2 of 3

    How do ActiveX Controls, OLE Controls, and COM Objects relate?

    An ActiveX control is an OLE control that is intended to be used inside a web browser. Likely an ActiveX control is marked Safe for Scripting and Safe for Initialization as well as being packaged to be installed via Authenticode. More information on the difference between OLE and ActiveX controls is available here.

    All ActiveX / OLE controls are COM objects, but not vice versa. ActiveX / OLE controls are built on COM and implement a required minimum set of interfaces in order to operate properly within any OLE container. More information on the requirements that a COM object must meet in order to be considered a valid OLE control can be found here.

    ActiveX Controls, OLE Controls, and COM Objects all can be instantiated in IE with an OBJECT tag or through script (“new ActiveXObject”, etc.) All are subject to Safe for Scripting, Safe for Initialization and the Kill-Bit.

    Will IE host any ActiveX Control, OLE Control, or COM Object?

    Sort of. Prior to MS05-052, IE treated all COM objects equally. Any registered COM object could be instantiated within the browser just as long as the Kill-Bit wasn’t in place for its CLSID. Safe for Scripting and Safe for Initialization would be verified only after instantiation as particular operations were attempted on the object. Think about it – there’s no way to call into a control’s implementation of IObjectSafety without actually instantiating the control!

    In MS05-052, IE made a change that affects the way controls are instantiated in the Internet zone. The IObjectSafety check is now frontloaded so that IE can determine control safety status quickly and abort instantiation as soon as a control is identified as unsafe. Extra unnecessary probing of COM objects upon instantiation was a contributing factor to the exploitability of many COM object instantiation bugs. Control authors can set the compatibility flag value of 0x00800000 on their controls to opt-out of this new behavior if necessary.

    How does the Kill-Bit interact with “Safe for Scripting” and “Safe for Initialization” (SFS / SFI)?

    The Kill-Bit trumps SFS / SFI. If a control has the Kill-Bit, it just won’t load within Kill-Bit aware applications, period.

    If I Kill-Bit my vulnerable object / control, should I still release a fixed version?

    If you are releasing a Kill-Bit for a vulnerable object, it makes sense to issue a code fix as well. A code fix will mitigate the threat posed by environments that provide an attack scenario through which the vulnerability can be exploited yet do not support the Kill-Bit. If you do release a fixed version as well as a Kill-Bit, make sure to give the control a new CLSID and issue a “Phoenix-Bit” (see below) as necessary if the update control must operate within Kill-Bit aware environments.

    What is the “Phoenix-Bit” a.k.a. AlternateCLSID?

    Since a Kill-Bit completely prevents a control from loading in the browser, there needs to be a way to safely revise a control without breaking web content that references the killed CLSID. The Phoenix-Bit does this – it allows control developers to kill the vulnerable CLSID and transparently redirect requests for the old CLSID to a new CLSID. The name “Phoenix-Bit” honors the mythical Phoenix bird known for its regenerative ability.

    When verifying that a CLSID has or has not been killed, MSHTML will check to see whether an alternate CLSID has been provided for use in place of a killed CLSID. This will allow pages or Kill-Bit aware applications that have not been revised to refer to the new CLSID and still function.

    To implement the Phoenix-Bit, add an “AlternateCLSID” string value to the killed CLSID under the ActiveX Compatibility key. The Phoenix-Bit requires that the Kill-Bit is also set. Example:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\

    {CLSID of killed ActiveX control}, Compatibility Flags, 0x0400

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\

    {CLSID of killed ActiveX control}, AlternateCLSID, “{CLSID of alternate ActiveX control}”

    clip_image002

     

    Warning - Serious problems might occur if you modify the registry incorrectly by using Registry Editor or by using another method. These problems might require that you reinstall the operating system. Modify the registry at your own risk.

    The alternate CLSID requires the curly braces. It is possible to chain redirects up to ten levels deep.

    The Phoenix-Bit was introduced in IE6 SP1 and was backported to downlevel versions (5.01 and 5.5) in 2003. It is supported on all fully patched versions of IE >= 5.01.

    If I implement the Phoenix-Bit should the control still support the old CLSID?

    If the control is intended to be hosted outside of IE, then yes. In that case the control should support both the old CLSID and the new CLSID. Otherwise, hosts that do not understand or honor the Phoenix-Bit will be broken if they reference the control by the old CLSID.

    Are there any alternatives to the Phoenix-Bit?

    Ditching your control’s existing CLSID may be difficult if the CLSID is hard-coded in many web pages. The recommended solution to this problem is the Phoenix-Bit (see above). Besides the Phoenix-Bit, there are a few potential alternate solutions you may want to investigate:

    • TreatAs is similar to the Phoenix-Bit but applies to any client of a particular object rather than just MSHTML or other Kill-Bit / Phoenix-Bit aware applications. Set TreatAs like this:
      HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{CLSID}\TreatAs = <CLSID_TreatAs>
      TreatAs is documented here.
    • It may not be necessary to Kill-Bit a vulnerable object if it was never shipped as a signed DLL / OCX, within a signed CAB, or within a signed executable installer. In the absence of a signed package it won’t be possible for a web page to foist an old / vulnerable signed control onto users as described above (see “Why does my vulnerable control / object need a Kill-Bit?”).
    • It may be possible to effectively kill a control by making a change to the underlying platform that breaks the older control while still allowing the new control to load properly. The change would need to affect the control’s ability to load before the potential vulnerability can be exploited. For example, imagine that setting a particular registry key to an invalid value causes a control to abort before initializing. Setting this key could effectively block the old / vulnerable versions of the control from loading while a new / fixed version of the control could ignore the invalid value.
    • Internet Explorer has implemented a mechanism to block download / installation of specific signed binaries based on their hash. Hashes are stored under HKLM\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\Restriction Policies\Hashes.

    Is there an easy way for users to block ActiveX controls in Internet Explorer without setting a Kill-Bit?

    Yes, the Add-on Manager in XP SP2 and above allows users to easily disable specific ActiveX controls in Internet Explorer. It’s worth mentioning though that this is not technically equivalent to setting a Kill-Bit. So for example, Windows applications that respect the Kill-Bit to block ActiveX controls may or may not respect the Add-on Manager settings.

    - Security Vulnerability Research & Defense Bloggers

    *Postings are provided "AS IS" with no warranties, and confers no rights.*

  • Security Research & Defense

    The Kill-Bit FAQ: Part 1 of 3

    It is very common for Microsoft security bulletins to include “Kill-Bits” to disable individual ActiveX controls / COM objects. Here is the first part of a three-part FAQ we have developed to answer some questions around the Kill-Bit and related functionality.

    The Kill-Bit FAQ – Part 1 of 3

    What is the Kill-Bit?

    The Kill-Bit (a.k.a. “killbit”) is not actually a bit. The Kill-Bit is a registry entry for a particular CLSID that marks the COM object / ActiveX control referenced by that CLSID as non-loadable in the browser and other scriptable environments. Microsoft releases Kill-Bits in security updates to block vulnerable ActiveX controls and COM objects which are vulnerable to security flaws when hosted in the browser.

    Issuing a Kill-Bit for the control marks that particular control as forbidden to instantiate in the browser. Issue a Kill-Bit by setting the Compatibility Flags value to 0x400 for a control in the registry as described in KB Article 240797.

    Where are Kill-Bits in the registry?

    Kill-bits are located in the registry:
    x86 IE / x86 OS: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\CLSID of the ActiveX control

    x64 IE / x64 OS: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\CLSID of the ActiveX control

    x86 IE / x64 OS: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\ActiveX Compatibility\CLSID of the ActiveX control

    (3/11/2009 Update: added detail on x86 / x64 scenarios)

    clip_image002

    Warning - Serious problems might occur if you modify the registry incorrectly by using Registry Editor or by using another method. These problems might require that you reinstall the operating system. Modify the registry at your own risk.

    Note that not all CLSIDs listed in this location are killed, only controls containing 0x400 in the Compatibility Flags DWORD value. The acceptable values for Compatibility Flags are documented here.
    If you are setting a Kill-Bit, you may want to ensure that you don’t wipe out any existing Compatibility Flags set for the CLSID being killed. If you are removing a CLSID, to preserve any pre-existing Compatibility Flags, subtract 0x400 from the Compatibility Flags DWORD value and only remove the CLSID key if the Compatibility Flags value was set to 0x400 exactly.

    What applications respect the Kill-Bit?

    The Kill-Bit is respected in Internet Explorer (all zones) and also in Microsoft Office scenarios where objects are embedded within documents. The Kill-Bit should also be effective by default in any other application or platform that hosts the IE browser’s rendering engine (MSHTML). A notable exception are HTAs – with an HTA it is already possible to load unsafe controls and run arbitrary code. HTAs are an unsafe file type.

    (3/11/2009 Update: HTAs do currently respect the Kill-Bit for objects instantiated via the OBJECT tag.  The Kill-Bit is not respected when HTAs instantiate objects in script.  Thanks to Nicolas Noakes for reporting this. The Kill-Bit behavior within HTAs may change in the future to become more consistent.)

    A control could conceivably have a flaw so severe that a Kill-Bit does not effectively block all attack vectors. For example, imagine a control that is found to implement a web server which suffers from a buffer overrun in the code responsible for parsing web requests. In this case, a code fix must be issued – simply implementing a Kill-Bit will not provide a comprehensive solution because any application which uses the control is exposed to the vulnerability.

    If an application or platform hosts controls and allows those controls to effectively be driven by untrusted data, that environment should respect Safe for Scripting, Safe for Initialization and Kill-Bit logic. Otherwise, the environment should provide some other equivalently or more restrictive policy, such as an allow-list of known-good scriptable objects.

    Why does my vulnerable control / object need a Kill-Bit?

    Kill-Bits must be issued to prevent old / vulnerable signed versions of controls from being effectively foisted on users. Even if a user has a fixed version of the control on their system, a renamed / signed DLL or OCX served from a malicious web page could revert their machine to an insecure state.

    Additionally, the “Always trust content from…” checkbox on the Authenticode dialog box, if checked for a particular trusted publisher, could allow old / vulnerable signed versions of controls to install silently. Otherwise, the victim of such an attack would be presented with an Authenticode dialog from a presumably trustworthy publisher. Once the old / vulnerable control is installed, the attacker can immediately script to it.

    Kill-Bits are effective regardless of their origin but obviously wider distribution of a Kill-Bit ensures more comprehensive protection. If you would like Microsoft to distribute a Kill-Bit in Windows on your behalf, contact the MSRC and include details on the CLSID(s) in question.

    What is the relationship between an OBJECT tag’s CLSID and CODEBASE attributes?

    It is possible to specify any CLSID paired with any CODEBASE in an OBJECT tag. If that CLSID isn’t already registered, IE will attempt to download the control specified in the CODEBASE attribute of the OBJECT tag. It isn’t feasible for IE to know what control a package installs before that package is actually installed.

    Will controls with the Kill-Bit still load in other applications?

    Yes. See “What applications respect the Kill-Bit?” above.

    Is it still possible to download and install an ActiveX control with the Kill-Bit?

    Yes. Setting the Kill-Bit on a control only affects that control’s ability to instantiate within Kill-Bit aware hosts such as IE.

    - Security Vulnerability Research & Defense Bloggers

    *Postings are provided "AS IS" with no warranties, and confers no rights.*

    Updates March 11, 2009 - updated blog post and flagged where updates were made.

  • Security Research & Defense

    Not safe = not dangerous? How to tell if ActiveX vulnerabilities are exploitable in Internet Explorer

    In early January you may have read posts on security distribution lists regarding two ActiveX Controls released by Microsoft. We have investigated those controls and fortunately, they are not exploitable since IE does not treat them as being safe.  We wanted to give you some background on how to evaluate whether a potential vulnerability found in an ActiveX control is an exploitable condition in Internet Explorer.

    Each time IE finds an embedded ActiveX control in an HTML web page, IE will perform the following checks to verify if it is safe for initialization and scripting:

    • IE will determine if this ActiveX Control is kill-bitted or not. If it is, IE will not load the control.
    • IE will determine if this ActiveX Control implements IObjectSafety.
    • If it does, IE will query through this interface for “Safe for Initialization with data” and “Safe For Scripting”.
    • If it does not implement IObjectSafety, IE will look for these properties in the registry under the following implemented categories: {7DD95802-9882-11CF-9FA9-00AA006C42C4} (Safe for Initialization) and {7DD95801-9882-11CF-9FA9-00AA006C42C4}(Safe For Scripting).

    Once IE knows these two properties it will follow this logic (under the default configuration):

    • IE will load the control to query its IObjectSafety interface.
    • If the control does not implement IObjectSafety and does not have the Safe For Initialization or Safe For Scripting properties in the registry, IE will unload this ActiveX Control.
    • If the control is Safe for Initialization, IE will instantiate it and IE can receive data through param attributes and the DATA attribute of the object html tag.
    • If the control is not Safe for Scripting, IE will not script this control through JavaScript or any other scripting language.
    • If this control is Safe for Scripting, IE will allow scripting of this control.

    If a malicious web page tries to take advantage of any of these controls and its methods, IE will NOT script them due to the classid’s properties (“Safe for Initialization” and “Safe for Scripting”). The attacked user will see IE’s gold bar since IE treats them as unsafe, and scripting them is a requirement for the successful exploitation of these controls.

    image

    In general, IE (in the Internet Zone) will not script and/or load this type of classid as mentioned in this article: “INFO: How Internet Explorer Determines If ActiveX Controls Are Safe” http://support.microsoft.com/kb/q216434/

    Analysis about the recent posts can be found below:

    Clsid: {008B6010-1F3D-11D1-B0C8-00A0C9055D74}
    Progid: VisualFoxpro.Application.6
    Binary Path: C:\Program Files\Microsoft Visual Studio\Vfp98\vfp6.exe
    Implements IObjectSafety: False
    Safe For Initialization: False
    Safe For Scripting: False
    KillBitted: False

    With the installation of Visual Fox Pro 6 this classid will automatically be available in the system. Since it does not implement IObjectSafety, IE will determine whether the file is safe to use via some properties on the registry for this control such as “Safe for Initialization” and “Safe for Scripting”, in this case “false”.

    Clsid: {B617B991-A767-4F05-99BA-AC6FCABB102E}
    Binary Path: C:\Windows\System32\RICHTX32.OCX
    Implements IObjectSafety: True
    Safe For Initialization (IObjectSafety): True
    Safe For Scripting (IObjectSafety): False
    Safe For Initialization (Registry): False
    Safe For Scripting (Registry): False
    KillBitted: False

    Even though this control implements IObjectSafety, IE will not trust it since it is not marked as “Safe for Scripting”. “Safe for Scripting” is required in order to trigger the vulnerability: writing files via SaveFile() method. Since IE will not script it, there is no vulnerability through IE in its default secure configuration.

    We have attached source code to this blog post to list the various properties of ActiveX controls. This tool was used to generate the output above dumping the ActiveX properties of the milw0rm posts.

    - Security Vulnerability Research & Defense Bloggers

    *Postings are provided "AS IS" with no warranties, and confers no rights.*

    7/29/09 Update: Fixed a typo in the Safe for Scripting CLSID. Thanks to Leo Davidson for bringing this to our attention.

Page 25 of 26 (258 items) «2223242526