Last active
January 21, 2024 17:29
-
-
Save mrh1997/717b14f5783b49ca14310419fa7f03f6 to your computer and use it in GitHub Desktop.
Retrieve Windows Credential via Python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!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() |
A little improvement, I think...
import codecs
password = CT.string_at(cred_blob,cred_blob_size).decode('utf-16le', errors='ignore')
@apolkosnik: Thx for this tip. I incorporated it into my code...
Question : how can I get the Windows Session Password using Python ?
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
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!