StarMedia
Doriti să reactionati la acest mesaj? Creati un cont în câteva clickuri sau conectati-vă pentru a continua.
StarMedia

by Disconnect
 
AcasaAcasa  Ultimele imaginiUltimele imagini  ÎnregistrareÎnregistrare  Conectare  

 

 Mic tutorial pentru Anti-SQL-Inject

In jos 
AutorMesaj
Disconnect
Admin
Admin
Disconnect


Numarul mesajelor : 59
Data de inscriere : 13/06/2008

Mic tutorial pentru Anti-SQL-Inject Empty
MesajSubiect: Mic tutorial pentru Anti-SQL-Inject   Mic tutorial pentru Anti-SQL-Inject EmptySam Iun 28, 2008 7:09 am

*Am facut acest tutorial fiindca am vazut foarte multe servere in ultima vreme "picand" ...acesta este mai mult ca un sfat!
Nu dau credite nimanui credite-le nu isi au locul aici!

Folositi unul din web-urile de mai jos:
*Aceste web-uri nu pot fi injectate sau pana la momentrul de fata nu sau gasit hole-uri (gauri) pentru a le injecta...deci av recomand:
-MuWeb 0.3 http://files.filefront.com/DmgTeam+MuSite+V+10rar/;10671010;/fileinfo.html
-MuWeb 0.9 http://products.muweb.org/download.php
-DMG Team WebSite v0.1 http://files.filefront.com/DmgTeam+MuSite+V+10rar/;10671010;/fileinfo.html
*DMG Team WebSite v0.2 coming soon

Pentru inceput sa vorbim putin despre Injection:

Pentru o vizualizare mai "atractiva" vizitati: http://weblogs.studentclub.ro/ovidiupl/archive/2005/10/20/12168.aspx
Ovidiu Platon a scris:
Un mit despre SQL Injection

În prezent, cea mai mare parte a aplicaţiilor dezvoltate la noi şi în lumea largă folosesc pe undeva şi o bază de date, iar limbajul preferat pentru interacţiunea cu diferitele implementări de motoare relaţionale este SQL (Structured Query Language). În condiţiile în care securitatea are prioritate maximă în orice aplicaţie, nu e de mirare că noţiunea de SQL Injection, un atac foarte comun asupra bazelor de date, a fost tratată pe larg în diferite materiale.

În primul rând, să clarificăm puţin ce înseamnă injectarea de cod în general şi SQL Injection în particular. Injectarea de cod este procesul prin care cod executabil străin este introdus în memoria unui proces, de obicei deghizat în date, prin intermediul unei vulnerabilităţi oarecare. Un exemplu clasic de injectare de cod este exploatarea vulnerabilităţilor de tip buffer overrun, cu injectarea de cod executabil prin intermediul unui şir de caractere invalid şi neverificat de aplicaţie.

SQL Injection reprezintă introducerea de comenzi SQL într-un script utilizat de o aplicaţie de baze de date. Vectorul de atac îl reprezintă instrucţiunile SQL generate dinamic de aplicaţie, după cum vom vedea în detaliu puţin mai jos. Un atac SQL Injection poate avea consecinţe variate, de la divulgarea de informaţii confidenţiale şi până la preluarea controlului complet asupra serverului de baze de date, în funcţie de prezenţa altor vulnerabilităţi.

Problema îşi are originile în modalitatea tradiţională de a scrie interogările SQL: Direct în codul aplicaţiei, sub formă de şiruri de caractere concatenate pentru obţinerea interogării care va fi trimisă serverului. De exemplu, pentru a vedea dacă o combinaţie utilizator + parolă se află în baza de date, am putea scrie:

SELECT COUNT(*) FROM [dbo].[Users]
WHERE [Username] = 'user' AND [Password] = 'pass'

(Să trecem peste faptul că stocarea parolelor direct în baza de date e o idee foarte proastă). Într-o aplicaţie scrisă în C# cu ADO.NET, o astfel de comandă ar putea fi formulată în felul următor:

// Codul de mai jos nu tine cont de necesitati
// ale aplicatiilor reale: eliberarea resurselor, prinderea
// exceptiilor samd. Nu il folositi ca atare in aplicatii
// de productie
string connectionString;
string userName, password;
// ...
// Initializarile de rigoare
// ...
SqlConnection sqlConn = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = sqlConn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT COUNT(*) FROM [dbo].[Users] " +
"WHERE [Username] = '" + userName + "' AND [Password] = '" +
password + "'";
sqlConn.Open();
cmd.ExecuteNonQuery();
// ... Alte comenzi

