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

Windows NT 特定使用者身分執行程式:服務模擬與 LogonUser 實作

     編輯:關於VC++

在 Windows NT/2000/XP 環境下,以特定使用者身分啟動程序是系統管理與自動化部署的常見需求。然而 LogonUser() API 要求呼叫者擁有「Act as part of the operating system」特權,一般管理員帳戶不具備。本文介紹一種巧妙的解決方案:將工具程式暫時安裝為系統服務,在 LocalSystem 權限下執行 LogonUser() 與 CreateProcessAsUser(),完成後自動卸載服務。

核心架構流程

  1. 主控台程式檢查當前權限,若缺乏 SE_TCB_PRIVILEGE 則啟動服務安裝流程
  2. 以 CreateService() 安裝自身為服務,設定為 SERVICE_AUTO_START 或需求啟動
  3. 透過共享記憶體(Memory-Mapped File)傳遞參數:目標使用者名稱、密碼、命令列、工作目錄
  4. 服務在 ServiceMain() 中呼叫 LogonUser() 取得存取權杖
  5. 以 CreateProcessAsUser() 啟動目標程序
  6. 將執行結果(成功/錯誤碼)寫回共享記憶體
  7. 主程式讀取結果、顯示、停止並刪除服務

關鍵技術點

1. 安全性 API 應用

  • SID、ACE、ACL、安全描述符、特權、存取權杖操作
  • 輕量級模板類別封裝 Windows 安全 API,簡化程式碼

2. 服務控制管理器 (SCM) 程式設計

  • OpenSCManager()、CreateService()、StartService()、ControlService()、DeleteService()
  • 服務模板類別:僅 20 行代碼即可實作基本服務框架

3. 共享記憶體通訊

  • 使用 CreateFileMapping() + MapViewOfFile() 實現進程間資料交換
  • 模板類別自動管理核心物件生命週期(RAII 模式)

程式碼結構概覽


// 主程式進入點
int main(int argc, char* argv[])
{
    if (!HasRequiredPrivilege()) {
        InstallAndRunAsService(argc, argv);  // 安裝服務、啟動、等待結果、清理
        return 0;
    }
    // 已具備特權,直接執行
    return RunAsUser(...);
}

// 服務主函數
void WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
{
    // 從共享記憶體讀取參數
    // LogonUser() -> CreateProcessAsUser()
    // 結果寫回共享記憶體
}

使用方式

命令列直接執行程式名稱(無參數)即可顯示使用說明:

RunAsUser.exe
用法: RunAsUser.exe /user:Domain\User /password:Pwd /cmd:"Program.exe [args]"

適用場景

  • 自動化部署腳本以特定服務帳戶安裝軟體
  • 系統管理工具以不同身分執行診斷程式
  • 建置系統在受限帳戶下編譯/測試
  • 滲透測試與權限提升研究(合法授權範圍內)

注意事項

  • 需要本地管理員權限安裝服務(Administrators 群組預設具備)
  • 目標使用者需具備「Log on as a batch job」或「Log on as a service」權限
  • 密碼在共享記憶體中以明文傳遞,生產環境建議加密或使用更安全的 IPC 機制
  • Windows Vista+ 引入 UAC 與 Session 0 Isolation,此法可能需調整

原始碼亮點

隨附原始碼包含完整的:

  • 安全性模板類別庫(SID、ACL、Token 封裝)
  • 服務安裝/啟動/停止/移除封裝類
  • 共享記憶體自動管理類別
  • 錯誤處理與診斷追蹤機制

這些組件可獨立重用於其他需要系統級權限操作的專案中。

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