首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

Windows NT/2000 當前登入使用者密碼提取技術深度解析與安全性警示

     編輯:VC 教學

⚠️ 重要安全性聲明

本文僅供安全研究、系統管理、滲透測試授權範圍內的技術分析。
提取記憶體中明文/可逆加密密碼屬於高風險敏感操作,可能違反:
  • 《計算機信息網絡國際聯網安全保護管理辦法》
  • 《網絡安全法》第 27 條 (非法獲取數據罪)
  • 企業資安政策、滲透測試授權書範圍
嚴禁用於未授權系統、惡意竊取憑證、橫向移動等攻擊行為。
防禦方應部署 Credential Guard、LSA Protection、限制 SeDebugPrivilege、監控異常 OpenProcess/ReadProcessMemory 行為。

技術原理概述

Windows NT 內核將互動式登入使用者的憑證 (明文或可逆加密) 暫存於 Winlogon.exe 進程記憶體空間 中,供後續單一登入 (SSO)、網路驗證、解鎖畫面等功能使用。本技術透過以下步驟定位並解密:

  1. 提升權限:SeDebugPrivilege (需管理員/系統權限)
  2. 定位 Winlogon PID:遍歷系統進程,識別 winlogon.exe 且載入 msgina.dll (非 nwgina.dll)
  3. 掃描 Winlogon 虛擬記憶體:尋找使用者名/網域字串作為錨點
  4. 定位相對偏移的密碼結構:ENCODED_PASSWORD_INFO (含長度、雜湊位元組、加密密碼 Unicode 字串)
  5. 呼叫非文檔化 RtlRunDecodeUnicodeString 解密 (單位元組 XOR 滾動金鑰演算法)

核心差異:Windows NT 4.0 vs Windows 2000

特性Windows NT 4.0Windows 2000 (5.0)
使用者名/網域偏移固定結構偏移動態記憶體掃描 (VirtualQueryEx)
密碼結構偏移相對使用者名固定 0x400相對使用者名固定 0x800
雜湊位元組儲存編碼字串 Length 高位元組不儲存,需暴力嘗試 0x00-0xFF
解密呼叫次數1 次最多 256 次 (暴力破解雜湊位元組)

關鍵非文檔化 API (ntdll.dll)

代碼架構解析 (原文重點函數)

1. 權限提升 AddDebugPrivilege


BOOL AddDebugPrivilege() {
    HANDLE hToken; TOKEN_PRIVILEGES tp;
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
    tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    return AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL);
}

2. 定位 Winlogon PID FindWinLogon

  • 呼叫 NtQuerySystemInformation(0x10, ...) 獲取所有控制代碼表
  • 篩選 HandleType == 5 (Process 物件)
  • 對每進程建立除錯緩衝區,查詢模組清單
  • 尋找模組名含 "WINLOGON" 且載入 "MSGINA" (非 "NWGINA") 的進程

3. 記憶體掃描定位憑證

NT 4.0:讀取 PEB (0x7FFDF000) → 進程堆 → 掃描堆區域尋找使用者名/網域

Win2K:VirtualQueryEx 遍歷整個用戶模式位址空間 (0x00010000 ~ 0x7FFEFFFF),檢查 MEM_COMMIT 且非 PAGE_GUARD 的區域,ReadProcessMemory 讀取比對使用者名/網域

4. 解密演算法 RtlRunDecodeUnicodeString


// 簡化邏輯:單位元組 XOR 滾動金鑰
void RtlRunDecodeUnicodeString(BYTE bHash, PUNICODE_STRING pStr) {
    WCHAR* pw = pStr->Buffer;
    for (ULONG i = 0; i < pStr->Length / sizeof(WCHAR); i++) {
        pw[i] ^= bHash;
        bHash = (BYTE)(bHash + pw[i]); // 滾動金鑰
    }
}

Win2K 因不儲存雜湊位元組,需暴力嘗試 0x00-0xFF,驗證解碼結果是否為可列印 ASCII (0x20-0x7E)。

現代 Windows (Vista/7/8/10/11) 防禦機制

函數用途
NtQuerySystemInformation查詢系統進程/控制代碼資訊 (SystemInformationClass=0x10 控制代碼表)
RtlCreateQueryDebugBuffer建立進程除錯緩衝區
RtlQueryProcessDebugInformation查詢進程模組載入資訊 (識別 msgina.dll)
RtlRunDecodeUnicodeString解碼 Unicode 字串 (單位元組 XOR 滾動金鑰)
RtlDestroyQueryDebugBuffer釋放除錯緩衝區
機制版本原理對本技術影響
LSA Protection (RunAsPPL)8.1+LSASS 以 Protected Process Light 執行,拒絕非簽名除錯器附加完全阻擋 OpenProcess(PROCESS_VM_READ) 於 LSASS,但 Winlogon 非 PPL 仍理論可讀
Credential Guard (VBS)10 Enterprise+虛擬化隔離 LSASS,憑證存於 VTL 1,Host (VTL 0) 無法讀取徹底杜絕記憶體提取,Winlogon 亦不再持有明文密碼
Restricted Admin Mode8.1+RDP 限制管理模式,不將明文密碼傳送至目標減少記憶體中明文密碼殘留
SeDebugPrivilege 移除預設策略管理員不再預擁有 SeDebugPrivilege,需透過 GPO 明確授予提高攻擊門檻,需本地提權

防禦與偵測建議

  1. 啟用 Credential Guard (需 TPM 2.0、UEFI、Hyper-V、Enterprise 版)
  2. 設定 LSA Protection:HKLM\SYSTEM\CurrentControlSet\Control\Lsa\RunAsPPL = 1
  3. 限制 SeDebugPrivilege:GPO Computer Configuration → Windows Settings → Security Settings → Local Policies → User Rights Assignment → Debug programs 僅保留必要服務帳號
  4. 部署 EDR/AV 記憶體掃描:偵測 OpenProcess(PROCESS_VM_READ) → ReadProcessMemory 針對 winlogon.exe/lsass.exe 的異常序列
  5. 啟用 Windows Defender Credential Guard 事件日誌:Event ID 4673 (Sensitive Privilege Use)、4688 (Process Creation with SeDebugPrivilege)
  6. 定期輪換密碼、推行 MFA、使用 Windows Hello for Business / FIDO2 金鑰 取代密碼認證

合法替代方案 (系統管理/開發)

  • Windows Hello / FIDO2 / 憑證認證:無密碼認證,根除密碼竊取風險
  • 群組受控服務帳號 (gMSA):服務間認證自動輪換密碼
  • Remote Credential Guard:RDP 將認證導向本地裝置,遠端不留存
  • Just-In-Time (JIT) 提權:Azure AD PIM、CyberArk、BeyondTrust 等 PAM 方案
  • DPAPI / Credential Manager API:應用程式安全儲存秘密,而非記憶體明文

結語

本技術展示了 Windows 早期架構為了 SSO 便利性而在記憶體保留可逆加密密碼的設計權衡。現代 Windows 透過虛擬化隔離 (VBS)、保護進程 (PPL)、預設最小權限等纵深防禦,已大幅提高憑證竊取難度。安全從業者應專注於防禦部署、偵測規則、無密碼架構遷移,而非攻擊技術本身。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved