https://github.com/byt3bl33d3r/OffensiveNim Skip to content Toggle navigation Sign up * Product + Actions Automate any workflow + Packages Host and manage packages + Security Find and fix vulnerabilities + Codespaces Instant dev environments + Copilot Write better code with AI + Code review Manage code changes + Issues Plan and track work + Discussions Collaborate outside of code + Explore + All features + Documentation + GitHub Skills + Blog * Solutions + For + Enterprise + Teams + Startups + Education + By Solution + CI/CD & Automation + DevOps + DevSecOps + Case Studies + Customer Stories + Resources * Open Source + GitHub Sponsors Fund open source developers + The ReadME Project GitHub community articles + Repositories + Topics + Trending + Collections * Pricing [ ] * # In this repository All GitHub | Jump to | * No suggested jump to results * # In this repository All GitHub | Jump to | * # In this user All GitHub | Jump to | * # In this repository All GitHub | Jump to | Sign in Sign up {{ message }} byt3bl33d3r / OffensiveNim Public * Notifications * Fork 270 * Star 2.1k My experiments in weaponizing Nim (https://nim-lang.org/) License BSD-2-Clause license 2.1k stars 270 forks Star Notifications * Code * Issues 8 * Pull requests 1 * Actions * Projects 0 * Security * Insights More * Code * Issues * Pull requests * Actions * Projects * Security * Insights byt3bl33d3r/OffensiveNim This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository. master Switch branches/tags [ ] Branches Tags Could not load branches Nothing to show {{ refName }} default View all branches Could not load tags Nothing to show {{ refName }} default View all tags Name already in use A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch? Cancel Create 1 branch 0 tags Code * Local * Codespaces * Clone HTTPS GitHub CLI [https://github.com/b] Use Git or checkout with SVN using the web URL. [gh repo clone byt3bl] Work fast with our official CLI. Learn more. * Open with GitHub Desktop * Download ZIP Sign In Required Please sign in to use Codespaces. Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Launching Xcode If nothing happens, download Xcode and try again. Launching Visual Studio Code Your codespace will open once ready. There was a problem preparing your codespace, please try again. Latest commit @byt3bl33d3r byt3bl33d3r Merge pull request #55 from HuskyHacks/master ... 39dda69 Dec 13, 2022 Merge pull request #55 from HuskyHacks/master Simple Anti-analysis IsDebuggerPresent POC 39dda69 Git stats * 120 commits Files Permalink Failed to load latest commit information. Type Name Latest commit message Commit time .devcontainer Added sandbox_process_bin.nim example and added .devcontainer Feb 6, 2022 bin Initial commit Nov 9, 2020 rsrc Added embed_rsrc_bin.nim Apr 12, 2021 src changing comment filename Nov 28, 2022 wip Added more examples Dec 21, 2020 .gitignore Initial commit Nov 9, 2020 LICENSE Added license Nov 22, 2020 Makefile Added Powershell Execution Example Mar 22, 2021 README.md adding anti-analysis POC and README Nov 28, 2022 README_CN.md Update README_CN.md Jan 1, 2021 View code [ ] OffensiveNim Table of Contents Why Nim? Examples in this repo that work Examples that are a WIP Compiling the examples in this repo Easy Way (Recommended) Hard way (For the bold) Cross Compiling Interfacing with C/C++ Creating Windows DLLs with an exported DllMain Creating XLLs Optimizing executables for size Reflectively Loading Nim Executables Executable size difference when using the Winim library vs without Opsec Considerations Converting C code to Nim Language Bridges Debugging Setting up a dev environment Pitfalls I found myself falling into Interesting Nim libraries Nim for implant dev links Contributors README.md OffensiveNim OffensiveNim My experiments in weaponizing Nim for implant development and general offensive operations. Table of Contents * OffensiveNim + Why Nim? + Examples in this repo + Compiling the examples o Easy Way (Recommended) o Hard Way (For the Bold) + Cross Compiling + Interfacing with C/C++ + Creating Windows DLLs with an exported DllMain + Optimizing executables for size + Reflectively Loading Nim Executables + Executable size difference with the Winim Library + Opsec Considirations + Converting C Code to Nim + Language Bridges + Debugging + Setting up a dev environment + Pitfalls I found myself falling into + Interesting Nim Libraries + Nim for Implant Dev Links + Contributors Why Nim? * Compiles directly to C, C++, Objective-C and Javascript. * Since it doesn't rely on a VM/runtime does not produce what I like to call "T H I C C malwarez" as supposed to other languages (e.g. Golang) * Python inspired syntax, allows rapid native payload creation & prototyping. * Has extremely mature FFI (Foreign Function Interface) capabilities. * Avoids making you actually write in C/C++ and subsequently avoids introducing a lot of security issues into your software. * Super easy cross compilation to Windows from *nix/MacOS, only requires you to install the mingw toolchain and passing a single flag to the nim compiler. * The Nim compiler and the generated executables support all major platforms like Windows, Linux, BSD and macOS. Can even compile to Nintendo switch , IOS & Android. See the cross-compilation section in the Nim compiler usage guide * You could technically write your implant and c2 backend both in Nim as you can compile your code directly to Javascript. Even has some initial support for WebAssembly's Examples in this repo that work File Description pop_bin.nim Call MessageBox WinApi without using the Winim library pop_winim_bin.nim Call MessageBox with the Winim libary pop_winim_lib.nim Example of creating a Windows DLL with an exported DllMain Hosts the CLR, reflectively execute_assembly_bin.nim executes .NET assemblies from memory Hosts the CLR by directly clr_host_cpp_embed_bin.nim embedding C++ code, executes a .NET assembly from disk Shows how to quickly weaponize scshell_c_embed_bin.nim existing C code by embedding SCShell (C) directly within Nim fltmc_bin.nim Enumerates all Minifilter drivers Creates a suspended process blockdlls_acg_ppid_spoof_bin.nim that spoofs its PPID to explorer.exe, also enables BlockDLLs and ACG named_pipe_client_bin.nim Named Pipe Client named_pipe_server_bin.nim Named Pipe Server Embeds a resource (zip file) embed_rsrc_bin.nim at compile time and extracts contents at runtime A way to delete a locked or self_delete_bin.nim current running executable on disk. Method discovered by @jonasLyk Encryption/Decryption using encrypt_decrypt_bin.nim AES256 (CTR Mode) using the Nimcrypto library amsi_patch_bin.nim Patches AMSI out of the current process Patches the AMSI Provider DLL amsi_providerpatch_bin.nim (in this case MpOav.dll) to bypass AMSI. Published here etw_patch_bin.nim Patches ETW out of the current process (Contributed by ) wmiquery_bin.nim Queries running processes and installed AVs using using WMI Compresses, Base-64 encodes and outputs PowerShell code to out_compressed_dll_bin.nim load a managed dll in memory. Port of the orignal PowerSploit script to Nim. POC to locally inject dynamic_shellcode_local_inject_bin.nim shellcode recovered dynamically instead of hardcoding it in an array. shellcode_callback_bin.nim Executes shellcode using Callback functions Creates a suspended process and injects shellcode with VirtualAllocEx/ shellcode_bin.nim CreateRemoteThread. Also demonstrates the usage of compile time definitions to detect arch, os etc.. shellcode_fiber.nim Shellcode execution via fibers shellcode_inline_asm_bin.nim Executes shellcode using inline assembly syscalls_bin.nim Shows how to make direct system calls Hosts the CLR & executes execute_powershell_bin.nim PowerShell through an un-managed runspace Log password changes to a file passfilter_lib.nim by (ab)using a password complexity filter minidump_bin.nim Creates a memory dump of lsass using MiniDumpWriteDump http_request_bin.nim Demonstrates a couple of ways of making HTTP requests execute_sct_bin.nim .sct file Execution via GetObject() Dynamically execute VBScript scriptcontrol_bin.nim and JScript using the MSScriptControl COM object excel_com_bin.nim Injects shellcode using the Excel COM object and Macros keylogger_bin.nim Keylogger using SetWindowsHookEx Use memfd_create syscall to memfd_python_interpreter_bin.nim load a binary into an anonymous file and execute it with execve syscall. Plants shellcode from UUID array into heap space and uses uuid_exec_bin.nim EnumSystemLocalesA Callback in order to execute the shellcode. Unhooks ntdll.dll to evade EDR unhookc.nim /AV hooks (embeds the C code template from ired.team) Unhooks ntdll.dll to evade EDR unhook.nim /AV hooks (pure nim implementation) Uses Extra Window Memory Injection via Running taskbar_ewmi_bin.nim Application property of TaskBar in order to execute the shellcode. (ab)uses Window's implementation of fork() and acquires a handle to a remote process using the fork_dump_bin.nim PROCESS_CREATE_PROCESS access right. It then attempts to dump the forked processes memory using MiniDumpWriteDump () ldap_query_bin.nim Perform LDAP queries via COM by using ADO's ADSI provider This sandboxes a process by setting it's integrity level sandbox_process_bin.nim to Untrusted and strips important tokens. This can be used to "silently disable" a PPL process (e.g. AV/EDR) Use NetShareEnum to list the list_remote_shares.nim share accessible by the current user chrome_dump_bin.nim Read and decrypt cookies from Chrome's sqlite database suspended_thread_injection.nim Shellcode execution via suspended thread injection dns_exfiltrate.nim Simple DNS exfiltration via TXT record queries Execute shellcode embedded in rsrc_section_shellcode.nim the .rsrc section of the binary token_steal_cmd.nim Steal a token/impersonate and then run a command anti_analysis_isdebuggerpresent.nim Simple anti-analysis that checks for a debugger Examples that are a WIP File Description amsi_patch_2_bin.nim Patches AMSI out of the current process using a different method (WIP, help appreciated) excel_4_com_bin.nim Injects shellcode using the Excel COM object and Excel 4 Macros (WIP) Compiling the examples in this repo This repository does not provide binaries, you're gonna have to compile them yourself. This repo was setup to cross-compile the example Nim source files to Windows from Linux or MacOS. Easy Way (Recommended) Use VSCode Devcontainers to automatically setup a development environment for you (See the Setting Up a Dev Environment section). Once that's done simply run make. Hard way (For the bold) Install Nim using your systems package manager (for Windows use the installer on the official website) * brew install nim * apt install nim * choco install nim (Nim also provides a docker image on Dockerhub) You should now have the nim & nimble commands available, the former is the Nim compiler and the latter is Nim's package manager. Install the Mingw toolchain needed for cross-compilation to Windows (Not needed if you're compiling on Windows): * *nix: apt-get install mingw-w64 * MacOS: brew install mingw-w64 Finally, install the magnificent Winim library, along with zippy and nimcrypto * nimble install winim zippy nimcrypto Then cd into the root of this repository and run make. You should find the binaries and dlls in the bin/ directory Cross Compiling See the cross-compilation section in the Nim compiler usage guide, for a lot more details. Cross compiling to Windows from MacOs/*nix requires the mingw toolchain, usually a matter of just brew install mingw-w64 or apt install mingw-w64. You then just have to pass the -d=mingw flag to the nim compiler. E.g. nim c -d=mingw --app=console --cpu=amd64 source.nim Interfacing with C/C++ See the insane FFI section in the Nim manual. If you're familiar with csharps P/Invoke it's essentially the same concept albeit a looks a tad bit uglier: Calling MessageBox example type HANDLE* = int HWND* = HANDLE UINT* = int32 LPCSTR* = cstring proc MessageBox*(hWnd: HWND, lpText: LPCSTR, lpCaption: LPCSTR, uType: UINT): int32 {.discardable, stdcall, dynlib: "user32", importc: "MessageBoxA".} MessageBox(0, "Hello, world !", "Nim is Powerful", 0) For any complex Windows API calls use the Winim library, saves an insane amount of time and doesn't add too much to the executable size (see below) depending on how you import it. Even has COM support!!! Creating Windows DLLs with an exported DllMain Big thanks to the person who posted this on the Nim forum. The Nim compiler tries to create a DllMain function for you automatically at compile time whenever you tell it to create a windows DLL, however, it doesn't actually export it for some reason. In order to have an exported DllMain you need to pass --nomain and define a DllMain function yourself with the appropriate pragmas (stdcall, exportc, dynlib). You need to also call NimMain from your DllMain to initialize Nim's garbage collector. (Very important, otherwise your computer will literally explode). Example: import winim/lean proc NimMain() {.cdecl, importc.} proc DllMain(hinstDLL: HINSTANCE, fdwReason: DWORD, lpvReserved: LPVOID) : BOOL {.stdcall, exportc, dynlib.} = NimMain() if fdwReason == DLL_PROCESS_ATTACH: MessageBox(0, "Hello, world !", "Nim is Powerful", 0) return true To compile: nim c -d=mingw --app=lib --nomain --cpu=amd64 mynim.dll Creating XLLs You can make an XLL (an Excel DLL, imagine that) with an auto open function that can be used for payload delivery. The following code creates a simple for an XLL that has an auto open function and all other boilerplate code needed to compile as a link library. The POC compiles as a DLL, you can then change the extension to .xll and it will open in Excel and run the payload when double clicked: #[ Compile: nim c -d=mingw --app=lib --nomain --cpu=amd64 nim_xll.nim Will compile as a DLL, you can then just change the extension to .xll ]# import winim/lean proc xlAutoOpen() {.stdcall, exportc, dynlib.} = MessageBox(0, "Hello, world !", "Nim is Powerful", 0) proc NimMain() {.cdecl, importc.} proc DllMain(hinstDLL: HINSTANCE, fdwReason: DWORD, lpvReserved: LPVOID) : BOOL {.stdcall, exportc, dynlib.} = NimMain() return true There are many other sneaky things that can be done with XLLs. See more examples of XLL tradecraft here. Optimizing executables for size Taken from the Nim's FAQ page For the biggest size decrease use the following flags -d:danger -d:strip --opt:size Additionally, I've found you can squeeze a few more bytes out by passing --passc=-flto --passl=-flto to the compiler. Also take a look at the Makefile in this repo. These flags decrease sizes dramatically: the shellcode injection example goes from 484.3 KB to 46.5 KB when cross-compiled from MacOSX! Reflectively Loading Nim Executables Huge thanks to @Shitsecure for figuring this out! By default, Nim doesn't generate PE's with a relocation table which is needed by most tools that reflectively load EXE's. To generate a Nim executable with a relocation section you need to pass a few additional flags to the linker. Specifically: --passL:-Wl,--dynamicbase Full example command: nim c --passL:-Wl,--dynamicbase my_awesome_malwarez.nim Executable size difference when using the Winim library vs without Incredibly enough the size difference is pretty negligible. Especially when you apply the size optimizations outlined above. The two examples pop_bin.nim and pop_winim_bin.nim were created for this purpose. The former defines the MessageBox WinAPI call manually and the latter uses the Winim library (specifically winim/lean which is only the core SDK, see here), results: byt3bl33d3r@ecl1ps3 OffensiveNim % ls -lah bin -rwxr-xr-x 1 byt3bl33d3r 25K Nov 20 18:32 pop_bin_32.exe -rwxr-xr-x 1 byt3bl33d3r 32K Nov 20 18:32 pop_bin_64.exe -rwxr-xr-x 1 byt3bl33d3r 26K Nov 20 18:33 pop_winim_bin_32.exe -rwxr-xr-x 1 byt3bl33d3r 34K Nov 20 18:32 pop_winim_bin_64.exe If you import the entire Winim library with import winim/com it adds only around ~20ish KB which considering the amount of functionality it abstracts is 100% worth that extra size: byt3bl33d3r@ecl1ps3 OffensiveNim % ls -lah bin -rwxr-xr-x 1 byt3bl33d3r 42K Nov 20 19:20 pop_winim_bin_32.exe -rwxr-xr-x 1 byt3bl33d3r 53K Nov 20 19:20 pop_winim_bin_64.exe Opsec Considerations Because of how Nim resolves DLLs dynamically using LoadLibrary using it's FFI none of your external imported functions will actually show up in the executables static imports (see this blog post for more on this): [99911179-d] If you compile Nim source to a DLL, seems like you'll always have an exported NimMain, no matter if you specify your own DllMain or not (??). This could potentially be used as a signature, don't know how many shops are actually using Nim in their development stack. Definitely stands out. [99911079-4] Converting C code to Nim https://github.com/nim-lang/c2nim Used it to translate a bunch of small C snippets, haven't tried anything major. Language Bridges * Python integration https://github.com/yglukhov/nimpy + This is actually super interesting, especially this part. With some modification could this load the PythonxXX.dll from memory? * Jave VM integration: https://github.com/yglukhov/jnim Debugging Use the repr() function in combination with echo, supports almost all (??) data types, even structs! See this blog post for more Setting up a dev environment This repository supports VSCode Devcontainers which allows you to develop in a Docker container. This automates setting up a development environment for you. 1. Install VSCode and Docker desktop 2. Clone this repo and open it in VSCode 3. Install the Visual Studio Code Remote - Containers extension 4. Open the command pallete and select Remote-Containers: Reopen in Container command VScode will now build the Docker image (will take a bit) and put you right into your pre-built Nim dev environment! Pitfalls I found myself falling into * When calling winapi's with Winim and trying to pass a null value, make sure you pass the NULL value (defined within the Winim library) as supposed Nim's builtin nil value. (Ugh) * To get the OS handle to the created file after calling open() on Windows, you need to call f.getOsFileHandle() not f.getFileHandle () cause reasons. * The Nim compiler does accept arguments in the form -a=value or --arg=value even tho if you look at the usage it only has arguments passed as -a:value or --arg:value. (Important for Makefiles) * When defining a byte array, you also need to indicate at least in the first value that it's a byte array, bit weird but ok (https:/ /forum.nim-lang.org/t/4322) Byte array in C#: byte[] buf = new byte[5] {0xfc,0x48,0x81,0xe4,0xf0,0xff} Byte array in Nim: var buf: array[5, byte] = [byte 0xfc,0x48,0x81,0xe4,0xf0,0xff] Interesting Nim libraries * https://github.com/dom96/jester * https://github.com/pragmagic/karax * https://github.com/Niminem/Neel * https://github.com/status-im/nim-libp2p * https://github.com/PMunch/libkeepass * https://github.com/def-/nim-syscall * https://github.com/tulayang/asyncdocker * https://github.com/treeform/ws * https://github.com/guzba/zippy * https://github.com/rockcavera/nim-iputils * https://github.com/FedericoCeratto/nim-socks5 * https://github.com/CORDEA/backoff * https://github.com/treeform/steganography * https://github.com/miere43/nim-registry * https://github.com/status-im/nim-daemon Nim for implant dev links * https://web.archive.org/web/20210117002945/https://secbytes.net/ implant-roulette-part-1:-nimplant/ * https://securelist.com/zebrocys-multilanguage-malware-salad/90680 / * https://github.com/MythicAgents/Nimplant * https://github.com/elddy/Nim-SMBExec * https://github.com/elddy/NimScan Contributors Virtual hug to everyone who contributed [?] [6874747073] About My experiments in weaponizing Nim (https://nim-lang.org/) Resources Readme License BSD-2-Clause license Stars 2.1k stars Watchers 62 watching Forks 270 forks Releases No releases published Packages 0 No packages published Contributors 16 * @byt3bl33d3r * @FurkanAyar * @S3cur3Th1sSh1t * @Tycx2ry * @fkadibs * @jfmaes * @opexxx * @nodauf * @ILightThings * @Alh4zr3d * @NotoriousRebel + 5 contributors Languages * Nim 69.8% * C++ 29.5% * Other 0.7% Footer (c) 2023 GitHub, Inc. Footer navigation * Terms * Privacy * Security * Status * Docs * Contact GitHub * Pricing * API * Training * Blog * About You can't perform that action at this time. You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.