Skip to content

Instantly share code, notes, and snippets.

@elfmimi
Last active May 3, 2023 15:33
Show Gist options
  • Save elfmimi/845fdeee6b078c9a1ade3218884aaf21 to your computer and use it in GitHub Desktop.
Save elfmimi/845fdeee6b078c9a1ade3218884aaf21 to your computer and use it in GitHub Desktop.
POC: PowerShell script to retrieve your access token from Windows Credential Manager
# Howto execute this script:
# Unblock-File .\CredReadTest.ps1
# powershell -ExecutionPolicy RemoteSigned .\CredReadTest.ps1
#
# The following command displays a list of credentials:
# cmdkey /list
Write-Output "CredRead Test Program"
$type_def = @'
using System;
using System.Text;
using System.Runtime.InteropServices;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
public static class CredTest {
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct Win32Credential
{
public int Flags;
// public CredentialType Type;
public int Type;
[MarshalAs(UnmanagedType.LPWStr)]
public string TargetName;
[MarshalAs(UnmanagedType.LPWStr)]
public string Comment;
public FILETIME LastWritten;
public int CredentialBlobSize;
public IntPtr CredentialBlob;
// public CredentialPersist Persist;
public int Persist;
public int AttributeCount;
public IntPtr Attributes;
[MarshalAs(UnmanagedType.LPWStr)]
public string TargetAlias;
[MarshalAs(UnmanagedType.LPWStr)]
public string UserName;
}
public static string GetCredSecret(IntPtr credPtr) {
var credential = Marshal.PtrToStructure<Win32Credential>(credPtr);
var blob = new byte[credential.CredentialBlobSize];
Marshal.Copy(credential.CredentialBlob, blob, 0, blob.Length);
return Encoding.Unicode.GetString(blob);
}
}
'@
Add-Type -TypeDefinition $type_def
$member_def = @'
[DllImport("advapi32", EntryPoint = "CredReadW", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool CredRead(string target, int type, int reservedFlag, out IntPtr credential);
[DllImport("advapi32", EntryPoint = "CredFree", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern void CredFree(IntPtr credential);
'@
$interop = Add-Type -MemberDefinition $member_def -Namespace Interop -Name Interop -PassThru
$targetName = "git:https://github.com"
$credPtr = [IntPtr]::Zero
if ($interop::CredRead($targetName, 1, 0, [ref]$credPtr)) {
$secret = [CredTest]::GetCredSecret($credPtr)
# Notice CredFree must be called to free the memory allocated by CredRead
$interop::CredFree($credPtr)
Write-Output $secret
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment