Tässä harjoituksessa aloitamme todentamalla haavoittuvuuden ja sitten hyödynnämme tätä suorittamalla omaa PHP-koodia sovelluksessa. Aloita käynnistämällä tehtävä ja tee vaiheet perässä. Alta löydät myös tiedoston index.php lähdekoodit, joissa kyseinen haavoittuvuus piilee.
Lähdekoodi - index.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Mythical Encyclopedia</title>
</head>
<body>
<?php
if (!isset($_GET["country"])) {
include("languages.php");
}
else {
echo "<h1>Mythical Encyclopedia</h1>";
}
if (isset($_GET["country"])) {
$country = $_GET["country"];
if ($country == "us") {
$file = "./us.php";
}
else if ($country == "fr") {
$file = "./fr.php";
}
else if ($country == "fi") {
$file = "./fi.php";
}
else {
$file = "./" . $country;
}
include($file);
}
?>
</body>
</html>
Haavoittuvuuden todentaminen
PHP-koodista näemme, että index.php ensin tarkistaa, onko GET parametri country annettu (isset-funktio) ja jos tämä on annettu, niin tarkistetaan tämän parametrin sisältämä arvo if-else-if rakenteella.
Logiikka on seuraavanlainen.
- Jos country parametri on yhtä kuin us, parametri file on ./us.php.
- Jos country parametri on yhtä kuin fr, parametri file on ./fr.php.
- Jos country parametri on yhtä kuin fi, parametri file on ./fi.php.
- Muussa tapauksessa, file parametri on yhtä kuin ./ + country parametri.
Lopuksi suoritetaan include-funktio, jolle annetaan file parametri. Kyseinen funktio suorittaa ja palauttaa annetun tiedoston. Haavoittuvuus syntyy viimeisessä else-lausekkeessa, jossa file parametrille annetaan mikä vain arvo, minkä käyttäjä on antanut country parametrille, joka sitten annetaan include-funktiolle. Tästä syntyy LFI-haavoittuvuus.
Todennetaan haavoittuvuus suorittamalla seuraavanlainen HTTP-pyyntö.
GET https://www-bnmpokft3q.ha-target.com/index.php?country=../../../../../../etc/passwd HTTP/1.1
Hienoa! - Onnistuimme lukemaan järjestelmän sisäisen passwd - tiedoston. Antamamme parametri country sisälsi arvon ../../../../../../etc/passwd ja kun tämä annettiin include -funktiolle, oli tämän arvo ./../../../../../../etc/passwd, joka viittaa ensin sovelluksen juureen, jonka jälkeen etc -kansioon ja tämän sisällä olevaan passwd -tiedostoon.
Haavoittuvuuden hyödyntäminen
Katsotaan seuraavaksi, miten voimme suorittaa omaa PHP-koodia tätä hyödyntämällä. Ensinnäkin, on hyvä muistaa, että tässä tapauksessa sovellus käyttää include - funktiota, jonka dokumentaatio kertoo meille:
The include expression includes and evaluates the specified file.
Eli kyseinen funktio sisällyttää annetun tiedoston ja evaluoi (suorittaa) annetun tämän. Tämä tarkoittaa, että jos annettu tiedosto sisältää PHP-koodia, niin koodi suoritetaan. Tämä ei pidä aina paikkansa, sillä kaikki funktiot, mitä sovellus voi käyttää tiedoston sisällyttämiseksi eivät välttämättä suorita koodia vaan ainoastaan palauttavat sen raakana sivulle. Mutta include-funktion tapauksessa, PHP-koodi suoritetaan.
Tyypillisesti tämän kaltaisissa tilanteissa, hyökkääjän seuraava askel olisi yrittää tallentaa sovellukseen PHP-koodia missä muodossa tahansa, kunhan se eksyy jollekin tiedostolle, jonka hyökkääjä voi sitten sisällyttää sivulle. Tämä voi tapahtua esimerkiksi manipuloimalla HTTP-pyyntöä, siten että PHP-koodia ajautuu palvelimen loki-tiedostoon, jonka hyökkääjä voi sisällyttää sivulle. Keinoja on useita ja ovat tässä tapauksessa lähinnä riippuvaisia hyökkääjän luovuudesta.
Yritetään seuraavaksi sisällyttää apache2 -palvelun loki-tiedosto vastaavalla tavalla. /etc/passwd tilalle asetamme /var/log/apache2/access.log, joka on tyyppillinen sijainti, missä apache2 palvelin tallentaa HTTP-pyynnöt, joita palvelimelle on tullut.
Onnistuimme sisällyttämään palvelun access.log tiedoston. Datasta näkee, että palvelu tallentaa yleistä tietoa HTTP-pyynnöstä sekä User-Agent-otsakkeen, joka HTTP-pyynnössä on ollut. Palvelun lokitus on täysin konfiguroitavissa, joten lokitettu tieto ei ole aina sama. On hyvä myös muistaa, että loki-tiedostojen sijainti on yhtä lailla konfiguroitavissa, eikä niiden löytäminen ole aina näin helppoa.
Hyökkäys tapahtuu seuraavanlaisesti. Teemme HTTP-pyynnön, jossa käytämme User-Agent otsaketta, joka sisältää PHP-koodia. Sitten sisällytämme loki-tiedoston samalla tavalla kuin äsken ja include -funktion pitäisi suorittaa koodimme.
Käytämme tähän curl-komentoa, mutta saman voi tehdä millä haluaa, esimerkiksi Burpilla.
curl -H "User-Agent: <?php echo passthru('ls -al'); ?>" https://www-8ean5fizui.ha-target.com
Sitten sisällytämme saman access.log -tiedoston. (huom. kuva on otettu sivun HTML-koodista, joka näyttää komennon tulosteen hieman selvemmin. Klikkaa oikealla hiiren painikkeella sivusta ja valitse View Page Source)
Voimme nyt lukea lipun cat /flag.txt. Voit hyvänä harjoituksena itsenäisesti yrittää luoda itsellesi paremman tavan syöttää komentoja, esimerkiksi tallentamalla sovellukseen oman PHP-skriptin, joka sallii komentojen syöttämisen parametreista.
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ä.