Το sql injection στις data driven εφαρμογές (Μέρος Α’)

Το sql injection στις data driven εφαρμογές (Μέρος Α’)

Το sql injection στις data driven εφαρμογές είναι τεχνική ενσωμάτωσης κώδικα, η οποία χρησιμοποιείται για επιθέσεις στις εφαρμογές αυτές. Σύμφωνα με την τεχνική αυτή, κακόβουλα SQL statements εισάγονται σε ένα πεδίο εισόδου προς εκτέλεση, για παράδειγμα να εξάγουν ολόκληρη τη βάση μαζί με τα δεδομένα της στον επιτιθέμενο.

Η τεχνική SQL injection για να επιτύχει κάποιο αποτέλεσμα πρέπει να εκμεταλλεύεται αδυναμίες/ ελλείψεις ασφαλείας στο λογισμικό της εφαρμογής, όπως όταν τα δεδομένα εισόδου από το χρήστη φιλτράρονται λανθασμένα σε σχέση με τους χαρακτήρες διαφυγής που είναι ενσωματωμένοι στη γλώσσα SQL.

Το SQL injection αποτελεί ένα ευρέως διαδεδομένο τρόπο επίθεσης σε ιστοσελίδες, αλλά μπορεί να χρησιμοποιηθεί και για επίθεση/ υποκλοπή σε κάθε τύπο SQL βάσης δεδομένων. Επιτρέπει στον επιτιθέμενο να υποκλέψει ταυτότητα, υπάρχοντα δεδομένα, να προκαλέσει ισχυρά ζητήματα ακεραιότητας σε βάσεις οικονομικού περιεχομένου (πχ κενές συναλλαγές ή χρεώσεις λογαριασμών), να μπλοκάρει το σύνολο των υπάρχοντων δεδομένων, να καταστήσει τη βάση σε αχρησία, καθώς και να αναλάβει τα καθήκοντα του διαχειριστή της βάσης.

Παρακάτω παρατίθενται τύποι επιθέσεων ανάλογων των αδυναμιών του κώδικα SQL.

Το sql injection στις data driven εφαρμογές: από ελλιπές φιλτράρισμα των SQL escape characters

Αυτός ο τύπος SQL injection προκύπτει όταν τα δεδομένα που εισάγονται από το χρήστη δεν ελέγχονται ως προς τα escape characters και επομένως περνούν αυτούσια σε  κάποιο SQL statement. Το γεγονός αυτό οδηγεί στον επιδέξιο χειρισμό του SQL statement από τον επιτήδειο χρήστη του τερματικού που χρησιμοποιεί την εφαρμογή.
Η ακόλουθη γραμμή κώδικα αναπαριστά αυτήν την ευαισθησία:

statement = “SELECT * FROM users WHERE name = ‘” + userName + “‘;”

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

Για παράδειγμα, εάν η μεταβλητή αλλαχθεί με την τιμή ‘ OR ‘1’=’1 ή εάν χρησιμοποιηθούν σχόλια ώστε να αποκλείσουν τη συνέχεια του ερωτήματος (πχ τέλος ερώτησης), η εντολή που προκύπτει θα είναι η ακόλουθη, αντίστοιχα για κάθε περίπτωση:

SELECT * FROM users WHERE name = '' OR '1'='1';
SELECT * FROM users WHERE name = '' OR '1'='1' -- ';

Η εκτέλεση του παραπάνω παραμετροποιημένου κώδικα θα οδηγούσε την εφαρμογή στη βεβιασμένη επιλογή όλων των πεδίων δεδομένων από όλους τους χρήστες, αντί του ενός. Εξάλλου η αξία της τελευταίας συνθήκης ‘1’=’1′ είναι πάντα αληθής.

Το sql injection στις data driven εφαρμογές: από επιτρεπόμενη εκτέλεση πολλαπλών ερωτημάτων

Στο παράδειγμα που ακολουθεί στη θέση της μεταβλητής μπαίνουν παραπάνω από ένα ερωτήματα, στην περίπτωση που η διεπαφή της εφαρμογής επιτρέπει πολλαπλά statements.

SELECT * FROM users WHERE name = 'SELECT * FROM userinfo WHERE id=1; DROP TABLE users;';

Ολόκληρο το ερώτημα μεταφράζεται ως

SELECT * FROM users WHERE name = 'SELECT * FROM userinfo WHERE id=1; DROP TABLE users;';

.
Προκαλεί τη διαγραφή ολόκληρου του πίνακα χρηστών, καθώς και την επιστροφή των στοιχείων/ πληροφοριών των χρηστών από τον πίνακα userinfo.
Παρότι οι περισσότεροι SQL servers επιτρέπουν την εκτέλεση πολλών ερωτημάτων στη σειρά, κάποια SQL API, όπως το PHP’s mysql_query()  το αποκλείουν για λόγους ασφαλείας. Έτσι ο επιτιθέμενος αποτρέπεται από το να εμβολιάσει τον Server με πολλαπλά ερωτήματα.

Το sql injection στις data driven εφαρμογές: από ασαφή καθορισμό του τύπου δεδομένων εισαγωγής

Αυτός ο τύπος SQL injection μπορεί να προκύψει εάν τα πεδία όπου η εισαγωγή δεδομένων πραγματοποιείται από το χρήστη δεν έχουν καθοριστεί σαφώς ως προς τον τύπο δεδομένων για τον οποίο προορίζονται. Επίσης όταν δεν πραγματοποιείται έλεγχος κατά την εισαγωγή ή δεν υπάρχουν δικλείδες ασφαλείας.
Ανάλογο παράδειγμα είναι το ακόλουθο, όπου το πεδίο που πρόκειται να χρησιμοποιηθεί σε ερώτημα έχει οριστεί ως πεδίο αριθμητικού τύπου. Ο συντάκτης του κώδικα δεν έχει προνοήσει για την επικύρωση του τύπου των δεδομένων εισαγωγής. Κατ’ επέκταση ο χρήστης έχει τη δυνατότητα να εισάγει συμβολοσειρά στο ίδιο πεδίο:

statement = “SELECT * FROM userinfo WHERE id =” + variable + “;”

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

Για παράδειγμα θέτοντας την έκφραση

SELECT * FROM users WHERE name = 'SELECT * FROM userinfo WHERE id=1; DROP TABLE users;';

αντί του ορίσματος variable, το ερώτημα που προκύπτει θα διαγράψει ολόκληρο τον πίνακα users από τη βάση δεδομένων. Το ερώτημα δηλαδή ισοδυναμεί με το ακόλουθο:

SELECT * FROM users WHERE name = 'SELECT * FROM userinfo WHERE id=1; DROP TABLE users;';

Απάντηση

Αυτός ο ιστότοπος χρησιμοποιεί το Akismet για να μειώσει τα ανεπιθύμητα σχόλια. Μάθετε πώς υφίστανται επεξεργασία τα δεδομένα των σχολίων σας.