Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DLL Injection with CreateRemoteThread

Tags:

If you take a look at the following working code of a simple DLL injection:

  //Open the target process with read , write and execute priviledges    Process = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_READ|PROCESS_VM_WRITE|PROCESS_VM_OPERATION, FALSE, ID);      //Get the address of LoadLibraryA    LoadLibrary = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");      // Allocate space in the process for our DLL     Memory = (LPVOID)VirtualAllocEx(Process, NULL, strlen(dll)+1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);      // Write the string name of our DLL in the memory allocated     WriteProcessMemory(Process, (LPVOID)Memory, dll, strlen(dll)+1, NULL);      // Load our DLL     CreateRemoteThread(Process, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibrary, (LPVOID)Memory, NULL, NULL);      //Let the program regain control of itself    CloseHandle(Process);  

The thing confuses me is that GetProcAddress returns the LoadLibraryA fucntion address of the current process, how can you pass it as a parameter to CreateRemoteThread and expect the target process to run it?

like image 551
James King Avatar asked Mar 30 '14 21:03

James King


People also ask

What is CreateRemoteThread?

The CreateRemoteThread function causes a new thread of execution to begin in the address space of the specified process. The thread has access to all objects that the process opens. Prior to Windows 8, Terminal Services isolates each terminal session by design.

How is DLL injected?

DLL injection is a method of executing arbitrary code in the address space of a separate live process. DLL injection is commonly performed by writing the path to a DLL in the virtual address space of the target process before loading the DLL by invoking a new thread.

What can you do with DLL injection?

In computer programming, DLL injection is a technique used for running code within the address space of another process by forcing it to load a dynamic-link library. DLL injection is often used by external programs to influence the behavior of another program in a way its authors did not anticipate or intend.

Can DLL injection be detected?

And finally, Reflective DLL Injection uses custom function that can easily avoid detection. However at DEF CON 20 Andrew King demonstrated that he was able to detect DLL's injected using reflective DLL injection. His presentation was called "Detecting Reflective Injection".


2 Answers

It works by accident. It is a very common accident, Microsoft makes a great deal of effort to ensure that the operating system DLLs, like kernel32.dll, have a base address that doesn't conflict with any other DLLs. Further enhanced by kernel32.dll getting loaded very early at process initialization so low odds that it has to fight to get its preferred base address.

You'll get away with easily. It is notable that this has gone wrong in the past, there was an XP security update oops that caused gdi32.dll to get relocated and made lots of machines fall over at boot. The correct way is fairly painful, CreateToolhelp32Snapshot() + Module32First/Next() to find the relocation offset isn't great joy. Frankly, you probably ought to not do this at all if the operating system is "weird" like that.

like image 141
Hans Passant Avatar answered Sep 16 '22 15:09

Hans Passant


Address Space Layout Randomisation (ASLR) is an anti-exploit mitigation feature handled by Windows, and it allows address relocation to help prevent attackers from determining the address for exploitation of something in memory (stops hard-coding of addresses/offsets). However, Windows modules only change their addresses per session.

If you have a process which uses kernel32.dll (not all processes use kernel32.dll and I'll explain this further in a few minutes), the address to a routine might be 55AA1122 as an example (that's an invalid example address). Now, the next process with kernel32.dll, will have the same address for 55AA1122 for the same routine as the previous.... Only if the processes are both of the same architecture.

32-bit processes will have the same addresses for kernel32.dll exports, among other Windows module exports too (e.g. NTDLL, USER32, etc.). 64-bit processes will have different addresses to the 32-bit processes, however the 64-bit processes will all have the same addresses for the Windows modules, too!

Remote thread creation was not an "accident", Microsoft intentionally implemented it. Why? Microsoft use it a lot during Windows themselves, also for Asynchronous Procedure Calls. Microsoft also hot-patch things often for their own routines as an anti-reversing trick, or if they lose the source code to their own projects, haha.

Now regarding kernel32.dll being loaded into a process, it is only loaded into processes which use the Win32 API. This includes 99% of programs in the world, however it is possible to compile a native process which will not use it. This will however force you to use Native API and no Win32 API completely, and a Windows process called smss.exe does exactly this. You can also compile Native DLLs which don't even have a normal Win32 API DLL Entry routine.

To put it short, the addresses for Windows module routines change once per boot. It'll maintain the same until the next reboot, and so on. 32-bit processes have their own shared addresses of Windows modules for each process, as does 64-bit processes. Therefore, you cannot use LoadLibraryA address of a 64-bit process whilst targeting DLL injection for a 32-bit process, unless you use the 32-bit Kernel32.dll LoadLibraryA address. A better idea would be to use LdrLoadDll anyway, or just shell-code injection of a reflective DLL loader stub.

like image 35
PspSetProcessPpmPolicy Avatar answered Sep 16 '22 15:09

PspSetProcessPpmPolicy