Security Research & Defense

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

August, 2013

  • Assessing risk for the August 2013 security updates

    Today we released eight security bulletins addressing 23 CVE’s. Three bulletins have a maximum severity rating of Critical while the other five have a maximum severity rating of Important. We hope that the table below helps you prioritize the deployment of the updates appropriately for your environment.

    Bulletin Most likely attack vector Max Bulletin Severity Max Exploit-ability Index Likely first 30 days impact Platform mitigations and key notes
    MS13-059

    (Internet Explorer)

    Victim browses to a malicious webpage. Critical 1 Likely to see reliable exploits developed within next 30 days. Also addresses the ASLR bypass used as part of one of the CanSecWest pwn2own exploits (IE9 broker issue used in the VUPEN Adobe Flash exploit). 
    MS13-060

    (Unicode font in browser)

    Victim with Indic language pack installed browses to a malicious webpage. Critical 2 Less likely to see reliable exploit code within 30 days. Affects only Windows XP and Windows 2003 machines where the Bangali font is installed. More detail here: http://www.bhashaindia.com/ilit/GettingStarted.aspx?languageName=Tamil
    MS13-061

    (Oracle Outside In for Exchange)

    Attacker sends email with malicious attachment and lures victim to view the attachment as a webpage within Outlook Web Access. The attacker could potentially compromise the server-side process generating the web page. Critical 2 Less likely to see reliable exploit code within 30 days.

    Addresses Oracle Outside In issues included in the Oracle July 2013 security update: http://www.oracle.com/technetwork/topics/security/cpujuly2013-1899826.html

    MS13-063

    (Kernel)

    Attacker who is already running code on a machine uses this vulnerability to elevate from low-privileged account to SYSTEM. Important 1 Likely to see reliable exploits developed within next 30 days. Also addresses CVE-2013-2556, the LdrHotPatchRoutine Windows ASLR bypass used as part of a CanSecWest pwn2own exploit.  You can read more about that aspect of this update in this SRD blog post.
    MS13-062

    (RPC)

    Attacker on the same machine as a higher-privileged user making asynchronous RPC requests to a remote resource may be able to have RPC request executed as the higher-privileged user. (Example: print server scenario where higher privileged user is continually submitting print jobs) Important 1 Likely to see reliable exploits developed within next 30 days. However, limited scenarios in which attack could be used. This is a post-auth race condition attack with several pre-conditions. Difficult to trigger reliably.
    MS13-066

    (Active Directory Federated Services)

    Attacker can leverage information leak to lock out service account used by ADFS, denying service to users. Important 3 Denial of service only.  
    MS13-065

    (ICMP)

    Attacker send malicious ICMP packet causing denial-of-service on victim recipient. Important 3 Denial of Service only. Difficult to reproduce this one. Likely will require third party driver installed and packet stored in memory aligned with the page boundary.
    MS13-064

    (NAT driver)

    Attacker can send malicious network attack against Direct Access server causing denial-of-service. Important 3 Denial of Service only. Only affects machines running WinNat service. This service was first introduced with Windows Server 2012 and is off by default.

    - Jonathan Ness, MSRC Engineering

  • Cryptographic Improvements in Microsoft Windows

    You might remember that in June 2013 we released Security Advisory 2854544 announcing additional options for enterprise customers to manage their digital certificate handling configuration on the Windows platform. The particular functionality announced in Security Advisory 2854544 was first built into Windows 8, Windows Server 2012, and Windows RT and then back-ported to other operating systems. At the time, we also announced our plan to release additional updates to this advisory – all aimed at bolstering Windows cryptography and certificate-handling infrastructure. These efforts are not in response to any specific incident, but rather just the continuing evolution of how he handle digital certificate to ensure the safest possible computing environment for our customers.

    What’s New Today?

    Today, we have released the next in that planned set of advisories. Security Advisory 2862973 announces the immediate availability of an update to restrict the use of the MD5 hashing algorithm in digital certificates that are a part of the Microsoft Root Program. We plan to release this update broadly through Windows Update on February 11, 2014 after customers have a chance to assess the impact of this update and take necessary actions in their enterprise. It is available today on the Microsoft Download Center.

    This MD5 update is enabled by a new framework for management of cryptography, described briefly below and in more detail on Microsoft Technet. These updates are meant to enhance customer privacy and security. Strong cryptography improves the functionality of signing features which allow users to validate the source and trustworthiness of content. It also improves the functionality of the underlying cryptography algorithms, increasing the cost of attacker efforts to perform content spoofing, man-in-the-middle (MiTM), and phishing attacks.

    We’ll look at the new cryptographic framework update first. It provides a number of features Administrators can use to monitor and deprecate weak cryptography. The features introduced focus on increasing the strength of asymmetric cryptography as used in the platform and deprecating hashing algorithms such as MD5.

    Increasing the strength of asymmetric cryptography

    Asymmetric cryptography is used to encrypt data / share secrets between two or more entities. Instead of using a single shared key to unlock a secret (symmetric-key cryptography), each entity has a public and private key to encrypt, decrypt and sign. In practice, the strength of asymmetric cryptography is dependent on the key size, algorithm used, and the trusted third party who validates the keys.

    Recent updates address these properties by providing users with options to manage which cryptographic algorithms are used (RSA, DSA or ECDSA), options to set minimum key length, and options to set allowed hashing algorithms for code signing and other functions.

    All updates and the current status of cryptographic improvements for cryptography are centrally tracked as a part of Microsoft Security Advisory 2854544 (Updates to Improve Cryptography and Digital Certificate Handling in Windows).

    Timeline of Cryptographic improvements 2012-2013

    Microsoft Security Advisory 2661254
    This update set a mandatory key length for RSA keys of 1024 bits or stronger by restricting the use of certificates with RSA keys less than 1024 bits in length.

    KB Article 2813430
    This update establishes functionality that enables consumers to update trusted and disallowed Certificate Trust Lists (CTL) in non-internet connected environments. CTL’s are a list of approved hashes or certificates approved by a trusted third party. This update allows customers more control in which parties they trust.

    KB Article 2862966
    This update established a framework for managing asymmetric cryptography by adding features for monitoring and directly controlling which cryptographic algorithms are used (RSA, DSA or ECDSA), options to set minimum key length as well as to set which hashing algorithms will be permitted for code signing and other functions. All functionality is documented in detail on Microsoft TechNet.

    Microsoft Security Advisory 2862973
    This update released today as Downloadable Content (DLC) gives customers the option to restrict the use of certificates that utilize the MD5 hashing algorithm as part of their digital signature. We recommend that customers download and test the update in their environment at the earliest opportunity, this will be especially useful for environments that have little or no inventory of their cryptographic and certificate dependencies. This update will only affect MD5 as used in server authentication, code signing and time stamping. There are exceptions for certain certificates and timestamps, please see KB 2862973 for additional details. Microsoft is planning to release this update through Windows Update on February 11, 2014 after customers have a chance to assess the impact of this update and take necessary actions in their enterprise.

    - William Peteroy, MSRC

  • Mitigating the LdrHotPatchRoutine DEP/ASLR bypass with MS13-063

    Today we released MS13-063 which includes a defense in depth change to address an exploitation technique that could be used to bypass two important platform mitigations: Address Space Layout Randomization (ASLR) and Data Execution Prevention (DEP). As we’ve described in the past, these mitigations play an important role in making it more difficult and costly for attackers to exploit vulnerabilities. The bypass technique that has been addressed by MS13-063 was described by Yang Yu of NSFocus Security Labs at the CanSecWest security conference earlier this year. This bypass was also independently discovered by other researchers and was used by VUPEN in one of their exploits for the Pwn2Own 2013 contest as well. A few months ago, we released EMET 4.0 which included a mitigation for this specific bypass. In this blog post, we wanted to provide some background on how the bypass works and how it has been addressed by MS13-063.

    How the bypass works

    The bypass takes advantage of a predictable memory region known as SharedUserData that exists at a fixed location (0x7ffe0000) in every process on every supported version of Windows. On 64-bit versions of Windows prior to Windows 8, this region contains pointers to multiple functions in the 32-bit version of NTDLL that is used by WOW64 processes as shown below:

     

    The presence of these pointers at a predictable location in memory can enable an attacker to bypass ASLR if they have the ability to read anywhere in memory. In this case, the bypass technique takes things a step further by taking advantage of one of the functions listed above: LdrHotPatchRoutine.  This function is part of the hotpatching support provided by Windows and one of the noteworthy things it does when called is load a DLL from a path that has been passed in as a field of the first parameter. This means that if an attacker can use a vulnerability to call LdrHotPatchRoutine, they could execute arbitrary code as a side effect of loading a malicious DLL of their choosing, such as from a UNC path, and thus bypass DEP implicitly.

    Depending on the vulnerability that is being exploited, it can be fairly straightforward for an attacker to trigger a call through the pointer to LdrHotPatchRoutine in SharedUserData with a controlled parameter, thus bypassing both ASLR and DEP. Use after free vulnerabilities involving C++ objects with a virtual table pointer are particularly well-suited for being able to apply this technique. These vulnerabilities have become a preferred vulnerability class of exploit writers in recent years. The reason use after free issues are particularly amendable is because attackers typically control the entire content of the C++ object that has been freed prior to a virtual method call.  As such, an attacker only needs a virtual method call site where they can control the virtual table pointer being called through and the first parameter that is passed to the virtual method.  For example, if we assume that EDX points to memory that is controlled by the attacker:

    mov ecx, [edx+0x4]   ; load pointer to fake object into ECX
    mov eax, [ecx]       ; load fake virtual table pointer 0x7ffe0344 into EAX
    push ecx             ; push pointer to controlled content as first parameter
    call [eax+0xc]       ; call [0x7ffe0344 + 0xc] which points to LdrHotPatchRoutine

    As a result of the above sequence, LdrHotPatchRoutine will be called and the DLL path referred to in the fake structure that is passed as the first parameter will be loaded, thus bypassing both ASLR and DEP.

    How the fix works

    The bypass described above relies on the fact that a pointer to LdrHotPatchRoutine can be found at a predictable location in memory. As such, one way to mitigate this bypass is to simply eliminate the predictable pointer to LdrHotPatchRoutine from SharedUserData. This is approach taken in the security update for MS13-063. After installing this update on Windows 7 64-bit, we can see that not only has the pointer to LdrHotPatchRoutine been eliminated, but in fact all other image pointers have been eliminated as well:

     

    As a result, not only is the LdrHotPatchRoutine bypass mitigated, but so is any other bypass that relies on leveraging the image pointers that were present in SharedUserData on 64-bit versions of Windows. The potential for abusing one or more of these pointers was something that we were aware of during the development of Windows 8 and as such we took steps to eliminate all image pointers from SharedUserData on both 32-bit and 64-bit versions of Windows 8. This is why Windows 8 was not susceptible to this bypass. It should be noted that although MS13-063 removes all image pointers from SharedUserData on 64-bit versions of Windows 7, there is still one image pointer present in SharedUserData on 32-bit versions of Windows 7 and prior (the SystemCall function pointer).

    For those who are curious, the pointers that were originally stored in SharedUserData have now been moved to an exported global data structure named LdrSystemDllInitBlock in NTDLL. This data structure is populated during process initialization with the required pointers. Since NTDLL is randomized by ASLR, an attacker cannot reliably predict where these pointers will be stored in memory.

     

    Bounty program

    Although we were already aware of the underpinnings of this bypass before it was publicly described, it is a great example of a technique that could have qualified for our recently announced Mitigation Bypass Bounty Program. This bounty program offers exceptional rewards (up to $100,000) for novel exploitation techniques that affect the latest versions of our products. In this case, the bypass was generic, could be made reliable, had reasonable requirements, applied to high impact user mode application domains, and had elements that made it novel. Discovering and mitigating exploitation techniques of this nature can help us make our platform safer and more secure by breaking the techniques that attackers rely on to develop reliable exploits.

    - Matt Miller and William Peteroy

    Special thanks to our colleagues in Windows Sustained Engineering for their work on shipping this defense in depth update.

  • The story of MS13-002: How incorrectly casting fat pointers can make your code explode

    C++ supports developers in object-orientated programming and removes from the developer the responsibility of dealing with many object-oriented programming (OOP) paradigm problems. But these problems do not magically disappear. Rather it is the compiler that aims to provide a solution to many of the complexities that arise from C++ objects, virtual methods, inheritance etc. At its best the solution is almost transparent for the developers. But beware of assuming or relying on ‘under-the-hood’ behavior. This is what I want to share in this post - some aspects of how compilers deal with C++ objects, virtual methods, inheritance, etc. At the end I want to describe a real-world problem that I analyzed recently, which I called a “pointer casting vulnerability”.

    Pointers C vs C++

    C++ introduces classes supported by the C++ language standard, which is a big change. Compilers need to take care of many problems, e.g. constructors, destructors, separating fields, method calling etc.

    In C we are able to create a function-pointer so why shouldn't we be able to create a pointer-to-member-function in C++? What does it mean? If we have a class with implementation of any method, from the C developer point of view this is just a function declared inside the object. C++ should allow us to create pointer to exactly this method. It is called a pointer-to-member-function.

    How can you create them? It is more complex than a function pointer in C. Let's see an example:

    class Whatever {
    public:
    	int func(int p_test) {
    		printf("I'm method \"func()\" !\n");
    	}
    };
    
    typedef int   (Whatever::*func_ptr)(int);
    func_ptr p_func = &Whatever::func;
    Whatever *base = new Whatever();
    int ret = (base->*p_func)(0x29a);  
    

    The definition of the function pointer is not much different comparing to C. But the way to call the function from the pointer obviously is because of the implied this pointer. At this point some magic happens. Why do we need to have an instance of the class and why we are using it as a base to call the pointer? The answer requires us to analyze what these “pointers” look like in memory.

    Normal pointers (known from C language) have size of a CPU word. If the CPU operates on 32 bit registers, a C-like pointer will be 32 bits long and will contain just a memory address. But the pointer-to-function-member C++ pointers mentioned above are sometimes also called “fat pointers”. This name gives us a hint that they keep more information, not just a memory address. The fat pointer implementation is compiler-dependent, but their size is always typically bigger than a function pointer. In the Microsoft Visual C++ a pointer-to-member-function (fat pointer) can be 4, 8, 12 or even 16 bytes in size! Why so many options and why is so much memory needed? It all depends on the nature of the class it's associated with.

    Classes and inheritance

    The nature of a “pointer to member function” is driven by the layout of the class for the member function that we’re wanting to point to.

    There are some excellent references on the details of C++ object layout – see [1,2] for example. We give just one example class and associated layout: consider two unrelated classes that derive from the same base class:

    class Tcpip {
    public:
        short ip_id;
        virtual short chksum();
    };
    
    class Protocol_1 : 				class Protocol_2
    	: virtual public Tcpip {				: virtual public Tcpip {
    public:						public:
    	int value_1;					int value_2;
    	virtual int proto_1_init();			virtual int proto_2_init();
    };						};
    

    These two classes could be written by completely different developers or even companies. They don't need to be aware of each other. Now we imagine the situation that a third company wants to write a wrapper for these two protocols and export APIs that are independent of the specification of either. The new class could look like this:

    class Proto_wrap 
    	: public Protocol_1, public Protocol_2 {
    public:
    	int value_3;
    	int parse_something();
    };
    

    Note that having declared Protocol_1 as Protocol_1 with virtual inheritance means that there is a single version of ip_id (and chksum()) in the memory layout and the statement

    	pProtoWrap->chksum(); 

    is unambiguous. The layout of a Proto_wrap object is:

    (Without the virtual inheritance, each of Protocol_1 and Protocol_2 would have its own copy of the ip_id member, leading to ambiguity if we were to try something like: int a = pProto_wrap->ip_id )

    Pointer-to-member-function (fat pointers)

    Now that we have recalled some relevant background we can return to the original problem. Why are pointer-to-member-function bigger than a C-style function pointer? The Microsoft VC++ compiler can generate pointer-to-member-function (fat pointers) that are 4, 8, 12 or even 16 bytes long [3,4]. Why are there so many options and why do they need so much memory? Hopefully thinking about the object layout example above provides some hints...

    If we create a pointer-to-member-function to a static function it will be converted to a normal (C-like) pointer and will be 4-bytes long (on 32 bits arch, in other case CPU word size). Why? Because static functions have a fixed address that is unrelated to any specific object instance.

    In the single inheritance case, any member function can be referred to as an offset from a single ‘this’ pointer.

    In the multiple inheritance case however, given a derived object (e.g. Proto_wrap) it is not the case that its ‘this’ pointer is valid for each base class. Rather ‘this’ needs to be adjusted depending on which base class is being referred to. In this case “fat pointer” will be 2 CPU words long:

    				| offset | “this” |

    See [5] for a more detailed walkthrough.

    Additionally if our object uses virtual inheritance (the layout example given in the previous section), then we need to know not only which of the vtables is relevant (Protocol_1’s or Protocol_2’s) but also the offset within that corresponding to the member function that we’re wanting to point to. In this case the pointer-to-member-function size will be 12 bytes (3 CPU words size).

    This is not the end… You can also forward declare an object and in this case the compiler has no idea about its memory layout and will allocate a 16-byte structure for the pointer-to-member-function unless you specify the kind of inheritance associated with the object via special compiler switches/pragmas. [3,4].

    So now I will try to explain some interesting security-related behavior which I met during my work…

    C++ pointer casting vulnerability

    Let's analyze the following skeleton example. We have a base class, which is virtually inherited by two further classes: RealData holds some data ; Manage can process specific types of data; ‘BYTE *_ip’ is used as the means to direct which of Manage’s processing methods should be called.

    class UnknownBase;
    
    class RealData {
       friend Manage;
       public:
    ...
          ULONG_PTR  _lcurr;	// some real data...
          int   _flags;
          int   _flags2;
          int   _flags3;
    
    };
    
    class Manage : public virtual UnknownBase {   
          friend class ProcessHelper;
    public:
          BYTE *   _ip;
          RealData *    _curr;
    ...
    };
    
    class ProcessHelper  : virtual UnknownBase {
       public:
          typedef LONG_PTR (Manage::*ManageFunc)();
    
          struct DummyStruct {
             ManageFunc _executeMe;  // pointer to member function!
          };
    ...
    };
    
    LONG_PTR Manage::frame() {
       LONG_PTR offset = (this->*(((ProcessHelper::DummyStruct *) _ip)->_executeMe))();
       return offset;
    }
    

    The key to this vulnerability is the rather convoluted cast in Manage::frame(). Note the types involved:

    • _ip is of type BYTE * type
    • ProcessHelper::DummyStruct is a struct with a pointer-to-function member type ManageFunc

    So the ‘BYTE *’ data is actually being cast (in a roundabout way via a struct) to a ManageFunc pointer-to-member-function type, ie the instruction is really equivalent to:

    LONG_PTR offset = ((ManageFunc)_ip)();

    However the compiler errors out on such a statement, flagging that ‘BYTE *’ and ‘ManageFunc‘ are incompatible types (different sizes in particular!) to be casting to and from. It appears here that the developer worked round the compiler error by introducing the ‘struct DummyStruct’ subterfuge: they assumed that under the hood the ManageFunc really was just a standard pointer, and were able to indirectly achieve the incorrect cast… C/C++ will always allow the persistent developer to eventually do the wrong thing.

    Let’s run through how this breaks in practice. We create the following instances:

      Manage *temp_manage = new Manage;
      Real_block *temp_real_block = new RealData;
    

    To illustrate the issue we might set up the ‘flags’ members as follows:

      temp_real_block->_flags = 0x41414141;
      temp_real_block->_flags2 = 0x41414141;
      temp_real_block->_flags3 = 0x41414141;
    

    And let’s suppose the code does something like the following:

      temp_manage->_ip = (BYTE *)&temp_real_block->_lcurr;
      temp_manage->frame(); //  does the (ManageFunc)_ip) cast
    

    This leads to a crash - after casting to the DummyStruct structure with pointer-to-member-function our base casting expects to have a fat pointer memory layout associated with virtual inheritance, specifically expecting to find vbtable offset information at the 3rd CPU word: this value is taken and added to the whole pointer. In our case, _ip was pointing at _lcurr and so we have the following adjacent data:

          ULONG_PTR  _lcurr;
          int   _flags;
          int   _flags2;
          int   _flags3;
    

    So here, the arbitrary _flags data will be added to the memory address _lcurr in an attempt to form the address of the member function.

    Note that RTTI (run-time type information) does not help here; the incorrect cast is directly computing an incorrect memory address to call.

    The security consequences are potentially severe - full remote code execution (RCE). In such an incorrect ‘standard pointer’ to ‘pointer-to-member-function’ cast scenario, the data adjacent to the standard pointer will be used to calculate the address of the member function. If the attacker controls this then by choosing suitable values here, he can cause that address calculation to result in a value of his choosing, thus gaining control of execution.

    In the real vulnerability we didn’t have direct control over what will be written to the “_flags” field. But we were able to execute some code path which set “_flags” value to not zero – the number 2 (two). So we were able to set “_flags” to the value 2 and then execute vulnerable code. Because pointer was badly calculated (because 2 was added to the pointer), memory which was cast to the structure had bad values. Inside of the structure was function pointers and because they were shifted by 2 bytes, they were pointing somewhere in memory which always was somewhere in the heap range. An attacker could spray the heap and thus control this. [6]

    Summarize

    The higher level a language, the more problems the associated compilers must solve. But the developer is ultimately responsible for writing correct code. Typically C/C++ compilers will ultimately allow you to cast to and from unrelated types (C pointers to pointers-to-member-functions for example) and back again. Developers should avoid such illegal activity, take careful note of compiler warnings that occur when they break the rules, and be aware that if they persist they’re on their own… Microsoft Visual Compiler detects described situation and inform developers about that by printing appropriate message:

    error C2440: 'type cast' : cannot convert from 'BYTE *' to 'XXXyyyZZZ'. 
      There is no context in which this conversion is possible.

    Btw. I would like to thanks following people for help with my work:

    • Tim Burrell (MSEC)
    • Greg Wroblewski (MSEC PENTEST)
    • Suha Can

    Best regards,
    Adam Zabrocki

    References

    [1] Reversing Microsoft Visual C++ Part II: Classes, Methods and RTTI

    [2] C++: under the hood

    [3] MSDN: Inheritance keywords

    [4] MSDN: pointers-to-members pragma

    [5] Pointers to member functions are very strange animals

    [6] http://technet.microsoft.com/en-us/security/bulletin/ms13-002