Securexpo CTF 2024
·4 mins
Table of Contents
DLL Injection Challenge #
Challenge Overview #
- We were given a DLL named
InjecttMe.dll
and tasked with injecting it into a running process. - DLL injection is a technique where code is loaded into a running process to execute actions or manipulate the process. It’s commonly used in both legitimate applications and malware.
Walkthrough #
- Inject the provided DLL into a process using the Windows API, specifically
LoadLibraryA()
function. You can read more about it here
Housekeeping #
#include <windows.h>
#include <iostream>
- We include the Windows API header file with
#include <windows.h>
, which provides declarations for functions, macros, constants, and data structures used to interact with the Windows operating system. - We then include the standard C++ input/output stream library.
InjectDLLIntoCurrentProcess function #
- We are going to write a function that is going to inject the provided dll into the current process.
bool InjectDLLIntoCurrentProcess(const char* dllPath) {
HMODULE hDll = LoadLibraryA(dllPath);
if (hDll == NULL) {
std::cerr << "Failed to load DLL. Error code: " << GetLastError() << std::endl;
return false;
}
std::cout << "DLL successfully injected into current process." << std::endl;
return true;
}
Function Breakdown #
bool InjectDLLIntoCurrentProcess(const char* dllPath)
- We created function named
InjectDLLIntoCurrentProcess
that will take in thedllPath
as the argument. The function returns a boolean value.
HMODULE hDll = LoadLibraryA(dllPath);
- The line above loads the specified DLL (given by dllPath) into the memory of the current process and returns a handle
hDll
to the loaded module.
if (hDll == NULL) {
std::cerr << "Failed to load DLL. Error code: " << GetLastError() << std::endl;
return false;
}
std::cout << "DLL successfully injected into current process." << std::endl;
return true;
- If
LoadLibraryA()
fails, it returns NULL so ifhDll
containsNULL
as the value, we useGetLastError()
(another Windows API function) to retrieve the error code, helping us identify why the DLL failed to load (e.g., invalid path, permission issues) and print it out on standard error stream. We finally returnfalse
- If the DLL was successfully loaded, we pint on standard out
DLL successfully injected into current process
and returntrue
.
main function #
- We then write a
main
function.
int main() {
// Path to the target DLL
const char* dllPath = "C:\\Users\\Munene\\Desktop\\InjectMe.dll";
// Try to inject the DLL
if (InjectDLLIntoCurrentProcess(dllPath)) {
std::cout << "DLL loaded. Mission accomplished." << std::endl;
} else {
std::cerr << "Operation failed. Injection not completed." << std::endl;
return 1;
}
return 0;
}
Function Breakdown #
const char* dllPath = "C:\\Users\\Munene\\Desktop\\InjectMe.dll";
- This line defines a file path pointing to the InjectMe.dll file located on my desktop. You can place the DLL wherever you wish provided you provided the correct path.
if (InjectDLLIntoCurrentProcess(dllPath)) {
std::cout << "DLL loaded. Mission accomplished." << std::endl;
} else {
std::cerr << "Operation failed. Injection not completed." << std::endl;
return 1;
}
- This code checks if the function
InjectDLLIntoCurrentProcess(dllPath)
succeeds in injecting a DLL. If successful, it printsDLL loaded. Mission accomplished.
to the standard output. If it fails, it logs an error message,Operation failed. Injection not completed.
to the error stream and returns1
to indicate failure. - The main function then returns 0.
Putting Everything Together #
#include <windows.h>
#include <iostream>
// Function to inject the DLL into the current process
bool InjectDLLIntoCurrentProcess(const char* dllPath) {
HMODULE hDll = LoadLibraryA(dllPath);
if (hDll == NULL) {
std::cerr << "Failed to load DLL. Error code: " << GetLastError() << std::endl;
return false;
}
std::cout << "DLL successfully injected into current process." << std::endl;
return true;
}
int main() {
// Path to the target DLL
const char* dllPath = "C:\\Users\\Munene\\Desktop\\InjectMe.dll";
// Try to inject the DLL
if (InjectDLLIntoCurrentProcess(dllPath)) {
std::cout << "DLL loaded. Mission accomplished." << std::endl;
} else {
std::cerr << "Operation failed. Injection not completed." << std::endl;
return 1;
}
return 0;
}
Execution #
- We then compile the program and run it which gives us the flag!
Flag: flag{hey_there_did_you_inject_opr_reverse}
- Happy hacking!