| Both sides previous revisionPrevious revisionNext revision | Previous revision |
| second_order_sqli [2026/06/18 15:42] – mbunic | second_order_sqli [2026/06/18 17:52] (current) – mbunic |
|---|
| ====Second order SQL injection==== | ====Second order SQL injection==== |
| |
| **Second order SQL injection** je podskup **SQL injection** ranjivosti, koju je kompliciranije iskoristiti za izvršavanje napada, ali je i teže detektirati ovu ranjivost. | **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. |
| |
| Uobičajeni SQL injection je prisutan u slučajevima kada se korisnički unos direktno koristi za konstrukciju SQL upita, 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. | Uobičajeni SQL injection se pojavljuje kada se korisnički unos direktno koristi za konstrukciju SQL upita, dok se second order SQL injection izvršava tako da se neki korisnički unos prvo pohrani negdje na poslužitelju ili u bazu podataka, a zatim se pozivanjem neke druge funkcionalnosti, koja koristi taj pohranjeni korisnički unos, izvršava SQL injection. |
| |
| Jednostavan primjer bi bio aplikacija gdje se unos iz forma za registraciju korisnika koristi u SQL upitu za dodavanje korisnika u bazu koji dobro interpretira unos korisničkog imena kao string i nije ranjiv na SQL injection. | 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. |
| |
| Korisnik registracijom kao korisničko ime unosi vrijednost: | Aplikacija pri registraciji ispravno interpretira unos korisničkog imena kao string, te konstrukcija SQL upita za stvaranje korisnika nije ranjiva na SQL injection. |
| |
| <code>" user' or 'a' = 'a' -- " </code> | Pri registraciji napadač kao korisničko ime unosi vrijednost: |
| |
| čime se samo stvara novi korisnik s tim korisničkim imenom. | <code>user' or 'a' = 'a' -- </code> |
| |
| | čime se samo u bazi stvara novi korisnik s tim korisničkim imenom. |
| |
| 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, bez ikakvih zaštita, izvršio bi se SQL injection za vrijeme SQL upita u kojemu se odabranom korisniku mijenja lozinka. | 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 nezaštićenog koda za izmjenu lozinke bio: | 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 dobro filtriran jer se direktno koristi kao unos korisnika, dok se korisničko ime dohvaća iz baze te se zato pogrešno ne koristi na siguran način) | (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č s 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> | <code> |
| | UPDATE users SET password = 'moj_novi_password23' WHERE username = 'user' or 'a' = 'a' -- ' and password = 'stari_password' |
| | </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> |
| |
| No, uzimajući u obzir da je <code>--</code> jednako komentaru, prethodan kod jest ekvivalentan sljedećem: | 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> |
| |
| <code>UPDATE users SET password= ’moj_novi_password23’ WHERE username= ’user' or 'a' = 'a'</code> | Ovaj upit bi promijenio lozinku svih korisnika u: |
| |
| čime bi se svim korisnicima password promijenio u | |
| |
| <code>moj_novi_password23</code>. | <code>moj_novi_password23</code> |
| |
| __**Primjer**__ - **Zadatak s Hacknite platforme** - **e-Trgovina Union** | __**Primjer**__ - **Zadatak s Hacknite platforme** - **e-Trgovina Union** |
| 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 s 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 s 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. |
| 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. |
| jedino znamo da se dohvaćaju svi stupci iz tablice povijest, ali ne znamo točno koliko | 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, gdje ćemo imati koristiti tri stupca u SELECT izrazu. Primjer takvog pokušaja jest stvaranje korisničkog računa s korisničkim imenom: | 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> | <code> aaaa' UNION SELECT username,password,password FROM users -- </code> |
| |
| {{second_order_6.png}} | {{second_order_6.png}} |
| {{second_order_7.png}} | {{second_order_7.png}} |
| |
| Sada smo uspješno izvršili SQL injection pomoću kojega smo dohvatili i prikazali korisnička imena i hasheve lozinka 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 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//. |
| |
| Kako bi dobili njegovu lozinku, odnosno „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 administratovog hash-a lozinke u crackstation, dobivamo informaciju, da 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 s parovima tekstualnih vrijednosti i njihovih već izračunatih hash vrijednosti u raznim algoritmima. Unosom administratorovog hash-a lozinke u crackstation, dobivamo informaciju, da se ta hash vrijednost već nalazi u crackstation bazi i da je to hash vrijednost koja se dobiva hashiranjem vrijednosti //zlocinikazna// algoritmom //sha256//. |
| |
| {{second_order_8.png}} | {{second_order_8.png}} |