Welcome after one of the more lengthy breaks in the blog’s activity. Today, I would like to discuss none other than several interesting weaknesses around the implementation of menus (like, window menus) in the core component of the Microsoft Windows kernel – the infamous win32k.sys driver, also known as the “Java of Windows” in terms of overall security posture.
Now, menus have been a part of the Windows graphical interface since the very beginning of the operating system existence. The implementation became part of the Windows kernel at the time of porting a majority of the Windows manager (User) subsystem to a ring-0 component during Windows NT 4.0 development. The functionality consists of user-facing (i.e. the NtUserThunkedMenuInfo and NtUserThunkedMenuItemInfo system calls) and rendering portions of code; I have found several bugs or problems in both areas.
First of all, let’s start with the win32k!xxxSetLPITEMInfo function, which can be generally reached through the two following call chains in Windows 7 x86:
Two weeks ago (we’re running late, sorry!) Gynvael and I had the pleasure to attend one of the largest, most technical and renowned conferences in existence – Black Hat 2013 in Las Vegas, USA. The event definitely stood up to our expectations – the city was purely awesome (especially for someone who just turned 21 like me), the venue was at least as great, we saw many interesting and truly inspiring talks and a whole bunch of old friends, not to mention meeting a fair number of new folks. In addition to all this, our visit to Vegas turned out quite successful for other reasons too – our “Identifying and Exploiting Windows Kernel Race Conditions via Memory Access Patterns” work was nominated and eventually awarded a Pwnie (in fact, two mascots) in the “Most Innovative Research” category. Woot!
While the subject of memory access pattern analysis or the more general kernel instrumentation was only mentioned briefly when we originally released the first slide deck and whitepaper, as we mostly focused on the exploitation of constrained local kernel race conditions back then, our most recent Black Hat “Bochspwn: Identifying 0-days via System-Wide Memory Access Pattern Analysis” talk discussed the specifics of how the control flow of different operating systems’ kernels can be logged, examined or changed for the purpose of identifying various types of local vulnerabilities. Demos were presented live and are not available publicly (especially considering that one of them was a 0-day).
This is a quick reminder that Gynvael and I are going to attend BlackHat US 2013 in Las Vegas next week with the “Bochspwn: Identifying 0-days via System-Wide Memory Access Pattern Analysis” presentation on the second day of the event. The talk is going to largely extend our previous performance at SyScan this year (see blog post), detailing the implementation of our “Bochspwn” project, discussing other approaches to system-wide instrumentation and how it can be effectively used to discover different local vulnerability classes (not just double fetches!) in widely used kernels. We will also provide a follow up on using Bochspwn against open-source platforms (Linux, FreeBSD, OpenBSD), including extensive coverage of our findings there, and last but not least, we will release the Bochs instrumentation toolkit as an open-source project for everyone to hack on. If you happen to be in the Sin City at the time, don’t hesitate to come by and say hi! See you there!
If you are not going to make it this time, expect the presentation slide deck shortly after the conference.
In other news, our CTF team called “Dragon Sector” has recently started their own blog: http://blog.dragonsector.pl/. The website is supposed to feature write-ups from the more interesting CTF tasks we manage to solve during the competitions. With merely four posts so far, the blog is surely going to fill up with interesting posts as we play contests in the near future, so be sure to keep an eye on it.
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.
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):
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.
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.
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 ;-)
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.
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:
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.
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.