I’ve been meaning to post about this technique I figured out while developing the OSX x86_64 setuid/shell shellcode [1] [2] I posted about last week but school and work have been pretty busy. It’s a simple technique that allows you to still test your shellcode on Unix-based OSes with non-executable stacks and heaps and can come in pretty handy for making sure your shellcode is right.

Non-Executable Stack & Heap

After developing your shellcode in an assembly environment (NASM/YASM, etc) and freeing it of null-bytes, it’s nice to be able to test your code in C environment (maybe you’re dyslexic and swapped a byte or two!). However, almost all modern day operating systems implement a non-executable stack and/or heap. That means, memory in these spaces have the Execute Disable Bit enabled; also referred to as the NX bit andW^X for the heap.

That means using ‘malloc’ to allocate space on the heap for your shellcode is not going to work, neither is a local char[SIZE] buffer since that will reside on the stack.

Anonymous Memory Map

To get around this, we can use an anonymous memory map sort of like ‘malloc’ but in addition we can pass in arguments to ‘mmap’ to make the mapped memory executable!

Here is an explanation of the anonymous parameter we pass to ‘mmap’ from the man page.

MAP_ANON
This flag tells the system to create an anonymous mapping, not connected to a file. filedes and off are ignored, and the region is initialized with zeros.
Anonymous maps are used as the basic primitive to extend the heap on some systems. They are also useful to share data between multiple tasks without creating a file.

On some systems using private anonymous mmaps is more efficient than using malloc for large blocks. This is not an issue with the GNU C library, as the included malloc automatically uses mmap where appropriate.

mmap returns the address of the new mapping, or -1 for an error.

and the executable parameter

PROT_EXEC

Data can be executed.

Shellcode Testing Template

You can use the simple template below by replacing <YOUR SHELLCODE> with the respective shellcode you are testing and <SIZE OF YOUR SHELLCODE> with the number of bytes of your shellcode.

#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>
 
int (*sc)();
 
char shellcode[] = "<YOUR SHELLCODE>";
 
int main(int argc, char **argv) {
 
    void *ptr = mmap(0, <SIZE OF YOUR SHELLCODE>, 
            PROT_EXEC | PROT_WRITE | PROT_READ, MAP_ANON
            | MAP_PRIVATE, -1, 0);
 
    if (ptr == MAP_FAILED) {
        perror("mmap");
        exit(-1);
    }
 
    memcpy(ptr, shellcode, sizeof(shellcode));
    sc = ptr;
 
    sc();
 
    return 0;
}

That’s all there is too it! Questions or comments? I would love to hear them.

Also, if anyone has a similar technique for Windows (since I’m not familiar with the Windows API yet), I’d be willing to add it to this post.