Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Ξεπερνώντας το DEP με Stack Buffer Overflow

Îåêßíçóå áðü ôï ìÝëïò Thiseas. Τελευταία δημοσίευση από το μέλος Thiseas στις 11-11-2007, 14:23. Υπάρχουν 4 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  11-11-2007, 12:52 37206

    Ξεπερνώντας το DEP με Stack Buffer Overflow

    Ξεπερνώντας το DEP

    ~~~~~~~~~~~~~~~~~~

    Η micro$oft σε μια προσπάθεια να εμποδίσει το buffer overflow εφάρμοσε μια «νέα» τεχνική (της 10ετίας του 70) για να προστατέψει τους χρήστες από την εκτέλεση μη εξουσιοδωτημένου κώδικα.

     

    Δεν θα αναλύσω με λεπτομέριες την μεθοδολογία του DEP (για περισσότερες λεπτομέριες δείτε [1],[2]) εδώ παρά μόνο θα αναφέρω το εξής:

    Αυτό που έκανε η Micro$oft ήτανε να απαγορέυσει να εκτελείται κώδικας στο stack segment ή καλύτερα στο data segment, όπως επίσης και να ελέγχει αν έχει γίνει buffer overflow του EIP χρησιμοποιόντας ένα «cookie» ή αλλιώς μια υπογραφή στο stack που την ελέγχει κατά την προσπέλαση του.

    Με αυτόν τον τρόπο θεώρησε οτι θα μπορούσε να αποτρέψει κάποιον που κάνει ένα buffer overflow να «πάρει» κάποιο box.

    Για να δείτε αν την έχετε ενεργοποιημένη αυτην την δυνατότητα στα XP πατήστε δεξί click στο MyComputer μετά properties. Μετά πατήστε το TAΒ advanced και εκεί που λέει performance πατήστε το  button [Settings]. Μόλις ανοίξει το Performance Options πατήστε το TAB “Data Execution Prevention”... Xειρότερο μέρος δεν είχανε να το κρύψουνε?? Τεσπα... Τι να πω!!

     

    Το παράδειγμα που θα σας δείξω πραγματοποιεί ένα ελεγχόμενο buffer overflow και μέσα από αυτό τρέχει ένα πρόγραμμα του λειτουργικού συστήματος.... ας πούμε το... windows explorer.

     

    Το «καλό» της υπόθεσης είναι οτι η τεχνική λειτουργεί είτε έχουμε ενεργοποιημένο το DEP!! είτε όχι.

     

    Πρέπει να πούμε βέβαια οτι το DEP έχει δύο είδη. Hardware DEP και Software DEP. Το hardware DEP δεν υποστηρίζετε από τον επεξεργαστή Pentium 4, παρά μόνο από της τελευταίας γενιάς των AMD, Intel. H Δοκιμή έγινε σε Win XP Pro με SP2 σε Pentium 4, οπότε το bypassing έγινε σε software DEP scheme ;-)

    Βέβαια όσοι μπορούν και έχουν πρόσβαση σε επεξεργαστές που υποστησίζουν Hardware DEP θα ήταν πολύ χρήσιμο να μας πούνε τις «εντυπώσεις» του...

     

    Ένα ευπαθές (vulnerable) πρόγραμμα

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Ας κατασκευάσουμε ένα ευπαθές πρόγραμμα σε buffer overflow. Χρησιμοποίησα τη Micro$oft C++ (Visual Studio 2005).

    Σημείωση: Για να μπορέσει να λειτουργήσει η δοκιμή μας (για την δοκιμή) σετάρουμε τις εξής flags του compiler:

    Basic Runtime Checks: Default

    Buffer Security Check: No (GS-)

    Για command line lovers:

    /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /MDd /Yu"stdafx.h" /Fp"Debug\BufferOverflow_Attack.pch" /Fo"Debug\\" /Fd"Debug\vc80.pdb" /W3 /nologo /c /Wp64 /ZI /TP /errorReport:prompt

     

    Επίσης να ξεκαθαρίσω πως οτιδήποτε πω και αναφέρετε σε μεγέθοι αφορά στον στον 32μπιτο Pentium 4 και όλους τους όμοιους του ;-) π.χ. AMD κλπ.

     

    Ας έρθω επιτέλους στο πρόγραμμα:

    /*
    A vulnerable Program.
    (c) by Thiseas 2007
    */

    #include <stdio.h>
    #include <string.h>

    int main(int argc, char *argv[])
    {
    char s[06];

    strcpy(s,argv[1]);
    printf("The string is %s\n",s);
    return 0;
    }
     

     

    ** Μη μου πει κανείς οτι δεν χρησιμοποιούμε πια την strcpy!! Δεν είναι αυτός ο στόχος εδώ. Το πρόγραμμα είναι καθαρά εκπαιδευτικό για να διευκολύνει την διαδικασία!

     

    Απ’ ότι βλέπουμε η μεταβλητή s καταχωρεί ότι δώθηκε σαν πρώτο command line argument. Έχει μήκος 8 bytes. Έτσι αν δώσουμε:

    C:> vuln hello!

    The string is hello!

     

    Τι θα γίνει όμως αν δώσουμε κάτι μεγαλύτερο από 8 bytes?

    Ας δούμε...

    C:> vuln aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

    The string is aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

    Unhandled exception at 0x61616161 in vuln.exe: 0xC0000005: Access violation reading location 0x61616161.

     

     

    Χμ... έσκασε.

    Ξέρετε τι είναι το 0x61616161?

    Είναι η τιμή του καταχωρητή (register) EIP (Extended Instruction Pointer) ο οποίος δείχνει την επόμενη πρός εκτέλεση εντολή. Αυτός χωράει 4 bytes. Δηλαδή είναι 61 61 61 61. Το 61 είναι ένας 16δικός αριθμός που αναπαριστά τον χαρακτήρα a.

    Μα βέβαια τον a!! Θυμάστε..! δώσαμε aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa. Οπότε καταφέραμε να γραψουμε επάνω στο EIP!!

    Σε ποιά θέση όμως της σειράς aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa έγινε το overflow?

    Κάποιος θα έλεγε στην 7η, δηλαδή στην αμέσως επόμενη από αυτήν που ορίζει το μήκος της μεταβλητής μας (s).

    Nice try... δεν είναι όμως έτσι.

     

    Υπάρχουνε 2 τρόποι να βρούμε την ακριβή διεύθυνση:

    Ο θεωρητικός και ο πρακτικός.

    Έστω οτι δεν γνωρίζουμε θεωρία και ας πάμε με την γνωστή μέθοδο “blind attack”.

     

    Αυτό που πρέπει να ξέρουμε είναι οτι (στο stack) oι μεταβλητές μας αποθηκεύονται σε θέσεις των 4ων Bytes. Για να βρούμε που ακριβώς σκάει το πρόγραμμα θα κανουμε ένα κόλπο. Θα δώσουμε:

    C:> vuln xxxxyyyyzzzzaaaabbbbcccc

    The string is xxxxyyyyzzzzaaaabbbbcccc

    Unhandled exception at 0x61616161 in vuln.exe: 0xC0000005: Access violation reading location 0x61616161.

     

    Πάλι 61!! Δηλαδή το aaaa στις θέσεις 13-16 (4 θέσεις!). Τι είναι εκεί? Μα η διεύθυνση που δείχνει ο καταχωτητής της επόμενης προς εκτέλεση εντολής (ο EIP).

    Άρα!!!!!

    Άν σε αυτές τις θέσεις βάλω μια «δική» μου διεύθυνση τότε το πρόγραμμα θα συνεχίσει την εκτέλεση του από εκεί που θα του πω εγώ!

     

    Και λίγη θεωρία

    ~~~~~~~~~~~~~~~

    Γιατι ο IP «κοιτά» στην θεση 13?

    Στο stack που καταχωρούνται οι τιμές που δίνουμε είναι ως εξής:

    xxxx <- s[4]

    yyyy <- s[2]

    zzzz <- EBP

    aaaa <- EIP !!!!!!! Εδώ γίνεται το overflow.

    bbbb

    cccc

     

    Μπορεί την μεταβλητή s να την έχουμε δηλώσει σαν μέγεθος 6 αλλά στην πραγματικότητα τα bytes που θα «κρατηθούν» στην μνήμη θα είναι πολλαπλάσια του 4, δηλαδή στην περίπτωση μας 8. Tα πρώτα 8 byteς, λοιπόν, φυλάχθηκαν για να κρατήσουν τα δεδομένα της μεταβλητής s.

    Τα επόμενα 4 κρατούνται για τον καταχωρητή Base Pointer [7]. Τέλος, τα επόμενα 4 bytes κρατούνται από τον καταχωρητή EIP. Δηλαδή αυτόν που μας ενδιαφέρει!

     

    Επίθεση!

    ~~~~~~~~

    Για την επίθεση θα χρησιμοποιήσουμε την εξής τεχνική:

    Θα κάνουμε redirection τον EIP σε μια διεύθυνση που δείχνει σε μια api function (την WinExec) μέσα στην system dll kernel32.dll. Αυτήν την dll την «βλέπουνε» όλα τα executables. Με αυτόν τον τρόπο δεν θα μπορέσει το DEP να καταλάβει αν το redirection έγινε από άλλο πρόγραμμα με «κακό» σκοπό ή από το ίδιο το πρόγραμμα «θύμα» μέσω μιας κανονικής κλήσης που αποτελούσε μέρος της κανονικής ροής του προγράμματος.

    Αυτό που μας λείπει τώρα είναι η διεύθυνση της WinExec.

     

    Για να την βρούμε θα χρησιμοποιήσουμε ένα μικρό αλλά πολύ χρήσιμο προγραμματάκι. Το depends.exe (μπορούμε να το κατεβάσουμε από το site της micro$oft).

    Ξεκινάμε το πρόγραμμα.  Πατάμε Open και επιλέγουμε το vuln.exe.

    Η οθόνη του προγράμματος χωρίζετε σε 5 μέρη:

    12

    13

    44

    55

    Επιλέχτε Kernel32.DLL στο μέρος 1.

    Μετά, επιλέχτε (στο μέρος 3) την WinExec function. Κρατήστε την διεύθυνση της WinExec. Ας την ονομάσουμε [FA] – (function address)

    Τωρα, κρατήστε ένα ακόμα πράγμα:

    Το entry point address της Kernel32.DLL που είναι η στήλη “Preffered Base” στο κομμάτι 5. Ας την ονομάσουμε [KBA] - (Kernel Base Address).

    Η διεύθυνση που μας ενδιφέρει βρίσκεται από τον τύπο:

    [KBA]+[FA].

     

    Στο box μου αυτή η διεύθυνση είναι η 0x7c86136d.

     

    Αυτό που μένει τώρα είναι να κάνουμε την επίθεση.

    Εδώ (κλασικά) θα χρησιμοποιήσουμε Perl. Ο λόγος είναι οτι δεν μπορούμε με ποιο έυκολο τρόπο να περάσουμε στην command line του vuln.exe την 16δική διεύθυνση 0x7c86136d παρά μόνο αν το καλέσουμε μέσα από ένα άλλο πρόγραμμα (αυτό της Perl).

     

    Φτιάχνουμε, λοιπόν, το εξής γελοίο πρόγραμμα σε perl:

    # c:\perl\bin\perl attack.perl
    #
    # Buffer overflow using Command line attach.
    # (c) by Thiseas 2007
    #
    $prg = "vuln xxxxyyyyzzzz\x6d\x13\x86\x7c explorer.exe";
    system($prg);
     

     

    Δώστε βάση στην διεύθυνση που περνάμε ... είναι με την ανάποδη σειρά από αυτήν που βρήκαμε... Αυτό δεν θα το εξηγήσω, βρήτε και κάτι μόνοι σας, εκτός από αυτούς που ήδη το γνωρίζουν, στους οποίους ζητώ συγγνώμη για τον... «εξυπνακισμό» μου!!

     

    Το παραπάνω προγραμματάκι με overflow καλεί τον windows explorer.. ;)

    Θα δούμε οτι «παίζει» ανεξάρτητα από το αν έχουμε activate το DEP ή οχι.

    Παίζοντας με το παραπάνω παράδειγμα μπορούμε να βγάλουμε και άλλα χρήσιμα συμπεράσματα όπως επίσης και κάποια... παράδοξα. Δεν θα τα πω όλα εδώ όμως... άλλοστε αυτό το αρθράκι σκοπεύει στην περαιτέρω  μελέτη από εσάς μιας και ο στόχος είναι η γνώση που αποκτιέται από την προσωπική αφιέρωση και κόπο, γιατί μόνο τότε αξίζει πραγματικά.

     

     

    Happy Programming

     

     

    Bye By Thiseas

     

     

    Αναφορές

    [1]. http://support.microsoft.com/kb/875352

    [2]. http://msdn2.microsoft.com/en-us/library/aa366553.aspx

    [3]. http://www.uninformed.org/?v=2&a=4

    [4]. http://www.nextgenss.com/papers/defeating-w2k3-stack-protection.pdf

    [5]. http://en.wikipedia.org/wiki/X86_assembly_language

    [6.]. http://en.wikipedia.org/wiki/Processor_register

    [7]. http://www.cs.miami.edu/~burt/journal/NT/basepointer.html
    [8.]. http://www.maxpatrol.com/defeating-xpsp2-heap-protection.pdf

     

     

     

     


    Nothing to declare...
  •  11-11-2007, 13:20 37208 σε απάντηση της 37206

    Απ: Ξεπερνώντας το DEP με Stack Buffer Overflow

    Αυτό που μόλις περιέγραψες είναι ένα πολύ καλό μάθημα σε buffer overflows, αλλά δεν έχει καμία σχέση με το DEP, καθότι το DEP εμποδίζει την εκτέλεση από data pages, και εσύ έκανες jump μέσα στα pages του kernel32.dll που είναι μια χαρά εκτελέσιμα. Επιπλέον, σε Vista με το address space layout randomization δεν έχει και πολλές ελπίδες.


    Νατάσα Μανουσοπούλου
  •  11-11-2007, 13:57 37210 σε απάντηση της 37208

    Απ: Ξεπερνώντας το DEP με Stack Buffer Overflow

    Νατάσα Μανουσοπούλου:

    ... αλλά δεν έχει καμία σχέση με το DEP, καθότι το DEP εμποδίζει την εκτέλεση από data pages, και εσύ έκανες jump μέσα στα pages του kernel32.dll που είναι μια χαρά εκτελέσιμα.

    Δύο ερωτήσεις...
    1. Έκανα μόνο Jump Νατάσα?? R u sure? Εδώ έκανα overwrite τον BP!! Δεν το είδες? Δεν είναι απλό jump. Overflow είναι...
    2. Που είναι το περήφιμο cooky checker? οεο ?? [http://research.microsoft.com/users/jpincus/mitigations.pdf]

    Επίσης...: Δεν είπα οτι κάνω Break το DEP, αλλα bypass!! Άλλοστε αυτο μου μετράει είναι το αποτέλεσμα...

    Νατάσα, εκτελώ όποιο πρόγραμμα θέλω... Καταλαβαίνεις τι σημαίνει αυτό....

    To DEP βγήκε για να προστατέψει κάποιον να φτάσει στο αποτελέσμα (ας πούμε) Χ μέσω ενός 3ου προγράμματος θεωριτικά άσχετου.
    Εγώ μέσω αυτού,... έφτασα στο Χ.... [bye bye DEP]

    What it counts is the result.


    Nothing to declare...
  •  11-11-2007, 14:15 37213 σε απάντηση της 37210

    Απ: Ξεπερνώντας το DEP με Stack Buffer Overflow

    Το Data Execution Prevention σε εμποδίζει να κάνεις jump/call/whatever IP change σε σελίδες μαρκαρισμένες από τον memory manager σαν data, ώστε να ελαχιστοποιούνται οι συνέπειες όταν μια εφαρμογή είναι ευπαθής σε buffer overflow. Το παράδειγμα που έδωσες ΔΕΝ κάνει κάτι τέτοιο. Κάνει ένα παλιό καλό buffer overflow, που έχει περιγραφεί πάρα πολλές φορές και δεν αποτελεί τίποτα καινούργιο. Το να κάνεις overwrite τον BP, ναι, είναι έμμεσο jump (ret για την ακρίβεια) κάπου αλλού, που όμως εξακολουθεί να ζει σε executable pages.

    Αν θέλεις να μάθεις περισσότερα για το DEP μπορείς να ανατρέξεις στις σχετικές σελίδες του MSDN και της KB, που μπορείς να βρεις πολύ εύκολα και γρήγορα με μια αναζήτηση.

    Over and out.


    Νατάσα Μανουσοπούλου
  •  11-11-2007, 14:23 37215 σε απάντηση της 37213

    Απ: Ξεπερνώντας το DEP με Stack Buffer Overflow

    Νατάσα Μανουσοπούλου:
    Αν θέλεις να μάθεις περισσότερα για το DEP μπορείς να ανατρέξεις στις σχετικές σελίδες του MSDN και της KB, που μπορείς να βρεις πολύ εύκολα και γρήγορα με μια αναζήτηση.Over and out.

    Thanks Νατάσα.... θα τις έχω υπ όψη μου...!!!
    ... την επομένη φορά που θα βγάλει η μαμά θα βγάλει κάτι εξίσου "secure".

    PS: Μιας και μιλήσαμε για "διάβασμα", δεν θα πείραζε να κάνω κι εγώ μια παραίνεση: Ρίξε μια ματιά στις αναφορές που έχω (ειδικα τα 4,8). Θα μάθεις αρκετά πράγματα.

    bye bye


    Nothing to declare...
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems