“Argument injection” je podvrsta “command injection” napada. Razlikuje se u tome što se u argument injectionu, “napad” može ugraditi samo u jedan argument naredbe, dok se u command injectionu kôd može ubaciti i usred naredbe. Dok se u klasičnom command injectionu često mogu dodavati i mijenjati argumenti naredbe ili čak dodavati potpuno nove naredbe vještim korištenjem komandnih operatora, prostor za „manevriranje“ u argument injectionu je znatno manji i više ovisi o kontekstu same naredbe u čiji se argument vrši argument injection.
Petar nema uvijek pristup računalu s instaliranim GCC kompajlerom, pa je odlučio napraviti online C kompajler kako bi mu mogućnost kompajliranja C koda bila dostupna u bilo kojem trenutku. Možeš li provjeriti je li Petrov online kompajler siguran? Dostupan ti je izvorni kod web aplikacije. Napomena: Zadatak se periodički resetira (svaka 4 sata). Ako je zadatak nedostupan pričekajte 1-2 minute. http://chal.platforma.hacknite.hr:13001
Pregledom stranice i izvornog kôda zadatka može se primijetiti da je namjena web aplikacije kompiliranje učitanog (eng. Uploaded) C koda u izvršnu datoteku korištenjem GCC kompajlera. Učitana datoteka se pohrani u direktorij na serverskoj strani, ime datoteke se zapamti, nakon čega server korištenjem subprocess modula pokreće naredbe za kompajliranje učitane datoteke u novom procesu korištenjem ljuske (eng. Shell). Naredba koja se pokreće se sastoji od pozivanja GCC-a s argumentima i spremljenim imenom učitane datoteke. Provjerava se završava li ime učitane datoteke s ekstenzijom “.c”. Prikazano na slici 1.
Nakon provjere, učitana datoteka se pohranjuje, a ime datoteke, koje uključuje cijelu putanju, se prvo razdjeljuje u listu i onda izravno šalje kao argument u pozivanje subprocess modula za izvršavanje naredbe kompilacije. Ovo se može vidjeti praćenjem korištenja varijable „sanitized“ prikazano na slici 2.
Ovaj command injection ima ograničenje. Ne može se, umjesto pozivanja GCC prevoditelja, ubaciti neka arbitrarna bash naredba korištenjem uobičajenih bash operatora kao što su ‘;’, ‘&’, ‘|’ …, nego će se uvijek pozivati GCC prevoditelj. Dakle, napadač može samo pokušati na lukav način u ime datoteke ugraditi naredbu koju želi da se izvrši (command injection). Kako bi se uspješno poslalo ime datoteke koje sadrži injektiranu naredbu, ime datoteke mora uspješno proći kroz filter koju implementira funkcija „allowed_file“. Kako se provjerava samo završava li ime datoteke s “.c”, ime naše datoteke treba nakon injektirane naredbe završavati s „.c“. Da bi se command injection u naredbi pozivanja GCC-a efektivno iskoristio, trebaju se istražiti funkcionalnosti i zastavice GCC-a, kako bi se pronašao način za iskorištavanje pronađene ranjivosti, tj. da se „nagovori“ GCC da izvrši naredbu koju napadač želi. GCC ima funkcionalnost pozivanja subkomandi unutar wrapper programa, korištenjem -wrapper zastavice. Ova funkcionalnost se može iskoristiti kako bi se pokrenuo bash process i dala mu se naredba koju napadač želi izvršiti.
Potrebno je i analizirati kôd kako bi se pronašlo može li napadač nekako dobiti rezultat pokretanja injektiranje naredbe preko sučelja aplikacije. Ako ne može, onda treba provjeriti može li se izvući preko weba ili može li se pokrenuti reverse shell, kako bi se ispravnoi oblikovala injektirana naredba. Analizom izvornog kôda prikazanom na slici 2. , može se uočiti da će se rezultat izvršavanja subprocessa ispisati kao paragraf na vraćenoj stranici.
Kada je poznato da se command injection može izvršiti i vidjeti rezultat izvođenja naredbe na sučelju aplikacije, može se prvo konstruirati tekst payloada za pokretanje naredbe „ls“. Prvo se generira neka vrlo jednostavna .c datoteka čiji kod nije bitan, te joj se ime odmah promijeni u tekst payloada, ili se poslan zahtjev s normalnim imenom datoteke presretne burp suiteovim presretačem (eng. Proxy) i tamo promjeni.
Payload ime datoteke za pokretanje ls naredbe, uz zaobilaženje filtera glasi:
program.c -wrapper bash,-c,ls, .c
Zaustavljeni zahtjev u burp suitevom presretaču s ovim payloadom je prikazan na slici 4.
Slanjem ovog zahtjeva, na stranici se ispisuju sve datoteke u trenutnom direktoriju, gdje se vidi da je prisutna i datoteka koju napadač traži, npr. flag.txt. Prikazano na slici 5.
Kada je poznato da se flag.txt nalazi u trenutnom direktoriju, potrebno je samo dohvatiti sadržaj flag.txt datoteke, što se može učiniti bash naredbom „cat“. No ovdje se nalazi novi problem, svaka injektirana naredba koja se izvršava, se šalje unutar -wrapper argumenta novo pokrenutom procesu bash preko -c argumenta. Sve naredbe koje se sastoje od jedne riječi se mogu normalno ovdje navesti i izvršiti, no čim se naredba sastoji od više riječi, pri razdjeljivanju imena i putanje datoteke prije slanja na pokretanje subprocess modula, razdvoji se u listu na svim razmacima. Nakon toga samo prva riječ naredbe bude proslijeđena kao argument pozvanom bashu preko -c argumenta. Zato se naredba ls normalno izvršava, a naredba cat flag.txt, bi poslala samo „cat“ kao -c argument pozvanom bashu. Potrebno je pronaći način da se znakovima definira razmak ili odjeljivanje dviju riječi u naredbi koja je izvršena u pozvanom bashu preko -c argumenta, bez korištenja samog razmaka. Za to postoji prikladno rješenje, svaki bash process standardno ima definiranu IFS (Internal Field Separator), varijablu, koju shell koristi kako bi znao gdje razdijeliti riječi ili polja naredbe. Pokretanjem naredbe
echo "$IFS" | cat -A
u bashu, može se vidjeti koji su znakovi definirani kao razdjeljivači. Oni su uobičajeno space, tab i newline. Da bi u naredbi „cat flag.txt“ imali razmak, ali da ga filter ne vidi, možemo izravno dohvatiti vrijednost definirane IFS varijable u kontekstu (trenutku izvođenja) bash procesa. Da bi se to postiglo, razmak u naredbi „cat flag.txt“ se treba zamijeniti dohvaćanjem vrijednosti te varijable – „${IFS}“ kako bi imali naredbu ekvivalentnog značenja, ali drukčije zapisanu – „cat${IFS}flag.txt“. Koristeći ovaj pristup, potpuna naredba za dohvaćanje flaga je:
program.c -wrapper bash,-c,cat${IFS}flag.txt, .c
Slanjem zahtjeva za učitavanje datoteke s ovim imenom, dobiva se rješenje zadatka prikazano na slici 6.