SQL Injection
Last updated
Last updated
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
RootedCON είναι η πιο σχετική εκδήλωση κυβερνοασφάλειας στην Ισπανία και μία από τις πιο σημαντικές στην Ευρώπη. Με αποστολή την προώθηση της τεχνικής γνώσης, αυτό το συνέδριο είναι ένα καυτό σημείο συνάντησης για επαγγελματίες της τεχνολογίας και της κυβερνοασφάλειας σε κάθε τομέα.
Μια SQL injection είναι μια αδυναμία ασφαλείας που επιτρέπει στους επιτιθέμενους να παρεμβαίνουν σε ερωτήματα βάσης δεδομένων μιας εφαρμογής. Αυτή η ευπάθεια μπορεί να επιτρέψει στους επιτιθέμενους να δουν, τροποποιήσουν ή διαγράψουν δεδομένα που δεν θα έπρεπε να έχουν πρόσβαση, συμπεριλαμβανομένων πληροφοριών άλλων χρηστών ή οποιαδήποτε δεδομένα μπορεί να έχει πρόσβαση η εφαρμογή. Τέτοιες ενέργειες μπορεί να οδηγήσουν σε μόνιμες αλλαγές στη λειτουργικότητα ή το περιεχόμενο της εφαρμογής ή ακόμη και σε παραβίαση του διακομιστή ή άρνηση υπηρεσίας.
Όταν μια ιστοσελίδα φαίνεται να είναι ευάλωτη σε SQL injection (SQLi) λόγω ασυνήθιστων απαντήσεων του διακομιστή σε εισόδους σχετικές με SQLi, το πρώτο βήμα είναι να κατανοήσουμε πώς να εισάγουμε δεδομένα στην ερώτηση χωρίς να την διαταράξουμε. Αυτό απαιτεί την αναγνώριση της μεθόδου για να ξεφύγουμε από το τρέχον πλαίσιο αποτελεσματικά. Αυτά είναι μερικά χρήσιμα παραδείγματα:
Τότε, πρέπει να ξέρετε πώς να διορθώσετε το ερώτημα ώστε να μην υπάρχουν σφάλματα. Για να διορθώσετε το ερώτημα μπορείτε να εισάγετε δεδομένα ώστε το προηγούμενο ερώτημα να αποδεχτεί τα νέα δεδομένα, ή μπορείτε απλά να εισάγετε τα δεδομένα σας και να προσθέσετε ένα σύμβολο σχολίου στο τέλος.
Σημειώστε ότι αν μπορείτε να δείτε μηνύματα σφάλματος ή μπορείτε να εντοπίσετε διαφορές όταν ένα ερώτημα λειτουργεί και όταν δεν λειτουργεί, αυτή η φάση θα είναι πιο εύκολη.
Μια αξιόπιστη μέθοδος για την επιβεβαίωση μιας ευπάθειας SQL injection περιλαμβάνει την εκτέλεση μιας λογικής λειτουργίας και την παρατήρηση των αναμενόμενων αποτελεσμάτων. Για παράδειγμα, μια παράμετρος GET όπως ?username=Peter
που αποδίδει ταυτόσημο περιεχόμενο όταν τροποποιηθεί σε ?username=Peter' or '1'='1
υποδεικνύει μια ευπάθεια SQL injection.
Ομοίως, η εφαρμογή μαθηματικών λειτουργιών χρησιμεύει ως μια αποτελεσματική τεχνική επιβεβαίωσης. Για παράδειγμα, αν η πρόσβαση σε ?id=1
και ?id=2-1
παράγει το ίδιο αποτέλεσμα, αυτό είναι ενδεικτικό SQL injection.
Παραδείγματα που δείχνουν την επιβεβαίωση λογικών λειτουργιών:
Αυτή η λίστα λέξεων δημιουργήθηκε για να προσπαθήσει να επιβεβαιώσει SQLinjections με τον προτεινόμενο τρόπο:
Σε ορισμένες περιπτώσεις δεν θα παρατηρήσετε καμία αλλαγή στη σελίδα που δοκιμάζετε. Επομένως, ένας καλός τρόπος για να ανακαλύψετε τυφλές SQL injections είναι να κάνετε τη βάση δεδομένων να εκτελεί ενέργειες που θα έχουν επίδραση στον χρόνο που χρειάζεται η σελίδα για να φορτώσει. Επομένως, θα συνδυάσουμε στην SQL ερώτηση μια ενέργεια που θα χρειαστεί πολύ χρόνο για να ολοκληρωθεί:
Σε ορισμένες περιπτώσεις οι λειτουργίες ύπνου δεν θα επιτρέπονται. Τότε, αντί να χρησιμοποιήσετε αυτές τις λειτουργίες, μπορείτε να κάνετε το ερώτημα να εκτελεί σύνθετες λειτουργίες που θα διαρκέσουν αρκετά δευτερόλεπτα. Παραδείγματα αυτών των τεχνικών θα σχολιαστούν ξεχωριστά για κάθε τεχνολογία (αν υπάρχουν).
Ο καλύτερος τρόπος για να αναγνωρίσετε το back-end είναι να προσπαθήσετε να εκτελέσετε λειτουργίες των διαφόρων back-end. Μπορείτε να χρησιμοποιήσετε τις λειτουργίες ύπνου της προηγούμενης ενότητας ή αυτές (πίνακας από payloadsallthethings:
Επίσης, αν έχετε πρόσβαση στην έξοδο του ερωτήματος, θα μπορούσατε να κάνετε εκτύπωση της έκδοσης της βάσης δεδομένων.
Μια συνέχεια, θα συζητήσουμε διάφορες μεθόδους για να εκμεταλλευτούμε διάφορους τύπους SQL Injection. Θα χρησιμοποιήσουμε το MySQL ως παράδειγμα.
Αν μπορείτε να δείτε την έξοδο του ερωτήματος, αυτή είναι η καλύτερη μέθοδος για να το εκμεταλλευτείτε. Πρώτα απ' όλα, πρέπει να ανακαλύψουμε τον αριθμό των στηλών που επιστρέφει το αρχικό αίτημα. Αυτό συμβαίνει επειδή και τα δύο ερωτήματα πρέπει να επιστρέφουν τον ίδιο αριθμό στηλών. Δύο μέθοδοι χρησιμοποιούνται συνήθως για αυτόν τον σκοπό:
Για να προσδιορίσετε τον αριθμό των στηλών σε ένα ερώτημα, προσαρμόστε σταδιακά τον αριθμό που χρησιμοποιείται στις ρήτρες ORDER BY ή GROUP BY μέχρι να ληφθεί μια ψευδής απάντηση. Παρά τις διακριτές λειτουργίες των GROUP BY και ORDER BY μέσα στο SQL, και οι δύο μπορούν να χρησιμοποιηθούν με τον ίδιο τρόπο για να προσδιορίσουν τον αριθμό των στηλών του ερωτήματος.
Επιλέξτε όλο και περισσότερες τιμές null μέχρι η ερώτηση να είναι σωστή:
Πρέπει να χρησιμοποιείτε null
τιμές, καθώς σε ορισμένες περιπτώσεις ο τύπος των στηλών και στις δύο πλευρές του ερωτήματος πρέπει να είναι ο ίδιος και το null είναι έγκυρο σε κάθε περίπτωση.
Στα επόμενα παραδείγματα θα ανακτήσουμε το όνομα όλων των βάσεων δεδομένων, το όνομα του πίνακα μιας βάσης δεδομένων, τα ονόματα των στηλών του πίνακα:
Υπάρχει ένας διαφορετικός τρόπος για να ανακαλύψετε αυτά τα δεδομένα σε κάθε διαφορετική βάση δεδομένων, αλλά η μεθοδολογία είναι πάντα η ίδια.
Όταν η έξοδος ενός ερωτήματος είναι ορατή, αλλά μια ένεση βασισμένη σε ένωση φαίνεται ανέφικτη, αυτό σημαίνει την παρουσία μιας κρυφής ένεσης βασισμένης σε ένωση. Αυτό το σενάριο συχνά οδηγεί σε μια κατάσταση τυφλής ένεσης. Για να μετατραπεί μια τυφλή ένεση σε μια βασισμένη σε ένωση, πρέπει να διακριθεί το εκτελούμενο ερώτημα στο backend.
Αυτό μπορεί να επιτευχθεί μέσω της χρήσης τεχνικών τυφλής ένεσης μαζί με τους προεπιλεγμένους πίνακες που είναι συγκεκριμένοι για το Σύστημα Διαχείρισης Βάσεων Δεδομένων (DBMS) στόχου σας. Για να κατανοήσετε αυτούς τους προεπιλεγμένους πίνακες, συνιστάται να συμβουλευτείτε την τεκμηρίωση του DBMS στόχου.
Αφού έχει εξαχθεί το ερώτημα, είναι απαραίτητο να προσαρμόσετε το payload σας ώστε να κλείσει με ασφάλεια το αρχικό ερώτημα. Στη συνέχεια, προστίθεται ένα ερώτημα ένωσης στο payload σας, διευκολύνοντας την εκμετάλλευση της νέας προσβάσιμης ένεσης βασισμένης σε ένωση.
Για πιο ολοκληρωμένες πληροφορίες, ανατρέξτε στο πλήρες άρθρο που είναι διαθέσιμο στο Healing Blind Injections.
Εάν για κάποιο λόγο δεν μπορείτε να δείτε την έξοδο του ερωτήματος αλλά μπορείτε να δείτε τα μηνύματα σφάλματος, μπορείτε να κάνετε αυτά τα μηνύματα σφάλματος να εξάγουν δεδομένα από τη βάση δεδομένων. Ακολουθώντας μια παρόμοια ροή όπως στην εκμετάλλευση βασισμένη σε ένωση, θα μπορούσατε να καταφέρετε να εξάγετε τη βάση δεδομένων.
Σε αυτή την περίπτωση δεν μπορείτε να δείτε τα αποτελέσματα του ερωτήματος ή τα σφάλματα, αλλά μπορείτε να διακρίνετε πότε το ερώτημα επιστρέφει μια αληθινή ή μια ψευδή απάντηση επειδή υπάρχουν διαφορετικά περιεχόμενα στη σελίδα. Σε αυτή την περίπτωση, μπορείτε να εκμεταλλευτείτε αυτή τη συμπεριφορά για να εξάγετε τη βάση δεδομένων χαρακτήρα προς χαρακτήρα:
Αυτή είναι η ίδια περίπτωση όπως πριν αλλά αντί να διακρίνετε μεταξύ μιας αληθινής/ψευδούς απάντησης από το ερώτημα μπορείτε να διακρίνετε μεταξύ ενός σφάλματος στο SQL ερώτημα ή όχι (ίσως επειδή ο HTTP server καταρρέει). Επομένως, σε αυτή την περίπτωση μπορείτε να προκαλέσετε ένα SQLerror κάθε φορά που μαντεύετε σωστά τον χαρακτήρα:
Σε αυτή την περίπτωση δεν υπάρχει κανένας τρόπος να διακρίνουμε την απάντηση του ερωτήματος με βάση το περιεχόμενο της σελίδας. Αλλά, μπορείτε να κάνετε τη σελίδα να χρειάζεται περισσότερο χρόνο για να φορτώσει αν ο μαντεμένος χαρακτήρας είναι σωστός. Έχουμε ήδη δει αυτή την τεχνική σε χρήση πριν για να επιβεβαιώσουμε μια SQLi ευπάθεια.
Μπορείτε να χρησιμοποιήσετε τις stacked queries για να εκτελέσετε πολλαπλές ερωτήσεις διαδοχικά. Σημειώστε ότι ενώ οι επόμενες ερωτήσεις εκτελούνται, τα αποτελέσματα δεν επιστρέφονται στην εφαρμογή. Επομένως, αυτή η τεχνική είναι κυρίως χρήσιμη σε σχέση με τυφλές ευπάθειες όπου μπορείτε να χρησιμοποιήσετε μια δεύτερη ερώτηση για να ενεργοποιήσετε μια αναζήτηση DNS, μια συνθήκη σφάλματος ή μια καθυστέρηση χρόνου.
Oracle δεν υποστηρίζει stacked queries. MySQL, Microsoft και PostgreSQL τις υποστηρίζουν: QUERY-1-HERE; QUERY-2-HERE
Αν κανένας άλλος μέθοδος εκμετάλλευσης δεν λειτούργησε, μπορείτε να προσπαθήσετε να κάνετε τη βάση δεδομένων να εξάγει τις πληροφορίες σε έναν εξωτερικό host που ελέγχετε. Για παράδειγμα, μέσω ερωτήσεων DNS:
Δείτε το SQLMap Cheatsheet για να εκμεταλλευτείτε μια ευπάθεια SQLi με sqlmap.
Έχουμε ήδη συζητήσει όλους τους τρόπους εκμετάλλευσης μιας ευπάθειας SQL Injection. Βρείτε μερικά ακόμη κόλπα που εξαρτώνται από την τεχνολογία βάσης δεδομένων σε αυτό το βιβλίο:
Ή θα βρείτε πολλά κόλπα σχετικά με: MySQL, PostgreSQL, Oracle, MSSQL, SQLite και HQL σε https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection
RootedCON είναι η πιο σχετική εκδήλωση κυβερνοασφάλειας στην Ισπανία και μία από τις πιο σημαντικές στην Ευρώπη. Με αποστολή την προώθηση της τεχνικής γνώσης, αυτό το συνέδριο είναι ένα καυτό σημείο συνάντησης για επαγγελματίες της τεχνολογίας και της κυβερνοασφάλειας σε κάθε πειθαρχία.
Λίστα για να προσπαθήσετε να παρακάμψετε τη λειτουργία σύνδεσης:
Login bypass ListΑυτό το ερώτημα επιδεικνύει μια ευπάθεια όταν το MD5 χρησιμοποιείται με true για ακατέργαστη έξοδο σε ελέγχους ταυτοποίησης, καθιστώντας το σύστημα ευάλωτο σε SQL injection. Οι επιτιθέμενοι μπορούν να εκμεταλλευτούν αυτό δημιουργώντας εισόδους που, όταν κατακερματίζονται, παράγουν απροσδόκητα μέρη SQL εντολών, οδηγώντας σε μη εξουσιοδοτημένη πρόσβαση.
Συνιστώμενη λίστα:
Πρέπει να χρησιμοποιήσετε ως όνομα χρήστη κάθε γραμμή της λίστας και ως κωδικό πρόσβασης πάντα: Pass1234. &#xNAN;(Αυτά τα payloads περιλαμβάνονται επίσης στη μεγάλη λίστα που αναφέρθηκε στην αρχή αυτής της ενότητας)
ΑΝ το ' διαφεύγει μπορείτε να χρησιμοποιήσετε %A8%27, και όταν το ' διαφύγει θα δημιουργηθεί: 0xA80x5c0x27 (╘')
Python script:
Για να το κάνετε αυτό, θα πρέπει να προσπαθήσετε να δημιουργήσετε ένα νέο αντικείμενο με το όνομα του "κύριου αντικειμένου" (πιθανώς admin στην περίπτωση χρηστών) τροποποιώντας κάτι:
Δημιουργήστε χρήστη με το όνομα: AdMIn (κεφαλαία & πεζά γράμματα)
Δημιουργήστε έναν χρήστη με το όνομα: admin=
SQL Truncation Attack (όταν υπάρχει κάποιο είδος περιορισμού μήκους στο όνομα χρήστη ή το email) --> Δημιουργήστε χρήστη με το όνομα: admin [πολλοί χώροι] a
Εάν η βάση δεδομένων είναι ευάλωτη και ο μέγιστος αριθμός χαρακτήρων για το όνομα χρήστη είναι για παράδειγμα 30 και θέλετε να προσποιηθείτε τον χρήστη admin, προσπαθήστε να δημιουργήσετε ένα όνομα χρήστη που ονομάζεται: "admin [30 χώροι] a" και οποιοδήποτε κωδικό πρόσβασης.
Η βάση δεδομένων θα ελέγξει αν το εισαγόμενο όνομα χρήστη υπάρχει μέσα στη βάση δεδομένων. Εάν όχι, θα κόψει το όνομα χρήστη στο μέγιστο επιτρεπόμενο αριθμό χαρακτήρων (σε αυτή την περίπτωση σε: "admin [25 χώροι]") και στη συνέχεια θα αφαιρέσει αυτόματα όλους τους χώρους στο τέλος ενημερώνοντας μέσα στη βάση δεδομένων τον χρήστη "admin" με τον νέο κωδικό πρόσβασης (μπορεί να εμφανιστεί κάποιο σφάλμα αλλά αυτό δεν σημαίνει ότι δεν έχει λειτουργήσει).
Περισσότερες πληροφορίες: https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html & https://resources.infosecinstitute.com/sql-truncation-attack/#gref
Σημείωση: Αυτή η επίθεση δεν θα λειτουργεί πλέον όπως περιγράφεται παραπάνω στις τελευταίες εγκαταστάσεις MySQL. Ενώ οι συγκρίσεις εξακολουθούν να αγνοούν τα κενά στο τέλος από προεπιλογή, η προσπάθεια εισαγωγής μιας συμβολοσειράς που είναι μεγαλύτερη από το μήκος ενός πεδίου θα έχει ως αποτέλεσμα ένα σφάλμα, και η εισαγωγή θα αποτύχει. Για περισσότερες πληροφορίες σχετικά με αυτό το έλεγχο: https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation
Προσθέστε όσο το δυνατόν περισσότερα ','',''
θεωρείτε ότι χρειάζεται για να βγείτε από τη δήλωση VALUES. Εάν εκτελείται καθυστέρηση, έχετε μια SQLInjection.
Η ρήτρα ON DUPLICATE KEY UPDATE
στο MySQL χρησιμοποιείται για να καθορίσει ενέργειες που πρέπει να αναλάβει η βάση δεδομένων όταν γίνεται μια προσπάθεια εισαγωγής μιας γραμμής που θα είχε ως αποτέλεσμα μια διπλή τιμή σε έναν UNIQUE δείκτη ή PRIMARY KEY. Το παρακάτω παράδειγμα δείχνει πώς μπορεί να εκμεταλλευτεί αυτή η δυνατότητα για να τροποποιηθεί ο κωδικός πρόσβασης ενός λογαριασμού διαχειριστή:
Example Payload Injection:
Ένα payload εισαγωγής μπορεί να κατασκευαστεί ως εξής, όπου δύο γραμμές προσπαθούν να εισαχθούν στον πίνακα users
. Η πρώτη γραμμή είναι μια παγίδα, και η δεύτερη γραμμή στοχεύει το υπάρχον email ενός διαχειριστή με σκοπό την ενημέρωση του κωδικού πρόσβασης:
Here's how it works:
Το ερώτημα προσπαθεί να εισάγει δύο γραμμές: μία για generic_user@example.com
και μία άλλη για admin_generic@example.com
.
Εάν η γραμμή για admin_generic@example.com
υπάρχει ήδη, η ρήτρα ON DUPLICATE KEY UPDATE
ενεργοποιείται, δίνοντας εντολή στο MySQL να ενημερώσει το πεδίο password
της υπάρχουσας γραμμής σε "bcrypt_hash_of_newpassword".
Κατά συνέπεια, η αυθεντικοποίηση μπορεί στη συνέχεια να επιχειρηθεί χρησιμοποιώντας admin_generic@example.com
με τον κωδικό πρόσβασης που αντιστοιχεί στο bcrypt hash ("bcrypt_hash_of_newpassword" αντιπροσωπεύει το bcrypt hash του νέου κωδικού πρόσβασης, το οποίο θα πρέπει να αντικατασταθεί με το πραγματικό hash του επιθυμητού κωδικού πρόσβασης).
Όταν προσπαθείτε να δημιουργήσετε έναν νέο χρήστη, απαιτούνται το όνομα χρήστη, ο κωδικός πρόσβασης και το email:
Με αυτή την τεχνική μπορείτε να εξάγετε πληροφορίες δημιουργώντας μόνο 1 λογαριασμό. Είναι σημαντικό να σημειωθεί ότι δεν χρειάζεται να σχολιάσετε τίποτα.
Χρησιμοποιώντας hex2dec και substr:
Για να αποκτήσετε το κείμενο μπορείτε να χρησιμοποιήσετε:
Χρησιμοποιώντας hex και replace (και substr):
RootedCON είναι η πιο σχετική εκδήλωση κυβερνοασφάλειας στην Ισπανία και μία από τις πιο σημαντικές στην Ευρώπη. Με αποστολή την προώθηση της τεχνικής γνώσης, αυτό το συνέδριο είναι ένα καυτό σημείο συνάντησης για επαγγελματίες της τεχνολογίας και της κυβερνοασφάλειας σε κάθε τομέα.
Routed SQL injection είναι μια κατάσταση όπου το ερωτηματικό που μπορεί να εισαχθεί δεν είναι αυτό που δίνει έξοδο, αλλά η έξοδος του ερωτήματος που μπορεί να εισαχθεί πηγαίνει στο ερώτημα που δίνει έξοδο. (Από Έγγραφο)
Example:
No Space (%20) - παρακάμψη χρησιμοποιώντας εναλλακτικές κενές θέσεις
No Whitespace - παράκαμψη χρησιμοποιώντας σχόλια
No Whitespace - παράκαμψη χρησιμοποιώντας παρενθέσεις
No Comma - παράκαμψη χρησιμοποιώντας OFFSET, FROM και JOIN
Λίστα αποκλεισμού χρησιμοποιώντας λέξεις-κλειδιά - παράκαμψη χρησιμοποιώντας κεφαλαία/μικρά γράμματα
Blacklist χρησιμοποιώντας λέξεις-κλειδιά χωρίς διάκριση πεζών-κεφαλαίων - παράκαμψη χρησιμοποιώντας έναν ισοδύναμο τελεστή
Μπορείτε να βρείτε μια πιο λεπτομερή εξήγηση αυτού του κόλπου στο gosecure blog. Βασικά, μπορείτε να χρησιμοποιήσετε την επιστημονική σημειογραφία με απροσδόκητους τρόπους για να παρακάμψετε το WAF:
Πρώτα απ' όλα, παρατηρήστε ότι αν το αρχικό ερώτημα και ο πίνακας από τον οποίο θέλετε να εξαγάγετε τη σημαία έχουν τον ίδιο αριθμό στηλών μπορείτε απλά να κάνετε: 0 UNION SELECT * FROM flag
Είναι δυνατόν να έχετε πρόσβαση στην τρίτη στήλη ενός πίνακα χωρίς να χρησιμοποιήσετε το όνομά της χρησιμοποιώντας ένα ερώτημα όπως το εξής: SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;
, οπότε σε μια sqlinjection αυτό θα φαίνεται έτσι:
Ή χρησιμοποιώντας ένα comma bypass:
Αυτή η τεχνική ελήφθη από https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/
RootedCON είναι η πιο σχετική εκδήλωση κυβερνοασφάλειας στην Ισπανία και μία από τις πιο σημαντικές στην Ευρώπη. Με αποστολή την προώθηση της τεχνικής γνώσης, αυτό το συνέδριο είναι ένα καυτό σημείο συνάντησης για επαγγελματίες της τεχνολογίας και της κυβερνοασφάλειας σε κάθε πειθαρχία.
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)