LFI2RCE via Eternal waiting

Support HackTricks

Basic Information

Podrazumevano, kada se fajl otpremi na PHP (čak i ako to ne očekuje), generisaće privremeni fajl u /tmp sa imenom kao što je php[a-zA-Z0-9]{6}, iako sam video neke docker slike gde generisani fajlovi ne sadrže cifre.

U slučaju lokalne inkluzije fajla, ako uspete da uključite taj otpremljeni fajl, dobićete RCE.

Napomena: podrazumevano PHP dozvoljava otpremanje samo 20 fajlova u jednoj zahtev (postavljeno u /etc/php/<version>/apache2/php.ini):

; Maximum number of files that can be uploaded via a single request
max_file_uploads = 20

Takođe, broj potencijalnih imena datoteka je 62*62*62*62*62*62 = 56800235584

Druge tehnike

Druge tehnike se oslanjaju na napad PHP protokola (nećete moći ako kontrolišete samo poslednji deo putanje), otkrivanje putanje datoteke, zloupotrebu očekivanih datoteka, ili uzrokovanje segmentacione greške u PHP-u tako da otpremljene privremene datoteke nisu obrisane. Ova tehnika je veoma slična prethodnoj, ali bez potrebe da se pronađe zero day.

Tehnika večnog čekanja

U ovoj tehnici samo treba da kontrolišemo relativnu putanju. Ako uspemo da otpremimo datoteke i učinimo da LFI nikada ne završi, imaćemo "dovoljno vremena" da brute-force-ujemo otpremljene datoteke i pronađemo bilo koju od njih.

Prednosti ove tehnike:

  • Samo treba da kontrolišete relativnu putanju unutar include

  • Ne zahteva nginx ili neočekivani nivo pristupa log datotekama

  • Ne zahteva 0 day da izazove segmentacionu grešku

  • Ne zahteva otkrivanje putanje

Glavni problemi ove tehnike su:

  • Potrebna je specifična datoteka(e) da budu prisutne (može ih biti više)

  • Luda količina potencijalnih imena datoteka: 56800235584

  • Ako server ne koristi cifre, ukupna potencijalna količina je: 19770609664

  • Po defaultu samo 20 datoteka može biti otpremljeno u jednom zahtevu.

  • Maksimalan broj paralelnih radnika korišćenog servera.

  • Ova ograničenja sa prethodnim mogu učiniti da ovaj napad traje predugo

  • Timeout za PHP zahtev. Idealno bi trebalo da bude večan ili da ubije PHP proces bez brisanja privremeno otpremljenih datoteka, inače će to takođe biti problem

Dakle, kako možete učiniti da PHP include nikada ne završi? Samo uključivanjem datoteke /sys/kernel/security/apparmor/revision (nažalost, nije dostupna u Docker kontejnerima...).

Pokušajte jednostavno pozivajući:

php -a # open php cli
include("/sys/kernel/security/apparmor/revision");

Apache2

Podrazumevano, Apache podržava 150 paralelnih konekcija, prema https://ubiq.co/tech-blog/increase-max-connections-apache/ moguće je povećati ovaj broj do 8000. Pratite ovo da biste koristili PHP sa tim modulom: https://www.digitalocean.com/community/tutorials/how-to-configure-apache-http-with-mpm-event-and-php-fpm-on-ubuntu-18-04.

Podrazumevano, (kako mogu da vidim u svojim testovima), PHP proces može trajati večno.

Hajde da uradimo malo matematike:

  • Možemo koristiti 149 konekcija da generišemo 149 * 20 = 2980 temp fajlova sa našim webshell-om.

  • Zatim, koristimo poslednju konekciju da brute-force potencijalne fajlove.

  • Pri brzini od 10 zahteva/s vreme je:

  • 56800235584 / 2980 / 10 / 3600 ~= 530 sati (50% šanse u 265h)

  • (bez cifara) 19770609664 / 2980 / 10 / 3600 ~= 185h (50% šanse u 93h)

Imajte na umu da u prethodnom primeru potpuno DoS-ujemo druge klijente!

Ako je Apache server unapređen i mogli bismo da zloupotrebimo 4000 konekcija (na pola puta do maksimalnog broja). Mogli bismo da kreiramo 3999*20 = 79980 fajlova i broj bi bio smanjen na oko 19.7h ili 6.9h (10h, 3.5h 50% šanse).

PHP-FMP

Ako umesto korišćenja regularnog php modula za apache za pokretanje PHP skripti web stranica koristi PHP-FMP (to poboljšava efikasnost web stranice, tako da je uobičajeno naći ga), postoji nešto drugo što se može učiniti da se poboljša tehnika.

PHP-FMP omogućava da se konfiguriše parametar request_terminate_timeout u /etc/php/<php-version>/fpm/pool.d/www.conf. Ovaj parametar označava maksimalan broj sekundi kada zahtev za PHP mora da se završi (beskonačno podrazumevano, ali 30s ako je parametar otkomentarisano). Kada se zahtev obrađuje od strane PHP-a, označeni broj sekundi, on se ubija. To znači da, ako je zahtev učitavao privremene fajlove, zato što je php obrada prekinuta, ti fajlovi neće biti obrisani. Stoga, ako možete da napravite zahtev koji traje to vreme, možete generisati hiljade privremenih fajlova koji neće biti obrisani, što će ubrati proces pronalaženja njih i smanjiti verovatnoću DoS-a na platformi trošeći sve konekcije.

Dakle, da bismo izbegli DoS, pretpostavimo da napadač koristi samo 100 konekcija u isto vreme i maksimalno vreme obrade php-a od strane php-fmp (request_terminate_timeout) je 30s. Stoga, broj temp fajlova koji se može generisati po sekundi je 100*20/30 = 66.67.

Zatim, da generiše 10000 fajlova napadač bi trebao: 10000/66.67 = 150s (da generiše 100000 fajlova vreme bi bilo 25min).

Zatim, napadač bi mogao koristiti tih 100 konekcija da izvrši pretragu brute-force. **** Pretpostavljajući brzinu od 300 req/s vreme potrebno za eksploataciju je sledeće:

  • 56800235584 / 10000 / 300 / 3600 ~= 5.25 sati (50% šanse u 2.63h)

  • (sa 100000 fajlova) 56800235584 / 100000 / 300 / 3600 ~= 0.525 sati (50% šanse u 0.263h)

Da, moguće je generisati 100000 privremenih fajlova na EC2 srednjoj instanci:

Imajte na umu da bi za aktiviranje vremenskog ograničenja bilo dovoljno uključiti ranjivu LFI stranicu, tako da uđe u večnu petlju uključivanja.

Nginx

Izgleda da podrazumevano Nginx podržava 512 paralelnih konekcija u isto vreme (i ovaj broj se može poboljšati).

Podržite HackTricks

Last updated