Skip to content

Instantly share code, notes, and snippets.

@mrh1997
Last active January 21, 2024 17:29
Show Gist options
  • Save mrh1997/717b14f5783b49ca14310419fa7f03f6 to your computer and use it in GitHub Desktop.
Save mrh1997/717b14f5783b49ca14310419fa7f03f6 to your computer and use it in GitHub Desktop.
Retrieve Windows Credential via Python
#!python3
"""
Access windows credentials
"""
from typing import Tuple
import ctypes as CT
import ctypes.wintypes as WT
CRED_TYPE_GENERIC = 0x01
LPBYTE = CT.POINTER(WT.BYTE)
LPWSTR = WT.LPWSTR
LPCWSTR = WT.LPWSTR
class CREDENTIAL_ATTRIBUTE(CT.Structure):
_fields_ = [
('Keyword', LPWSTR),
('Flags', WT.DWORD),
('ValueSize', WT.DWORD),
('Value', LPBYTE)]
PCREDENTIAL_ATTRIBUTE = CT.POINTER(CREDENTIAL_ATTRIBUTE)
class CREDENTIAL(CT.Structure):
_fields_ = [
('Flags', WT.DWORD),
('Type', WT.DWORD),
('TargetName', LPWSTR),
('Comment', LPWSTR),
('LastWritten', WT.FILETIME),
('CredentialBlobSize', WT.DWORD),
('CredentialBlob', LPBYTE),
('Persist', WT.DWORD),
('AttributeCount', WT.DWORD),
('Attributes', PCREDENTIAL_ATTRIBUTE),
('TargetAlias', LPWSTR),
('UserName', LPWSTR)]
PCREDENTIAL = CT.POINTER(CREDENTIAL)
advapi32 = CT.WinDLL('Advapi32.dll')
advapi32.CredReadA.restype = WT.BOOL
advapi32.CredReadA.argtypes = [LPCWSTR, WT.DWORD, WT.DWORD, CT.POINTER(PCREDENTIAL)]
def GetGenericCredential(name:str) -> Tuple[str, str]:
"""
Returns a Tuple of Name and Password of a Generic Windows Credential
Uses bytes in Py3 and str in Py2 for url, name and password.
"""
cred_ptr = PCREDENTIAL()
if advapi32.CredReadW(name, CRED_TYPE_GENERIC, 0, CT.byref(cred_ptr)):
username = cred_ptr.contents.UserName
cred_blob = cred_ptr.contents.CredentialBlob
cred_blob_size = cred_ptr.contents.CredentialBlobSize
cred_str = CT.string_at(cred_blob, cred_blob_size)
password = cred_str.decode('utf-16le', errors='ignore')
advapi32.CredFree(cred_ptr)
return username, password
else:
raise IOError("Failure reading credential")
def main():
name, pwd = GetGenericCredential('git:https://github.com')
print("GITHUB NAME:", name)
print("GITHUB PASSWORD:", pwd)
if __name__ == '__main__':
main()
@rolangom
Copy link

I'm using this script in a node package. See: https://github.com/rolangom/wincred

@burque505
Copy link

I used a scarcely modified version of your code, posted here, to allow automating Box.com with Robin, the RPA language.
Works great, thank you!

@apolkosnik
Copy link

A little improvement, I think...

import codecs

password = CT.string_at(cred_blob,cred_blob_size).decode('utf-16le', errors='ignore')

@mrh1997
Copy link
Author

mrh1997 commented Oct 6, 2020

@apolkosnik: Thx for this tip. I incorporated it into my code...

@HGStyle
Copy link

HGStyle commented Sep 28, 2022

Question : how can I get the Windows Session Password using Python ?

@mrh1997
Copy link
Author

mrh1997 commented Sep 28, 2022

Do you mean the current windows users password? I am pretty sure that this is not possible (neither with python nor with C). It would be a big security flaw.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment