Multistage

PRIMJER - Zadatak s Hacknite platforme – Multistage

Ponekad su stvari kompliciranije nego što se na prvi pogled čine
Napomena 1: administrator na remote instanci ima jako dugu, nasumično generiranu lozinku
Napomena 2: lozinka administratora za lokalno testiranje je password123
Napomena 3: funkcionalnost registracije i password reseta je onemogućena (disabled)
Napomena: Zadatak se periodički resetira (svaka 4 sata). Ako je zadatak nedostupan pričekajte 1-2 minute.
Hint: Krivotvorite remember me cookie
http://chal.platforma.hacknite.hr:13008
 multistage-local.zip

Uz zadatak dostupna je i zip datoteka multistage-local.zip.

Pristupom na web stranicu, može se vidjeti forma za upload slike prikazana na slici 1.

Ostali resursi stranice su nedostupni, jer se prvo treba prijaviti (login) kako bi im se pristupilo.

U dostupnom izvornom kodu, pod resources/views/upload.blade.php dostupan je izvorni kod stranice na slici 1. Izvorni kod prikazan je na slici 2.

Ovdje se vidi da se koristi funkcionalnost “resize”. Kako bi se pronašla implementacija ove funkcionalnosti, može se potražiti stringom „resize“ u svim datotekama, koji će biti pronađen u datoteci „imageController.php“, koja se nalazi na putanji ./app/http/Controllers. Sadržaj datoteke je prikazan na slici 3.

Ovdje se može uočiti da se koristi alat “imagemagick” u PHP metodi “process”, koja pokreće i izvršava naredbe u novoj ljusci. Ovo izgleda kao dio koda koji bi potencijalno mogao biti ranjiv.

Kako bi se sakupilo više informacija o alatu imagemagick, može se pogledati Dockerfile prikazan na slici 4.

Ovdje je važno uočiti 6. liniju:

ENV IMAGEMAGICK_VERSION=7.1.0-49

Koja označava da je verzija alata 7.1.0-49.

Pretraživanjem upita „ImageMagick 7.1 0 49 exploit“ putem Interneta, može se pronaći da postoji ranjivost “CVE-2022-44268 - Arbitrary File Read za ovu verziju alata”. Za ovu ranjivost postoji već više gotovih Proof of Concept (PoC) materijala koji se mogu koristiti, u ovom primjeru će se koristiti sljedeći:

https://github.com/Sybil-Scan/imagemagick-lfi-poc

Na stranici su dostupna uputstva za korištenje. Nakon preuzimanja projekta i instalacije svih potrebnih paketa, generiranje payload PNG slike koja čita file „/etc/passwd“ se može pokrenuti naredbom:

python3 generate.py -f "/etc/passwd" -o exploit.png

Nakon uploada slike exploit.png, od stranice se dobiva odgovor na kojemu se navodi putanja do slike nad kojom se pokrenula naredba resize, prikazano na slici 5.

Pristupom putanji za sliku nad kojom se izvršila naredba resize alatom imagemagick, može se preuzeti prikazana slika. Nad preuzetom slikom se pokreće (Linux) naredba:

identify -verbose preuzetaSlika.png

Pokretanjem ove naredbe, u polju „Raw profile type“ bi se trebao nalaziti sadržaj ciljane datoteke payloada - /etc/passwd u heksadecimalnom zapisu. Ovo je prikazano na slici 6.

Kako bi dobili sadržaj datoteke u čitljivom obliku iz heksadecimalnog zapisa u polju, sadržaj se jednostavno može kopirati (počevši od 726f6… ) u CyberChef i dekodirati opcijom „From Hex“ ili se sadržaj može dekodirati u Pythonu korištenjem naredbe:

print(bytes.fromhex("<hex sadržaj iz polja>").decode("utf-8"))

Nakon dekodiranja, dobiva se sadržaj datoteke /etc/passwd u čitljivom obliku, što je prikazano na slici 7.

Ovime je dokazano da ovaj napad radi i da se može uspješno iskoristiti za čitanje sadržaja različitih datoteka sa servera.

