=======================
Attacking the Windows 7/8 Address Space Randomization
Copyright (C) 2013 Kingcope
"Was nicht passt wird passend gemacht"
(English: "If it don't fit, use a bigger hammer.")
German phrase
=======================
Synopsis - What this text is all about
=======================
The following text is what looks like an attempt to circumvent windows 7 and
windows 8 memory protections in order to execute arbritrary assembly code.
The presented methods are in particular useful for client-side attacks as used
for example in browser exploits.
The topic that is discussed is a very complex one. At the time I started the
research I thought the idea behind the attack will be applied to real-world
scenarios quick and easy. I had to be convinced by the opposite.
The research was done without knowing much about the real internals of the
windows memory space protection but rather using brute force, trial & failure
in order to achieve what will be presented in the upcoming text. Be warned -
the methods to attack the protection mechanisms hereby presented are not
failsafe and can be improved. Tough in many cases it is possible to
completely bypass Windows 7 and especially Windows 8 ASLR by using the
techniques.
Target Software
=======================
The used operating systems are Windows 7 and Windows 8, the included PoC code
runs on 32 Bits platforms and exploits Internet Explorer 8. All can be applied
to Internet Explorer 9 with modifications to the PoC code.
For Internet Explorer 10 the memory protection bypass is included and
demonstrated in the PoC. Executing code through return oriented programming
is left as an excercise to the reader.
The PoC makes use of the following vulnerability and therefore for testing the
PoC the patch must not be installed.
MS12-063 Microsoft Internet Explorer execCommand Use-After-Free Vulnerability
This vulnerability is identified as CVE-2012-4969.
It might be possible to use the very same method to exploit other browsers
as other browsers give similar opportunities to the exploit writer. I don't want
to sound crazy but even other Operating Systems might be affected by this, yet
unconfirmed.
Current ways to exploit browsers
=======================
Today alot of attention is brought to client side exploits especially inside
web browsers. Normally the exploitation is done through the old known method
of spraying the heap. This is done by populating the heap with nopsleds and
actual shellcode. By filling the heap in this way a heap overrun can be used
to rewrite the instruction pointer of the processor to a known heap address
where the shellcode resides quite deterministic.
In order to bypass protections like Data Execution Prevention a ROP chain is
built. There are exploits that install a stack pivot in the first place in
order to exploit a heap overrun as it would be a stack based buffer overrun
using a "return into code" technique. The mentioned modern ways to exploit
heap corruptions are documented very well.
When it comes to Windows 7 and Windows 8 exploitation the exploit writer
will face the obstacle of randomized memory space. There remains the simple
question where do I jump to when having control over the instruction pointer?
It might by possible to leak memory directly from the web browser and use this
information to gain information about the correct offsets and executable code
sections. This requires knowledge about a memory leak bug tough and therefore
is not used alot. Another option is to use old DLLs that do not have their
image bases randomized, for example older Java versions are known to have un-
randomized image bases. This option requires the use of third-party software
that has to be installed.
This text will present a new way to deal with the 'where do i jump when
I have code execution' problem.
Introduction to Windows memory randomization
=======================
Windows 7 and Windows 8 have a special security relevant protection programmed
in. The so called A.S.L.R or '[A]ddress [S]pace [L]ayout [R]andomization' that
does nothing more than randomize every piece of memory, say its offsets.
For example the program image is randomized, the DLLs the program uses are
randomized too. There is not a single piece of memory from what one could say
after a reboot the data in the memory space will be at the same place as before
the reboot. The addresses even change when a program is restarted.
ActiveX and other useful features
=======================
Web browser exploits have many advantages to other kinds of exploits.
For example JavaScript code can be executed inside the webbrowser. This is also
the tool that heap spraying makes use of.
Let us have a look at what happens if we load an ActiveX object dynamically
when a web page loads. The ActiveX object we will load is the Windows Media
Player control. This can either be done using JavaScript or plain HTML code.
At the point the ActiveX object is loaded Windows will internally load the
DLLs into memory space if they previously where not inside the programs
memory space. The offset of loading the DLLs in memory space is completely
random. At least it should be. Let us now see how we can manage to put a DLL
into memory space at a fixed address by loading an ActiveX object at runtime.
Exhausting memory space and squeezing DLLs into memory
=======================
The nuts and bolts of what is presented here is the idea that DLLs are loaded
into memory space if there is memory available, and if there is no memory or
only small amounts of memory available then the DLL will be put into the
remaining memory hole. This sounds simple. And it works, we can load a DLL
into a remaining memory hole. First of all the exploit writer has to code
a javascript routine that does fill memory until the memory boundary is hit
and a javascript exception is raised. When the memory is filled up the installed
javascript exception handler will execute javascript code that frees small
chunks of memory in several steps, each step the javascript code will try to
load an ActiveX object. The result is that the DLL (sometimes there are several
DLLs loaded for an ActiveX object) will be loaded at a predictable address.
This means that now the exploit writer has a predictable address to jump to and
the 'where do i jump when I have code execution' problem is solved.
One problem the method has is that Windows will become unresponsive at the time
memory is exhausted but will resume normal operation after the DLL is loaded
at a fixed address and the memory is freed using the javascript code.
Summary of exploitation stages:
* Fill the heap with random bytes until all memory is used up.
During the heap filling stage Windows might become unresponsive and will relax
soon afterwards
·* Free small heap blocks one by one and try adding a DLL
(for example by using a new ActiveX Object that is loadable without a warning
by Internet Explorer) This DLL (and the DLLs that are loaded from it) will
be squeezed into the remaining memory region (the space that was freed by us
through JavaScript). This address is fixed and predictable for us to jump to
* Free the remaining memory blocks which were allocated before
* Spray the heap using the well known method
* Finally trigger the heap corruption and jump to this fixed DLL base to
execute our code in a ROP manner.
To say it abstract the exploit writer has to be especially careful about the
timing in the JavaScript code and about the memory the exploit routines
themselves take up.
ROP chain and the LoadLibrary API
=======================
At the time we have loaded the DLL at a predictable address it is possible to
use a ROP chain in order to execute shellcode. The PoC code goes a much simpler
path. It will use a short ROP chain and call the LoadLibrary API that is
contained in the Windows Media Player DLLs. This way another DLL can be fetched
from a WebDAV share and loaded into the Internet Explorer memory space in order
to fully execute arbritrary code.
Windows 8 singularity
=======================
Testcases have shown that Windows 8 behaves more vulnerable to the method than
Windows 7. In Windows 8 the DLL will be loaded at the very low address 0x10000
and more reliable than in Windows 7. Windows 7 is much more persistant in
loading the DLL at a fixed memory address. The testcases for Windows 7 have
shown that the DLL will be loaded at the predictable address at least 7 out of
10 times of loading the exploit.
The PoC codes
=======================
There are two different PoCs, one for Windows 7 and one for Windows 8.
The Windows 8 code is a slightly modified version of the Windows 7 code.
Please note that Windows Defender detects the Win8 PoC as being an exploit and
blocks execution. The parts which are detectable by windows defender are
not needed for the A.S.L.R. attack to work. Please disable Windows Defender
if you test the Windows 8 PoC for now.
The Windows 7 PoC is successful if it loads gdiplus.dll at the predictable
fixed offset 0x7F7F0000. If you are lucky and have set up the exploit
appropriately the payload will be executed, which is currently a MessageBox that
pops up.
The Windows 8 PoC is successful if it loads gdiplus.dll at the predictable
fixed offset 0x10000.
Please note that wmp.dll (Windows Media Player DLL) and gdiplus.dll should not
be in the Internet Explorer address space prior to executing the PoC for it
to succeed.
As a final note, the PoC does not depend on the ActiveX control that is added it
can be changed with some effort to load a different DLL.
Here are the mappings I tested when the PoC succeeds:
Windows 7 32-Bit Service Pack 0 & Service Pack 1 across reboots:
Address Size Owner Section Contains Type Access
7F7F0000 00001000 gdiplus PE header Imag R RWE
7F7F1000 0016B000 gdiplus .text code,imports Imag R RWE
7F95C000 00008000 gdiplus .data data Imag R RWE
7F964000 00001000 gdiplus Shared Imag R RWE
7F965000 00012000 gdiplus .rsrc resources Imag R RWE
7F977000 00009000 gdiplus .reloc relocations Imag R RWE
Windows 8 32-Bit across reboots:
Address Size Owner Section Contains Type Access
00010000 00001000 gdiplus PE header Imag R RWE
00011000 00142000 gdiplus .text code,exports Imag R RWE
00153000 00002000 gdiplus .data Imag R RWE
00155000 00003000 gdiplus .idata imports Imag R RWE
00158000 00012000 gdiplus .rsrc resources Imag R RWE
0016A000 00009000 gdiplus .reloc relocations Imag R RWE
The archive containing the PoCs is found here: http://www.farlight.org/rlsa.zip
Enjoy!