Skip to content

Instantly share code, notes, and snippets.

@agowa
Last active August 27, 2024 05:54
Show Gist options
  • Save agowa/848701839ad10e429d1652d57f07779d to your computer and use it in GitHub Desktop.
Save agowa/848701839ad10e429d1652d57f07779d to your computer and use it in GitHub Desktop.
Get rid of "S-1-5-2" within your access token
Add-Type -TypeDefinition @'
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Management.Automation;
public static class LsassImpersonation
{
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool OpenProcessToken(
IntPtr ProcessHandle,
DesiredAccess DesiredAccess,
out IntPtr TokenHandle
);
//Use these for DesiredAccess
private enum DesiredAccess : uint
{
STANDARD_RIGHTS_REQUIRED = 0x000F0000,
STANDARD_RIGHTS_READ = 0x00020000,
TOKEN_ASSIGN_PRIMARY = 0x0001,
TOKEN_DUPLICATE = 0x0002,
TOKEN_IMPERSONATE = 0x0004,
TOKEN_QUERY = 0x0008,
TOKEN_QUERY_SOURCE = 0x0010,
TOKEN_ADJUST_PRIVILEGES = 0x0020,
TOKEN_ADJUST_GROUPS = 0x0040,
TOKEN_ADJUST_DEFAULT = 0x0080,
TOKEN_ADJUST_SESSIONID = 0x0100,
TOKEN_READ = (
DesiredAccess.STANDARD_RIGHTS_READ |
DesiredAccess.TOKEN_QUERY
),
TOKEN_ALL_ACCESS = (
DesiredAccess.STANDARD_RIGHTS_REQUIRED |
DesiredAccess.TOKEN_ASSIGN_PRIMARY |
DesiredAccess.TOKEN_DUPLICATE |
DesiredAccess.TOKEN_IMPERSONATE |
DesiredAccess.TOKEN_QUERY |
DesiredAccess.TOKEN_QUERY_SOURCE |
DesiredAccess.TOKEN_ADJUST_PRIVILEGES |
DesiredAccess.TOKEN_ADJUST_GROUPS |
DesiredAccess.TOKEN_ADJUST_DEFAULT |
DesiredAccess.TOKEN_ADJUST_SESSIONID
)
}
private static WindowsImpersonationContext impersonationContext;
public static void Invoke(ScriptBlock scriptBlock)
{
// Get Copy of LSASS Token for impersonation
IntPtr lsassToken = IntPtr.Zero;
Process sourceProcess = Process.GetProcessesByName("lsass")[0];
OpenProcessToken(sourceProcess.Handle, DesiredAccess.TOKEN_READ | DesiredAccess.TOKEN_DUPLICATE | DesiredAccess.TOKEN_IMPERSONATE, out lsassToken);
// Create a WindowsImpersonationContext object by impersonating the Windows identity.
impersonationContext = (new WindowsIdentity(lsassToken)).Impersonate();
// Invoke PowerShell ScriptBlock
scriptBlock.Invoke();
// Stop impersonating the user.
impersonationContext.Undo();
}
}
'@
$script:UpdateSession = New-Object -ComObject 'Microsoft.Update.Session'
$UpdateSession.ClientApplicationID = 'PowerShell Windows Update Installer'
# The LsassImpersonation is required for circumventing a check inside of the underlaying com module.
# If the access token contains S-1-5-2 (aka, logged on remotely e.g. Enter-PSSession) the invokation is denied
[LsassImpersonation]::Invoke(
{
$Downloader = $UpdateSession.CreateUpdateDownloader()
$Downloader.Updates = $UpdatesToDownload
$Downloader.Download()
}
)
[LsassImpersonation]::Invoke(
{
$Installer = $UpdateSession.CreateUpdateInstaller()
$Installer.Updates = $UpdatesToInstall
$Script:InstallationResult = $Installer.Install()
}
)
LogWrite "Installation Result: $($InstallationResult.ResultCode)"
LogWrite "Reboot Required: $($InstallationResult.RebootRequired)"
//This is here just for better syntax highlighting of the above c# code inside of the type definition
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Management.Automation;
public static class LsassImpersonation
{
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool OpenProcessToken(
IntPtr ProcessHandle,
DesiredAccess DesiredAccess,
out IntPtr TokenHandle
);
//Use these for DesiredAccess
private enum DesiredAccess : uint
{
STANDARD_RIGHTS_REQUIRED = 0x000F0000,
STANDARD_RIGHTS_READ = 0x00020000,
TOKEN_ASSIGN_PRIMARY = 0x0001,
TOKEN_DUPLICATE = 0x0002,
TOKEN_IMPERSONATE = 0x0004,
TOKEN_QUERY = 0x0008,
TOKEN_QUERY_SOURCE = 0x0010,
TOKEN_ADJUST_PRIVILEGES = 0x0020,
TOKEN_ADJUST_GROUPS = 0x0040,
TOKEN_ADJUST_DEFAULT = 0x0080,
TOKEN_ADJUST_SESSIONID = 0x0100,
TOKEN_READ = (
DesiredAccess.STANDARD_RIGHTS_READ |
DesiredAccess.TOKEN_QUERY
),
TOKEN_ALL_ACCESS = (
DesiredAccess.STANDARD_RIGHTS_REQUIRED |
DesiredAccess.TOKEN_ASSIGN_PRIMARY |
DesiredAccess.TOKEN_DUPLICATE |
DesiredAccess.TOKEN_IMPERSONATE |
DesiredAccess.TOKEN_QUERY |
DesiredAccess.TOKEN_QUERY_SOURCE |
DesiredAccess.TOKEN_ADJUST_PRIVILEGES |
DesiredAccess.TOKEN_ADJUST_GROUPS |
DesiredAccess.TOKEN_ADJUST_DEFAULT |
DesiredAccess.TOKEN_ADJUST_SESSIONID
)
}
private static WindowsImpersonationContext impersonationContext;
public static void Invoke(ScriptBlock scriptBlock)
{
// Get Copy of LSASS Token for impersonation
IntPtr lsassToken = IntPtr.Zero;
Process sourceProcess = Process.GetProcessesByName("lsass")[0];
OpenProcessToken(sourceProcess.Handle, DesiredAccess.TOKEN_READ | DesiredAccess.TOKEN_DUPLICATE | DesiredAccess.TOKEN_IMPERSONATE, out lsassToken);
// Create a WindowsImpersonationContext object by impersonating the Windows identity.
impersonationContext = (new WindowsIdentity(lsassToken)).Impersonate();
// Invoke PowerShell ScriptBlock
scriptBlock.Invoke();
// Stop impersonating the user.
impersonationContext.Undo();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment