SQL-Injektio

Mitä ovat SQL-injektiot?

Helppo
20 min

Mikä SQL?

SQL (Structured Query Language) on yleinen kyselykieli jolla sovellukset voivat jutella tietokantansa kanssa. Sovellukset käyttävät tietokantaa tietojen tallennukseen ja hakemiseen.

Käydään läpi muutama perusasia. Alla on tarkkaan valikoitu lista asioita joita nimenomaan hakkerit tarvitsevat SQL-injektiohyökkäyksiä varten.

Yksinkertainen esimerkki

Tässä on kysely joka hakee (SELECT) nimi- ja sähköposti (name, email) -sarakkeet käyttäjätaulusta (FROM users). Kokeile ajaa se! Hakatemiassa on selaimessa emuloitu SQL-tietokanta jolla voit leikkiä.

SQL Playground

Kaikki sarakkeet

Jos haluat palauttaa kaikki sarakkeet, kirjoita sarakevalitsimeen tähti (*).

SQL Playground

Tulosten suodattaminen

Yleensä et halua palauttaa ihan jokaista riviä tietokannasta, vaan suodattaa ne jonkun hakukriteerin perusteella. Tähän tarkoitukseen on WHERE-lauseke.

SQL Playground

Tulosten järjestäminen

Jos haluat järjestellä tulokset vaikkapa käyttäjän nimen perusteella, voit tehdä niin ORDER BY -lausekkeella.

SQL Playground

ORDER BY -lausekkeen perään voi lisätä järjestyksen, ensimmäisestä viimeiseen (ASC, oletus) tai viimeisestä ensimmäiseen (DESC).

SQL Playground

ORDER BY voi ottaa myös numeron, vaikka 1, joka tarkoittaisi että "järjestä ensimmäisen sarakkeen mukaan" (joka sattuu kyselyssä olemaan id).

SQL Playground

Kyselyiden yhdistäminen

Jos haluat tehdä kaksi hakua, vaikkapa "nimi kaikista käyttäjistä" ja "nimi kaikista eläimistä", ja palauttaa molempien kyselyiden tulokset yhdistettynä, voit käyttää UNION SELECT -lauseketta.

SQL Playground

Kommentit

SQL-kyselyyn voi lisätä kommentin -- merkeillä, joka katkaisee kyselyn ja jonka jälkeen loput "kyselystä" tulkitaan muistiinpanoksi, ei SQL:ksi. On tärkeää huomata, että -- kommentin jälkeen tulee aina välilyönti, muuten SQL on väärän muotoista eikä kysely mene läpi (se saattaa mennä läpi tässä emuloidussa SQL-ympäristössä mutta yleensä oikeassa tietokannassa se ei mene läpi).

SQL Playground

Kommentteja voi tehdä joskus, vähän tietokantaratkaisusta riippuen, myös risuaidalla (#).

Kommentti on mahdollista avata ja sulkea kesken kyselyn käyttämällä /* kommentti */ muotoa.

SQL Playground

Mikä sitten on SQL-injektio?

SQL-injektio, kuten kaikki muutkin injektiohaavoittuvuudet, aiheutuu siitä että hyökkääjä päästetään muokkaamaan protokollan rakennetta, ja johtaa siihen että hyökkääjä pääsee protokollan sallimissa rajoissa tekemään ikävyyksiä sovelluksessa. Protokolla on tässä tapauksessa SQL ja ikävyydet yleensä käytännössä tarkoittavat hyökkääjän mielivaltaista pääsyä tietokantaan ja joskus koko palvelimelle.

Käytännön esimerkki

Leikitään että meillä on sovellus, johon käyttäjä voi kirjautua sähköpostiosoitteella ja salasanalla.

Sovelluksen koodi voisi olla seuraavanlainen.

def login_nappia_painettu():
  email = email_tekstikentan_arvo()
  password = salasana_kentan_arvo()
  kysely = f"SELECT id FROM users WHERE email='{email}' AND password='{password}'"
  tietokannasta_palautuneet_rivit = tee_sql_kysely(kysely)
  if len(tietokannasta_palautuneet_rivit) == 0:
    uudelleenohjaa_kayttaja("/kirjautuminen-epaonnistui")
  else:
    ensimmaisen_palautuneen_kayttajan_id = tietokannasta_palautuneet_rivit[0]
    kirjaa_kayttaja_sisaan(ensimmaisen_palautuneen_kayttajan_id)
  uudelleenohjaa_kayttaja("/tervetuloa")

Kun käyttäjä koittaa kirjautua osoitteella john.doe@example.com ja oikealla salasanalla (s3cr3t), tietokanta palauttaa yhden rivin ja sovellus kirjaa käyttäjän sisään kyseisen rivin sisältämällä käyttäjätunnisteella. Kaikki toimii tässä vaiheessa ihan oikein.

SQL Playground

Kun käyttäjä koittaa kirjautua väärällä salasanalla, tietokanta ei palauta yhtään riviä, ja käyttäjälle annetaan virhe että kirjautuminen epäonnistui. Edelleen kaikki toimii kuten pitää.

SQL Playground

Mutta mitä tapahtuu, jos käyttäjä antaa salasanan jossa on hipsu (')? Kysely ei enää menekään läpi, ja sovellus kaatuu hallitsemattomasti, koska yhtäkkiä SQL ei olekaan enää oikeanmuotoista ja tietokantakysely epäonnistuu. Hipsuja on yksi liikaa. Tietokantapalvelin odotti että uudellekin hipsulle löytyisi vastakappale. Jos lähetät sovellukselle hipsun (tai lainausmerkit), ja saat virheilmoituksen takaisin, epäile aina SQL-injektiohaavoittuvuutta.

SQL Playground

Entäs jos hyökkääjä muokkaakin SQL:ää haluamaansa muotoon ja saakin sen toimimaan uudestaan? Jos käyttäjä antaisikin salasanan kissa' OR 1=1-- ?

SQL Playground

Kysely palauttaakin yhtäkkiä kaikki käyttäjät tietokannasta, ja sovellus virheellisesti kirjaa käyttäjän sisään ensimmäisenä käyttäjänä joka tietokannasta sattui palautumaan, vaikkei salasana ollut oikea. 1=1 on aina totta joten jokainen rivi palautettiin, ja sovelluksen itse lisäämä hipsu saatiin pois rikkomasta kyselyn rakennetta kommentoimalla se ulos.

Tämä oli yksinkertainen, ja voisi sanoa että hyvin klassinen, esimerkki SQL-injektiohaavoittuvuudesta. Käymme kurssilla läpi lukuisia tekniikoita haavoittuvuuden löytämiseksi ja hyväksikäyttämiseksi.

Miten haavoittuvuudelta voi suojautua?

Paras tapa on olla rakentamatta SQL:ää käsin ollenkaan, ja antaa modernin ohjelmointikirjaston (ORM / Object Relational Mapper) hoitaa matalan tason keskustelu tietokannan kanssa. Toinen vaihtoehto on käyttää kirjastoa (prepared statements), jolla voi turvallisesti parameterisoida SQL-kyselyitä, niin että kirjasto hoitaa vaarallisten merkkien (kuten tässä tapauksessa hipsuilla oli mahdollista "karata" merkkijonon sisältä kyselyn rakenteeseen) käsittelyn.

MySQLi Tunnistautumisen Ohittaminen 1

Tässä labrassa opit SQL-injektio -haavoittuvuuksien hyödyntämisen perusteet. Labra on suunniteltu näyttämään mitä kulissien takana tapahtuu kun käyttäjä kirjataan sisään. Näet SQL-kyselyt ja kyselyiden yhteydessä tapahtuvat virheet.

Tavoite

Kirjaudu admin-käyttäjänä sisään.

Vihje

Tehtävät

Flag

Löydä lippu (flag) labraympäristöstä ja syötä se alle.

hakatemia pro

Valmis ryhtymään eettiseksi hakkeriksi?
Aloita jo tänään.

Hakatemian jäsenenä saat rajoittamattoman pääsyn Hakatemian moduuleihin, harjoituksiin ja työkaluihin, sekä pääset discord-kanavalle jossa voit pyytää apua sekä ohjaajilta että muilta Hakatemian jäseniltä.