Pokušaj čitanja datoteke /flag.txt neće biti moguć – pojavit će se server error, jer u Dockerfileu flag.txt ima postavljene dozvole na read only samo za vlasnika datoteke, koji je „www-data“, a korisnik koji je pridružen procesu koji izvršava naredbe ImageMagick alata je „magick“. Relevantne naredbe u Dockerfileu su prikazane na slici 8.

Može se zaključiti da je potrebno pročitati neku drugu datoteku koja će sadržavati podatke koji će omogućiti pristup stranici. Pregledom daljnjih naredbi prikazanih na slici 9. može se vidjeti da se koristi datoteka “database.sql” za stvaranje druge datoteke “database.sqlite” u kojoj su vjerojatno definirani inicijalni korisnici sustava, kao npr. “admin”.

Provjerom sadržaja datoteke “database.sql”, ova pretpostavka se može i potvrditi, te se također može i uočiti da u bazi postoji i zapis „remember_token“, čija je vrijednost cenzurirana. Ovo je prikazano na slici 10.

Kako bi se pročitao remember_token, potrebno je dohvatiti datoteku /var/www/database.sqlite, za koju se payload može generirati naredbom:

python3 generate.py -f "/var/www/database.sqlite" -o exploit.png

Postupak se ponavlja kao pri dohvatu datoteke /etc/passwd, ali pošto je sadržaj datoteke database.sqlite znatno veći, on neće odmah biti prikazan korištenjem naredbe:

identify -verbose preuzetaSlika.png

Nego je potrebno izlučiti (engl. extract) sadržaj polja “Raw Profile Type” u drugu datoteku. To se može napraviti korištenjem alata ExifTool, pomoću naredbe:

exiftool -b -RawProfileTypeSqlite preuzetaSlika.png > extracted_profile.bin

Kako bi se izlučeni sadržaj uspješno konvertirao, potrebno je izbrisati početak zapisa u datoteci, što se može jednostavno napraviti alatom HxD Hex Editor. Dio početka datoteke koji treba izbrisati prikazan je na slici 11.

Sad se ova uređena datoteka može uploadati na CyberChef, dekodirati opcijom „From Hex“ i onda se dekodirani ispis može preuzeti kao nova datoteka koja se može pohraniti s nastavkom .sqlite. Ova dekodirana datoteka se onda može ili lokalno analizirati nekim SQLite browserom / viewerom ili se može koristiti neka online verzija. Pri analizi ove datoteke SQLite viewerom, može se uspješno identificirati remember_token od korisnika admin. Ovo je prikazano na slici 12.

U Dockerfileu se nalazi još jedna važna naredba prikazana na slici 13.

Naredba

php artisan key:generate

je naredba Laravela za generiranje nasumičnog ključa aplikacije - APP_KEY. Taj ključ se koristi za korisničke sesije i pojedine enkripcije, čime bi mogao biti koristan za pristup sustavu. Nakon što je ključ nasumično generiran prethodno spomenutom naredbom, on se pohranjuje u “.env” datoteku u kojoj su pohranjene pojedine informacije, postavke i varijable pokrenute aplikacije. Puna putanja ove datoteke je:

/var/www/html/.env

Još jednom se ponavlja postupak za čitanje ove datoteke, prvo generacijom payloada naredbom:

python3 generate.py -f "/var/www/html/.env" -o exploit.png

Nakon čega je dovoljno slijediti isti postupak koji se koristio i pri dohvatu datoteke /etc/passwd, preuzimanjem „resize-ane“ slike sa servera i ispisom hex vrijednosti korištenjem naredbe:

identify -verbose preuzetaSlika.png

Nakon toga se ponovno hex zapis može dekodirati korištenjem CyberChefa ili Pythona. Nakon dekodiranja, APP_KEY može uspješno biti pročitan, što je prikazano na slici 14.

Vidi se da je APP_KEY u base64 zapisu, što se može jednostavno dešifrirati.

U tekstu zadatka je dostupan hint:

Hint: Krivotvorite remember me cookie

Generiranje kolačića admina

