Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 解密Windows凭据文件_C#_C++_Delphi_Winapi - Fatal编程技术网

C# 解密Windows凭据文件

C# 解密Windows凭据文件,c#,c++,delphi,winapi,C#,C++,Delphi,Winapi,我进入了一个需要管理(写/读)缓存凭据的项目。在我的例子中,特别是(TERMSRV)或流行的远程桌面 在我的Windows 7上,我已经发现文件存储在“AppData\Local\Microsoft\Credentials”中。当我打开mstsc(远程桌面客户端)并保存凭证时,将在此目录上创建一个新文件(神秘且受系统保护)。我试着在记事本上打开文件,它是加密数据。据我所见,Windows似乎使用数据保护API(DPAPI),特别是/functions来保存/检索缓存的凭据 我的第一次尝试是在函数

我进入了一个需要管理(写/读)缓存凭据的项目。在我的例子中,特别是(TERMSRV)或流行的远程桌面

在我的Windows 7上,我已经发现文件存储在“AppData\Local\Microsoft\Credentials”中。当我打开mstsc(远程桌面客户端)并保存凭证时,将在此目录上创建一个新文件(神秘且受系统保护)。我试着在记事本上打开文件,它是加密数据。据我所见,Windows似乎使用数据保护API(DPAPI),特别是/functions来保存/检索缓存的凭据

我的第一次尝试是在函数上,但我发现域密码(正是终端服务的类型)只能由身份验证包读取。在这个发现之后,我开始搜索一些工具,我发现一些人正在向LSASS进程中注入一个DLL来完成这项工作。但我看到它成功地解密了我保存的密码,并且通过Process Explorer,我没有看到在LSASS上注入任何新的DLL。看起来他使用CryptUnprotectData直接处理凭证文件

问题是:是否有任何方法可以从这个文件中检索缓存的密码,而无需插入dll并执行此类操作?如果是,方法将是加密未保护的数据?最后,如果是,函数接收的数据是什么?文件的内容是什么?我只是不明白如何使用这个函数,从哪里开始

编辑::

我只在Windows/WinAPI标签上发布了这个问题,但几乎没有视图,也没有答案。我相信主要的问题是语言无关的,但我在Delphi中做这个项目,所以这里是CredRead的Delphi代码,它只获取用户名,但不能列出密码,因为帐户是域类型(CRED_type_domain_password)


这与C++/C#有什么关系?在WinAPI上没有人知道答案。这个问题与语言无关,是一个关于windows功能的问题,你可以在这里回答并粘贴你的C++/C#代码(如果你有),如果这个问题解决了,我会接受答案。Delphi中的代码只是人们对我尝试的内容有一个想法的一个片段。您的最终目标是什么,使用缓存凭据登录到终端服务,还是模仿Netpass中的功能?PS:您的代码泄漏内存,您需要通过
CredFree
释放CreadReadW返回的缓冲区。我的第一个目标是模拟功能,以便能够读取/写入已创建的凭据,包括现有凭据。是的,CredFree是必要的,我只是没有这样做,因为我看到代码不起作用,所以我不知道我是应该继续这样做(crederead)还是尝试其他方法…你必须同时做这两件事(CredEnumerate/CreadRead)并解密文件以恢复密码…这与C++/C#有什么关系?在WinAPI上没有人知道答案。这个问题与语言无关,是一个关于windows功能的问题,你可以在这里回答并粘贴你的C++/C#代码(如果你有),如果这个问题解决了,我会接受答案。Delphi中的代码只是人们对我尝试的内容有一个想法的一个片段。您的最终目标是什么,使用缓存凭据登录到终端服务,还是模仿Netpass中的功能?PS:您的代码泄漏内存,您需要通过
CredFree
释放CreadReadW返回的缓冲区。我的第一个目标是模拟功能,以便能够读取/写入已创建的凭据,包括现有凭据。是的,CredFree是必要的,我只是没有这样做,因为我看到代码不起作用,所以我不知道我是应该继续这样做(crederead)还是尝试其他方法…你必须同时做(CredEnumerate/CreadRead)和解密文件来恢复密码。。。
type
 PCREDENTIAL_ATTRIBUTEW = ^_CREDENTIAL_ATTRIBUTEW;
  _CREDENTIAL_ATTRIBUTEW = record
    Keyword: LPWSTR;
    Flags: DWORD;
    ValueSize: DWORD;
    Value: LPBYTE;
  end;


  PCREDENTIALW = ^_CREDENTIALW;
  _CREDENTIALW = record
    Flags: DWORD;
    Type_: DWORD;
    TargetName: LPWSTR;
    Comment: LPWSTR;
    LastWritten: FILETIME;
    CredentialBlobSize: DWORD;
    CredentialBlob: LPBYTE;
    Persist: DWORD;
    AttributeCount: DWORD;
    Attributes: PCREDENTIAL_ATTRIBUTEW;
    TargetAlias: LPWSTR;
    UserName: LPWSTR;
  end;

PCredentialArray = array of PCREDENTIALW;

const
  CRED_TYPE_GENERIC                 = 1;
  CRED_TYPE_DOMAIN_PASSWORD         = 2;
  CRED_TYPE_DOMAIN_CERTIFICATE      = 3;
  CRED_TYPE_DOMAIN_VISIBLE_PASSWORD = 4;
  CRED_TYPE_MAXIMUM                 = 5;  // Maximum supported cred type
  CRED_TYPE_MAXIMUM_EX              = CRED_TYPE_MAXIMUM + 1000;  // Allow new applications to run on old OSes

var
  Form1: TForm1;

function CredReadW(TargetName: LPCWSTR; Type_: DWORD; Flags: DWORD; var Credential: PCREDENTIALW): BOOL; stdcall; external 'advapi32.dll';
function CredEnumerateW(Filter: LPCWSTR; Flags: DWORD; out Count: DWORD; out Credential: PCredentialArray): BOOL; stdcall; external 'advapi32.dll';

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  Credentials: PCredentialArray;
  Credential: PCREDENTIALW;
  UserName: WideString;
  i: integer;
  dwCount: DWORD;
begin
    if CredEnumerateW(PChar('TERM*'), 0, dwCount, Credentials) then
    begin
      for i:= 0 to dwCount - 1  do
        begin
            if CredReadW(Credentials[i].TargetName, Credentials[i].Type_, 0, Credential) then
            begin
              UserName:= Credential.UserName;
              Memo1.Lines.Add(Credentials[i].TargetName + ' :: ' + UserName + ' >> ' + IntToStr(Credentials[i].Type_));
              Memo1.Lines.Add(IntToStr(Credential.CredentialBlobSize));
            end;
        end;
    end;
end;