2

I am trying to read the Windows Credential vault using ctypes API, but I am unsure how to cast back the function result back into a usable ctypes.Structure.

import ctypes
class CREDENTIALS(ctypes.Structure):
    _fields_ = [
        ("Flags", ctypes.c_int),
        ("Type", ctypes.c_int),
        ("TargetName", ctypes.c_wchar_p),
        ("Comment", ctypes.c_wchar_p),
        ("CredentialBlobSize", ctypes.c_int),
        ("CredentialBlob", ctypes.c_wchar_p),
        ("AttributeCount", ctypes.c_int),
        ("Attributes", ctypes.c_wchar_p),
        ("TargetAlias", ctypes.c_wchar_p),
        ("UserName", ctypes.c_wchar_p)
]
advapi32 = ctypes.oledll.LoadLibrary('Advapi32.dll')
advapi32.CredReadW.restype = ctypes.c_bool
advapi32.CredReadW.argtypes = [ctypes.c_wchar_p, ctypes.c_int, ctypes.c_int, ctypes.POINTER(CREDENTIALS)]
target = "login.example.com"
pcred = ctypes.pointer(CREDENTIALS())
ok = advapi32.CredReadW(target,1,0,pcred)
cred = pcred.contents
print ok, pcred, cred.UserName, cred.CredentialBlob

Result:

1 <__main__.LP_CREDENTIALS object at 0x012CECB0> None None

The function returns true ,so it works but the pointer contents seems blank. What am I doing wrong?

Stavr00
  • 3,219
  • 1
  • 16
  • 28
  • Since it looks like you're on x86 does adding `_pack_ = 1` inside your CREDENTIALS type help? – Flexo Nov 22 '14 at 11:05

1 Answers1

3

oledll should be windll. oledll is used for functions that return HRESULT.

The definition of CREDENTIAL is missing some fields (LastWritten and Persist). The definition (link) is:

typedef struct _CREDENTIAL {
  DWORD                 Flags;
  DWORD                 Type;
  LPTSTR                TargetName;
  LPTSTR                Comment;
  FILETIME              LastWritten;
  DWORD                 CredentialBlobSize;
  LPBYTE                CredentialBlob;
  DWORD                 Persist;
  DWORD                 AttributeCount;
  PCREDENTIAL_ATTRIBUTE Attributes;
  LPTSTR                TargetAlias;
  LPTSTR                UserName;
} CREDENTIAL, *PCREDENTIAL;
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
  • Thanks for your help, I've fixed the structure definition to use the WinDLL types: `from ctypes import Structure, POINTER, WinDLL` `from ctypes.wintypes import LPWSTR, DWORD, BOOL, FILETIME, LPVOID` – Stavr00 Nov 24 '14 at 15:45