Za generiranje remember me kolačića admin korisnika, potrebni su APP_KEY aplikacije, radi enkripcije i remember_token korisnika admin. Obje vrijednosti su poznate iz preuzetih datoteka .env i database.sqlite. Sljedeći korak je samo generirati remember me kolačića admin korisnika, postaviti ga pri pristupu aplikaciji i pročitati flag s dostupnim administratorskim pristupom stranici.

Jedan jednostavan postupak kako generirati isti remember me kolačić, kao što je na instanci zadatka koja je na platformi, je da se lokalno pokrene cijeli sustav čiji source kod je dostupan, ali s istim vrijednostima APP_KEY I remember_token korisnika admin. Također može se i promijeniti lozinka korisnika admin, kako bi se moglo ulogirati u lokalnu instancu s tim korisnikom i dobiti kolačić. Sustav je najjednostavnije pokrenuti kao docker kontejner, korištenjem već dostupnog Dockerfilea.

Kako bi se namjestio APP_KEY na lokalnoj instanci da odgovara pročitanom APP_KEY-u s platforme, prvo treba u Dockerfileu maknuti naredbu:

php artisan key:generate

Koja se nalazi na 111. liniji, kako se ne bi generirao novi nasumični APP_KEY pri pokretanju lokalne instance, nego bi se koristila statično postavljena vrijednost. Nakon toga je potrebno u .env file promijeniti vrijednost APP_KEY u vrijednost pročitanu s platforme. Ovo je prikazano na slici 15.

Nakon što su Dockerfile i .env file namješteni, potrebno je promijeniti database.sql file, te u njemu promijeniti remember_token u vrijednost pročitanu s platforme i promijeniti hash passworda, u hash passworda koji je poznat. Trenutačno je vrijednost password neki bcrypt hash nepoznate vrijednosti, što se vidi po prefiksu $2y$. Može se napisati jednostavna PHP skripta koja će generirati bcrypt hash za lozinku admin, koja će se postaviti u databse.sql korisniku admin. Primjer ovakve PHP skripte je:

<?php
$password = 'admin';
$hash = password_hash($password, PASSWORD_BCRYPT);
echo $hash;

Pokretanjem ove skripte naredbom:

php skripta.php

bit će ispisan bcrypt hash, koji se onda zajedno s pročitanom remember_token vrijednošću može upisati u database.sq, što je prikazano na slici 16.

Sada je je potrebno sagraditi docker kontejner s promijenjenim izvornim kodom naredbom: (ovo može potrajati duže)

docker build . -t multistage

Te se onda izgrađeni kontejner može pokrenuti s mapiranim unutarnjim portom 80 na vanjski port 3000 naredbom:

docker run -d -p 3000:80 multistage

Sada bi na putanji localhost:3000 trebala biti dostupna lokalna instanca projekta. Odlaskom na:

Localhost:3000/login

Može se ulogirati s e-mailom iz baze i postavljenom lozinkom. Potrebno je odabrati opciju „Remember me“ (slika 17).

Nakon uspješne prijave, bit će generiran remember me kolačić, kojemu se jednostavno može pristupiti koristeći internetski preglednik. Otvaranjem razvojnih alata internetskog preglednika (F12), dostupan je prozorčić „Application“ u kojemu je zapisana vrijednost remember me kolačića. Ovo je prikazano na slici 18.

Potrebno je samo prekopirati ime i vrijednost remember me kolačića (remember_web_59ba… označen plavom bojom na slici 18.) s lokalne instance na instancu zadatka na platformi. U implementaciji zadatka remember me kolačić ne sadržava hash lozinke, što se nekada zna koristiti, pa je zato ovaj pristup moguć, inače bi bilo potrebno još naknadno mijenjati kolačić.

Nakon što je kolačić dodan na instancu zadatka na platformi, odlaskom na putanju:

http://chal.platforma.hacknite.hr:13008/home

Bit će ispisano da je prijava uspješna kao korisnik admin. Prikazano na slici 19.

Sada se flag može dohvatiti pristupom putanji

http://chal.platforma.hacknite.hr:13008/flag

Na toj putanji je flag ispisan i zadatak je uspješno riješen.