User Tools

Site Tools


second_order_sqli

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
second_order_sqli [2023/12/04 14:45] lsssecond_order_sqli [2026/06/18 17:52] (current) mbunic
Line 1: Line 1:
 ====Second order SQL injection==== ====Second order SQL injection====
  
-Second order SQL injection je podskup SQL injection ranjivosti, koji je kompliciraniji za izvršiti, ali je i razvojnim programerima teže detektirati takvu ranjivost . Razlika je što obični (first order) SQL injection je prisutan u slučajevima kada se korisnički unos, koji se odmah izvršava unutar nekog SQL upita, nije dobro sanitiziran i osiguran, dok second order SQL injection se izvršava tako da se neki korisnički unos prvo pohrani negdje na server ili u bazu podataka, a zatim se pozivanjem neke druge funkcionalnosti, koja koristi taj pohranjeni korisnički unos izvršava SQL injection.+**Second order SQL injection** je podskup **SQL injection** ranjivosti. Iskorištavanje ove ranjivosti je kompleksnije od uobičajenog SQL injectiona, ali ju je također teže detektirati.
  
-Jednostavan primjer bi bio aplikacijagdje je forma za registraciju korisnika zaštićena od SQL injectiona tako što dobro interpretira unos korisnika kao string i ne može se „escape-ati“ pomoćposebnih znakovate bi korisnik pokušajem registracijom gdje unosi vrijednost  <code>" user' or 'a' = 'a' — " </code>u polje imena novog korisnikasamo stvorio novog korisnika kojemu bi username bio <code>" user' or 'a' = 'a' —  "</code> , ali kada bi taj korisnik koristio funkcionalnost promjene lozinke, gdje se pri promjeni lozinke koristi SQL upit u koji se ubacuje korisničko ime korisnika kojemu se mijenja lozinka, ako kod nije ispravno zaštićen, izvršio bi seSQL injection unutar SQL koda u kojemu bi se trebalo odabranom korisniku promijeniti lozinku+Uobičajeni SQL injection se pojavljuje kada se korisnički unos direktno koristi za konstrukciju SQL upitadok se second order SQL injection izvršava tako da se neki korisnički unos prvo pohrani negdje na poslužitelju ili bazu podataka, a zatim se pozivanjem neke druge funkcionalnostikoja koristi taj pohranjeni korisnički unos, izvršava SQL injection.
  
-Primjer nezaštićenog koda za izmjenu lozinke bio:  +Jednostavan primjer bila bi aplikacija u kojoj se unos iz forme za registraciju korisnika koristi u SQL upitu za dodavanje korisnika u bazu na siguran način, ali se taj unos pri kasnijem korištenju ne koristi ispravno. 
 + 
 +Aplikacija pri registraciji ispravno interpretira unos korisničkog imena kao string, te konstrukcija SQL upita za stvaranje korisnika nije ranjiva na SQL injection. 
 + 
 +Pri registraciji napadač kao korisničko ime unosi vrijednost: 
 + 
 +<code>user' or 'a' = 'a' --  </code> 
 + 
 +čime se samo u bazi stvara novi korisnik s tim korisničkim imenom.  
 + 
 +Ako postoji funkcionalnost za promjenu lozinke, gdje se koristi SQL upit u koji se ubacuje korisničko ime korisnika kojemu se mijenja lozinka, bez adekvatnih zaštita, može doći do SQL injectiona. 
 + 
 +Primjer ranjivog koda za izmjenu lozinke:  
  
 <code>  <code> 
-"UPDATE users SET password=" + novi_password + "WHERE username=" + korisnicko_ime "and password="stari password+UPDATE users SET password = '" + novi_password + "WHERE username = '" + korisnicko_ime "and password = '" + stari_password +"'"
 </code> </code>
  
-(pretpostavka je da je korisnikov unos novog passworda također dobro filtriran)+(pretpostavka je da je unos lozinke dobro filtriran jer se koristi izravno kao vanjski unos, dok se korisničko ime dohvaća iz baze i zato se pogrešno koristi bez dodatne zaštite)
  
-Pri pokretanju ovog koda za prethodno registriranog korisnika s unosom novog passworda „moj_novi_password23“, kod koji bi se izvršio bi bio:+Kada bi napadač prethodno definiranim korisničkim imenom pokušao promijeniti svoju lozinku, unosom novog passworda „moj_novi_password23“, konstruirani SQL upit bi bio:
  