Un exerciţiu mic pentru cititori: Să spunem că după apelarea procedurii stocate, într-o variabilă întreagă numită userCount avem numărul de utilizatori pentru care combinaţia utilizator + parolă există în baza de date. Cum e mai bine să scriem testul: if (userCount != 0) sau if (userCount == 1)? De ce?

Ce se întâmplă dacă, dintr-un motiv sau altul, în loc de numele de utilizator, cineva introduce ' OR 1 = 1 --?

Comanda SQL devine:

SELECT COUNT(*) FROM [dbo].[Users]
WHERE [Username] = '' OR 1 = 1 -- AND [Password] = '...'

Problema e că primul apostrof devine perechea celui care deschidea şirul reprezentând numele utilizatorului, 1 = 1 este întotdeauna adevărat, OR este adevărat dacă unul din operanzi este adevărat, şi atunci expresia din clauza WHERE e adevărată tot timpul. (Şirul -- reprezintă un comentariu în Transact SQL - varietatea de SQL din Microsoft SQL Server - şi textul de după acest şir este ignorat.)

Exemplul de mai sus e un fel de "Hello, World!" al SQL Injection şi îl găsiţi în nenumărate materiale. O aplicaţie ce îşi construieşte interogările în mod dinamic în acest fel e o gaură de securitate aşteptând să fie exploatată, iar exemplul dat este inocent în comparaţie cu ce se poate obţine prin SQL Injection.

În general vulnerabilităţi de acest gen apar în aplicaţii web, deoarece modelul aplicaţie web + bază de date este foarte popular. Nu vă lăsaţi păcăliţi, asta nu înseamnă că doar aplicaţiile web sunt vulnerabile. Orice aplicaţie care îşi construieşte cererile în mod dinamic ca în exemplul dat expune acest gen de vulnerabilităţi. Dar nu aici doream să ajung.

Mitul pe care vreau să îl scutur puţin este "Prin utilizarea procedurilor stocate riscul atacurilor de tip SQL Injection dispare". Această afirmaţie ascunde de fapt o altă afirmaţie cu care nu sunt de acord: Cererile formulate dinamic sunt în mod inerent "diabolice". Mai mult, unii adoptă afirmaţia de mai sus ca atare şi o susţin cu fervoare religioasă, fără să ştie toate aspectele problemei.

Nu mă înţelegeţi greşit: Sunt un fan uriaş al procedurilor stocate. Motivele pentru care folosesc aproape exclusiv proceduri stocate ţin de modularizarea codului (care duce la localizarea modificărilor şi la uşurinţa în întreţinere), de posibilitatea de a testa procedurile stocate individual, de securizarea lor prin liste de control al accesului, de eleganţa aplicaţiei pe ansamblu.

Cu toate acestea, există unele lucruri pe care procedurile stocate nu le pot face în mod elegant. Să vă dau un exemplu simplu: Să presupunem că avem o tabelă cu utilizatori care conţine printre altele două coloane (varchar de o lungime oarecare, pentru simplitate), numite FirstName şi LastName. Să presupunem că pe undeva prin aplicaţia construită pe această bază de date am un câmp text în care utilizatorii pot introduce nume care să fie căutate în baza de date. Pentru că avem o aplicaţie extrem de simplă nu folosim Full Text Search sau alte artificii spectaculoase, ci recurgem la o interogare banală.

Dacă un utilizator introduce "Ioan Popescu" în câmpul text, presupunem că doreşte să vadă acele persoane din baza de date care au în componenţa numelui complet ambele cuvinte. Atunci, o interogare ar putea arăta în felul următor:

SELECT * FROM [dbo].[Users]
WHERE (([FirstName] LIKE '%Ioan%') OR ([LastName] LIKE '%Ioan%')) AND
(([FirstName] LIKE '%Popescu%') OR ([LastName] LIKE '%Popescu%'))

Dacă, însă, utilizatorul introduce "Ioan Gigel Popescu", interogarea devine:

SELECT * FROM [dbo].[Users]
WHERE (([FirstName] LIKE '%Ioan%') OR ([LastName] LIKE '%Ioan%')) AND
(([FirstName] LIKE '%Gigel%') OR ([LastName] LIKE '%Gigel%')) AND
(([FirstName] LIKE '%Popescu%') OR ([LastName] LIKE '%Popescu%'))

Aşa ceva nu e tocmai banal de implementat într-o procedură stocată, ţinând cont că nu se poate şti în avans cum va arăta clauza WHERE. Cum nu dorim să formulăm cererea în mod dinamic, am cam rămas fără opţiuni, nu? Ei bine, nu. Soluţia o reprezintă cererile parametrizate. Presupunând că folosim C#, ADO.NET şi SQL Server, iată cum ar arăta o cerere parametrizată pentru prima interogare:

