7.6 KiB
LFI2RCE via Ewige wag
Leer AWS-hacking van nul tot held met htARTE (HackTricks AWS Red Team Expert)!
Ander maniere om HackTricks te ondersteun:
- As jy jou maatskappy geadverteer wil sien in HackTricks of HackTricks in PDF wil aflaai, kyk na die SUBSCRIPTION PLANS!
- Kry die amptelike PEASS & HackTricks swag
- Ontdek The PEASS Family, ons versameling eksklusiewe NFTs
- Sluit aan by die 💬 Discord-groep of die telegram-groep of volg ons op Twitter 🐦 @carlospolopm.
- Deel jou hacktruuks deur PR's in te dien by die HackTricks en HackTricks Cloud github-repos.
Basiese Inligting
Standaard, as 'n lêer na PHP geüpload word (selfs as dit nie verwag word nie), sal dit 'n tydelike lêer in /tmp
genereer met 'n naam soos php[a-zA-Z0-9]{6}
, alhoewel ek sommige Docker-beelde gesien het waar die gegenereerde lêers nie syfers bevat nie.
In 'n plaaslike lêerinsluiting, as jy daarin slaag om daardie geüploade lêer in te sluit, sal jy RCE kry.
Let daarop dat PHP standaard slegs toelaat om 20 lêers in 'n enkele versoek op te laai (ingestel in /etc/php/<version>/apache2/php.ini
):
; Maximum number of files that can be uploaded via a single request
max_file_uploads = 20
Ook, die aantal potensiële lêernaam is 62*62*62*62*62*62 = 56800235584
Ander tegnieke
Ander tegnieke steun op die aanval van PHP-protokolle (jy sal nie in staat wees as jy slegs die laaste deel van die pad beheer nie), die blootstelling van die lêerpad, die misbruik van verwagte lêers, of om PHP te laat ly aan 'n segmentasie-fout sodat opgelaaide tydelike lêers nie uitgevee word nie.
Hierdie tegniek is baie soortgelyk aan die vorige een, maar sonder om 'n zero day te vind.
Ewige wagtegniek
Met hierdie tegniek hoef ons slegs 'n relatiewe pad te beheer. As ons daarin slaag om lêers op te laai en die LFI nooit te laat eindig nie, sal ons "genoeg tyd" hê om opgelaaide lêers brute force en enigeen van die opgelaaide lêers te vind.
Voordele van hierdie tegniek:
- Jy hoef net 'n relatiewe pad binne 'n insluiting te beheer
- Vereis nie nginx of 'n onverwagte vlak van toegang tot loglêers nie
- Vereis nie 'n 0-dag om 'n segmentasie-fout te veroorsaak nie
- Vereis nie 'n padblootstelling nie
Die hoofprobleme van hierdie tegniek is:
- Daar moet 'n spesifieke lêer(s) teenwoordig wees (daar mag meer wees)
- Die krankzinnige hoeveelheid potensiële lêernaam: 56800235584
- As die bediener nie syfers gebruik nie, is die totale potensiële hoeveelheid: 19770609664
- Standaard kan slegs 20 lêers in 'n enkele versoek opgelaai word.
- Die maksimum aantal parallelle werkers van die gebruikte bediener.
- Hierdie beperking saam met die voriges kan hierdie aanval te lank laat duur
- Tyduitloop vir 'n PHP-versoek. Dit moet idealiter ewig wees of die PHP-proses doodmaak sonder om die tydelik opgelaaide lêers te verwyder. As dit nie die geval is nie, sal dit ook 'n probleem wees.
So, hoe kan jy 'n PHP-insluiting nooit laat eindig nie? Deur net die lêer /sys/kernel/security/apparmor/revision
in te sluit (ongelukkig nie beskikbaar in Docker-houers nie).
Probeer dit net deur te roep:
php -a # open php cli
include("/sys/kernel/security/apparmor/revision");
Apache2
Standaard ondersteun Apache 150 gelijktijdige verbindinge, volgens https://ubiq.co/tech-blog/increase-max-connections-apache/ is dit moontlik om op te grade tot 8000. Volg hierdie stappe om PHP met daardie module te gebruik: https://www.digitalocean.com/community/tutorials/how-to-configure-apache-http-with-mpm-event-and-php-fpm-on-ubuntu-18-04.
Standaard (soos ek in my toetse sien), kan 'n PHP-proses eindeloos duur.
Laten ons 'n paar wiskunde doen:
- Ons kan 149 verbindinge gebruik om 149 * 20 = 2980 tydelike lêers met ons webshell te genereer.
- Gebruik dan die laaste verbinding om potensiële lêers te brute-force.
- Teen 'n spoed van 10 versoek/s is die tye:
- 56800235584 / 2980 / 10 / 3600 ~= 530 ure (50% kans in 265h)
- (sonder syfers) 19770609664 / 2980 / 10 / 3600 ~= 185h (50% kans in 93h)
{% hint style="warning" %} Let op dat in die vorige voorbeeld ons ander kliënte heeltemal DoS! {% endhint %}
As die Apache-bediener verbeter word en ons 4000 verbindinge kan misbruik (halfpad na die maksimum getal). Ons kan 3999*20 = 79980
lêers skep en die getal sal verminder word tot ongeveer 19.7h of 6.9h (10h, 3.5h 50% kans).
PHP-FMP
As daar in plaas van die gewone php-mod vir Apache gebruik gemaak word van PHP-FMP om PHP-skripte uit te voer (dit verbeter die doeltreffendheid van die webblad, so dit is algemeen om dit te vind), is daar iets anders wat gedoen kan word om die tegniek te verbeter.
PHP-FMP maak dit moontlik om die parameter request_terminate_timeout
te konfigureer in /etc/php/<php-version>/fpm/pool.d/www.conf
.
Hierdie parameter dui die maksimum aantal sekondes aan wanneer versoek aan PHP moet beëindig (standaard oneindig, maar 30s as die parameter uitgekommentaar is). Wanneer 'n versoek deur PHP verwerk word vir die aangeduide aantal sekondes, word dit afgesluit. Dit beteken dat as die versoek tydelike lêers oplaai, omdat die php-verwerking gestop is, sal daardie lêers nie uitgevee word nie. Daarom, as jy 'n versoek kan maak wat so lank duur, kan jy duisende tydelike lêers genereer wat nie uitgevee sal word nie, wat die proses van hulle vind versnel en die waarskynlikheid van 'n DoS tot die platform verminder deur alle verbindinge te gebruik.
Om dus 'n DoS te vermy, neem aan dat 'n aanvaller slegs 100 verbindinge gelyktydig sal gebruik en die maksimum verwerkingstyd van PHP deur php-fmp (request_terminate_timeout
) is 30s. Daarom is die aantal tydelike lêers wat per sekonde gegenereer kan word 100*20/30 = 66.67
.
Dan, om 10000 lêers te genereer, sal 'n aanvaller benodig: 10000/66.67 = 150s
(om 100000 lêers te genereer, sal die tyd 25 minute wees).
Dan kan die aanvaller daardie 100 verbindinge gebruik om 'n brute-force soektog uit te voer. Met 'n spoed van 300 versoek/s is die tyd wat nodig is om dit uit te buit as volg:
- 56800235584 / 10000 / 300 / 3600 ~= 5.25 ure (50% kans in 2.63h)
- (met 100000 lêers) 56800235584 / 100000 / 300 / 3600 ~= 0.525 ure (50% kans in 0.263h)
Ja, dit is moontlik om 100000 tydelike lêers te genereer in 'n EC2 medium grootte instansie:
{% hint style="warning" %} Let op dat om die tydlimiet te aktiveer, sou dit genoeg wees om die kwesbare LFI-bladsy in te sluit, sodat dit in 'n ewige insluitlus beland. {% endhint %}
Nginx
Dit lyk asof Nginx standaard 512 parallelle verbindinge op dieselfde tyd ondersteun (en hierdie getal kan verbeter word).