-<code>UPDATE users SET password= ’moj_novi_password23’  WHERE username=  ’user' or 'a' = 'a' — ’ and password= 'stari_password'</code> 
  
-No, uzimajući u obzir da je </code></code> jednako komentaru, prethodan kod jest ekvivalentan sljedećem: +<code> 
 +UPDATE users SET password = 'moj_novi_password23'  WHERE username =  'user' or 'a' = 'a' -- ' and password = 'stari_password' 
 +</code>
  
-<code>UPDATE users SET password= moj_novi_password23’  WHERE username=  ’user' or 'a' = 'a'</code>, čime bi se svim korisnicima password promijenio u <code>moj_novi_password23</code>.+Dvije crtice koje se pojavljuju u upitu su oznaka za početak komentara u mnogim relacijskim bazama podataka. 
 + 
 +<code> -- tekst nakon ove oznake se ne evaluira kao SQL upit nego se smatra komentarom </code> 
 + 
 +Radi toga se dio upita nakon pojave te oznake više ne tretira kao SQL kod, pa je zato prethodni upit ekvivalentan sljedećem:  
 + 
 +<code>UPDATE users SET password = 'moj_novi_password23 WHERE username = 'user' or 'a' = 'a'</code> 
 + 
 +Ovaj upit bi promijenio lozinku svih korisnika u
 + 
 + 
 +<code>moj_novi_password23</code>
  
 __**Primjer**__ - **Zadatak s Hacknite platforme** - **e-Trgovina Union** __**Primjer**__ - **Zadatak s Hacknite platforme** - **e-Trgovina Union**
  
-**TODOubaci opis zadatka ovdje**+<file> 
 +Lokalna trgovina je odlučila napraviti svoju web stranicu na kojoj kupci mogu pratiti svoju povijest kupovine. Korisnici se mogu sami registrirati na tu stranicu, i pri svakoj fizičkoj kupnji u trgovini mogu dati svoje korisničko ime kako bi se njihova povijest kupovine unijela u bazu podatka. Stranica bi mogla biti korisna svim sadašnjim i budućim kupcima trgovine! 
 + 
 +Flag je u formatu CTF2021[brojevi] 
 + 
 +http://chal.platforma.hacknite.hr:10010 
 +</file>
  
 Pri rješavanju zadatka, prvo što nam se nudi je forma za registraciju. Pri rješavanju zadatka, prvo što nam se nudi je forma za registraciju.
  
-**TODO: slika ovdje**+{{second_order_1.png}}
  
 Analizom izvornog koda ovog zadatka, koji je također dostupan u zadatku, vidimo da se SQL upit tako formiran da se nad njime ne mogu izvršavati SQL injekcije, što je prikazano u slici ispod. Analizom izvornog koda ovog zadatka, koji je također dostupan u zadatku, vidimo da se SQL upit tako formiran da se nad njime ne mogu izvršavati SQL injekcije, što je prikazano u slici ispod.
  
-**TODO: slika ovdje**+{{second_order_2.png}}
  
 Naime, kod koristi tzv. parametrizirane upite koji onemogućavaju SQL injekciju. Naime, kod koristi tzv. parametrizirane upite koji onemogućavaju SQL injekciju.
Line 37: Line 67:
 Analizom ostalih dijelova koda, može se vidjeti da se parametrizirani upiti koriste na svim mjestima, osim u funkciji //sadrzaj()//, unutar //user.php// datoteke. Analizom ostalih dijelova koda, može se vidjeti da se parametrizirani upiti koriste na svim mjestima, osim u funkciji //sadrzaj()//, unutar //user.php// datoteke.
  
-**TODO: slika ovdje**+{{second_order_3.png}}
  
 Ovdje vidimo da se parametar <code>$_SESSION["user"]</code> ne ubacuje u SQL upit na sigurni način, odnosno da postoji ranjivost. No parametar <code>$_SESSION["user"]</code> se već nalazi unutar sustava, taj parametar odgovara korisničkom imenu s kojim smo se registrirali. Ovdje vidimo da se parametar <code>$_SESSION["user"]</code> ne ubacuje u SQL upit na sigurni način, odnosno da postoji ranjivost. No parametar <code>$_SESSION["user"]</code> se već nalazi unutar sustava, taj parametar odgovara korisničkom imenu s kojim smo se registrirali.
Line 47: Line 77:
 Kao prvi pokušaj iskorištavanja ranjivosti možemo probati napraviti korisnički račun kojemu će korisničko ime biti  Kao prvi pokušaj iskorištavanja ranjivosti možemo probati napraviti korisnički račun kojemu će korisničko ime biti 
  
-<code> aaa' or '1' = '1' – </code>+<code> aaa' or '1' = '1' -- </code>
  
-Nakon stvaranja korisničkog računa sa ovim korisničkim imenom, vidimo da se sada unutar tablice povijesti proizvoda nalaze proizvodi svih ostalih korisnika u sustavu, kao što je prikazano na slici ispod.+Nakon stvaranja korisničkog računa ovim korisničkim imenom, vidimo da se sada unutar tablice povijesti proizvoda nalaze proizvodi svih ostalih korisnika u sustavu, kao što je prikazano na slici ispod.
  
-**TODO: slika ovdje**+{{second_order_4.png}}
  
-Ovo znači da smo uspjeli izvršiti SQL injekciju nad sustavom i da sada znamo iskoristiti ranjivost. Sada još samo moramo pronaći način kako napraviti SQL injekciju sa kojom ćemo dohvatiti one podatke koji nas zanimaju. +Ovo znači da smo uspjeli izvršiti SQL injekciju nad sustavom i da sada znamo iskoristiti ranjivost. Sada još samo moramo pronaći način kako napraviti SQL injekciju kojom ćemo dohvatiti one podatke koji nas zanimaju. 
  
-Iz koda znamo da u bazi postoji tablica //users//, sa poljima  //username//, //password// i //role//. Taj dio koda je vidljiv na slici 21.+Iz koda znamo da u bazi postoji tablica //users//, poljima  //username//, //password// i //role//. Taj dio koda je vidljiv na slici 21.
    
 Sada možemo pokušati izvršiti SQL injection, gdje će korisničko ime biti: Sada možemo pokušati izvršiti SQL injection, gdje će korisničko ime biti:
  
-<code> aaaa' UNION SELECT username, password FROM users – </code>+<code> aaaa' UNION SELECT username, password FROM users -- </code>
  
 Kako bismo dohvatili imena i lozinka korisnika iz baze. Izvršavanjem ove SQL injekcije, dobivamo error koji je prikazan na slici ispod. Kako bismo dohvatili imena i lozinka korisnika iz baze. Izvršavanjem ove SQL injekcije, dobivamo error koji je prikazan na slici ispod.
  
-** TODO: slika **+{{second_order_5.png}}
  
 Ovaj error nam govori da broj parametara u SELECT izrazu koji smo konstruirali ne odgovara broju parametara u SELECT izrazu s kojim radimo UNION. Ovaj error nam govori da broj parametara u SELECT izrazu koji smo konstruirali ne odgovara broju parametara u SELECT izrazu s kojim radimo UNION.
Line 69: Line 99:
 Iz koda znamo da izraz odgovara sljedećem: Iz koda znamo da izraz odgovara sljedećem:
  
 +<code>
 SELECT * FROM povijest WHERE korisnik= '  aaaa' UNION SELECT username,password FROM users  --  SELECT * FROM povijest WHERE korisnik= '  aaaa' UNION SELECT username,password FROM users  -- 
 +</code>
  
-Iako se u tablici za prikaz proizvoda na početnoj stranici nalaze samo dva stupca, SQL izraz kojeg mi manipuliramo, iz kojega se naknadno prikazuju ta dva stupca na stranici ima više od dva stupca, no ne možemo točno znati koliko, budući da u djelu koda „ SELECT * FROM povijest “, jedino znamo da se dohvaćaju svi stupci iz tablice povijest, ali ne znamo točno koliko 
  
-U sljedećem pokušaju možemo probati izvršiti SQL injectiongdje ćemo imati koristiti tri stupca SELECT izrazu. Primjer takvog pokušaja jest stvaranje korisničkog računa s korisničkim imenom:+Iako se u tablici za prikaz proizvoda na početnoj stranici nalaze samo dva stupca, SQL izraz kojeg mi manipuliramo, iz kojega se naknadno prikazuju ta dva stupca na stranici ima više od dva stupca, no ne možemo točno znati kolikobudući da djelu koda 
  
-<code> aaaa' UNION SELECT username,password,password FROM users – </code>+<code> 
 +SELECT FROM povijest  
 +</code>
  
