What is Local File Inclusion (LFI) Vulnerability?

Moderne webapplicaties zijn niet meer wat ze geweest zijn. De vrijwel onbeperkte bandbreedte en de oneindige opslagruimte die cloud computing biedt.

De microservices die monolithische architecturen te slim af zijn, door gelaagde apps op te splitsen in kleine, onafhankelijke componenten. De single-page apps die de meeste resources (inclusief de primaire DOM-elementen) één keer per app-cyclus laden, zodat u de site kunt gebruiken en alleen de vereiste dynamische inhoud bijwerkt.

Snelheid. Flexibiliteit. Eenvoudige software-integratie. Cross-compatibiliteit. Kosteneffectiviteit. Kortom, moderne web-apps zijn door en door krachtig. Tegelijkertijd zijn ze ook gemakkelijk vatbaar voor aanvallen met externe en lokale bestandsinclusie. Maar wat is een aanval met lokale bestandsinclusie (LFI) eigenlijk?

Wat is LFI?

Om u een idee te geven, LFI’s zijn kwetsbaarheden in webapplicaties die mogelijk worden ‘dankzij’ blunders van programmeurs. Door een beveiligingslek in webapplicaties te introduceren, stellen onoplettende programmeurs onbevoegde gebruikers in staat bestanden te openen, downloadfunctionaliteit te misbruiken, beschikbare informatie te doorzoeken en meer.

Hoe is dit mogelijk aan de kant van de hackers? Via de ‘dynamische bestandsinclusie’-lek. Door deze inclusie-mechanismen, die ontwikkelaars in de app implementeren, te exploiteren, kunnen cybercriminelen een extern bestand in de originele mix gooien. Vanaf daar is het enige wat nog gedaan moet worden een simpel kwaadaardig script uitvoeren. Zodra het script zijn werk heeft gedaan, kunt u net zo goed de deur openzetten, want het wordt gratis landgoed in de app, en de gastheer bent u niet.

Maar wat maakt huidige web-apps zo vatbaar voor een LFI-kwetsbaarheid? Goede vraag.

Het probleem ligt bij elke server-side scriptingtaal op het web die er toe doet. Meer specifiek, bij het deel waar ze vertrouwen op bestandsinclusies om de code van web-apps netjes en overzichtelijk (en onderhoudbaar) te houden. Daarnaast laten bestandsinclusies web-apps toe om bestanden rechtstreeks uit het bestandssysteem te lezen, downloadfunctionaliteit in te schakelen, configuratiebestanden te parsen, enzovoort.

Waar zit het probleem, vraagt u zich misschien af? Het probleem kan en zal, vaker wel dan niet, aan de kant van de programmeurs ontstaan. Wanneer de bestandsinclusie-mechanismen niet correct worden geïmplementeerd, hebben ervaren hackers geen moeite om de inclusiemogelijkheden van deze mechanismen te exploiteren. Door een effectieve lokale bestandsinclusie-aanval te creëren en uit te voeren, kunnen cybercriminelen vertrouwelijke informatie openbaar maken, een cross-site script (XSS) injecteren of remote code execution (RCE) ontketenen.

Klinkt een beetje breed? Laten we ze dan één voor één bekijken.

Voorbeelden van lokale bestandsinclusie

Omdat het exploiteren van een LFI-kwetsbaarheid technisch zo eenvoudig is als het toevoegen van een extern bestand aan het systeem van het doelwit, zijn er meerdere manieren waarop hackers dit kunnen doen. Dit zijn de meest populaire methoden:

De PHP-bestandscase

Volgens de Web Tech surveys gebruikt maar liefst 79,2% van de websites PHP. Ja, 79,2% van ALLE websites, u leest het goed. En PHP heeft zeker zijn voordelen. Tegelijkertijd brengt dezelfde scripttaal de meeste web-apps van vandaag in gevaar.

Zoals u weet, gebruiken website- en web-app-ontwikkelaars die PHP gebruiken deze twee functies om de inhoud van het ene PHP-bestand in een ander op te nemen:

  1. De include() functie
  2. De require() functie.

Wat deze functies onderscheidt, is hoe ze reageren op problemen met het laden van bestanden. De eerste, de include-functie, geeft een waarschuwing, maar laat het script desondanks doorlopen. De tweede, de require-functie, veroorzaakt daarentegen een fatale fout en stopt daarmee het script.

Dus, hoe ziet een PHP-bestandinclusie-aanval eruit? Zoiets als dit:

https://example.com/?page=filename.php

Dit is een stuk code dat kwetsbaar zou zijn voor een LFI-aanval. U ziet, wanneer de invoer niet correct wordt gevalideerd, hebben aanvallers geen moeite om de invoer (zie onderstaand voorbeeld) aan te passen en de app te manipuleren om toegang te krijgen tot beperkte bestanden, mappen en algemene informatie via de “../” directive. Meestal aangeduid als Directory Path Traversal, ziet dit er als volgt uit:

https://example.com/?page=../../../../etc/test.txt

In dit geval hoefde de cybercrimineel alleen maar “filename.php” te vervangen door “../../../../etc/test.txt” in de URL-pad en, et voilà, ze hadden toegang tot het testbestand. In dit stadium konden de indringer(s) een kwaadaardig script op uw server uploaden en dat script openen met behulp van lokale bestandsinclusie.

Om het uiteen te zetten, zijn er vier stappen in dit proces:

  1. De indringers identificeren een webomgeving met onvoldoende en/of onveilige browserinvoer validatie van de gebruikers van de applicatie.
  2. De URL-string wordt aangepast met de “../” directive om Directory Path Traversal mogelijk te maken.
  3. Het kwaadaardige .php-bestand wordt via een backdoor op de hostserver geüpload om het script te lokaliseren met behulp van de padovergangsmethode.
  4. De hacker mag zijn kwaadaardige script tekeer laten gaan op de host-app vanwege onjuiste validatie.

Hoe kunt u een dergelijke aanval voorkomen?

Om te beginnen kunt u een *whitelist* met geaccepteerde taalparameters instellen. Wanneer een sterke invoermethode geen optie is, kunt u invoerfiltering en validatie van doorgegeven paden toepassen. Door op deze methoden te vertrouwen, kunt u onbedoelde tekens en tekenpatronen uit de vergelijking verwijderen.

Dat gezegd hebbende, dit vereist dat u alle problematische tekencombinaties anticipeert. Omdat dit het geval is, zou een praktischere oplossing zijn om vooraf gedefinieerde Switch/Case-instructies te gebruiken. Hiermee bepaalt het systeem automatisch welke bestanden kunnen worden opgenomen zonder te vertrouwen op URL- en formulierparameters om een pad dynamisch te genereren.

De geprinte paginacase

Soms moet u de uitvoer van het bestand over meerdere webpagina’s delen (zoals u doet met bijvoorbeeld headerbestanden). Deze aanpak is het meest logisch wanneer u wilt dat de wijzigingen op elke pagina waar het bestand is opgenomen, zichtbaar zijn. Dit kunnen platte HTML-bestanden zijn die geen parsers aan de serverzijde nodig hebben om ze te interpreteren. Ze kunnen ook worden gebruikt om afzonderlijke gegevensinvoer te benadrukken, waaronder eenvoudige tekstbestanden.

Stel dat u verschillende .txt-bestanden met helpteksten hebt en deze bestanden via uw web-app beschikbaar wilt maken. Met dat in gedachten kunt u ze zichtbaar maken via een link, niet ongelijk aan deze:

https://example.com/?helpfile=login.txt

In dit geval wordt de inhoud van het tekstbestand rechtstreeks naar de pagina afgedrukt zonder de informatie eerst in een database op te slaan.

Hoe kan dit leiden tot een kwetsbaarheid voor lokale bestandsinclusie?

Wanneer u geen adequate filtering hebt, kunnen aanvallers de bovenstaande link gemakkelijk wijzigen in iets als dit:

https://example.com/?helpfile=../secret/.htpasswd

Als gevolg hiervan kunnen ze toegang krijgen tot de wachtwoordhashes in het .htpasswd-bestand en alle gebruikersgegevens die dit bestand doorgaans bevat. Met deze inloggegevens zouden de digitale dieven vervolgens toegang kunnen krijgen tot beperkte gebieden van de server en daar ernstige schade aanrichten. Bovendien zouden dezelfde hackers mogelijk zelfs verborgen configuratiebestanden met gevoelige informatie (zoals wachtwoorden) kunnen lezen.

Oké, wat is de tegenactie hier?

Oké, wat is de tegenactie hier?

Wat betreft bestanden die op een pagina worden afgedrukt, zijn de meest effectieve tegenacties dezelfde die u zou toepassen tegen downloadbestanden. Benieuwd wat die zijn? Geweldig. Maar laten we eerst uitzoeken wat dit geval maakt.

Download bestandencase

Er zijn bestanden die webbrowsers automatisch openen wanneer ze worden benaderd, niet ongelijk aan PDF-bestanden. Dus wanneer u dit soort bestanden als downloads wilt aanbieden in plaats van ze in het browservenster weer te geven, voegt u extra headers toe, waarmee de browser wordt geïnstrueerd om het te verwerken.

Met een header als Content-Disposition: attachment; filename=file.pdf in het verzoek, slaat de browser het ‘openen’-gedeelte over en downloadt het bestand in plaats daarvan.

Om u een voorbeeld te geven: sommige bedrijven hebben brochures in PDF-formaat, zodat de bezoekers van de site een link als deze kunnen gebruiken om ze te downloaden:

https://example.com/?download=brochure1.pdf

Hoe kan dit een LFI-kwetsbaarheid creëren?

Makkelijk, zo. Om specifieker te zijn, wanneer u het verzoek niet valideert, kunnen aanvallers de bestanden opvragen waarop de web-app zelf is gebouwd, waardoor ze toegang krijgen tot de broncode. Door dit te doen, kunnen ze andere kwetsbaarheden in de web-app vinden, of “gewoon” de inhoud van gevoelige bestanden lezen.

Een extra slecht nieuwsfeitje is dat hackers deze exploit kunnen combineren met de eerder genoemde directory traversal-methode. Als gevolg hiervan kan dezelfde functie hen toestaan de broncode van het connection.php-bestand te lezen:

https://example.com/?download=../include/connection.php

En, ervan uitgaande dat deze hackers de gebruikersdatabase, host en wachtwoordwaarden vinden (wat geen onwaarschijnlijk scenario is), zullen ze ook in staat zijn om de database te verzamelen met deze gestolen inloggegevens. Op dit punt zullen de cybercriminelen de middelen hebben om databasecommando’s uit te voeren en de serverstructuur te compromitteren (tenzij de databasegebruiker geen schrijfrechten op bestanden heeft).

Wat doet u om dit te voorkomen?

  • Sla de bestandspaden op in een database en ken er individuele ID’s aan toe. Wanneer u dat doet, kunnen gebruikers niets anders dan de ID zien, dus ze kunnen het bestandspad niet bekijken en wijzigen.
  • Whitelisten van geverifieerde en beveiligde bestanden. Vanaf daar kunt u elke andere bestandsnaam en pad negeren.
  • Plaats geen bestanden op webservers die gecompromitteerd kunnen worden, en vaker wel dan niet. Gebruik in plaats daarvan databases.
  • Voer geen bestanden uit in opgegeven mappen. Zorg er in plaats daarvan voor dat de server automatisch downloadheaders stuurt.

Echte LFI-voorbeelden

We hebben veel dappere platforms ten prooi zien vallen aan een lokale bestandsinclusie-aanval. En, u zult verrast zijn, het zijn niet alleen maar kleine websites die eerder een LFI-klap hebben opgelopen. Namelijk:

RedHat website. Hoewel bijna een decennium geleden aangepakt en opgelost, kampte de RedHat-site rond 2013 met verschillende beveiligingsproblemen. Deze problemen stelden hackers in staat om de database van de site te extraheren via Blind SQLi. Het bedrijf bevestigde ook dat de site kwetsbaar was voor LFI- en XSS-aanvallen.
Weather.gov. Tien jaar geleden gebruikte de KHS hacktivistengroep een LFI-kwetsbaarheid tegen weather.gov en kon gevoelige informatie over The National Weather Service openen en extraheren. Natuurlijk, als hacktivistengroep, maakten de hackers uit Kosovo die informatie daarna publiekelijk beschikbaar.
Whatsapp Media Server. In hetzelfde jaar dat RedHat werd blootgesteld, bleek de Whatsapp-mediaserverinterface kwetsbaar voor Traversal Local File Inclusion. Met dit zwakke punt konden cybercriminelen gebruikersnamen verzamelen via een “/etc/passwd”-bestand en andere gevoelige bestanden, waaronder logbestanden zoals “/apache/logs/error.log” en “/apache/log/access.log”.

Conclusie

Lokale bestandsinclusie-kwetsbaarheden zijn geen grap. Enkele van de grootste platforms ter wereld zijn er in de loop der jaren het slachtoffer van geworden, en de lijst blijft groeien. Tegelijkertijd, zolang u de bovenstaande suggesties volgt en waakzaam blijft, zou u in staat moeten zijn om ongedeerd te blijven werken.

Beter veilig dan spijt: het ultieme LFI-preventie-cheat sheet

Voer uw zakelijke e-mailadres in
Wat is Lokale Bestandsinclusie (LFI)?