Jektor – A Windows User-Mode Shellcode Execution Tool That Demonstrates Various Techniques That Malware Uses

This utility focuses on shellcode

 

Anti-virus detection?:

Pre-pending a set of NOPs to a Msfvenom XOR encrypted shellcode payload while using dynamic function address resolutions seems to bypass Windows Defender.

IAT Import Evasion

Jektor makes use of dynamic function address resolutions using LoadLibrary and GetProcessAddress to make

  1. Allocate a region of memory big enough for the shellcode using VirtualAlloc
  2. Move the globally defined shellcode buffer into the newly allocated memory region with memcpy/RtlCopyMemory
  3. Create a new thread that includes the base address of the allocated memory region with CreateThread
  4. Wait for the new thread to be created/executed with WaitForSingleObject to ensure the payload detonates

After the memory region for the shellcode payload is allocated as RWX and the payload is moved into it, you can easily discover this region of memory by looking for any region of memory in the process that is marked as RWX, then if you inspect it you can seen the shellcode payload was moved into it, highlighted below are the first five bytes of the shellcode payload that executes a

Hunting for RWX regions of memory is a quick way to identify potentially malicious activity on your system.

Remote shellcode execution via CreateRemoteThread

Another technique to create threads for shellcode execution is to call the CreateRemoteThread function, this will allow you to create threads remotely in another process. But the catch is that you will also want to allocate and write the shellcode payload into the remote process as well, since you’ll create a thread remotely that executes the payloads address that’s allocated within that process. In order to allocate the payload remotely, you’ll need to use the VirtualAllocEx function, this function is different from VirtualAlloc in that it can allocate memory regions in remote processes. To do this, Jektor creates a new process with the CREATE_NO_WINDOW flag set using CreateProcessW, this is used to spawn a new hidden notepad process. One the new process is spawned it remotely allocated memory in it and then uses WriteProcessMemory to write the shellcode payload into the allocated memory region. After this it calls CreateRemoteThread to execute the shellcode payload.

  1. Spawn a new process using CreateProcessW with CREATE_NO_WINDOW set
  2. Open a HANDLE to the newly spawed process by PID with OpenProcess and dwProcessId from PROCESS_INFORMATION
  3. Allocate memory remotely in the spawned process for the shellcode with VirtualAllocEx
  4. Write the shellcode payload into the allocated memory region with WriteProcessMemory
  5. Detonate the remotely created shellcode payload with CreateRemoteThread and the HANDLE from OpenProcess

Local shellcode execution via EnumTimeFormatsEx

  1. Allocate memory locally for the shellcode payload with VirtualAlloc
  2. Move the shellcode payload into the newly allocated region with memcpy/RtlCopyMemory
  3. Detonate the shellcode by passing it as the lpTimeFmtEnumProcEx parameter for EnumTimeFormatsEx

Local shellcode execution via CreateFiber

  1. Get a HANDLE to the current thread using GetCurrentThread
  2. Convert the main thread to a Fiber using ConvertThreadToFiber
  3. Allocate memory for the shellcode payload with VirtualAlloc
  4. Copy the shellcode buffer into the newly allocated memory region with memcpy
  5. Create a new fiber with the base address of the allocated memory region as the lpStartAddress parameter for CreateFiber
  6. Detonate the shellcode by scheduling the fiber with SwitchToFiber
  7. Perform cleanup by deleting the created fiber with DeleteFiber

Local shellcode execution via QueueUserAPC

  1. Allocate memory for the shellcode buffer with VirtualAlloc
  2. Get a handle to the current process with GetCurrentProcess
  3. Write the shellcode payload into the newly allocated memory region with WriteProcessMemory
  4. Get a handle to the current thread with GetCurrentThread
  5. Queue a new APC routine pass the address of the allocated memory region as the pfnAPC parameter to QueueUserAPC
  6. Trigger the shellcode payload by calling the undocumented NtTestAlert function which clears the APC queue for the current thread
  7. Perform cleanup by closing the handles to the current thread and current process

 

Download Jektor

If you like the site, please consider joining the telegram channel or supporting us on Patreon using the button below.

Discord

Original Source