-**TODOslika ovdje**+jedino znamo da se dohvaćaju svi stupci iz tablice povijest, ali ne znamo točno koliko 
 + 
 +U sljedećem pokušaju možemo probati izvršiti SQL injection, koristeći tri stupca u SELECT izrazu. Primjer takvog pokušaja jest stvaranje korisničkog računa s korisničkim imenom: 
 + 
 +<code> aaaa' UNION SELECT username,password,password FROM users -- </code> 
 + 
 +{{second_order_6.png}}
  
 Vidimo da smo uspješno dobili hasheve lozinki svih korisnika u sustavu. Također vidimo da se na stranici prikazuje samo zadnji parametar koji smo unijeli u našem SELECT izrazu, koji je u ovom slučaju password. Ako želimo prikazati više informacija, možemo koristiti SQL-ov operator konkatenacije:  „  ||  “, da bi prikazali više vrijednosti u jednom stupcu, na primjer da bi prikazali username i password odvojene znakom dvotočke, za zadnji parametar trebamo umjesto samo password, unijeti „ username|| ': '||password “, koristeći ovu vrijednost za zadnji parametar, finalno korisničko ime kojim ćemo izvršiti SQL injection koji nam treba jest:  Vidimo da smo uspješno dobili hasheve lozinki svih korisnika u sustavu. Također vidimo da se na stranici prikazuje samo zadnji parametar koji smo unijeli u našem SELECT izrazu, koji je u ovom slučaju password. Ako želimo prikazati više informacija, možemo koristiti SQL-ov operator konkatenacije:  „  ||  “, da bi prikazali više vrijednosti u jednom stupcu, na primjer da bi prikazali username i password odvojene znakom dvotočke, za zadnji parametar trebamo umjesto samo password, unijeti „ username|| ': '||password “, koristeći ovu vrijednost za zadnji parametar, finalno korisničko ime kojim ćemo izvršiti SQL injection koji nam treba jest: 
Line 83: Line 122:
 <code>aaaa' UNION SELECT username,password, username|| ': '||password FROM users --</code> <code>aaaa' UNION SELECT username,password, username|| ': '||password FROM users --</code>
  
-**TODO: slika ovdje**+{{second_order_7.png}} 
 + 
 +Sada smo uspješno izvršili SQL injection pomoću kojega smo dohvatili i prikazali korisnička imena i hasheve lozinki svih korisnika u sustavu, Možemo vidjeti da su korisnici korisnički računi koje smo stvarali za izvršavanje SQL injekcija, te da jest zadnji korisnik, korisnik s korisničkim imenom //admin//
  
-Sada smo uspješno izvršili SQL injection pomoću kojega smo dohvatili i prikazali korisnička imena i hasheve lozinka svih korisnika u sustavuMožemo vidjeti da su korisnici korisnički računi koje smo stvarali za izvršavanje SQL injekcijate da jest zadnji korisnikkorisnik sa korisničkim imenom //admin//. +Kako bi dobili njegovu lozinkuodnosno „revers“ hasha njegove lozinke, možemo iskoristiti crackstation.net, veliku bazu podataka s parovima tekstualnih vrijednosti i njihovih već izračunatih hash vrijednosti u raznim algoritmima. Unosom administratorovog hash-a lozinke u crackstationdobivamo informacijuda se ta hash vrijednost već nalazi u crackstation bazi i da je to hash vrijednost koja se dobiva hashiranjem vrijednosti //zlocinikazna// algoritmom //sha256//.
  
-Kako bi dobili njegovu lozinku, odnosno „revers“ hasha njegove lozinke, možemo iskoristiti crackstation.net, veliku bazu podataka sa parovima tekstualnih vrijednosti i njihovih već izračunatih hash vrijednosti u raznim algoritmima. Unosom administratovog hash-a lozinke u crackstation, dobivamo informaciju, da se ta hash vrijednost već nalazi u crackstaion bazi i da je to hash vrijednost koja se dobiva hashiranjem vrijednosti //zlocinikazna// algoritmom //sha256//.+{{second_order_8.png}}
  
 Sada prijavom u sustav s korisničkim imenom //admin// i lozinkom //zlocinikazna//, dobivamo flag koji je rješenje zadatka. Sada prijavom u sustav s korisničkim imenom //admin// i lozinkom //zlocinikazna//, dobivamo flag koji je rješenje zadatka.
second_order_sqli.1701701156.txt.gz · Last modified: 2025/12/01 11:40 (external edit)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki