2010-09-09 55 views
1

我寫了一些示例代碼,當我從正常用戶帳戶的上下文中的Windows命令提示符調用時,使用CredEnumerate()轉儲所有用戶保存的憑證。但是,我真的希望能夠從SYSTEM用戶上下文中完成此操作,因此我已經從SYSTEM cmd提示符測試了我的程序。爲什麼Win32 API函數CredEnumerate()返回ERROR_NOT_FOUND如果我模擬?

當我跑我的程序作爲SYSTEM,我跑的LogonUser像這樣:

bLoggedOn = LogonUser(userName.c_str(), domain.c_str(), password.c_str(), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &userToken_); 

然後我在令牌運行ImpersonateLoggedOnUser()給我的本地用戶的安全上下文。在此之後我做的:

bOk = CredEnumerate(NULL, 0, &count, &pCredentials); 

而且我預計這以同樣的方式返回憑據,如果我不從系統中消失了,人格化。任何人都可以發現我錯過的任何東西,真正把自己置於用戶的環境中嗎?

+1

這些憑據是否存儲在註冊表中?也許你需要在調用CredEnumerate之前加載用戶的註冊表配置單元。您可以使用Process Monitor來查看是否發生了這種情況。 – Luke 2010-09-09 21:24:29

+0

嗯,這是一個很好的想法,我沒有考慮過它。但是我實際上也遇到了同樣的問題,即使我正在模擬的用戶實際登錄時,我使用psexec踢了一個系統propt。據推測,在這種情況下,用戶的註冊表配置單元將被加載。 – Benj 2010-09-10 09:06:48

+1

憑證管理API的文檔似乎表明這些憑證與登錄會話相關聯。也許LogonUser導致一個新的登錄會話,所以憑證不存在那裏。您可以通過使用現有令牌調用ImpersonateLoggedOnUser()來測試此功能,而不是通過LogonUser()獲取一個令牌。 – Luke 2010-09-10 11:37:40

回答

2

我想我自己可以自己回答這個問題,因爲我已經花了很多年的時間研究如何做到這一點,我不確定它是否廣爲人知。 CredEnumerate/CredRead永遠不會爲域密碼提供密碼信息,無論您使用什麼流程上下文或您擁有什麼令牌,儘管它似乎在MSDN上提示。獲取訪問保存的憑證信息的唯一方法是使用lsasrv.dll中的未記錄函數LSAICryptUnprotectData()。這可以解密您在%APPDATA%\ Microsoft \ Credentials中找到的文件,並且可以爲CredEnumerate提供一個相同的數據結構,除了填入密碼。唯一的問題是必須在lsass.exe的進程上下文中完成Windows安全子系統),沒有特權等設置足以讓一個正常的進程有權這樣做。如果您是黑客,您可以通過執行CreateRemoteThread()將線程注入到lsass.exe中,或者如果您嘗試以合法的方式執行此操作,即以某種方式擴展Windows操作系統對於像我一樣的第三方應用程序,您可以通過創建一個lsass將加載的Windows身份驗證軟件包來實現此目的。然後,此AP可以使用命名管道或某種此類方法來允許與其他代碼進行交互。

+0

看看這個:http://securityxploded.com/networkpasswordsecrets.php – 2013-06-12 17:26:22