Το προφίλ μας στο Google Plus
5

Τι είναι αυτό το XSS, επιτέλους;

Σε άρθρο του deltaHacker 008 κάνουμε ορισμένες επιδείξεις επιθέσεων που εκμεταλλεύονται αδυναμίες XSS. Για να τις παρακολουθήσετε, οφείλετε πρώτα να κατανοήσετε το ίδιο το XSS ή αλλιώς Cross-Site Scripting. Βάζοντας τα πράγματα σε μια σειρά, ξεκινάμε περιγράφοντας δύο μεθόδους εκτέλεσης scripts στο σύγχρονο web.

Η πρώτη μέθοδος ονομάζεται server-side scripting. Πρόκειται για την εκτέλεση προγραμμάτων (scripts) από τον ίδιο τον server, τα οποία βρίσκονται επίσης στον server. Σ’ αυτή την περίπτωση, τα προγράμματα γράφονται σε κάποια γλώσσα σαν την PHP και η ύπαρξή τους δεν γίνεται άμεσα αντιληπτή στον επισκέπτη της σελίδας. Ο τελευταίος, άλλωστε, δεν έχει κανέναν τρόπο για να δει τον πηγαίο κώδικα αυτών των προγραμμάτων, παρά μόνο τα “προϊόντα” από την εκτέλεσή τους. Με αυτό τον τρόπο λειτουργούν σχεδόν όλα τα σημερινά websites. Γνωστά παραδείγματα προγραμμάτων που εκτελούνται από τον ίδιο τον server αποτελούν τα λεγόμενα CMS (Content Management Systems), όπως τα WordPress, Joomla κ.ά. Αυτά μάλιστα τα προγράμματα συνεργάζονται και με άλλες εφαρμογές του server, όπως είναι οι βάσεις δεδομένων.

Η δεύτερη μέθοδος εκτέλεσης προγραμμάτων έχει να κάνει με το λεγόμενο client-side scripting. Πρόκειται για την εκτέλεση προγραμμάτων (και πάλι scripts) από τον υπολογιστή του επισκέπτη κι όχι από τον server του website! Σ’ αυτή την περίπτωση, ο κώδικας είναι γραμμένος σε κάποιο αρχείο του website αλλά εκτελείται από τον web browser του επισκέπτη. Τέτοια scripts γράφονται σε γλώσσες όπως η JavaScript κι ο χρήστης, τουλάχιστον κατά κανόνα, μπορεί να δει τον πηγαίο τους κώδικα. Τα αντίστοιχα προγράμματα χρησιμοποιούνται για την εμφάνιση μενού, αναδυόμενων παραθύρων και μηνυμάτων ή για την επικύρωση των στοιχείων μιας φόρμας (π.χ., έλεγχος αν η μορφή του email είναι σωστή, αν ο κωδικός είναι ισχυρός κ.ο.κ.).

Στα περισσότερα σύγχρονα sites χρησιμοποιούνται και οι δύο παραπάνω τρόποι εκτέλεσης. Ωστόσο, για τη μελέτη των επιθέσεων XSS θα εστιάσουμε στη δεύτερη. Ας δούμε ένα κλασσικό παράδειγμα κώδικα σε JavaScript, εξετάζοντας μια απλή σελίδα HTML.

<html>
  <head>
    <script type="text/javascript">
      function show_alert()
      { alert("Είμαι ένα ωραίο alert box!"); }
    </script>
  </head>
  <body>
    <input type="button" onClick="show_alert()" value="deltahacker.gr" />
  </body>
</html>

Με τον παραπάνω κώδικα κατασκευάζουμε μια σελίδα HTML, η οποία περιέχει μόνο ένα κουμπάκι. Όταν πατήσουμε το κουμπάκι (δηλαδή όταν συμβεί το event ονόματι onClick), θα τρέξει η συνάρτηση show_alert(), την οποία έχουμε γράψει σε JavaScript. Με τη σειρά της, αυτή η συνάρτηση δημιουργεί ένα παράθυρο pop-up, με χρήση της μεθόδου alert(). Ο σχετικός κώδικας εκτελείται τοπικά, από τον browser του υπολογιστή μας. Μπορείτε να δείτε το αποτέλεσμα στην εικόνα 1.

Εικόνα 1: Το αποτέλεσμα ενός απλού προγράμματος σε JavaScript, το οποίο δημιουργεί ένα pop-up με το πάτημα του αντίστοιχου κουμπιού.

