Windows 2000/XP 預設允許 Null Session(空會話) 連接 IPC$ 共享,匿名用戶可枚舉大量 NetBIOS 資訊。本文詳述可獲取資訊類別、核心 API 呼叫序列、資料結構與防禦對策。僅供防禦研究與授權滲透測試使用。
| 類別 | 關鍵 API | 主要資料結構 | 說明 |
|---|---|---|---|
| 主機時間 | NetRemoteTOD | TIME_OF_DAY_INFO | GMT 時間,可推算時區 |
| OS 指紋 | NetServerGetInfo (Level 101) | SERVER_INFO_101 | 平台 ID、版本 (5.0=2K, 5.1=XP, 6.0=Longhorn)、伺服器類型位元遮罩 |
| 共享列表 | NetShareEnum (Level 1) | SHARE_INFO_1 | 含隱藏共享 (ADMIN$, IPC$),類型:磁碟/列印/IPC/特殊 |
| 用戶列表 | NetQueryDisplayInformation (Level 1) | NET_DISPLAY_USER | 帳號、全名、UID、旗標 (停用/鎖定/智慧卡/委派等) |
| 本地群組 | NetLocalGroupEnum (Level 1) | LOCALGROUP_INFO_1 | 群組名稱與備註 |
| 全域群組 | NetQueryDisplayInformation (Level 3) | NET_DISPLAY_GROUP | 含 GID、屬性,可再呼叫 NetGroupGetUsers 列舉成員 |
| 傳輸協定 | NetServerTransportEnum (Level 0) | SERVER_TRANSPORT_INFO_0 | 協定名稱、網路位址、作用中連線數 |
| 作用中會話 | NetSessionEnum (Level 10) | SESSION_INFO_10 | 客戶端名稱、用戶名、活動/閒置時間 |
NETRESOURCE nr = {0};
nr.dwType = RESOURCETYPE_ANY;
nr.lpRemoteName = _T("\\\\TargetIP\\ipc$");
TCHAR username[100] = _T(""), password[100] = _T("");
// 連接
DWORD ret = WNetAddConnection2(&nr, username, password, 0);
if (ret != ERROR_SUCCESS) return -1;
// ... 枚舉操作 ...
// 斷開
TCHAR ipc[100];
wsprintf(ipc, _T("\\\\%s\\ipc$"), szTarget);
WNetCancelConnection2(ipc, 0, TRUE);
// 共享列表示例
DWORD er=0, tr=0, resume=0;
PSHARE_INFO_1 pBuf = NULL;
do {
NET_API_STATUS ns = NetShareEnum(server, 1, (PBYTE*)&pBuf,
MAX_PREFERRED_LENGTH, &er, &tr, &resume);
if (ns == NERR_Success || ns == ERROR_MORE_DATA) {
for (DWORD i=0; i
所有 NetApiBufferFree(pBuf) 必須配對呼叫,避免洩漏。
HKLM\SYSTEM\CurrentControlSet\Control\Lsa\RestrictAnonymous = 1 (限制匿名存取)單一 wmain 入口,依序呼叫 datetime、fingerprint、netbios、users、localgroup、globalgroup、transport、session。支援 Unicode,含錯誤碼處理與進度輸出。
完整命令列掃描工具原始碼 (T-SMB Scan),含詳細註解與編譯說明。