A story of win32k!cCapString, or unicode strings gone bad

In the most recent blog post (“Fun facts: Windows kernel and guard pages”), we have learned how the code coverage of kernel routines referencing user-mode memory can be determined by taking advantage of the fact that kernel-mode code triggers guard page exceptions in the same way as user-mode does. Today, I will present how the trick can be used in a practical attack against an actual 0-day vulnerability in the Windows kernel. Don’t get too excited though – the bug is a very peculiar type of an information disclosure class, not particularly useful in any sort of real-life attack. Despite being of minimal severity due to the extent of information the bug makes it possible to leak, it makes a great example of how the misuse of the UNICODE_STRING structure and related kernel routines can lead to opening up a security loophole in the operating system.

Microsoft has been aware of the issue for over 4 months, but due to its low severity, I believe it is rather unlikely it will be fixed any time soon.

Unicode string security

All of the most recent versions of the Windows operating system (starting with Windows 2000) internally handle textual strings using the UTF-16 encoding and a UNICODE_STRING structure defined as follows:

typedef struct _LSA_UNICODE_STRING {
  USHORT Length;
  USHORT MaximumLength;
  PWSTR  Buffer;

Together with the structure definition, both user- and kernel-mode API interfaces provide a set of functions designed to initialize, examine, compare and otherwise operate on unicode strings, e.g. RtlInitUnicodeString, RtlAnsiStringToUnicodeString or RtlAppendUnicodeStringToString. In the above listing, the Length field represents the current length of the string in bytes (it must be a multiplicity of two due to the encoding used), MaximumLength indicates the total capacity of the buffer in bytes and Buffer points to the actual data. Note that both Length and MaximumLength fields are only 16-bits long, which is by far enough to accommodate the size of any string used during normal operation of the system. Perhaps contrary to intuition, the relatively limited ranges of the integers (making it possible to easily craft a string of a maximum size) do not pose any serious threat with regards to integer arithmetic, because overflowing either fields doesn’t give the attacker much edge. If you think about it, getting Length to be smaller than the actual length of the string can only lead to overwriting the existing buffer contents, but will never result in writing past the pool allocation. Similarly, setting MaximumLength to an overly small number only puts a more strict limitation on how many bytes can be stored in the corresponding buffer, or causes all subsequent calls to fail due to an invalid Length > MaximumLength condition. As a consequence, integer overflows are not of much interest in this context.

Read moreA story of win32k!cCapString, or unicode strings gone bad

Fun facts: Windows kernel and guard pages

It has been a while since I last posted here, so I guess it’s high time to get back to work and share some more interesting Windows kernel internals goodies. Before we get to that, however, let’s start with a few announcements. First of all, there is a number of great infosec conferences coming up and it just so happens that I have been accepted to speak at a few of them. The list includes:

  • SyScan in Singapore (22-26th of April) with Gynvael Coldwind: “Bochspwn: Exploiting Kernel Race Conditions Found via Memory Access Patterns”. We will be discussing a personal project of ours that led to the discovery of around 50 local vulnerabilities in the Windows kernel, some of them already patched in the February and April security bulletins (ms13-016, ms13-017, ms13-031, ms13-036).
  • NoSuchCon in Paris (15-17th of May): “Abusing the Windows Kernel: How to Crash an Operating System With Two Instructions”
  • SEConference in Cracow (24-25th of May): “Bezpieczeństwo jądra Windows, lub jak zabić system dwoma instrukcjami”
  • CONFidence in Cracow (28-29th of May) with Gynvael Coldwind: “Beyond MOV ADD XOR – the unusual and unexpected in x86”
  • BlackHat US in Las Vegas (27th of July – 1st of August) with Gynvael Coldwind: TBA (not yet accepted, but going there either way)

If you are planning to attend any of the above, feel free to ping me so that we can have a beer or two. Otherwise, I will be posting the slides / whitepapers on the blog directly following my presentation at each event, in case you’re interested in the materials.

In other news, last Tuesday Microsoft unexpectedly patched the NTFS.sys device driver vulnerability that we described several months ago in the “Introducing the USB Stick of Death” blog post, despite making a prior claim that vulnerabilities which require Administrative and/or physical access to the victim machine are out of scope and are not considered security issues. While this is surprising in itself, the ms13-036 bulletin containing the fix has apparently broken a lot of Windows-driven platforms, to the point where the vendor removed the specific 2823324 update from the download center entirely. Such situations are uncommon to see, and this particular one is most likely evidence of how third-party software can rely on unsupported or internal OS behavior. I would be really interested to read a post-mortem, but I guess a binary diff of the old and new (if one comes out) patch will have to do. Stay tuned for the analysis.

Now, let’s get to the merit of this post.

Read moreFun facts: Windows kernel and guard pages

PDF Fuzzing Fun Continued: Status Update

(Collaborative post by Mateusz “j00ru” Jurczyk and Gynvael Coldwind)

Almost five months ago, Gynvael Coldwind and I wrote about an effort to improve the security of popular PDF parsing and rendering software; back then, we were primarily focused on the Chrome PDF Renderer and latest Adobe Reader applications. In order to achieve our results, we used several hundred CPU cores to create a unique, minimal set of PDF documents aimed at optimal code coverage. That corpus, which we now consider a fundamental part of our bug hunting success, was used as fuzzing input to numerous mutation algorithms (basic bitflipping, undisclosed PDF-specific algorithms that respect the primary rules of a document’s structure, and things in between).

As a quick recap, we found more than 50 vulnerabilities ranging from low (unlikely exploitable) to high (serious memory errors) severity in the PDF-parsing component of Google Chrome with the help of AddressSanitizer. All of these were fixed by the Chrome Security Team by August 2012, mostly by Chris Evans – kudos! In addition to that, we also reported around 60 Adobe Reader crashes appearing to be unique in June last year. This consequently resulted in a total of 25 separate fixes addressed by 12 CVEs, as described by the Adobe in their APSB12-16 security bulletin and implemented in the new 9.5.2 and 10.1.4 versions of the software for Windows and Mac OS X platforms. Unfortunately, a few very important questions remained unanswered, such as “what about the remainder of the reported bugs?” and “what about the security of Reader for Linux users?”. With Adobe releasing new versions for all supported Reader branches and platforms today (9, X, XI for Windows, Mac OS X and Linux), we would like to take the chance to give you an update on where we stand with PDF fuzzing, and what thoughts we have around Reader and the many other pieces of software people use in their daily work with documents.

Let’s start with Google Chrome – has anything changed since our last posting? Well, we’ve kept playing with different fuzzing configurations and algorithmic approaches, and discovered 20 new security issues over the last six months, summing up to a total of 78 unique bugs found and fixed in the renderer in 2012. As of now, we are not aware of any unfixed non-DoS issues in the PDF Chrome component.

[134955] [135488] [137106] [137288] [137302] [137547] [137556] [137606] [137635] [137880] [137928] [144579] [145079] [145121] [145163] [146462Medium CVE-2012-2875: Various lower severity issues in the PDF viewer. Credit to Mateusz Jurczyk of Google Security Team, with contributions by Gynvael Coldwind of Google Security Team.

[143798] [144072] [147402High CVE-2012-2890: Use-after-free in PDF viewer. Credit to Mateusz Jurczyk of Google Security Team, with contributions by Gynvael Coldwind of Google Security Team.

[145029] [145157] [146460High CVE-2012-2895: Out-of-bounds writes in PDF viewer. Credit to Mateusz Jurczyk of Google Security Team, with contributions by Gynvael Coldwind of Google Security Team.

Read morePDF Fuzzing Fun Continued: Status Update

CVE-2012-2553: Windows Kernel VDM use-after-free in win32k.sys

Microsoft addressed several Windows kernel vulnerabilities in the MS12-075 security bulletin released in November this year, some of them residing in every version of the win32k.sys driver shipped with the NT family line systems. Apart from the obviously extremely interesting remote web browser => ring-0 arbitrary code execution issue, there have also been two other Local Privilege Escalation bugs, at least one of which was directly related to the management of legacy 16-bit applications running within a VDM (Virtual DOS Machine). Since the topics of use-after-free vulnerabilities in the Windows kernel – and especially in old and poorly understood functionality – seems to be very appealing for most, this post aims to cover some of the technical details related to that particular security flaw. In addition to (hopefully) having some didactic and entertainment value, this write-up and the very existence of that bug illustrates how trivial it still is to find elevation of privileges vulnerabilities in undocumented, rarely used features present in the Windows operating system since more than fifteen or twenty years by now. As a side note, a similar (yet unrelated) issue in the same code area has been previously found by Tarjei Mandt back in 2010 and documented in his excellent “CVE-2010-3941: Windows VDM Task Initialization Vulnerability” post over two years ago. There is also more evidence of Windows VDM and its kernel-mode support (WOW32) being subject of in-depth security research in the past: for example, see “Microsoft Windows NT #GP Trap Handler Allows Users to Switch Kernel Stack” (Pwnie Award Winner) or “EEYE: Windows VDM Zero Page Race Condition Privilege Escalation“.

The vulnerability

Some basic information regarding internal structures used by the WOW-related win32k.sys system calls has already been described by Tarjei in his article. In short, GUI threads can call a “public” win32k!xxxRegisterUserHungAppHandlers routine (being a part of the win32k!apfnSimpleCall interface) either through the win32k!NtUserCallTwoParam system call or user32!RegisterUserHungAppHandlers – a convenient user-mode wrapper. The service is purposed to be used within the NTVDM.EXE process, a container for 16-bit DOS apps. It is primarily responsible for allocating a WOWPROCESSINFO kernel structure, assigning it to an internal ppiCurrent->pwpi field within PROCESSINFO (corresponding to the current process) and inserting into a linked list pointed to by a global win32k!gpwpiFirstWow symbol as shown on the following listing:

Read moreCVE-2012-2553: Windows Kernel VDM use-after-free in win32k.sys

Defeating Windows Driver Signature Enforcement #3: The Ultimate Encounter

I hope you haven’t got bored with bypassing the Driver Signature Enforcement mechanism (present on all 64-bit Microsoft Windows operating systems since Vista) just yet – in either case, stay calm… this is going to be the last post of the series. After using multiple drivers shipped with the OS in the default configuration to trigger Blue Screens of Death from user-mode, and implementing a complete bypass of the functionality by using a design flaw in how the CSRSS subsystem interacts with the win32k.sys kernel module, I am going to present one final argument that the idea of preventing ring-3 applications with administrative privileges from causing bad things happen in kernel-mode is fundamentally flawed and would be never fully effective, unless a complete rewrite of the Windows kernel (including revisiting many low-level system assumptions) would be in order. Don’t keep it too seriously though – I am not claiming that the described Windows behavior has security implications of any kind – rather, it’s just a kernel curiosity illustrating how reliant the kernel is on certain assumptions that haven’t had a chance to be validated for many years.

To provide some context, several years ago Alex Ionescu and omega_red from the woodmann.com reverse-engineering forums discovered that invoking certain graphical system calls (i.e. the ones handled by win32k.sys) from within one of a few system processes would result in an unhandled kernel exception, a system bugcheck and potentially an exploitable condition (the original crash was caused by a NULL Pointer Dereference). None of the system processes would ever call the affected system services in a way that would bring the system down, so the only way for an attacker to achieve the same effect would be to inject a malicious payload into one of the highly-privileged processes and execute it – an activity which clearly takes an Administrator account to succeed.  Alex got so intrigued by the post that he performed an in-depth investigation of this weird behavior and later presented the results of his work along with some other win32k.sys security-related findings on the BlackHat US 2008 conference in a presentation called “Pointers and Handles: A Story of Unchecked Assumptions in the Windows Kernel“. In short, the graphical driver blindly dereferenced an internal pointer storing a reference to the caller’s desktop, but since some processes (e.g. CSRSS.EXE) were not assigned to any specific desktop, the kernel module would end up using a NULL pointer as a valid one: as straight-forward as it sounds.

Read moreDefeating Windows Driver Signature Enforcement #3: The Ultimate Encounter

ZeroNights slides, Hack In The Box Magazine #9 and other news

First of all, it has been reported to me that the system call list for Microsoft Windows Vista SP0 available at j00ru.vexillium.org/syscalls/nt/32 was wrong, containing syscall numbers for beta2 version of the system instead of the actual RTM Service Pack 0. The issue has already been resolved – apologies for any confusion this might have caused.

Secondly, I have just recently had a presentation on ZeroNights 2012 in Moscow regarding reference counting and how its implementations found in the Windows kernel would often lead to exploitable local elevation of privileges conditions. The slides are available for over a week now – if you haven’t checked them out yet, be sure to take a look: Windows Kernel Reference Count Vulnerabilities – Case Study. The conference overall was really good – I enjoyed several interesting, (non-)technical talks by @thegrugq (“OPSEC: Because Jail is for wuftpd”), @NTarakanov (“The Art of Binary Diffing or how to find 0-dayz for free”), @d_olex (“Applied anti-forensics: rootkits, kernel vulnerabilities and then some”), @Agarri_FR (“That’s why I love XML hacking!”) and a few more. Additionally, the organizers really seemed to be trying their best to ensure painless and enjoyable trip and stay in Russia. One major drawback of the event is that even though it’s advertised to be an “international” conference, most of the talks were given in Russian (sometimes with live English translation), and so was the audience – I’m not quite sure how many foreign people (apart from the speakers) you could meet there – probably not too many :) Still, it’s a great idea to visit the conference and meet some of the leet Russian hackers that you wouldn’t have a chance to speak with, otherwise.

Last but not least, another issue of the great Hack In The Box Magazine was released just a few days ago – it’s now the ninth edition! To complete the tradition, I took care of the “Windows Security” section this time as well, preparing a brief article with a long title: “Memory Copy Functions in Local Windows Kernel Exploitation”. In short, some implementations of the standard memcpy and memmove functions tend to write data backwards (e.g. starting from the end of the destination memory region rather tham from the beginning) under certain circumstances, which appears to be an useful observation if the attacker has a certain degree of control over the dst, src and size parameters. I hope you will enjoy it.

The magazine can be downloaded from here (HITB-Ezine-Issue-009.pdf, 11.6 MB)

Read moreZeroNights slides, Hack In The Box Magazine #9 and other news

Crawling MSDN for fun and profit

Regardless of whether you are a Windows exploitation guru, a professional win32 application developer or someone whose curiosity occasionally tells him to dig up the MSDN library looking for interesting quirks or undocumented functionality, the following examples of MSDN article excerptions are very likely to look familiar to you:

Simply put, the operating system operates on an enormous number of structures, unions and flags defined and developed throughout the 20+ years of Windows being around. Many of them are used internally within userland, kernel space or both parts of a specific functionality implementation, while typical developers never get a chance to even learn about them. Often times, however, these constructs are used to actively communicate with the operating system from within third-party software, be it a regular word processor or a custom device driver for an uncommon sound card. While reading through the Microsoft documentation library (perhaps this also applies to other environments?), it is exceedingly easy to stumble upon a sentence like “don’t use it”, “always set it to zero” or “if you use it, Windows might format your C: disk you can encounter undefined behavior”. It always sounds very mysterious, but in reality, there can be only several different reasons for that:

Read moreCrawling MSDN for fun and profit

Defeating Windows Driver Signature Enforcement #2: CSRSS and thread desktops

To stand by my claim that the Microsoft Windows operating system has been built on the fundamental assumption that administrative privileges would always be equivalent to granting the ability to run arbitrary ring-0 code, I have decided to briefly discuss yet another portion of some Windows internals and how they could be easily misused by a system administrator to unlawfully cross the admin / kernel boundary on a X86-64 platform, and effectively elevate his rights on the machine by loading an unsigned device driver of his choice. The technique is directly related to CSRSS (the infamous Client/Server Runtime Subsystem), a part of Windows that has likely motivated most of the dirty relict hacks in the kernel that still remain visible in the most recent versions of the OS.

As usual, let’s start with some historical context. Back in July 2007, omega_red started a thread on the woodmann RCE forums, stating that he had found a GDI bug (Blue Screen of Death triggerable from user-mode) that required “pretty unusual conditions” to work. A few days into the discussion, Alex Ionescu chimed in and said that inspired by omega’s finding, he had spent a night looking around the win32k.sys module and located four vulnerabilities that he would be willing to present on the BlackHat conference; and so he did – the slides from his BlackHat USA 2008 conference talk titled “Pointer and Handles” can be found here. All issues discussed by Alex are fairly interesting, so be sure to check out the slides if you haven’t already; the important one for us would be the NULL Pointer Dereference within CSRSS.EXE via xxxCreateThreadInfo. The kernel routine would dereference an internal CurrentW32Thread->Desktop pointer without prior sanitization, thus using a pointer that was never initialized for the special subsystem process, in the first place. Oh, in fact there might be a “few more instances of such bugs in the kernel nowadays, but stay tuned… :-)

Read moreDefeating Windows Driver Signature Enforcement #2: CSRSS and thread desktops

Defeating Windows Driver Signature Enforcement #1: default drivers

One of the obvious things about the Windows operating system for anyone actively working on its kernel security is that the Driver Signature Enforcement (DSE in short) is not effective and can be bypassed with relative ease by any determined individual. From a historical perspective, the “feature” was introduced in the 64-bit build of Windows Vista in 2007 and has been shipped with all 64-bit Windows editions since then. In essence, it was designed to prevent unsigned device drivers (or kernel modules in general) from being loaded and executed with ring-0 privileges. Consequently, it broke one of the fundamental Windows assumptions followed since the early years of the NT family – administrative privileges in the system would no longer be equivalent to the ability to run arbitrary ring-0 code, effectively introducing a completely new layer of privilege separation in the system.

Soon after the change was presented to wide audience, the enforcement was spectacularly defeated by Joanna Rutkowska, who took advantage of the fact that users in the Administrators group had been granted access to raw disk data and thus were able to modify parts of the pagefile.sys swap file potentially containing paged-out ring-0 code, to later execute the injected payload by crafting a special kernel-mode request (IRP to the NULL.sys driver in that particular case). Joanna’s and Alexander’s presentation was titled IsGameOver() Anyone? and received quite a lot of media attention at the time (mid 2007), starting a global discussion regarding the sense and security implications of introducing the mechanism. As a direct outcome, Microsoft decided to address this particular attack by disabling user-mode access to raw disk contents, and later on follow up with additional page hash/signing implementation for the hibernation and swap files (thanks Alex!). Since five years ago, the mechanism hasn’t been publicly criticized or otherwise discussed anymore – perhaps everyone just got used to its existence and (in)effectiveness.

Read moreDefeating Windows Driver Signature Enforcement #1: default drivers

Introducing the USB Stick of Death

(Bug found by Gynvael Coldwind, exploit developed by Mateusz “j00ru” Jurczyk)

Several months back we have been playing with different file systems on various system platforms, examining the security posture and robustness of numerous device drivers’ implementations. One of the configurations we spent some time on was the commonly used NTFS on Microsoft Windows – as the file system is rather complex and still largely unexplored, we could expect its device driver to have some bugs to that would be easily uncovered. In addition, it was certainly tempting to be able to simply insert a USB stick, have it automatically mounted by the operating system and immediately compromise it by triggering a vulnerability in ntfs.sys. We had some promising results during the process, one being an interesting bug (though not quite dangerous) that we managed to analyze and exploit into a local elevation of privileges. In today’s post, we are providing some specifics regarding the nature of the vulnerability, and how it can be taken advantage of to acquire system privileges on the Microsoft Windows 7 64-bit platform.

Please note that the presented issue requires the attacker to obtain physical access to the machine and have a local user in the system. Consequently, the only scenario in which it might be a problem security-wise is a local computer shared between multiple users with restricted privileges (e.g. schools, universities, hostels) and thus has been rated as low-severity by both us and MSRC, which has been informed about the matter and claimed to have passed the information to the Windows team for potential fixing as a stability issue somewhere in the future. We are releasing some of its technical details as an interesting case study of Windows kernel exploitation using somewhat novel techniques to achieve reliable execution of code with escalated privileges. Enjoy!

Read moreIntroducing the USB Stick of Death