Πολύ ωραία! Μόλις είδαμε ένα απλό παράδειγμα χρήσης της JavaScript. Τώρα μπορούμε να μιλήσουμε για μια άλλη σημαντική έννοια, η οποία σχετίζεται με την εμφάνιση των websites από τον browser μας: Το Document Object Model ή σκέτο DOM. Το DOM αποτελεί έναν τρόπο αναπαράστασης του περιεχομένου μιας σελίδας HTML, ο οποίος τηρεί την ιεραρχία των στοιχείων που την απαρτίζουν. Ας δούμε ένα παράδειγμα. Ας υποθέσουμε ότι έχουμε τον παρακάτω κώδικα HTML.

<html>
  <head>
    <title>DOM Example</title>
  </head>
  <body>
    <h1>XSS attacks!</h1>
    <p>DeltaHacker.gr</p>
  </body>
</html>

Αν ανοίξουμε αυτή την απλή σελίδα HTML, ο browser θα σχηματίσει εσωτερικά (χωρίς να μας τη δείξει) μια ιεραρχική δενδρική δομή, όπως ορίζεται από το DOM. Μπορείτε να δείτε τη σχετική δομή στην εικόνα 2.

Εικόνα 2: Σύμφωνα με το μοντέλο DOM, ένας browser είναι σε θέση να αναπαριστά κάθε στοιχείο σε μια ιστοσελίδα. Στην εικόνα φαίνεται μια αναπαράσταση αυτού του μοντέλου, για μια απλή σελίδα (ο αντίστοιχος κώδικας HTML φαίνεται στο κείμενο).

Αναρωτιέστε γιατί μας ενδιαφέρει αυτή η δομή; Το DOM, πέρα από έναν τρόπο αναπαράστασης μιας ιστοσελίδας, αποτελεί κι έναν τρόπο πρόσβασης στα επιμέρους στοιχεία της. Χρησιμοποιώντας το DOM, δηλαδή, μπορούμε να αποκτήσουμε πρόσβαση σε στοιχεία της σελίδας ή να προσθέσουμε νέα. Μάλιστα, όταν μιλάμε για μια σελίδα δεν αναφερόμαστε μόνο σε όσα εμφανίζονται αλλά και σε οποιοδήποτε παρεμφερές στοιχείο όπως, π.χ., τα cookies. Κάπου εδώ αρχίζουν τα ωραία :) Δεν ξέρουμε αν σας πέρασε από το μυαλό, αλλά θα μπορούσαμε να τροποποιήσουμε το DOM μέσω JavaScript. Ας δούμε ένα απλό παράδειγμα.

<html>
  <head>
    <title>DeltaHacker Title</title>
  </head>
  <body>
    Ο τίτλος του εγγράφου είναι:
    <script type="text/javascript">
      document.write(document.title);
    </script>
  </body>
</html>

Ο κώδικας JavaScript που εμπεριέχεται στην παραπάνω σελίδα HTML εμφανίζει το κείμενο “Ο τίτλος του εγγράφου είναι: DeltaHacker Title”. Αυτό επιτυγχάνεται με τη μέθοδο document.write του DOM, σε συνδυασμό με την ιδιότητα document.title (επίσης του DOM). Η δυνατότητα της JavaScript να αλληλεπιδρά με το DOM αποτελεί *ένα* από τα αίτια για τις επιθέσεις XSS.

Μα, δεν κάνει κανείς τίποτα;
Κάνουν, πώς δεν κάνουν; Οι προγραμματιστές των web browser, για παράδειγμα, δεν κάθονται με σταυρωμένα τα χέρια. Γι’ αυτό και έχουν αναπτυχθεί αρκετές τεχνικές ώστε να αποφεύγονται οι κακόβουλες ενέργειες. Καταρχάς, τα scripts τρέχουν μέσα σε ένα sandbox. Φανταστείτε τα sandbox σαν κουτιά, που περιορίζουν το χώρο δράσης των scripts και δεν τα αφήνουν να αλληλεπιδράσουν με εξωτερικά στοιχεία. Έτσι, τα scripts ενός website μπορούν να επιτελούν λειτουργίες σχετικές με το web και μόνο. Οι άσχετες ενέργειες, όπως, π.χ., η δημιουργία αρχείων στο λειτουργικό σύστημα, εμποδίζονται από το sandbox. Επίσης, κάτι πολύ σημαντικό στην ασφάλεια των σύγχρονων browser είναι η “πολιτική της ιδίας προέλευσης” (same-origin policy). Ο εν λόγω μηχανισμός απαγορεύει οποιαδήποτε αλληλεπίδραση των script ενός website, με στοιχεία ή δεδομένα άλλων websites. Για παράδειγμα, αν έχουμε επισκεφθεί σε ένα tab τη σελίδα deltahacker.gr και σε ένα άλλο το gmail.com, τα scripts του deltahacker.gr δεν θα μπορούν να επιδράσουν στο email μας. Οι δύο ιστοσελίδες θα είναι πλήρως διαχωρισμένες.

Μολαταύτα –και παρά τα προηγούμενα– οι επιθέσεις που σχετίζονται με την παράνομη εκτέλεση κακόβουλου κώδικα είναι πάρα πολύ συχνές. Αναφερόμαστε στις επιθέσεις Cross-Site Scripting, οι οποίες αποτελούν το δεύτερο μεγαλύτερο κίνδυνο για τις δικτυακές εφαρμογές (τα πρωτεία ανήκουν στις επιθέσεις SQL injection). Η μεγάλη επιτυχία αυτών των επιθέσεων οφείλεται κυρίως στην απροσεξία (ή στην έλλειψη γνώσεων) από πλευράς των προγραμματιστών. Αφού λοιπόν δεν προσέχουν, ας δούμε τι ζημιά μπορούν να προκαλέσουν ή να πάθουν…

Επιθέσεις Cross-Site Scripting
Οι ευπάθειες που επιτρέπουν τις επιθέσεις τύπου XSS είναι από τις παλαιότερες που έχουν εντοπιστεί σε δικτυακές εφαρμογές. Το XSS αναφέρθηκε για πρώτη φορά σαν πρόβλημα το 1996, αλλά πολλοί προγραμματιστές εξακολουθούν να το αγνοούν! Το XSS επιτυγχάνεται εξαιτίας διαφόρων αδυναμιών στον κώδικα των ιστοσελίδων, οι οποίες επιτρέπουν στους επιτιθέμενους να προσπεράσουν τους μηχανισμούς προστασίας των browser. Τελικός σκοπός μιας επίθεσης XSS είναι η εκτέλεση κώδικα JavaScipt στον browser του επισκέπτη. Στην ουσία, πρόκειται για ένα είδος εισαγωγής κακόβουλου κώδικα (code injection) μέσα στον κώδικα μιας νομότυπης κατά τα άλλα ιστοσελίδας. Αυτός ο κώδικας, όμως, δεν εκτελείται από τον web server, αλλά από τους browser των επισκεπτών! Κατά κύριο λόγο, αυτές οι επιθέσεις είναι εφικτές επειδή οι προγραμματιστές παραβλέπουν το λεγόμενο input validation. Με άλλα λόγια, επειδή θεωρούν αξιόπιστα όλα όσα δίνει ο χρήστης.

Επειδή η θεωρητική περιγραφή δεν είναι ποτέ αρκετή, ας δούμε και ένα παράδειγμα. Ας υποθέσουμε ότι σε κάποια σελίδα ενός website, εμφανίζεται ο παρακάτω κώδικας σε PHP:

<?php echo '<p>Hello '.$_GET['name'].'</p>'; ?>

Ο κώδικας τυπώνει ένα προσωποποιημένο μήνυμα χαιρετισμού, λαμβάνοντας από το URL το όνομα του χρήστη με τη μέθοδο GET (βλ. και εικόνα 3).

Εικόνα 3: Το περιεχόμενο της μεταβλητής name χρησιμοποιείται ως έξοδος για τη σελίδα. Μπορούμε άραγε να εισάγουμε κάτι κακόβουλο εδώ;

Ας υποθέσουμε τώρα ότι στο μηχάνημά μας εκτελείται ένας web server και ότι ο παραπάνω κώδικας βρίσκεται στο αρχείο hello.php, το οποίο με τη σειρά του βρίσκεται στο document root. Αν επισκεφθούμε τη διεύθυνση

http://localhost/hello.php?name=DeltaHacker

θα εμφανιστεί το μήνυμα “Hello DeltaHacker”. Τι θα γινόταν αν αντί ενός απλού αλφαριθμητικού βάζαμε κώδικα σε JavaScript; Η σελίδα μας θα αντέγραφε τον κώδικα στην έξοδό της και ο browser θα τον παραλάμβανε και θα τον εκτελούσε! Αυτό το κομμάτι κώδικα ονομάζεται payload. Ας κάνουμε μια δοκιμή, επισκεπτόμενοι το ακόλουθο URL:

http://localhost/hello.php?name=<script>alert('XSS');</script>

Το αποτέλεσμα φαίνεται στην εικόνα 4. Ο browser εμφάνισε ένα παράθυρο pop-up κι εμείς μόλις πραγματοποιήσαμε την πρώτη μας (αθώα) επίθεση XSS. Όπως καταλαβαίνετε, για να δουλέψει μια επίθεση XSS αυτό που εισάγει ο χρήστης θα πρέπει να χρησιμοποιείται σαν τμήμα της “εξόδου” της σελίδας. Με απλά λόγια, αυτό που δίνει ο χρήστης θα πρέπει να ενσωματώνεται στην τελική μορφή της σελίδας και αποστέλλεται στον browser αυτούσιο.

Εικόνα 4: Η συγκεκριμένη σελίδα δεν φιλτράρει το περιεχόμενο της μεταβλητής name. Έτσι, καταφέραμε να εκτελέσουμε ένα μικρό κομμάτι κώδικα JavaScript, το οποίο εμφάνισε ένα ωραίο pop-up.

Κατηγορίες XSS
Οι επιθέσεις XSS μπορούν να χωριστούν σε τρεις κύριες κατηγορίες. Το βασικό κριτήριο διαχωρισμού είναι ο τρόπος με τον οποίο ο κακόβουλος κώδικας (payload) καταλήγει στον browser του θύματος. Βλέπετε, άλλος είναι αυτός που εισάγει τον κώδικα και σε άλλου τον browser πρέπει να εκτελεστεί! Έτσι, έχουμε τις ακόλουθες τρεις κατηγορίες.

Reflected XSS. Στα Reflected XSS (γνωστά και ως Non-persistent XSS), τα ίδια τα θύματα στέλνουν (άθελα) το κακόβουλο payload στη σελίδα. Η σελίδα κατασκευάζει την έξοδό της ενσωματώνοντας αυτόν τον κώδικα, έτσι ο κώδικας επιστρέφει στο θύμα και εκτελείται από τον browser. Όλο αυτό μπορεί να ακούγεται παράδοξο, αλλά δεν είναι! Ποιος τρελός θα έκανε ζημιά στο μηχάνημά του; Κι όμως, συμβαίνει πολύ συχνά. Για παράδειγμα, συμβαίνει όταν πείσουμε (εξαπατήσουμε) το θύμα να πατήσει πάνω σε κάποιο ειδικά διαμορφωμένο link, το οποίο έχει ενσωματωμένο στο URL του ένα κακόβουλο payload. Στη συγκεκριμένη περίπτωση ο επιτιθέμενος ποντάρει στην άγνοια του θύματος. Αυτή η μορφή των επιθέσεων XSS διευκολύνονται από υπηρεσίες σμίκρυνσης URL (bit.ly, goo.gl κ.ά.). Βλέπετε, τα URL που παράγουν αυτές οι υπηρεσίες κρύβουν τον τελικό τους στόχο κι αποτελούν πρώτης τάξεως κρυψώνα για κακόβουλο κώδικα. Φυσικά, για να πετύχει ένα XSS αυτού του είδους χρειάζεται και μια καλή δόση social engineering. Μια επίθεση Reflected XSS πραγματοποιείται μόνο όταν το θύμα πατήσει στο μολυσμένο link. Με τη χρήση του Reflected XSS, οι επιτιθέμενοι μπορούν να κλέψουν το session ID (cookie) του θύματος και να περιηγηθούν στη σελίδα μέσα από το λογαριασμό του. Επίσης, με το Reflected XSS πραγματοποιούνται και αλλοιώσεις στην εμφάνιση των site (defacement). Στην εικόνα 5 φαίνεται μια όχι και τόσο αθώα επίσκεψή μας στο site του πανεπιστημίου Harvard ;) Επιθέσεις τύπου Reflected XSS ανακαλύπτονται κάθε ημέρα και μπορείτε να παρακολουθείτε τα σχετικά νέα από αυτή τη σελίδα.

Εικόνα 5: Θα περίμενε κανείς ότι οι web developer ενός πανεπιστήμιου σαν το Harvard είναι προετοιμασμένοι για επιθέσεις XSS... Δυστυχώς, μόλις έγιναν Stallowned ;)

Persistent XSS. Σε μια επίθεση Persistent XSS το κακόβουλο payload δεν εκτελείται μόνο σε κάποιον μεμονωμένο χρήστη, αλλά σε όλους τους επισκέπτες της μολυσμένης σελίδας. Αυτό συμβαίνει γιατί το payload αποθηκεύεται στη βάση δεδομένων του website και φορτώνεται αυτόματα από τον κώδικα των ιστοσελίδων! Αναρωτιέστε πώς μπορεί να γίνει κάτι τέτοιο; Σκεφτείτε για παράδειγμα ένα πρόχειρα κατασκευασμένο guestbook. Εξαιτίας της απροσεξίας του προγραμματιστή, όταν γράφουμε κάτι στη σχετική φόρμα αυτό καταχωρείται στη βάση δεδομένων χωρίς έλεγχο ή φιλτράρισμα. Έτσι, όταν κάποιος αθώος επισκέπτης πηγαίνει στη σελίδα του guestbook, ο κώδικάς μας φορτώνεται από τη βάση και αποστέλλεται αυτόματα στον browser. Πρόκειται για την πιο επικίνδυνη μορφή XSS, καθώς είναι ιδιαίτερα μαζική! Τα Persistent XSS δεν είναι σπάνια και πραγματοποιούνται σε websites τα οποία χρησιμοποιούν βάσεις δεδομένων (τα CMS, τα forum κ.ο.κ.). Με μια επίθεση Persistent XSS ασχολούμαστε και στο σχετικό άρθρο του deltaHacker 008.

DOM-based XSS. Ο συγκεκριμένος τύπος XSS βασίζεται στο DOM. Αυτή τη φορά δεν χρειάζεται να στείλουμε τον κακόβουλο κώδικα στον server ώστε να επιστραφεί στον browser του θύματος, ούτε να τον αποθηκεύσουμε στη βάση δεδομένων του website. Αυτή η επίθεση θα μπορούσε να λειτουργήσει και τοπικά, σε μια στατική σελίδα HTML, την οποία έχουμε αποθηκεύσει στο μηχάνημά μας. Προϋπόθεση για κάτι τέτοιο είναι η αξιοποίηση των μεθόδων DOM από τη σελίδα, για τη λήψη του URL στο οποίο εμφανίζονται. Για παράδειγμα, σκεφτείτε τις μεθόδους document.URL και document.location. Αν στο address bar του browser εισάγουμε κάποιο κακόβουλο payload, αυτές οι μέθοδοι DOM θα το διαβάσουν, θα το ενσωματώσουν στη σελίδα και τελικά θα καταλήξει να εκτελεστεί από τον browser. Αυτή η τεχνική είναι αρκετά περίπλοκη και δεν χρειάζεται να μπούμε σε λεπτομέρειες, αν μη τι άλλο για να μη χάσουμε τη γενική εικόνα. Μπορείτε να διαβάσετε περισσότερα για το DOM-based XSS στην αντίστοιχη σελίδα του OWASP project.

5 Responses to “Τι είναι αυτό το XSS, επιτέλους;”

  1. hackertom | 24/06/2012 at 18:38

    Μια χαρά η παρουσίαση… Θα μπορούσατε να κάνετε και ένα άρθρο με
    social engineering, και cookie stealer code σε κάποιο free host server … :-P

    Για να εκπαιδευτικούς λόγους πάντα … [?]

    • subZraw | 24/06/2012 at 18:52

      Μα, δεν χρειαζόταν να το πεις αυτό :)
      Εννοείται πως ό,τι κάνουμε το κάνουμε για εκπαιδευτικούς λόγους.

    • A.Kontos | 25/06/2012 at 19:22

      Αν δεν κάνω λάθος τα άρθρα που ζητάς υπάρχουν ήδη!! Για το cookie stealer : http://deltahacker.gr/2011/08/29/session-fixation-baby/ αλλά και στο άρθρο στο τεύχος 003 “συγγραφή ασφαλούς κώδικα μέρος 2/2”. Τώρα για το social enginneering έχουν δημοσιευθεί αρκετά άρθρα στο site , αλλά υπάρχουν και σε όλα τα τεύχη(001-009).

  2. hackertom | 26/06/2012 at 13:13

    Συγνώμη για το κάπως off topic αλλά μήπως θα μπορούσατε να κάνετε και κάποιο tutorial για το Boolean Based SQL Injection ?

Leave a Reply

You must be logged in to post a comment.

Σύνδεση

Αρχείο δημοσιεύσεων