Dailydave mailing list archives

(windows is vulnerable too) & final comments on naming


From: spender () grsecurity net (Brad Spengler)
Date: Wed, 7 Mar 2007 10:19:46 -0500

  So why doesn't linux do like 'doze does, and permanently map a guard 
page at
0x0 in all user-spaces?

What version of Windows are you using?  Maybe you're getting confused
with the behavior that giving a NULL address as a hint to any
allocation/mapping function is a special case within the OS to select
its own address.  Luckily though, the address passed in is rounded down
internally, so giving an address of 1 will let you allocate at the 0
address.

Here's some code to execute as an unprivileged user:
#include "windows.h"

typedef unsigned int (*_NtAllocateVirtualMemory)(IN HANDLE
ProcessHandle, IN OUT PVOID *BaseAddress, IN ULONG ZeroBits, IN OUT
PULONG RegionSize, IN ULONG AllocationType, IN ULONG Protect );

int _tmain(int argc, _TCHAR* argv[])
{
    HMODULE ntdll;
    MEMORY_BASIC_INFORMATION buff;
    unsigned int status;
    PCHAR buf = NULL;
    ULONG size = 0xffff;
    PCHAR buf2 = (PCHAR)1;
    _NtAllocateVirtualMemory fptr;
    ntdll = GetModuleHandle("NTDLL.DLL");
    fptr = (_NtAllocateVirtualMemory)GetProcAddress(ntdll,
"NtAllocateVirtualMemory");
    status = fptr((HANDLE)0xffffffff,(PVOID *) &buf2, 0, &size,
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    printf("status = %08lx buf = %08lx\n", status, buf);
    VirtualQuery(NULL, &buff, sizeof(buff));
    printf("prot: %08lx\n", buff.Protect);
    buf2[0] = 0x10;
    printf("no crash %08lx, %02x\n", &buf2[0], buf2[0]);
    return 0;
}

it'll verify a RWX allocation (0x40) and that the byte at 0x00000000
contains 0x10.  If there were a permanently mapped guard page (and I
don't think a real PAGE_GUARD page is what you really want) at 0,
stuff like ntvdm wouldn't work.  These bugs are exploitable in Windows.

A final comment on the naming of the bug:
I think it's a mistake to lump in null ptr + controlled offset with
the null ptr + small fixed offset.  The former case would likely be some
overflow, integer or otherwise, in the same category as <any ptr> + 
controlled offset.  Calling it a "null ptr deref bug" is also somewhat 
out of consistency, since if you've seen an OOPS where the faulting 
address is within the first page of virtual memory, it's called the same.
From the bugreport for the vulnerability:
Jul  7 13:04:52 doriath kernel: [  105.041722] BUG: unable to handle
kernel NULL pointer dereference at virtual address 00000018

Anyways, as I mentioned before, this is all really under the larger 
class of invalid userland pointer dereferences, which just mapping (or 
preventing a mapping) at 0 will not protect against.

-Brad

Attachment: signature.asc
Description: Digital signature

_______________________________________________
Dailydave mailing list
Dailydave () lists immunitysec com
http://lists.immunitysec.com/mailman/listinfo/dailydave

Current thread: