为什么Win32 API函数CredEnumerate()的返回ERROR_NOT_FOUND如果我模拟? [英] Why does Win32 API function CredEnumerate() return ERROR_NOT_FOUND if I'm impersonated?

查看:1008
本文介绍了为什么Win32 API函数CredEnumerate()的返回ERROR_NOT_FOUND如果我模拟?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经写了一些样品code,当我从Windows命令提示符下,转储的所有用户保存的凭据使用CredEnumerate()调用普通用户帐户的上下文中。但是,我真的希望能够从SYSTEM用户上下文中这样做,所以我从一个系统的测试我的程序的命令提示符。

I've written some sample code which when I call from the windows command prompt under the context of a normal user account, dump's all the user's saved credentials using CredEnumerate(). However, I really want to be able to do this from SYSTEM user context so I've tested my program from a SYSTEM cmd prompt.

当我运行我的程序作为SYSTEM,我跑的LogonUser像这样:

When I running my program as SYSTEM, I run LogonUser like so:

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

然后我在令牌运行ImpersonateLoggedOnUser()给我本地用户的安全上下文。在此之后我做的:

Then I run ImpersonateLoggedOnUser() on the token to give me the security context of the local user. After this I do:

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

和我预计这以同样的方式返回凭据,如果我不是从系统中消失了,模拟。任何人都可以点任何东西,我已经错过了真正把自己摆在用户的上下文?

And I'd expect this to return the credentials in the same way as if I'd not gone in from system and impersonated. Can anyone spot anything that I've missed to truly put myself in the user's context?

推荐答案

我想我奥特来回答这个问题我自己,因为我现在已经花了年龄工作如何做到这一点,我不知道它是广为人知。 CredEnumerate / CredRead永远不会不管你现在的进程上下文或者你有什么记号提供域密码的密码信息,尽管它似乎在MSDN上的暗示。以访问保存的凭证信息的唯一途径就是这样做的使用无证功能LSAICryptUnprotectData()这是在LSASRV.DLL。这可以解密您在%APPDATA%\\微软\\凭据找到文件,并可以提供相同的数据结构CredEnumerate除非填写密码。唯一的缺点是,这必须LSASS.EXE的进程上下文中完成(该窗安全子系统),无privilledges等的设置是足以给一个正常的处理的权利要做到这一点。如果你是一个黑客,你可以通过执行CreateRemoteThread的()注入一个线程进入LSASS.EXE或者,如果你想这样做的合法的方式做到这一点,即你正在扩展Windows操作系统以某种方式对于第三方应用程序,就像我是,你可以通过创建一个Windows身份验证软件包,LSASS将加载做到这一点。然后,该AP可以使用命名管道或某些这样的方法,让你的code其余互动。

I guess I aught to answer this question myself since I've now spent ages working out how to do this and I'm not sure it's widely known. CredEnumerate/CredRead will never provide password information for domain passwords no matter what process context you're in or what token you have despite what it seems to hint at on MSDN. The only way to get access to the saved credential information is to do so using the undocumented function LSAICryptUnprotectData() which is in lsasrv.dll. This can decrypt the files you find in %APPDATA%\Microsoft\Credentials and can provide an identical data structure to CredEnumerate except with the password filled in. The only catch is that this must be done in the process context of lsass.exe (The windows security subsystem), no setting of privilledges etc is enough to give a normal process the rights to do this. If you're a hacker you can do this by performing a CreateRemoteThread() to inject a thread into lsass.exe or if you're trying to do this in a legitimate way, i.e you're extending the Windows operating system in some way for a third party application, like I was, you can do this by creating a Windows authentication package which lsass will load. This AP can then use a named pipe or some such method to allow interaction with the rest of your code.

这篇关于为什么Win32 API函数CredEnumerate()的返回ERROR_NOT_FOUND如果我模拟?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