diff --git a/DInvoke/DInvoke/DynamicInvoke/Native.cs b/DInvoke/DInvoke/DynamicInvoke/Native.cs index 332021a..96aadb7 100644 --- a/DInvoke/DInvoke/DynamicInvoke/Native.cs +++ b/DInvoke/DInvoke/DynamicInvoke/Native.cs @@ -58,7 +58,7 @@ public static Data.Native.NTSTATUS RtlCreateUserThread( // Craft an array for the arguments object[] funcargs = { - Process, ThreadSecurityDescriptor, CreateSuspended, ZeroBits, + Process, ThreadSecurityDescriptor, CreateSuspended, ZeroBits, MaximumStackSize, CommittedStackSize, StartAddress, Parameter, Thread, ClientId }; @@ -95,8 +95,8 @@ public static Data.Native.NTSTATUS NtCreateSection( } // Update the modified variables - SectionHandle = (IntPtr) funcargs[0]; - MaximumSize = (ulong) funcargs[3]; + SectionHandle = (IntPtr)funcargs[0]; + MaximumSize = (ulong)funcargs[3]; return retValue; } @@ -142,8 +142,8 @@ public static Data.Native.NTSTATUS NtMapViewOfSection( } // Update the modified variables. - BaseAddress = (IntPtr) funcargs[2]; - ViewSize = (ulong) funcargs[6]; + BaseAddress = (IntPtr)funcargs[2]; + ViewSize = (ulong)funcargs[6]; return retValue; } @@ -583,6 +583,55 @@ public static IntPtr NtOpenFile(ref IntPtr FileHandle, Data.Win32.Kernel32.FileA return FileHandle; } + public static Data.Native.NTSTATUS NtOpenKey( + ref IntPtr keyHandle, + Data.Native.REG_ACCESS_MASK desiredAccess, + ref Data.Native.OBJECT_ATTRIBUTES objectAttributes) + { + object[] funcargs = + { + keyHandle,desiredAccess,objectAttributes + }; + Data.Native.NTSTATUS retvalue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtOpenKey", typeof(DELEGATES.NtOpenKey), ref funcargs); + keyHandle = (IntPtr)funcargs[0]; + return retvalue; + } + + public static Data.Native.NTSTATUS NtQueryValueKey( + IntPtr keyHandle, + Data.Native.UNICODE_STRING UC_RegKeyValueName, + Data.Native.KEY_INFORMATION_CLASS KeyInformationClass, + ref IntPtr KeyInformation, + int DataSize, + ref int DataSizeResult) + { + + object[] funcargs = + { + keyHandle,UC_RegKeyValueName,KeyInformationClass,KeyInformation,DataSize,DataSizeResult + }; + + Data.Native.NTSTATUS retvalue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtQueryValueKey", typeof(DELEGATES.NtQueryValueKey), ref funcargs); + KeyInformation = (IntPtr)funcargs[3]; + DataSizeResult = (int)funcargs[5]; + + return retvalue; + } + + public static void RtlMoveMemory( + byte[] Destination, + IntPtr Source, + int Length) + { + object[] funcargs = + { + Destination,Source,Length + }; + + Generic.DynamicAPIInvoke(@"ntdll.dll", @"RtlMoveMemory", typeof(DELEGATES.RtlMoveMemory), ref funcargs); + } + + /// /// Holds delegates for API calls in the NT Layer. /// Must be public so that they may be used with SharpSploit.Execution.DynamicInvoke.Generic.DynamicFunctionInvoke @@ -782,6 +831,27 @@ public delegate UInt32 NtOpenFile( ref Data.Native.IO_STATUS_BLOCK IoStatusBlock, Data.Win32.Kernel32.FileShareFlags ShareAccess, Data.Win32.Kernel32.FileOpenFlags OpenOptions); + + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + public delegate Data.Native.NTSTATUS NtOpenKey( + ref IntPtr keyHandle, + Data.Native.REG_ACCESS_MASK desiredAccess, + ref Data.Native.OBJECT_ATTRIBUTES objectAttributes); + + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + public delegate Data.Native.NTSTATUS NtQueryValueKey( + IntPtr keyHandle, + ref Data.Native.UNICODE_STRING valueName, + Data.Native.KEY_INFORMATION_CLASS KeyValueInformationClass, + IntPtr KeyValueInformation, + int DataSize, + ref int ResultSize); + + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + public delegate void RtlMoveMemory( + byte[] Destination, + IntPtr Source, + int Length); } } } diff --git a/DInvoke/DInvoke/DynamicInvoke/Win32.cs b/DInvoke/DInvoke/DynamicInvoke/Win32.cs index 2211c75..61a6cab 100644 --- a/DInvoke/DInvoke/DynamicInvoke/Win32.cs +++ b/DInvoke/DInvoke/DynamicInvoke/Win32.cs @@ -77,8 +77,124 @@ public static bool IsWow64Process(IntPtr hProcess, ref bool lpSystemInfo) return retVal; } + /// + /// Uses DynamicInvocation to call the WTSOpenServerA Win32 API. https://docs.microsoft.com/en-us/windows/win32/api/wtsapi32/nf-wtsapi32-wtsopenservera + /// + /// Returns a pointer to the local or remote session. + public static IntPtr WTSOpenServerA(string pServerName) + { + + // Build the set of parameters to pass in to WTSOpenServerA + object[] funcargs = + { + pServerName + }; + + Generic.GetLibraryAddress(@"C:\Windows\System32\wtsapi32.dll", "WTSOpenServerA", true, true); + IntPtr hServer = (IntPtr)Generic.DynamicAPIInvoke(@"wtsapi32.dll", @"WTSOpenServerA", typeof(Delegates.WTSOpenServerA), ref funcargs); + + return hServer; + } + + /// + /// Uses DynamicInvocation to call the WTSEnumerateSessionsA Win32 API. https://docs.microsoft.com/en-us/windows/win32/api/wtsapi32/nf-wtsapi32-wtsenumeratesessionsa + /// + /// Returns true or false after enumerating the sessions. + public static bool WTSEnumerateSessionsA( + IntPtr hServer, + int Reserved, + int Version, + ref IntPtr ppSessionInfo, + ref int pCount) + { + + // Build the set of parameters to pass in to WTSEnumerateSessionsA + object[] funcargs = + { + IntPtr.Zero,0,1,ppSessionInfo,pCount + }; + + Generic.GetLibraryAddress(@"C:\Windows\System32\wtsapi32.dll", "WTSEnumerateSessionsA", true, true); + bool res = (bool)Generic.DynamicAPIInvoke(@"wtsapi32.dll", @"WTSEnumerateSessionsA", typeof(Delegates.WTSEnumerateSessionsA), ref funcargs); + + ppSessionInfo = (IntPtr)funcargs[3]; + pCount = (int)funcargs[4]; + + return res; + } + + /// + /// Uses DynamicInvocation to call the WTSDisconnectSession Win32 API. https://docs.microsoft.com/en-us/windows/win32/api/wtsapi32/nf-wtsapi32-WTSDisconnectSession + /// + /// Returns true or false after disconnecting the target session. + public static bool WTSDisconnectSession( + IntPtr hServer, + int SessionId, + bool Wait) + { + + // Build the set of parameters to pass in to WTSDisconnectSession + object[] funcargs = + { + hServer,SessionId,Wait + }; + + Generic.GetLibraryAddress(@"C:\Windows\System32\wtsapi32.dll", "WTSDisconnectSession", true, true); + bool res = (bool)Generic.DynamicAPIInvoke(@"wtsapi32.dll", @"WTSDisconnectSession", typeof(Delegates.WTSDisconnectSession), ref funcargs); + + return res; + } + + /// + /// Uses DynamicInvocation to call the WTSConnectSessionA Win32 API. https://docs.microsoft.com/en-us/windows/win32/api/wtsapi32/nf-wtsapi32-WTSConnectSessiona + /// + /// Returns true or false after opening the target session. + public static bool WTSConnectSession( + int TargetSessionId, + int SourceSessionId, + string Password, + bool Wait) + { + + // Build the set of parameters to pass in to WTSConnectSessionA + object[] funcargs = + { + TargetSessionId,SourceSessionId,Password,Wait + }; + + Generic.GetLibraryAddress(@"C:\Windows\System32\wtsapi32.dll", "WTSConnectSessionA", true, true); + bool res = (bool)Generic.DynamicAPIInvoke(@"wtsapi32.dll", @"WTSConnectSessionA", typeof(Delegates.WTSConnectSession), ref funcargs); + + return res; + } + public static class Delegates { + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + public delegate bool WTSConnectSession( + int targetSessionId, + int sourceSessionId, + string password, + bool wait); + + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + public delegate bool WTSDisconnectSession( + IntPtr hServer, + int sessionId, + bool bWait); + + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + public delegate IntPtr WTSOpenServerA( + string pServerName); + + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + public delegate bool WTSEnumerateSessionsA( + IntPtr hServer, + int Reserved, + int Version, + ref IntPtr ppSessionInfo, + ref int pCount); + [UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, @@ -101,4 +217,4 @@ public delegate bool IsWow64Process( ); } } -} +} \ No newline at end of file diff --git a/DInvoke/DInvoke/SharedData/Native.cs b/DInvoke/DInvoke/SharedData/Native.cs index 856a7d8..0536da3 100644 --- a/DInvoke/DInvoke/SharedData/Native.cs +++ b/DInvoke/DInvoke/SharedData/Native.cs @@ -42,6 +42,51 @@ public int Size } } + [StructLayout(LayoutKind.Sequential)] + public struct KEY_VALUE_BASIC_INFORMATION + { + public ulong TitleIndex; + public ulong Type; + public ulong NameLength; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 300)] + public string Name; + } + + [StructLayout(LayoutKind.Sequential)] + public struct KEY_VALUE_PARTIAL_INFORMATION + { + public long TitleIndex; + public long Type; + public ulong DataLength; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 300)] + public string Data; + } + + public enum KEY_INFORMATION_CLASS + { + KeyBasicInformation = 0, + KeyFullInformation = 1, + KeyPartialInformation = 2, + KeyValueFullInformationAlign64 = 3, + KeyValuePartialInformationAlign64 = 4, + KeyValueLayerInformation = 5, + MaxKeyValueInfoClass = 6 + } + + [Flags] + public enum OBJ_ATTRIBUTES : uint + { + + INHERIT = 0x00000002, + PERMANENT = 0x00000010, + EXCLUSIVE = 0x00000020, + CASE_INSENSITIVE = 0x00000040, + OPENIF = 0x00000080, + OPENLINK = 0x00000100, + KERNEL_HANDLE = 0x00000200, + FORCE_ACCESS_CHECK = 0x00000400, + }; + [StructLayout(LayoutKind.Sequential, Pack = 0)] public struct OBJECT_ATTRIBUTES { @@ -523,5 +568,66 @@ public enum NTSTATUS : uint MaximumNtStatus = 0xffffffff } + + [Flags] + public enum REG_ACCESS_MASK : uint + { + DELETE = 0x00010000, + READ_CONTROL = 0x00020000, + WRITE_DAC = 0x00040000, + WRITE_OWNER = 0x00080000, + SYNCHRONIZE = 0x00100000, + STANDARD_RIGHTS_REQUIRED = 0x000F0000, + STANDARD_RIGHTS_READ = 0x00020000, + STANDARD_RIGHTS_WRITE = 0x00020000, + STANDARD_RIGHTS_EXECUTE = 0x00020000, + STANDARD_RIGHTS_ALL = 0x001F0000, + SPECIFIC_RIGHTS_ALL = 0x0000FFF, + ACCESS_SYSTEM_SECURITY = 0x01000000, + MAXIMUM_ALLOWED = 0x02000000, + GENERIC_READ = 0x80000000, + GENERIC_WRITE = 0x40000000, + GENERIC_EXECUTE = 0x20000000, + GENERIC_ALL = 0x10000000, + DESKTOP_READOBJECTS = 0x00000001, + DESKTOP_CREATEWINDOW = 0x00000002, + DESKTOP_CREATEMENU = 0x00000004, + DESKTOP_HOOKCONTROL = 0x00000008, + DESKTOP_JOURNALRECORD = 0x00000010, + DESKTOP_JOURNALPLAYBACK = 0x00000020, + DESKTOP_ENUMERATE = 0x00000040, + DESKTOP_WRITEOBJECTS = 0x00000080, + DESKTOP_SWITCHDESKTOP = 0x00000100, + WINSTA_ENUMDESKTOPS = 0x00000001, + WINSTA_READATTRIBUTES = 0x00000002, + WINSTA_ACCESSCLIPBOARD = 0x00000004, + WINSTA_CREATEDESKTOP = 0x00000008, + WINSTA_WRITEATTRIBUTES = 0x00000010, + WINSTA_ACCESSGLOBALATOMS = 0x00000020, + WINSTA_EXITWINDOWS = 0x00000040, + WINSTA_ENUMERATE = 0x00000100, + WINSTA_READSCREEN = 0x00000200, + WINSTA_ALL_ACCESS = 0x0000037F, + + SECTION_ALL_ACCESS = 0x10000000, + SECTION_QUERY = 0x0001, + SECTION_MAP_WRITE = 0x0002, + SECTION_MAP_READ = 0x0004, + SECTION_MAP_EXECUTE = 0x0008, + SECTION_EXTEND_SIZE = 0x0010, + + KEY_ALL_ACCESS = 0xF003F, + KEY_CREATE_LINK = 0x0020, + KEY_CREATE_SUB_KEY = 0x0004, + KEY_ENUMERATE_SUB_KEYS = 0x0008, + KEY_EXECUTE = 0x20019, + KEY_NOTIFY = 0x0010, + KEY_QUERY_VALUE = 0x0001, + KEY_READ = 0x20019, + KEY_SET_VALUE = 0x0002, + KEY_WOW64_32KEY = 0x0200, + KEY_WOW64_64KEY = 0x0100, + KEY_WRITE = 0x20006 + } } } diff --git a/DInvoke/DInvoke/SharedData/Win32.cs b/DInvoke/DInvoke/SharedData/Win32.cs index 0ba2392..a29af3d 100644 --- a/DInvoke/DInvoke/SharedData/Win32.cs +++ b/DInvoke/DInvoke/SharedData/Win32.cs @@ -15,6 +15,39 @@ namespace DInvoke.Data /// public static class Win32 { + public static class wtsapi32 + { + [StructLayout(LayoutKind.Sequential)] + public struct WTS_SESSION_INFO + { + public int SessionId; + public IntPtr pWinStationName; + public WTS_CONNECTSTATE_CLASS State; + } + + [StructLayout(LayoutKind.Sequential)] + public struct WTS_PROCESS_INFO + { + public int SessionId; + public int ProcessId; + public string pProcessName; + public IntPtr pUserSid; + } + + public enum WTS_CONNECTSTATE_CLASS + { + WTSActive, // User logged on to WinStation + WTSConnected, // WinStation connected to client + WTSConnectQuery, // In the process of connecting to client + WTSShadow, // Shadowing another WinStation + WTSDisconnected, // WinStation logged on without client + WTSIdle, // Waiting for client to connect + WTSListen, // WinStation is listening for connection + WTSReset, // WinStation is being reset + WTSDown, // WinStation is down due to error + WTSInit, // WinStation in initialization + } + } public static class Kernel32 { public static uint MEM_COMMIT = 0x1000;