Jump to content

Read Windows Credential Manager - (Moved)


 Share

Recommended Posts

Is it possible to read credentials from Windows Credential Manager? I am trying to pull them to a login screen but I cannot figure out how to connect and retrieve the data. I want to avoid having to read from an INI file. 

Link to comment
Share on other sites

  • Moderators

Moved to the appropriate forum.

Moderation Team

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

I just tried and it works fine for me.

If you are looking for network passwords, then you can't read them from the credential store.  If I remember correctly, only creds stored as Legacy can return passwords.

Here is a fully working script instead of just the function that I linked to.

#include <Array.au3>
$aCredList = _Credentials_Enumerate()

_ArrayDisplay($aCredList, "Creds")

Func _Credentials_Enumerate()
    Local $sCredList
    Local $iCred = -1
    Local $aCredList[10000][2]  ;set max number of Creds initally to 10,000, will be reDimed down before returning the array

    $iPID = Run(@SystemDir & "\cmdkey.exe /list", @SystemDir, @SW_HIDE, $STDOUT_CHILD)
    ProcessWaitClose($iPID)
    $sOutput = StdoutRead($iPID)

    If StringInStr($sOutput, "Currently stored credentials:") Then

        $aSplit = StringSplit($sOutput, @CRLF)

        For $c = 1 to $aSplit[0]
            If StringInStr($aSplit[$c], "Target:") Then

                $sCredList = StringStripWS(StringRight($aSplit[$c], StringLen($aSplit[$c]) - StringInStr($aSplit[$c], "=")), 3) ;Get the Target Server name
                $iCred += 1                                                 ;Increase the Credential counter by 1
                $aCredList[$iCred][0] = $sCredList                          ;Store the credential target in the 2D array

                For $d = $c to $aSplit[0]                                   ;Continue searching the output for this credentials UserName
                    If StringInStr($aSplit[$d], "User:") Then

                        $sCredList = StringStripWS(StringRight($aSplit[$d], StringLen($aSplit[$d]) - StringInStr($aSplit[$d], ":")), 3) ;Get the UserName
                        $aCredList[$iCred][1] = $sCredList                  ;Store the credential UserName in the 2D array

                        ExitLoop                                            ;We found the UserName, so exit out of this loop to look for the next Credential Target line
                    EndIf
                Next

                $c = $d                                                     ;Set the C loop to where we found the UserName line to speed it up a little

            EndIf
        Next

    Else

        MsgBox(0, "Stored Creds", "No stored credentials were found")

    EndIf

    ReDim $aCredList[$iCred][2]

    Return  $aCredList

EndFunc ;_Credentials_Enumerate

 

Link to comment
Share on other sites

  • 3 weeks later...

I am going to try the code again tomorrow but I have included a screen shot of an example credential I am trying to pull from credential manager. Before I waste hours playing around with code, is it possible to pull the username and password?

 

image.png.4b699bac82240cdfb43f018621ba2307.png

Link to comment
Share on other sites

You should be able to run this function to get that if it's a local credential.

_Cred_Get("test", 1)

;================================================================================================
;===== Retrieve the Credentials for the specified item  =========================================
;================================================================================================
Func _Cred_Get($sTarget, $iType = 1)  ;Type: 2=Domain, 1=Local.  CAN'T RETURN DOMAIN PASSWORDS!!!
    Local $FuncRet[3]

    Local $structTarget = DllStructCreate("wchar[100]")
    DllStructSetData($structTarget,1,$sTarget)

    Local $hAdvapi32 = DllOpen("Advapi32.dll")
    If $hAdvapi32 = -1 Then
        Msgbox(0, "Error", "Failed to connect to the Credentials Store")
        Exit
    Endif

    Local $Ret = DllCall($hAdvapi32, 'bool', 'CredReadW', 'ptr', DllStructGetPtr($structTarget), 'dword', $iType, 'dword', 0, 'ptr*', 0)

    if $ret[0]=0 then Return SetError(1,0,$FuncRet)

    Local $structCREDENTIAL= "" & _
        "DWORD Flags;" & _
        "DWORD Type;"  & _
        "Ptr TargetName;" & _
        "Ptr Comment;" & _
        "UINT64 LastWritten;" & _
        "DWORD CredintialBlobSize;" & _
        "Ptr CredentialBlob;" & _
        "DWORD Persist;" & _
        "DWORD AttributeCount;" & _
        "Ptr Attributes;" & _
        "Ptr TargetAlias;" & _
        "Ptr Username"

    Local $tdata=DllStructCreate($structCREDENTIAL, $Ret[4])

    Local $userName = DllStructCreate("wchar[513]", DllStructGetData($tdata, 'Username'))
    Local $User = DllStructGetData($userName, 1)

    Local $CredentialBlobSize = DllStructGetData($tdata, 'CredintialBlobSize')
    Local $credentialBlob = DllStructCreate("wchar[512]", DllStructGetData($tdata, 'CredentialBlob'))
    Local $Password = StringLeft(DllStructGetData($credentialBlob, 1), $CredentialBlobSize/2)

    Local $Comment = DllStructCreate("wchar[256]", DllStructGetData($tdata, 'Comment'))
    Local $Comm = DllStructGetData($Comment, 1)

    Dim $FuncRet[] = [$User, $Password, $Comm]
    Return $FuncRet

EndFunc ;_Cred_Get

 

Link to comment
Share on other sites

  • Developers

Show what you have tried.... assuming you actually added the line to call the function as indicated in the previous post.

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

;================================================================================================
;===== Retrieve the Credentials for the specified item  =========================================
;================================================================================================
_Cred_Get("test", 1)

Func _Cred_Get($sTarget, $iType = 1)  ;Type: 2=Domain, 1=Local.  CAN'T RETURN DOMAIN PASSWORDS!!!
    Local $FuncRet[3]

    Local $structTarget = DllStructCreate("wchar[100]")
    DllStructSetData($structTarget,1,$sTarget)

    Local $hAdvapi32 = DllOpen("Advapi32.dll")
    If $hAdvapi32 = -1 Then
        Msgbox(0, "Error", "Failed to connect to the Credentials Store")
        Exit
    Endif

    Local $Ret = DllCall($hAdvapi32, 'bool', 'CredReadW', 'ptr', DllStructGetPtr($structTarget), 'dword', $iType, 'dword', 0, 'ptr*', 0)

    if $ret[0]=0 then Return SetError(1,0,$FuncRet)

    Local $structCREDENTIAL= "" & _
        "DWORD Flags;" & _
        "DWORD Type;"  & _
        "Ptr TargetName;" & _
        "Ptr Comment;" & _
        "UINT64 LastWritten;" & _
        "DWORD CredintialBlobSize;" & _
        "Ptr CredentialBlob;" & _
        "DWORD Persist;" & _
        "DWORD AttributeCount;" & _
        "Ptr Attributes;" & _
        "Ptr TargetAlias;" & _
        "Ptr Username"

    Local $tdata=DllStructCreate($structCREDENTIAL, $Ret[4])

    Local $userName = DllStructCreate("wchar[513]", DllStructGetData($tdata, 'Username'))
    Local $User = DllStructGetData($userName, 1)

    Local $CredentialBlobSize = DllStructGetData($tdata, 'CredintialBlobSize')
    Local $credentialBlob = DllStructCreate("wchar[512]", DllStructGetData($tdata, 'CredentialBlob'))
    Local $Password = StringLeft(DllStructGetData($credentialBlob, 1), $CredentialBlobSize/2)

    Local $Comment = DllStructCreate("wchar[256]", DllStructGetData($tdata, 'Comment'))
    Local $Comm = DllStructGetData($Comment, 1)

    Dim $FuncRet[] = [$User, $Password, $Comm]
    Return $FuncRet
EndFunc ;_Cred_Get

 

Link to comment
Share on other sites

  • Developers

An array is returned and you aren't doing anything with it. Something like this might tell you something:

$retarray = _Cred_Get("test", 1)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : Error code: ' & @error & @CRLF) ;### Debug Console
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $retarray[0] = ' & $retarray[0] & @CRLF) ;### Debug Console
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $retarray[1] = ' & $retarray[1] & @CRLF) ;### Debug Console
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $retarray[2] = ' & $retarray[2] & @CRLF) ;### Debug Console

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

I am still not getting anything.

 

_Cred_Get("test", 1)

Func _Cred_Get($sTarget, $iType = 1)  ;Type: 2=Domain, 1=Local.  CAN'T RETURN DOMAIN PASSWORDS!!!
    Local $FuncRet[3]

    Local $structTarget = DllStructCreate("wchar[100]")
    DllStructSetData($structTarget,1,$sTarget)

    Local $hAdvapi32 = DllOpen("Advapi32.dll")
    If $hAdvapi32 = -1 Then
        Msgbox(0, "Error", "Failed to connect to the Credentials Store")
        Exit
    Endif

    Local $Ret = DllCall($hAdvapi32, 'bool', 'CredReadW', 'ptr', DllStructGetPtr($structTarget), 'dword', $iType, 'dword', 0, 'ptr*', 0)

    if $ret[0]=0 then Return SetError(1,0,$FuncRet)

    Local $structCREDENTIAL= "" & _
        "DWORD Flags;" & _
        "DWORD Type;"  & _
        "Ptr TargetName;" & _
        "Ptr Comment;" & _
        "UINT64 LastWritten;" & _
        "DWORD CredintialBlobSize;" & _
        "Ptr CredentialBlob;" & _
        "DWORD Persist;" & _
        "DWORD AttributeCount;" & _
        "Ptr Attributes;" & _
        "Ptr TargetAlias;" & _
        "Ptr Username"

    Local $tdata=DllStructCreate($structCREDENTIAL, $Ret[4])

    Local $userName = DllStructCreate("wchar[513]", DllStructGetData($tdata, 'Username'))
    Local $User = DllStructGetData($userName, 1)

    Local $CredentialBlobSize = DllStructGetData($tdata, 'CredintialBlobSize')
    Local $credentialBlob = DllStructCreate("wchar[512]", DllStructGetData($tdata, 'CredentialBlob'))
    Local $Password = StringLeft(DllStructGetData($credentialBlob, 1), $CredentialBlobSize/2)

    Local $Comment = DllStructCreate("wchar[256]", DllStructGetData($tdata, 'Comment'))
    Local $Comm = DllStructGetData($Comment, 1)

    Dim $FuncRet[] = [$User, $Password, $Comm]
    Return $FuncRet

    $retarray = _Cred_Get("test", 1)
   ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : Error code: ' & @error & @CRLF) ;### Debug Console
   ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $retarray[0] = ' & $retarray[0] & @CRLF) ;### Debug Console
   ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $retarray[1] = ' & $retarray[1] & @CRLF) ;### Debug Console
   ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $retarray[2] = ' & $retarray[2] & @CRLF) ;### Debug Console

 EndFunc ;_Cred_Get

 

Link to comment
Share on other sites

  • Developers
8 hours ago, mknope said:

I am still not getting anything.

Makes sense when you don't put the code I provided at the top instead of what you already had unless you expect magic. ;) 

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...