Windows internals research provides a vast amount of room to explore, and sometimes you come across a particularly interesting subject you may have not known about or heard of: a subject that has very minimal documentation and seems to be a remnant of the days prior to native 64bit support.
These are the times that excite you because you’re certain you will find that brand new vulnerability that may lead to an exploit that affects all versions of the Windows Operating System.
Although this isn't one of those times for me, I wanted to share this “failure” (non-discovery) with you anyways and with any luck you may find something I missed during my own research. I use the term failure here very loosely because in reality, there is no failure when knowledge is gained. While I did not accomplish what I set out to do, I uncovered a wealth of new knowledge that may help you or I in future projects.
This is the beauty of security research. Knowledge is the ultimate victory.
Discovery
During some loosely related research I came across an API that I had never seen or used before: NtMapUserPhysicalPages. It sounded like an interesting name for an API. My first assumption was that this API allowed a user mode program to manipulate physical memory. After some MSDN-fu that's kind of what it was. This API was part of a technology Microsoft called Address Windowing Extensions (AWE).
From MSDN:
Address Windowing Extensions (AWE) is a set of extensions that allows an application to quickly manipulate physical memory greater than 4GB.
AWE solves this problem by allowing applications to directly address huge amounts of memory while continuing to use 32-bit pointers.
These extensions were created to address memory constraints with the 32-bit memory model. However, this isn't particularly what interested me. The documentation goes on to explain some of the restrictions placed when using this extension. These restrictions are what I was particularly interested in ‘testing’:
Virtual address ranges allocated for the AWE are not sharable with other processes (and therefore not inheritable). In fact, two different AWE virtual addresses within the same process are not allowed to map the same physical page. These restrictions provide fast remapping and cleanup when memory is freed.
At a high level, what this extension allows us to do is reserve physical pages of memory that are non-pageable in order to map them into our user-mode virtual address space. This reservation of non-paged memory allows fast memory access and fast memory remapping among the other stated advantages.
So what API’s are needed to utilize these Extensions?
MSDN lists them as:
- VirtualAlloc/Ex
- AllocateUserPhysicalPages
- MapUserPhysicalPages
- MapUserPhysicalPagesScatter
- FreeUserPhysicalPages
Oftentimes the best ideas come from challenging documentation. Documentation of an API or set of functions may declare one thing but the code may contain some flawed implementation of its intent. It’s our duty to challenge these intentions.
In order to actually use this extension, the host Operating System (OS) must have a specific policy enabled for the user (Lock Pages in Memory Policy). This policy is disabled by default for all users in a standard Windows installation; however, some machines running a variant of Windows Server with SQL Server have it enabled.
The Goal
After reading the documentation for AWE I decided to think about some ways we could (ab)use it. Can we somehow allow Process B to remap physical pages allocated by Process A utilizing the fast remapping capabilities of AWE?
It all starts with one question: let’s explore.
Throwing the First Punch (Round One)
We’ve got a basic idea of what we need to work with AWE, so let’s use the extension the way it was intended. MSDN tells us what API’s were needed so a simple usage looks like the code below: