Search the Community
Showing results for tags 'window'.
-
In this article, we will discuss HTML5 Web Messaging (or Cross Domain Messaging) attack vectors and security implementations. Why is it important to understand HTML5 attacks? HTML5 is one of the emerging technologies for next generation Web applications. It has brought a lot of new features to the Web. HTML5 applications are also widely used in the mobile app world. Along with the features, HTML5 has brought various new attack vectors as well. The main focus of this article is to show the possible attack vectors with the Cross Domain Messaging feature. Before going ahead with the security concepts of Cross Domain Messaging, let us understand the basics of how Cross Domain Messaging is implemented in HTML5. Cross Domain Messaging Due to the same origin policy restrictions before HTML5, sending messages between windows was only possible if both windows used the same protocol, port, and host. With the introduction of HTML5, all those restrictions are gone and we can now pass messages across domains without having to worry about Same Origin Policy restrictions. HTML5 has a new method called postMessage(). Using this, we can pass messages between windows regardless of their origin. Below is the syntax of postMessage(). Sending Window: otherWindow.postMessage(message, targetOrigin, [transfer]); otherWindow: This is a reference to another window. Message: The message to be passed to the receiving window. targetOrigin: The URL of the receiving window must be specified here. If we do not have any specific preference, we can specify it as “*”. Specifying “*” as ‘targetOrigin’ has some security implications we will discuss in later sections of this article. Transfer: This is optional. Receiving Window: When otherWindow.postMessage() is executed, a messageEvent will be dispatched at the receiver window. We can receive the message dispatched by the sender using the following code snippet. window.addEventListener("message",receiveMessage, false); function receiveMessage(event){ if (event.origin !== "http://site.com:8383") return; // ... } From the above code snippet, we can access the data and origin of this message as shown below. event.origin – Gives the origin of the message (The URI from which we are receiving this message). event.data – Gives the actual message being sent. Now, we have got some basic knowledge of what cross domain messaging in HTML5 is and how it is implemented in the applications. Let us now see the security implications of cross domain messaging. For demonstration purposes, I have set up the following lab. A: http://localhost:8383/ B: Romanian Security Team - Homepage As we can see, we have two different ports on the above two URLs. The first URL is running on port 8383 and the second URL is on the default port 80. So, it is obvious that they have two different origins, since the port numbers are different. In our lab setup, A is the message sender and B is the receiving window. We are going to load the second URL Romanian Security Team - Homepage as an iframe in the first URL. I can send messages from the domain http://localhost:8383/ to the domain Romanian Security Team - Homepage using the postMessage method. We can check it by clicking the “Send Message” button as shown below. The iframe which is loaded into the first URL is from a different origin, but we are able to send a message to it using HTML5’s postMessage() method. Now, let us look at some scenarios where this postMessage() implementation can introduce vulnerabilities into our applications. Case 1 Code at sender: receiver.postMessage('Hi There..!', '*');< When the sender has the above code where he specifies the target origin with a wildcard “*”, an unintended recipient (window) can receive this message from the sender. Since the receiving window is listening for incoming messages, anyone can load it into an iframe and can listen for the messages coming to it. So, it is a bad idea to give a wildcard when passing sensitive data to the receiving windows. How to fix this: It is possible to fix this just by adding the specific target in the target field. So, in this case http://localhost is the only origin that can receive this message. This is as shown below. receiver.postMessage('Hi There..!', 'http://localhost'); Case 2 Code at receiving window: function receiveMessage(e) { do something..! } In the above code, we are receiving the message from the sender and directly processing it without checking who sent this message. It is always important to check the origin of the message to prevent receiving messages from unauthorized senders. How to fix this: function receiveMessage(e) { if (e.origin !== "http://localhost:8383") return; do something..! } Always validate the origin from which you want to receive the messages. In our case, we want to receive messages only from http://localhost:8383. So, we are making a simple check to see if the message is coming from http://localhost:8383 using the property event.origin. If this is not matching, we won’t receive the message. Case 3 The next attack vector is the infamous Cross Site Scripting. Both the sender as well as receiver should always validate the messages being passed. If the data is inserted into HTML DOM without proper validation, then the application becomes vulnerable to DOM based Cross Site Scripting. The following code snippet shows how an application may become vulnerable when a malicious message is received from the attacker and it is inserted into the receiver’s HTML DOM using innerHTML property. Sender: receiver.postMessage("<img src='x' onerror=alert(1);>", 'http://localhost'); Receiver: function receiveMessage(e) { if (e.origin !== "http://localhost:8383") return; messageEle.innerHTML = "Message from localhost:8383: " + e.data; } When the above code is executed, it causes an XSS in the receiving window as shown in the figure below. How to fix this: The easiest way to fix this issue is to assign the data value to an element using textContent rather than using innerHTML. This is done as shown below. Sender: receiver.postMessage("<img src='x' onerror=alert(1);>", 'http://localhost'); Receiver: function receiveMessage(e) { if (e.origin !== "http://localhost:8383") return; element.textContent = "Message from localhost:8383: " + e.data; } When the above code is executed, we should see the text displayed in the receiving frame as “data” rather than code. As we can see in the above figure, the code is now not executed. Rather, it is displayed as normal text. Conclusion We have discussed the basics of Cross Domain Messaging and some of the possible attacks against this feature in HTML5. We will discuss other possible attacks against HTML5 web applications in later articles. Source
-
Introduction Today, Microsoft released their latest Patch Tuesday. This Patch includes a fix for vulnerability CVE-2015-0057, an IMPORTANT-rated exploitable vulnerability which we responsibly disclosed to Microsoft a few months ago. As part of our research, we revealed this privilege escalation vulnerability which, if exploited, enables a threat actor to complete control of a Windows machine. In other words, a threat actor that gains access to a Windows machine (say, through a phishing campaign) can exploit this vulnerability to bypass all Windows security measures, defeating mitigation measures such as sandboxing, kernel segregation and memory randomization. Interestingly, the exploit requires modifying only a single bit of the Windows operating system. We have verified this exploit against all supported Windows desktop versions, including Windows 10 Technical Preview. This entry starts by detailing the vulnerability. At first, it seemed to us impossible to exploit. After some hard word, however, we managed to produce a fully working exploit which we’ll describe. As part of this analysis, we also present a video which demonstrates the exploit. Finally, we conclude this entry with a buggy dead-code anecdote which we thought interesting to share. Responsible disclosure: although this blog entry is technical, we won’t reveal any code, or the complete details, to prevent any tech master from being able to reproduce an exploit. Background Over the last several years, privilege escalation vulnerabilities became all the more crucial for exploitation because they enable malicious code to run on the kernel. As such, a threat actor exploiting a privileged escalation vulnerability can bypass protective security mechanisms such as application sandboxes. Step by step with the attackers’ progress, Microsoft made extensive efforts to protect the kernel. The reasoning is that even if a vulnerability exists, exploiting it would be difficult, if not impossible. For example, here are just a few of the kernel protection mechanisms that are present in Windows 8.1:Kernel DEP – Ensures that most kernel data regions cannot be executed • Kernel DEP – Ensures that most kernel data regions cannot be executed • KASLR – Randomizes the kernel address-space to avoid figuring out where kernel modules exist • Integrity Level – Limits the ability of an unprivileged application to leak kernel-related information • Mitigation Of Common Attack Vectors – Hardens commonly abused structures (such as the Win32k wnd proc field) • SMEP – Prevents execution control transfers between kernel mode to user-mode • NULL Dereference Protection – Prohibits mapping of the first 64k of data in user-mode Albeit these hardening mechanisms, in the past year we have seen some notable presentations that demonstrated techniques to bypass these protections. The vulnerability which we describe in this entry, is a newly disclosed privilege escalation exploitable vulnerability that too bypasses these protections. The Vulnerability: a hole in the Win32k.sys module This particular vulnerability appears in the GUI component of Microsoft Windows Kernel, namely, the Win32k.sys module. This entry assumes a strong technical understanding of the Win32k.sys module. For detailed information on this module, please refer to Tajei Mandt, Gilad Bakas and Gil Dabah. Zooming into Window Scrollbars The Win32k module manages also the actual windows’ scrollbars. These scrollbars – whether horizontal or vertical – are set for each window. Let’s zoom into these scrollbars: As can be seen in Figure 1, each SBDATA structure defines the information regarding one of the scrollbars. The WSBflags is a bitmask that determines the state of the scrollbars. In order to enable and disable a window scrollbar, the function xxxEnableWndSBArrows is used. Through a single call, this function can alter the state of both scrollbars. It is precisely within this function wherein the vulnerability lies. Deep Diving into xxxEnableWndSBArrows The prototype of xxxEnableWndSBArrows is: • Wnd – A pointer to the relevant window • wSBflags – The scrollbar type (e.g. horizontal or vertical) • wArrows – Specifies whether the scrollbar’s arrows are enabled or disabled and indicates which arrows are enabled or disabled. In order to describe the vulnerability, we’ll take a look at the first part of the xxxEnableWndSBArrows function which can be broken down into 3 logical parts: Part 1 – Allocation of a new scrollbar (if needed) The function starts by checking whether there is already scrollbar information for that window and allocates a new scrollbar information struct, if needed. Technically speaking, the function reads the pSBInfo field (to recall, this field points to the tagSBINFO struct) and tests if the pointer is NULL. If the field is null and the wArrows parameter is not NULL, then a tagSBINFO struct is allocated for the window and the old flags of the scrollbars are set to 0. Otherwise the old flags are copied from the existing window’s scrollbars information. The code can be found in Figure 2. Part 2 – Setting the state of the horizontal scrollbar The flow continues by testing whether the state of horizontal scrollbar should be changed. According to what was set in the wArrows argument, the function enables or disables the arrows (figure 3). Part 3 – Testing the state of the scrollbar arrows The flow continues by checking whether the state of the arrows have changed. Technically speaking, this is done by checking the arrow’s flags (to note, there are a few more flag checks – but those are not interesting for our purpose). If the flags have changed and the window is visible then xxxDrawScrollbar is called. This is precisely the place where things get interesting. When digging into the code, it seems possible that the xxxDrawScrollBar will lead to a user–mode callback (Figure 4). The pivotal function in this call chain is the ClientLoadLibrary. This function performs the callback to the user-mode function __ClientLoadLibrary. Let’s return now to the code of xxxEnableWndSBArrows. Our examination showed that the tagSBINFO pointer is used without any verification after the callback. Ultimately, this could lead to a Use-After-Free (UAF) vulnerability since the function may continue to work with the freed scrollbar information (Figure 5). The Exploitation: manipulating windows properties After the callback, the function xxxEnableWndSBArrows continues and changes the state of the vertical scrollbar. At this stage, the function tries to enable or disable the flags. However, since the struct is already freed, we can use this to either Bitwise OR the first DWORD of the freed buffer with 0xC (if we disable the arrows) or to clear bit 3 and 4 (if we enable the arrows). See figure 6 For simplicity sake, we show how to manipulate 2 bits in order to “rule them all”. However, manipulating only one of them would be enough. The bit manipulation at first didn’t seem enough to result in anything significant, but we decided to keep trying. The most obvious things to try were to either increase the size of some buffer (using the bitwise OR) or decrease some reference counter (using the bitwise AND). After a short search we found an object that met the first requirement. This object is the properties list of a window. The Window Properties List Each window has a properties list. Generally, these properties can be used by the GUI application to store arbitrary values, though also Win32K uses this properties list in order to store internal data. The data structures used to hold the window’s properties can be seen in Figure 7. The first field, cEntries, is the number of entries in the properties array; iFirstFree is the index to the first free cell in the properties array; and props is the array itself. An application can set the window’s properties using the SetProp API. The prototype of the function is as follows: • hWnd – The handle to the window. • lpString – The of the property or an ATOM. • hData – The data to store. Adding properties to a window is performed through the CreateProp function, appearing in the win32k module. As can be seen in figure 8 its allocation algorithm is quite simple. If there is no room for a new property in the list, the function allocates a new properties list with one more entry. The function then proceeds to copy the buffer of the old properties to the new one, frees the old buffer and increases the entries count. There are several important things to note in this code: First, the properties are allocated from the Desktop heap (Uses DesktopAlloc). Also, tagSBINFO is allocated from this heap. This is crucial if we want to use the UAF vulnerability to alter the properties structure. Second, each new entry triggers the reallocation of the buffer. This means that we can easily trigger the reallocation of the buffer when it’s about to reach the size of the tagSBINFO structure. Doing this increases the chances that the buffer will be allocated over the freed tagSBINFO struct. Third, and most importantly, the cEntries field is located in the first DWORD of the struct. This means that we can increase its size (using the bitwise Or). After increasing the size of the properties array we basically achieved a classical buffer-overflow. Proof-of-Concept Video The above research led to the privilege escalation exploitation. We stop here, however, to avoid releasing any sensitive code. Our demo on a 64-bit Windows 10 Technical Preview provides the necessary proof-of-concept: Summary After some work we managed to create a reliable exploit for all versions of Windows – dating back as of Windows XP to Windows 10 preview (With SMEP and protections turned on). We have shown that even a minor bug can be used to gain complete control over any Windows Operating System. Nevertheless, we think that Microsoft efforts to make the its operating system more secure raised the bar significantly and made writing reliable exploits far harder than before. Unfortunately, these measures are not going to keep attackers at bay. We predict that attackers will continue incorporating exploits into their crime kits, making compromise inevitable. Last side note: funny code Examining the code of the xxxEnableWndSBArrows function showed that there are calls to the xxxWindowEvent function. At first glance it seemed that these two functions would be far easier to use as an exploitation stepping stone than the xxxDrawScrollbar function, as detailed above. However, after diving into the code it quickly became clear that the calls to xxxWindowEvent in the Horizontal scrollbar part of the code are actually dead-code (Figure 9). Looking at the code, there are two conditional calls to the function, xxxWindowEvent. These calls are executed only if the old flags of the scrollbar information differ from those of the new flags. However, by the time these conditions appear, the values of the old flags and the new flags are always equal. Hence, the condition for calling xxxWindowEvent is never met. This practically means that this dead-code was there for about 15-years doing absolutely nothing. Source
-
- function
- properties
-
(and 3 more)
Tagged with: