Skip to content

Instantly share code, notes, and snippets.

@micjabbour
Created August 8, 2020 12:40
Show Gist options
  • Save micjabbour/654e67d29cbd62be3587b9f1dd79eaac to your computer and use it in GitHub Desktop.
Save micjabbour/654e67d29cbd62be3587b9f1dd79eaac to your computer and use it in GitHub Desktop.
A Python script to dump all stored credentials from Windows Credential Manager into standard output.
"""
A Python script to dump all stored credentials from Windows Credential Manager into standard
output. It uses ctypes to interface with functions from Win32 Security and Identity API in order to
retrieve credentials for the current user.
Start using:
python cred_read.py
"""
import ctypes
from ctypes import wintypes
from collections import namedtuple
class FILETIME(ctypes.Structure):
"""
Defines the layout for the WINAPI FILETIME struct.
https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
"""
_fields_ = [
("dwLowDateTime", ctypes.c_int),
("dwHighDateTime", ctypes.c_int),
]
class CREDENTIAL_ATTRIBUTEW(ctypes.Structure):
"""
Defines the layout for the WINAPI CREDENTIAL_ATTRIBUTEW struct.
See https://docs.microsoft.com/en-us/windows/win32/api/wincred/ns-wincred-credential_attributew.
"""
_fields_ = [
("Keyword", wintypes.LPWSTR),
("Flags", wintypes.DWORD),
("ValueSize", wintypes.DWORD),
("Value", wintypes.LPBYTE)
]
class CREDENTIALW(ctypes.Structure):
"""
Defines the layout for the WINAPI CREDENTIALW struct.
https://docs.microsoft.com/en-us/windows/win32/api/wincred/ns-wincred-credentialw
"""
_fields_ = [
("Flags", wintypes.DWORD),
("Type", wintypes.DWORD),
("TargetName", wintypes.LPWSTR),
("Comment", wintypes.LPWSTR),
("LastWritten", FILETIME),
("CredentialBlobSize", wintypes.DWORD),
("CredentialBlob", wintypes.LPBYTE),
("Persist", wintypes.DWORD),
("AttributeCount", wintypes.DWORD),
("Attributes", ctypes.POINTER(CREDENTIAL_ATTRIBUTEW)),
("TargetAlias", wintypes.LPWSTR),
("UserName", wintypes.LPWSTR),
]
class Cred(namedtuple('Cred', ['target_name', 'username', 'password'])):
"""
A namedtuple that provides easy access to the relevant fields in WinAPI C CREDENTIALW objects
as Python strings.
"""
@staticmethod
def from_winapi_credential(pcred):
"""
Convert a pointer to a WinAPI C CREDENTIALW object into a Cred object
"""
pass_len = pcred.contents.CredentialBlobSize
pass_buffer = ctypes.create_unicode_buffer(pass_len + 1) # +1 for terminating null
ctypes.memmove(pass_buffer, pcred.contents.CredentialBlob, pass_len)
return Cred(pcred.contents.TargetName, pcred.contents.UserName, pass_buffer.value)
# prepare used WinAPI functions
advapi32 = ctypes.windll.advapi32
advapi32.CredReadW.restype = wintypes.BOOL
advapi32.CredReadW.argtypes = [wintypes.LPCWSTR, wintypes.DWORD, wintypes.DWORD,
ctypes.POINTER(ctypes.POINTER(CREDENTIALW))]
advapi32.CredEnumerateW.restype = wintypes.BOOL
advapi32.CredEnumerateW.argtypes = [wintypes.LPCWSTR, wintypes.DWORD, ctypes.POINTER(wintypes.DWORD),
ctypes.POINTER(ctypes.POINTER(ctypes.POINTER(CREDENTIALW)))]
kernel32 = ctypes.windll.kernel32
kernel32.GetLastError.restype = wintypes.DWORD
def get_cred_by_target_name(target_name):
"""
Returns the stored credentials for the given target_name as a Cred object
"""
pcred = ctypes.POINTER(CREDENTIALW)()
ok = advapi32.CredReadW(target_name, 1, 0, ctypes.byref(pcred))
if not ok:
error = kernel32.GetLastError()
raise RuntimeError(error)
cred = Cred.from_winapi_credential(pcred)
advapi32.CredFree(pcred)
return cred
def get_all_creds():
"""
Returns all credentials stored in the credential manager as a list of Cred objects
"""
count = wintypes.DWORD()
pcred = ctypes.POINTER(ctypes.POINTER(CREDENTIALW))()
ok = advapi32.CredEnumerateW(None, 1, ctypes.byref(count), ctypes.byref(pcred))
if not ok:
error = kernel32.GetLastError()
raise RuntimeError(error)
creds = [Cred.from_winapi_credential(pcred[i]) for i in range(count.value)]
advapi32.CredFree(pcred)
return creds
if __name__ == "__main__":
# write all stored credentials to standard output
print("\n".join(map(str, get_all_creds())))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment