Windows credential manager python

mrh1997 / wincred.py

This file contains 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 ()
unicodePassword = credPtr.contents.CredentialBlob[:passwordSize:2] 

My instinct tells me that this is probably a byte-value representing a text encoded using something other than UTF-8. Maybe UTF-16? Using the step-size «2» and then converting the bytes blindly using the chr builtin is in that case erroneous at best, or even a security risk at worst.

If my feeling is correct, it would be better to find out which encoding is used in the credential store and then simply use credPtr.contents.CredentialBlob.decode()

Actually this code was written for Python 2.7 ignoring Unicode. For real Unicode support there is more to do:

  • replace CreadReadA by CreadReadW and thus supporting unicode urls
  • replacing all LPTSTR by LPWSTR . This is especially important for UserName as it would be returned as unicode then
  • credPtr.contents.CredentialBlob is of type LP_c_byte . Thus you cannot use the method decode .
Читайте также:  Java звук при нажатии

I updated the code to support unicode correctly (and switched to Python 3 compatibility)

I’m curious as I am not familiar with the Windows API: Why is there a step-size of 2 when retrieving the value from the credentials blob?

Do you have a link to the documentation? Or was this reverse engineered?

And thanks a bunch for updating this! I’ll give it a go 😉

I aligned the code closer to PEP8 and made other things a bit more «pythonic» over at https://gist.github.com/exhuma/a310f927d878b3e5646dc67dfa509b42

In case you agree with the changes, you can merge them back if you like. Unfortunatly it’s not possible to do PRs on gists yet.

Источник

Как настроить Python Keyring для получения учетных данных из Windows Credential Manager в Windows 7?

Я потратил много времени на изучение пакета keyring, пытаясь получить простой пример для работы. Я использую python 2.7 на машине Windows 7-x64. Я установил пакет и подтвердил, что файлы находятся в папке Lib/site-packages. В этом фрагменте кода из документации по установке предполагается, что предполагается войти в «систему»?

import keyring keyring.get_password("system", "username") 

RuntimeError: рекомендованных бэкэнд не было. Установите пакет keyrings.alt, если вы хотите использовать не рекомендованные серверы.

Похоже, что он не распознает Windows как бэкэнд. Я чувствую, что мне не хватает простого шага. Любая помощь приветствуется, включая простой пример кода для выведения общих учетных данных из диспетчера учетных данных Windows.

У меня точно такая же проблема. Windows 7. Python 3.6. Установлен из конды, IIRC. Вы когда-нибудь решали это?

3 ответа

Наконец, эта работа. Информация от Шона указала мне в правильном направлении с установкой pywin32. Оттуда я пробовал и делал ошибку с созданием тестовых учетных данных в Windows Credential Manager и тестированием функции Python keyring.

Я только получил его работу с Generic Credentials, которая подходит для моих целей. Я установил Интернет или сетевой адрес для «проверки». Имя пользователя было установлено на «test_user». Пароль был установлен на «test123». (Цитаты, включенные здесь для обучения, не включаются при вводе их.

print keyring.get_password («test», «test_user») вернул результат «test123»

Надеюсь, эта информация поможет кому-то другому. Спасибо Шон за направление, необходимое для решения этой проблемы.

Источник

RodneyRichardson / wincred.py

This file contains 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

«»»
Access windows credentials
Credentials must be stored in the Windows Credentials Manager in the Control
Panel. This helper will search for «generic credentials» under the section
«Windows Credentials»
Example usage::
result = get_generic_credential(‘foobar’)
if result:
print(«NAME:», result.username)
print(«PASSWORD:», result.password)
else:
print(‘No matching credentials found’)
Based on https://gist.github.com/exhuma/a310f927d878b3e5646dc67dfa509b42
which was based on https://gist.github.com/mrh1997/717b14f5783b49ca14310419fa7f03f6
«»»
import ctypes as ct
import ctypes . wintypes as wt
from enum import Enum
from typing import NamedTuple , Optional
LPBYTE = ct . POINTER ( wt . BYTE )
Credential = NamedTuple ( ‘Credential’ , [
( ‘username’ , str ),
( ‘password’ , str )
])
def as_pointer ( cls ):
«»»
Class decorator which converts the class to ta ctypes pointer
:param cls: The class to decorate
:return: The class as pointer
«»»
output = ct . POINTER ( cls )
return output
class CredType ( Enum ):
«»»
CRED_TYPE_* enumeration (wincred.h)
https://docs.microsoft.com/en-us/windows/win32/api/wincred/ns-wincred-credentialw
«»»
GENERIC = 0x01
DOMAIN_PASSWORD = 0x02
DOMAIN_CERTIFICATE = 0x03
DOMAIN_VISIBLE_PASSWORD = 0x04
GENERIC_CERTIFICATE = 0x05
DOMAIN_EXTENDED = 0x06
MAXIMUM = 0x07
MAXIMUM_EX = MAXIMUM + 1000
@ as_pointer
class CredentialAttribute ( ct . Structure ):
«»»
PCREDENTIAL_ATTRIBUTEW structure (wincred.h)
https://docs.microsoft.com/en-us/windows/win32/api/wincred/ns-wincred-credential_attributew
«»»
_fields_ = [
( ‘Keyword’ , wt . LPWSTR ),
( ‘Flags’ , wt . DWORD ),
( ‘ValueSize’ , wt . DWORD ),
( ‘Value’ , LPBYTE )]
@ as_pointer
class WinCredential ( ct . Structure ):
«»»
CREDENTIALW structure (wincred.h)
https://docs.microsoft.com/en-us/windows/win32/api/wincred/ns-wincred-credentialw
«»»
_fields_ = [
( ‘Flags’ , wt . DWORD ),
( ‘Type’ , wt . DWORD ),
( ‘TargetName’ , wt . LPWSTR ),
( ‘Comment’ , wt . LPWSTR ),
( ‘LastWritten’ , wt . FILETIME ),
( ‘CredentialBlobSize’ , wt . DWORD ),
( ‘CredentialBlob’ , LPBYTE ),
( ‘Persist’ , wt . DWORD ),
( ‘AttributeCount’ , wt . DWORD ),
( ‘Attributes’ , CredentialAttribute ),
( ‘TargetAlias’ , wt . LPWSTR ),
( ‘UserName’ , wt . LPWSTR )]
def get_generic_credential ( name : str ) -> Optional [ Credential ]:
«»»
Returns a tuple of name and password of a generic Windows credential.
If no matching credential is found, this will return «None«
:param name: The lookup string for the credential.
«»»
advapi32 = ct . WinDLL ( ‘Advapi32.dll’ )
advapi32 . CredReadW . restype = wt . BOOL
advapi32 . CredReadW . argtypes = [ wt . LPCWSTR , wt . DWORD , wt . DWORD , ct . POINTER ( WinCredential )]
cred_ptr = WinCredential ()
if advapi32 . CredReadW ( name , CredType . GENERIC . value , 0 , ct . byref ( cred_ptr )):
try :
username = cred_ptr . contents . UserName
cred_blob = cred_ptr . contents . CredentialBlob
cred_blob_size = cred_ptr . contents . CredentialBlobSize
password_as_list = [ int . from_bytes ( cred_blob [ pos : pos + 2 ], ‘little’ )
for pos in range ( 0 , cred_blob_size , 2 )]
password = » . join ( map ( chr , password_as_list ))
return Credential ( username , password )
finally :
advapi32 . CredFree ( cred_ptr )
return None
def main ():
result = get_generic_credential ( ‘foobar’ )
if result :
print ( «NAME:» , result . username )
print ( «PASSWORD:» , result . password )
else :
print ( ‘No matching credentials found’ )
if __name__ == ‘__main__’ :
main ()
Читайте также:  Python шаг в срезе

Источник

Python – How to Configure Python Keyring to pull credentials from Windows Credential Manager on Windows 7

I’ve spent a lot of time researching the keyring package trying to get a simple example to work. I’m using python 2.7 on a windows 7-x64 machine. I’ve installed the package and confirmed that the files are within my Lib/site-packages folder.

In this code snippet from the installation docs what is supposed to go in «system»?

import keyring keyring.get_password("system", "username") 

When I run the code i get the following error:

RuntimeError: No recommended backend was available. Install the keyrings.alt package if you want to use the non-recommended backends.

It seems like it’s not recognizing Windows as the backend. I feel like I’m missing a simple step. Any help is appreciated including a simple code example of pulling generic credentials from Windows Credential Manager.

Best Solution

Finally got this working. The information from Shaun pointed me in the right direction with installing pywin32 . From there I did trial and error with creating test credentials in Windows Credential Manager and testing the Python keyring function.

I only got it working with Generic Credentials which is fine for my purposes. I set Internet or network address to «test» . Username was set to «test_user» . Password was set to «test123» . (Quotes included here for instruction, don’t include when entering them.

print keyring.get_password("test","test_user") 

returned the result «test123»

Hopefully this information helps somebody else. Thanks to Shaun for the direction needed to solve this.

Windows – How to you find out which process is listening on a TCP or UDP port on Windows

New answer, powershell

TCP

Get-Process -Id (Get-NetTCPConnection -LocalPort YourPortNumberHere).OwningProcess 

UDP

Get-Process -Id (Get-NetUDPEndpoint -LocalPort YourPortNumberHere).OwningProcess 

Old answer, cmd

(Add -n to stop it trying to resolve hostnames, which will make it a lot faster.)

Читайте также:  Python экранирование всех символов

Note Dane’s recommendation for TCPView. It looks very useful!

-a Displays all connections and listening ports.

-b Displays the executable involved in creating each connection or listening port. In some cases well-known executables host multiple independent components, and in these cases the sequence of components involved in creating the connection or listening port is displayed. In this case the executable name is in [] at the bottom, on top is the component it called, and so forth until TCP/IP was reached. Note that this option can be time-consuming and will fail unless you have sufficient permissions.

-n Displays addresses and port numbers in numerical form.

-o Displays the owning process ID associated with each connection.

Python – How to execute a program or call a system command

Use the subprocess module in the standard library:

import subprocess subprocess.run(["ls", "-l"]) 

The advantage of subprocess.run over os.system is that it is more flexible (you can get the stdout , stderr , the «real» status code, better error handling, etc. ).

Even the documentation for os.system recommends using subprocess instead:

The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using this function. See the Replacing Older Functions with the subprocess Module section in the subprocess documentation for some helpful recipes.

On Python 3.4 and earlier, use subprocess.call instead of .run :

Источник

Оцените статью