# tl;dr This short post shows a PoC port of https://www.netero1010-securitylab.com/eavsion/alternative-process-injection to Nim. Code available on https://github.com/zimnyaa/nim-noload-dll-hollowing I suggest you read the description above before proceeding, but it is not strictly necessary. # part i. module scanner First, I ported the injectable module scanner from C# to Nim. Here's how it works (in general): ```j load process -> sleep(2000) -> enumerate module information ... load process -> ^ sleep(2000) -> find a module to scan -> | inject -> sleep(2000) -> | check if process is alive -> | if so, mark module as injectable \ | | \_____________________________________________/ ``` This process allows obtaining a list of modules that can be overwritten without crashing the process (at least in the first two seconds). You are also limited in the size of the shellcode you can inject (by the size of the module), so the scanner outputs that as well. The shellcode used for testing is `messagebox` from `msfvenom`. The tool's usage is pretty straightforward: ![[module_splwow.gif]] # part ii. injecting After you have a way to determine where the .text section of your chosen module is located, you can use an arbitrary injection technique. Adapting it is pretty easy, for example: ```j VirtualAllocEx -> NtWriteVirtualMemory -> CreateRemoteThread becomes find module base -> VirtualProtectEx -> CreateRemoteThread ``` For testing purposes, I have used Nim process injection code by @ajpc500 (https://github.com/ajpc500/NimExamples) as a baseline. The only thing changed is finding and injecting to an unused module: >```nim ># finding the unused module base echo("[+] enumerating modules") EnumProcessModules(pHandle, &modulebuf[0], cb, &req) var mod_count: int = req div sizeof(HMODULE) echo("[+] iterating over modules") echo fmt"[?] total {mod_count} modules found" for i in 1..mod_count: > if GetModuleFileNameEx(pHandle, modulebuf[i], &mod_name[0], cast[DWORD](sizeof(mod_name))): > if "msvcp_win.dll" in toString(mod_name): > echo("[*] found module") > if GetModuleInformation(pHandle, modulebuf[i], &testmodinfo, cast[DWORD](sizeof(MODULEINFO))): > base_addr = cast[LPVOID](cast[int64](testmodinfo.lpBaseOfDll) + 4096) > echo fmt" module entrypoint {toHex(cast[int64](base_addr))}" >``` After that, it's just: ```j NtProtectVirtualMemory(RW) -> NtWriteVirtualMemory -> NtProtectVirtualMemory(RX) -> NtCreateThreadEx ``` # iocs Memory scanning still shows that the section was modified: >![[Pasted image 20220111183034.png]] >`moneta` scan of the victim process hollows-hunter only does so with `/hooks`: >![[Pasted image 20220323162908.png]] >hollows-hunter results > *note:* further OPSEC improvements (that may come in the future) include: > - shellcode encryption > - NimlineWhispers2 --randomize or denim for building > - writing shellcode in chunks with delays > - anti-sandbox checks # credits @[netero-1010](https://github.com/netero1010) for the original technique @[ajpc500](https://github.com/ajpc500), @[khchen](https://github.com/khchen) and @[byt3bl33d3r](https://github.com/byt3bl33d3r) for the amazing work on Nim Windows interfacing and offensive tradecraft (I bet you guys are credited on any Nim-related blogpost)