Skip to content

Changing the cursor shape in Windows proven difficult by NVIDIA (and AMD)

If you work in the software engineering or information security field, you should be familiar with all sorts of software bugs – the functional and logical ones, those found during the development and internal testing along with those found and reported by a number of complaining users, those that manifest themselves in the form of occassional, minor glitches in your system’s logic and those that can lose your company 440 million US dollars in 30 minutes; not to mention bugs which can enable attackers to remotely execute arbitrary code on your computer without you even realizing it. While the latter type of issues is usually of most interest to security professionals and 0-day brokers (not all developers, though) and thus the primary subject of this blog, this post is about something else – the investigation of a non-security (and hardly functional) bug I originally suspected win32k.sys for, but eventually discovered it was a problem in the NVIDIA graphics card device drivers.

My frequently used window order, with vim present in the background.

Figure 1. My typical work window order, with vim present in the background.

To give you some background, I am a passionate user of vim for Windows (gvim, specifically). When working with code, my usual set up for one of the monitors is a black-themed vim window set for full-screen, sometimes with other smaller windows on top when coding happens to be preempted with some other tasks. The configuration is illustrated in Figure 1 in a slightly smaller scale. A few weeks ago, I noticed that moving the mouse cursor from the vim window over the border of the foreground window (Process Explorer in the example) and inside it, the cursor would be occassionally rendered with colorful artifacts while changing the shape. Interestingly, these artifacts would only show up for a fraction of second and only during one in a hundred (loose estimate) hovers from vim to another window. Due to the fact that the condition was so rare, difficult to reproduce manually and hardly noticeable even when it occured, I simply ignored it at the time, swamped with work more important than some random pixels rendered for a few milliseconds once or twice a day.

Once I eventually found some spare time last week, I decided to thoroughly investigate the issue and find out the root cause of this weird behavior. I was primarily motivated by the fact that colorful artifacts appearing on the display could indicate unintended memory being rendered by the system, with the potential of pixels representing uninitialized kernel memory (thus making it a peculiar type of information disclosure vulnerability). Both me and Gynvael have found similar issues in the handling of image file formats by popular web browsers in the past, so the perspective of disclosing random kernel bytes seemed tempting and not too far off. Furthermore, I knew it was a software problem rather than something specific to one hardware configuration, as I accidentally encountered the bug on three different Windows 7 and 8 machines I use for my daily work.

Following a brief analysis, it turned out I was not able to reproduce the issue using any background window other than vim. While I started considering if this could be a bug in vim itself, I tested several more windows (moving the mouse manually for a minute or two) and finally found that the Notepad worked equally well in the role of a background. Not a vim bug, hurray!

As both windows share the same cursor shape while in edit mode – the I-beam, I concluded the bug must have been specific to switching from this specific shape to some other one. Precisely, while hovering the mouse over two windows and a boundary, the cursor switches from I-beam () to a horizontal resize () and later to a normal arrow (). Relying on the assumption that the bug is a race condition (or least timing related, as the problem only manifested while performing rapid mouse movements), I wrote the following proof of concept code to reproduce the problem in a more reliable manner (full source code here):

Continue reading ›

Kernel double-fetch race condition exploitation on x86 – further thoughts

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

It was six weeks ago when we first introduced our effort to locate and eliminate the so-called double fetch (e.g. time-of-check-to-time-of-use during user-land memory access) vulnerabilities in operating system kernels through CPU-level operating system instrumentation, a project code-named “Bochspwn” as a reference to the x86 emulator used (bochs: The Open Source IA-32 Emulation Project). In addition to discussing the instrumentation itself in both our SyScan 2013 presentation and the whitepaper we released shortly thereafter, we also went to some lengths trying to explain the different techniques which could be chained together in order to successfully and optimally exploit kernel race conditions, on the example of an extremely constrained win32k!SfnINOUTSTYLECHANGE (CVE-2013-1254) double fetch fixed by Microsoft in March 2013.

The talk has yielded a few technical discussions involving a lot of smart guys, getting us to reconsider several aspects of race condition exploitation on x86, and resulting in plenty of new ideas and improvements to the techniques we originally came up with. In particular, we would like to thank Halvar Flake (@halvarflake) and Solar Designer (@solardiz) for their extremely insightful thoughts on the subject. While we decided against releasing another 70 page long LaTeX paper to cover the new material, this blog post is to provide you with a thorough follow-up on efficiently winning memory access race conditions on IA-32 and AMD64 CPUs, including all lessons learned during the recent weeks.

Please note that the information contained in this post is mostly relevant to timing-bound kernel security issues with really small windows (in the order of several instructions) and vulnerabilities which require a significant amount of race wins to succeed, such as limited memory disclosure bugs. For exploitation of all other problems, the CPU subtleties discussed here are probably not quite useful, as they can be usually exploited without going into this level of detail.

