Skip to content

Instantly share code, notes, and snippets.

@jborean93
Last active December 5, 2023 10:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jborean93/f3717d1b92b7fb9c28e000f470324e7b to your computer and use it in GitHub Desktop.
Save jborean93/f3717d1b92b7fb9c28e000f470324e7b to your computer and use it in GitHub Desktop.
Gets the gMSA AccessToken (PowerShell 7.3+)
#Requires -Module Ctypes
$advapi32 = New-CtypesLib Advapi32.dll
$kernel32 = New-CtypesLib Kernel32.dll
$advapi32.Returns([bool]).ImpersonateLoggedOnUser = @([IntPtr])
$advapi32.Returns([bool]).RevertToSelf = @()
$kernel32.Returns([void]).CloseHandle = @([IntPtr])
# This is a quick and dirty way to impersonate SYSTEM
# Won't work if lsass is a protected process but there
# are other way to do the same thing
$proc = $kernel32.SetLastError().OpenProcess[IntPtr](
0x400, # PROCESS_QUERY_INFORMATION
$false,
(Get-Process -Name lsass).Id)
if ($proc -eq ([IntPtr]::Zero)) {
throw [System.ComponentModel.Win32Exception]$kernel32.LastError
}
$systemToken = [IntPtr]::Zero
$impersonated = $false
try {
$access = [System.Security.Principal.TokenAccessLevels]"Duplicate, Impersonate, Query"
if (-not $advapi32.SetLastError().OpenProcessToken[bool]($proc, $access, [ref]$systemToken)) {
throw [System.ComponentModel.Win32Exception]$advapi32.LastError
}
if (-not $advapi32.SetLastError().ImpersonateLoggedOnUser($systemToken)) {
throw [System.ComponentModel.Win32Exception]$advapi32.LastError
}
# The password is a special constant value for gMSA accounts.
# The only pre-req is your current user needs to be running as SYSTEM
# which we did above.
$impersonated = $true
$token = [IntPtr]::Zero
$res = $advapi32.SetLastError().CharSet('Unicode').LogonUserW[bool](
"myGMSA$",
"DOMAIN",
"_SA_{262E99C9-6160-4871-ACEC-4E61736B6F21}",
5, # LOGON32_LOGON_SERVICE
0, # LOGON32_PROVIDER_DEFAULT
[ref]$token)
if (-not $res) {
throw [System.ComponentModel.Win32Exception]$advapi32.LastError
}
}
finally {
if ($systemToken -ne ([IntPtr]::Zero)) { $kernel32.CloseHandle($systemToken) }
$kernel32.CloseHandle($proc)
if ($impersonated) {
if (-not $advapi32.RevertToSelf()) {
throw [System.ComponentModel.Win32Exception]$advapi32.LastError
}
}
}
try {
if (-not $advapi32.SetLastError().ImpersonateLoggedOnUser($token)) {
throw [System.ComponentModel.Win32Exception]$advapi32.LastError
}
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
}
finally {
$kernel32.CloseHandle[void]($token)
if (-not $advapi32.RevertToSelf[bool]()) {
throw [System.ComponentModel.Win32Exception]$advapi32.LastError
}
}
# Verify you are back to normal
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment