When it comes to hide their Identity, hooking probably the
popular way adopted by rootkits to camouflage them on the system. By adopting these
techniques rootkits hide a process, hide a network port, and redirect file writes
and many more.
More specifically Hooking is the process of intercepting a
program’s execution at a specific point in order to take another action. This
may be simply to trace execution at interesting points, or to redirect and
modify execution. At the point at which you wish to intercept, you place your
hook.
Here our focus will be on DLL Injections(User
Mode) because these assist hooking activities to inject and execute malicious
code.
As we know in Windows (and most modern
operating systems), there is a distinction between code that is running in
"user mode", and code that is running in "kernel mode",so
on this line Hooking process is divided into two categories
Hooking
techniques
User
Mode Kernel Mode
DLL Injections
DLL injection is the process of inserting code
into a running process. The code we usually insert is in the form of a DLL (Dynamic
Link Library) file,
since DLLs are meant to be loaded as needed at run time. However this doesn't
mean we cannot inject assembly in any other form
At the same time it is important to notice that
you'll need to have an appropriate level of privileges on the system to start
playing with other program's memory.
Windows API offers a number of functions that
allow us to attach and manipulate into other programs for debugging purposes.
We'll use following methods to perform our DLL Injection.
a)Registry:
In order
to inject a DLL into processes that link with USER32.DLL, you simply can add
the DLL name to the value of the following registry key:
HKEY_LOCAL_MACHINE\Software\Microsoft\WindowNT\CurrentVersion\Windows\AppInit_DLLs
The AppInit_DLLs infrastructure provides an easy
way to hook system APIs by allowing custom DLLs to be loaded into the address
space of every interactive application.
The above registry key has an entry for a set of
DLLs which are loaded in the process memory when the process loads User32.dll.
Many malwares try to add their malicious DLLs in the list by modifying the
registry key. As almost every user-mode interactive process imports User32.dll,
it definitely has a wider existence. Also, the value of the key LOADAPPINIT_DLL
should be 1 to allow User32.dll to globally enable the APPINIT_DLL key.
From Windows 7 onwards, a new code-signing
requirement is enforced. Developers must code-sign their DLLs if it has to be
included in the list so that users can trust the application. To further add
protection, Windows 8 has adopted secure boot mechanism. If the OS is secure
boot enabled, APPInit_DLLs mechanism is disabled as part of a no-compromise
approach. According to Microsoft, the AppInit_DLLs mechanism is not a
recommended approach for legitimate applications because it can lead to system
deadlocks and performance problems.
b) SetWindowsHookEx
It is popular
technique for injecting DLL into a targeted process relies on provided by
Windows Hooks. As mentioned in MSDN a hook is a trap in the system
message-handling mechanism. An application can install a custom filter function
to monitor the message traffic in the system and process certain types of
messages before they reach the target window procedure.
A hook is
normally implemented in a DLL in order to meet the basic requirement for
system-wide hooks. The basic concept of that sort of hooks is that the hook
callback procedure is executed in the address spaces of each hooked up process
in the system. To install a hook you call SetWindowsHookEx() with the appropriate parameters.
Once the application installs a system-wide hook, the operating system maps the
DLL into the address space in each of its client processes. Therefore global
variables within the DLL will be "per-process" and cannot be shared
among the processes that have loaded the hook DLL. All variables that contain
shared data must be placed in a shared data section. The diagram bellow shows
an example of a hook registered by Hook Server and injected into the address
spaces named "Application one" and "Application two".
.
c) CreateRemoteThread
The CreateRemoteThread function creates a thread
in the virtual address space of an arbitrary process. It can be used to inject
a custom DLL in the process memory of a remote process.
Following steps are followed in this approach:
1. Call OpenProcess function to get a handle of the target process. In parameters to the function, specify all process access permissions so that the local process is privileged enough to perform write operations later. If we fail to open process with the specified permissions, then there is no point of proceeding further because it will fail.
2. Get the address of Kernel32.LoadLibraryA method using GetProcAddress. Why we need this address you would realise later in step 5.
3. Allocate some memory inside target process’s address space using VirtualAllocEx. The memory size should be enough to store the full path string of the DLL to be injected.
4. Write argument to LoadLibrary to the process’s newly allocated memory using WriteProcessMemory function. In arguments we pass the full path string of DLL. The string has to be written in the target process memory because it can’t access a string in memory of some different process using a pointer.
5. Finally call CreateRemoteThread function with address of LoadLibrary function and the DLL string. This will result in a call to LoadLibrary method in the target process and hence load our DLL successfully. An interesting fact which can be observed here is that this method luckily works because LoadLibrary needs only one argument, and only those methods which have one argument can be called through CreateRemoteThread.
1. Call OpenProcess function to get a handle of the target process. In parameters to the function, specify all process access permissions so that the local process is privileged enough to perform write operations later. If we fail to open process with the specified permissions, then there is no point of proceeding further because it will fail.
2. Get the address of Kernel32.LoadLibraryA method using GetProcAddress. Why we need this address you would realise later in step 5.
3. Allocate some memory inside target process’s address space using VirtualAllocEx. The memory size should be enough to store the full path string of the DLL to be injected.
4. Write argument to LoadLibrary to the process’s newly allocated memory using WriteProcessMemory function. In arguments we pass the full path string of DLL. The string has to be written in the target process memory because it can’t access a string in memory of some different process using a pointer.
5. Finally call CreateRemoteThread function with address of LoadLibrary function and the DLL string. This will result in a call to LoadLibrary method in the target process and hence load our DLL successfully. An interesting fact which can be observed here is that this method luckily works because LoadLibrary needs only one argument, and only those methods which have one argument can be called through CreateRemoteThread.
Windows 7 onwards Session Separation technique is
being used to limit CreateRemoteThread hooking method. It ensures that core
system processes including services always run in session 0 while all user
process’s run in different sessions. However, NtCreateThreadEx API has come to
rescue as it allows any process to inject DLL into any other process
irrespective of session in which it is running as long as it has sufficient
privileges..
IAT Hooking
Import Address Table (IAT) is an array of links
representing the various DLLs imported by the PE loader during process
initiation. IAT hooking is a technique of modifying the address of a particular
DLL in the IAT with address of hook function. Before performing IAT hooking we
must make sure that we are able to put the hook function in the user’s address
space through any of the DLL injection methods. IAT hooking will not be
useful to us if the target program performs run-tie dynamic linking through
LoadLibrary and GetProcAddress APIs to get the real address of each DLL
functions. To get around this, hooking the GetProcAddress function would be the
only solution but it will be a much tougher job.
Inline Hooking
Inline Hooking is mostly seen in userland process
than kernel mode processes. Typically, an inline function hook is implemented
by overwriting the beginning of target function with an unconditional jump to a
Detour function. Detour function calls a Trampoline function, which contains
the overwritten bytes of the original target function, and then calls the
target function. The target function returns to the detour function which finally
gives control back to the source function. This whole process would appear more
clear from the diagram below.
Inline hooking is easy in XP because any function
prologue in XP is 5 bytes, and jump instruction also requires 5 bytes (1 byte
for JMP’s opcode and 4 bytes for address.)
0 comments:
Post a Comment