All experimental data presented in this post has been obtained using a hardware platform equipped with an Intel Xeon W3690 @3.47GHz CPU (with Hyper-Threading disabled) and DDR3 RAM, unless stated otherwise.

Continue reading ›

CONFidence 2013 and the x86 quirks

Mateusz Another week, another conference. Just a few days ago, Gynvael and I  had the pleasure to attend and present at the CONFidence 2013 infosec conference traditionally held in Cracow, Poland. The event requires no further introduction – it has been simply the best Polish conference in the security area since it first started, and this year’s edition was up to the usual high standard – we had some great time, meeting old and making new friends as well as enjoying some of the better talks.

With regards to our presentation, we originally intended it to be a gathering of references concerning all of the interesting quirks, undocumented behavior and other amusing facts (directly or indirectly related to the CPU architecture) that we heard or learnt about in both 32 and 64-bit x86 processors during the recent years. If you are closely following the CPU hacking and operating system security scene, you are probably aware of most of the material we presented – still, we hope it proves useful as a thorough reference and possibly motivates you to take a deeper look at some of the areas we discussed during the talk. In addition to what was covered on stage, you can also find several extra “further reading” slides containing references to information which did not fit into the elementary slide deck.

Download: Beyond MOV ADD XOR – the unusual and unexpected in x86 (PDF, 5.6MB)

Other than that, I also presented at a local Polish SEConference event in Cracow a few days earlier, using my NoSuchCon 2013 slide deck translated to Polish:

Download: Bezpieczeństwo jądra Windows, lub jak zabić system dwiema instrukcjami (PDF, 4.3MB)

That’s about it, have fun!

NoSuchCon’13 and crashing Windows with two instructions

The first edition of the NoSuchCon security conference held in Paris ended just a few days ago. Before anything else, I would like to thank all of the organizers (proudly listed at nosuchcon.org) for making the event such a blast! Both the location, venue and speaker line-up were amazing, with lots of free beer and wealth of people to chat with. Overall, I am very happy to have shown up there and I will definitely make sure to attend the second edition of the conference.

Other than drinking, discussing 0-days and visiting Paris, I also had the pleasure to give a talk about the usual subject – Windows kernel security. The exact title of my presentation was “Abusing the Windows Kernel: How to Crash an Operating System With Two Instructions“, and touched on the subject of several different exploitation techniques, internal CPU related behavior and security vulnerabilities (all related to the Windows operating system) that I discovered during the course of last several weeks / months.

While the slide deck was made available to the attendees right at the beginning of my talk at nosuchcon.org/talks (great idea!), I’m reposting them here anyway, in case you haven’t had a chance to take a look yet. In fact, a majority of the talks were interesting and highly technical, so be sure to check the available material for all presentations ;-)

Download

Slides: “Abusing the Windows Kernel: How to Crash an Operating System With Two Instructions” (3.3MB, PDF)

KiTrap0e advisory: “Abusing Windows NT #PF Trap Handler to Bugcheck and Leak Information

Continue reading ›

SyScan 2013, Bochspwn paper and slides

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

Singapore, photo by Arashi Coldwind

A few days ago we (Gynvael and I) gave a talk during the SyScan’13 conference in the fine city of Singapore, and as promised (though with a slight delay), today we are publishing both the slide deck and a white paper discussing memory access pattern analysis – a technique we recently employed with success to discover around 50 double-fetch vulnerabilities in Windows kernel and related drivers (Elevation of Privileges and Denial of Service class; see Microsoft Security Bulletins MS13-016, MS13-017, MS13-031 and MS13-036 released in February and April this year. Also, stay tuned for more security patches in May and June).

In our SyScan presentation, we explained the concept of kernel race conditions in interacting with user-mode memory, gave a brief rundown on how they can be identified by using CPU-level instrumentation of an operating system session, and later focused on how they can be successfully exploited with the help of several generic techniques (on the example of three Windows vulnerabilities discovered by the Bochspwn project). While we only had the time to go through a single case study (the CVE-2013-1254 vulnerability in win32k!SfnINOUTSTYLECHANGE), both slides and the paper contain a detailed analysis of another local privilege escalation: CVE-2013-1278 in nt!ApphelpCacheLookupEntry, and an amusing case of a double fetch behavior (it is not clear if it can be classified as a bug) found in the default kernel implementation of the standard nt!memcmp function, as a bonus.

We hope you will enjoy both the slides and whitepaper – considering the amount of time we have dedicated to the research, we would really appreciate your feedback.

Download:

Continue reading ›

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;
} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;

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.

Continue reading ›

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.

Continue reading ›

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.

Google ChromeLet’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.

Continue reading ›

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:

Continue reading ›

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.

Continue reading ›