// Sa presupunem ca tabloul e deja initializat
// si ca am verificat validitatea datelor
// (tabloul are cel putin un element,
// nu exista nici un null, nici un sir
// vid, am testat fiecare cuvant cu
// expresii regulate pentru a ne asigura
// ca avem doar litere samd).
string[] keywords;
string connectionString = "...";

SqlConnection sqlConn = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = sqlConn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM [dbo].[Users] WHERE ";
// ATENTIE: Codul de mai jos este doar un exemplu
// In cod real va recomand sa folositi StringBuilder
// pentru a concatena siruri multiple si sa scrieti
// cod mai putin criptic.
for (int i = 0; i <keywords> 0)
{
cmd.CommandText += " AND ";
}
cmd.CommandText += string.Format(
"(([FirstName] LIKE @Argument{0}) OR ([LastName] LIKE @Argument{0}))", i);
cmd.Parameters.Add(
string.Format("@Argument{0}", i),
SqlDbType.VarChar, 80).Value = keywords[i];
}
sqlConn.Open();
SqlDataReader reader = cmd.ExecuteReader();
// ... samd

Cu o abordare de genul acesta, prima interogare devine

SELECT * FROM [dbo].[Users]
WHERE (([FirstName] LIKE @Argument0) OR ([LastName] LIKE @Argument0)) AND
(([FirstName] LIKE @Argument1) OR ([LastName] LIKE @Argument1))

iar a doua devine

SELECT * FROM [dbo].[Users]
WHERE (([FirstName] LIKE @Argument0) OR ([LastName] LIKE @Argument0)) AND
(([FirstName] LIKE @Argument1) OR ([LastName] LIKE @Argument1)) AND
(([FirstName] LIKE @Argument2) OR ([LastName] LIKE @Argument2))

În exemplele date, Argument0 .. Argument2 conţin "%Ioan%", "%Gigel%", respectiv "%Popescu%" (fără ghilimele, evident). Avantajul este că indiferent ce ar conţine, şirurile de caractere nu vor modifica în nici un fel căutarea aşa cum o face un atac SQL Injection.

Repetaţi după mine: "Prin utilizarea cererilor parametrizate riscul atacurilor de tip SQL Injection dispare". În general, vă recomand să folosiţi proceduri stocate cu cea mai mare încredere, pentru că au o listă întreagă de avantaje. Ţineţi cont, însă, că invocarea procedurilor stocate este un caz particular de invocare al unei cereri parametrizate. Dacă ajungeţi într-o situaţie când trebuie neapărat să compuneţi dinamic o interogare, aceasta este modalitatea corectă de a o face.

Atrag atenţia asupra acestui aspect dintr-un motiv simplu: Unii oameni asociază procedurile stocate cu eliminarea SQL Injection fără a înţelege că parametrizarea este cea care duce la securizarea aplicaţiei. În aceste condiţii, respectivele persoane adoptă politici de genul "folosim doar proceduri stocate în aplicaţie", ajung în situaţii în care cererile formulate dinamic reprezintă singura soluţie, aşa că scriu o procedură stocată care acceptă un argument de tip şir de caractere, pe care îl execută în interior cu EXECUTE sau cu sp_executesql, fără să realizeze că au ajuns de unde au plecat.

Pentru a nu mai lungi vorba, să recapitulăm:

* NU concatenaţi şiruri de caractere pentru a forma comenzi SQL şi NU executaţi aceste comenzi prin nici un mijloc.
* Folosiţi numai cereri parametrizate. Încercaţi să folosiţi proceduri stocate în cât mai multe situaţii, iar când acest lucru nu este posibil creaţi interogările dinamic, dar cu argumentele transmise ca parametri.

Sper să vă fie de folos sfatul meu. Dacă mai aveţi alte sugestii legate de acest subiect, aştept comentarii.



De ce va recomand MuWeb-urile de mai sus?
Deoarece sunt unele dintre singurele web-uri care nu au ft multe "gauri"
Sus In jos
https://starmedia.forum-canada.com
 
Mic tutorial pentru Anti-SQL-Inject
Sus 
Pagina 1 din 1
 Subiecte similare
-
» Anti injectie script pentru DB!
» Un Program Pentru Muzica!
» Fuckoff pentru codati [AMXX]
» Programe Pentru Yahoo Messenger!
» Tutorial Zombie Mod

Permisiunile acestui forum:Nu puteti raspunde la subiectele acestui forum
StarMedia :: Mu Online :: Cum sa faci site pentru server de Mu Online-
Mergi direct la: