Remote File Inclusion

Contrariamente a quanto potrebbe pensare l’utente medio, il web non è (solo) una caotica nuvola invisibile dove viaggiano migliaia di terabyte di dati ogni giorno. Questa fondamentale entità ha, in realtà,

  • una struttura ben definita,
  • delle convenzioni

e

  • dei protocolli.

In particolare, per quanto concerne la struttura, i file che compongono le applicazioni (i siti) sono contenute in speciali macchine chiamate server. Come i comuni computer domestici, anche i server adottano delle strutture ad albero per ospitare i file e le cartelle. Se non venissero prese delle precauzioni, chiunque potrebbe viaggiare nell’albero dei file fino a leggere file privati o addirittura includere file esterni che andranno poi eseguiti a livello server.

Dunque, come vedremo in questo articolo, vale sempre il detto “mai fidarsi degli utenti”.

“Never trust the user” nella programmazione

Nel mondo della programmazione è molto diffuso un mantra piuttosto eloquente: “never trust the user”, mai fidarsi dell’utente.

Infatti, non si può mai sapere chi andrà effettivamente ad interagire con un prodotto software: forse l’utente sbadato che tenta di caricare un’immagine in un campo di testo, magari un altro gioca con i parametri url per scovare pagine segrete.

Oppure dall’altra parte dello schermo ci potrebbe essere una persona bene informata sul funzionamento dei software web, pronta a sfruttare la minima vulnerabilità per scopi illeciti.

Perciò, ogni buon artigiano del software sa che occorre rendere le autorizzazioni per l’interazione utente-software ben ristrette e definite, per non dare spazio a scenari imprevisti e potenzialmente pericolosi. La soglia di attenzione su questo tema deve rimanere sempre altissima, perché i punti di contatto tra le applicazioni web e il mondo esterno sono molteplici (ciò, si potrebbe argomentare, è dovuto in parte alla natura di internet come rete per lo scambio di informazioni e per l’interazione con esse).

Ad esempio, un utente interagisce attivamente con una web app tramite un form (software atto a reperire informazioni immesse da un utente). Chi gestisce il codice deve avere ben presente quali informazioni devono essere inserite nel form dall’utente, campo per campo, dalle dimensioni alla formattazione passando per il tipo di dato.

Fidarsi troppo degli utenti in questo caso potrebbe portare a varie conseguenze, come ad esempio

  • SQL Injection, che potrebbe comportare un danno ai dati contenuti nel database,

oppure

  • un attacco di tipo cross site (XSS).

Questi esempi riportano una interazione tra utente e interfaccia, ma è possibile elencare una famiglia di vulnerabilità che riguardano l’URL.

Accade spesso che per cambiare pagina e accedere a contenuti di altri file si utilizzi la chiamata per parametro url

(ad esempio, quando leggiamo [indirizzo web]/sezione?page=[file.estensione]).

Se non vengono prese delle precauzioni di sicurezza, questo tipo di indirizzamento può rappresentare una vulnerabilità per l’applicazione.

Gli attacchi Path Traversal rappresentano un gradino di partenza molto solido per attacchi via via più strutturati e pericolosi, come quelli di Local File inclusion e Remote File Inclusion, questi ultimi trattati più avanti.

In tutti e tre i casi il problema risiede nell’includere, nel programma in esecuzione sul server, un file indicato da un parametro URL senza implementare delle procedure di sicurezza standard.
Perciò, nel caso degli attacchi Path Traversal, l’attaccante nota il parametro nell’url che chiama un file e vi prova ad inserire una stringa che consenta di accedere ad aree altrimenti nascoste. Dopodiché basta accedere a file che sarebbero invisibili altrimenti e acquisire quante più informazioni sul sistema.

Esempio canonico è una stringa del tipo “../../../etc/passwd”.

Questa stringa, in sistemi Linux non protetti, consente di risalire l’albero (“../”) fino alla root dell’applicazione, per poi scendere (“etc/passwd”) nel file che contiene gli indirizzi delle varie password dell’app.
In realtà, con pochi semplici comandi, un attaccante potrebbe essere in grado di ricavare tutto l’albero.

Dunque, una applicazione vulnerabile a Path Traversal consente di muoversi nell’albero dei file presenti sul server.
Si ha Local File inclusion, invece, quando l’attaccante riesce a far eseguire un file precedentemente caricato sul server.

Può accadere, ad esempio, in siti che richiedono esplicitamente di caricare dei file ma poi, dietro le quinte, non prendono precauzioni di sicurezza per verificare la sicurezza del file. Questo attacco è portato a termine con l’intenzione di far eseguire al server delle web shell, così da poter avere una solida base e arrivare a modificare completamente l’interfaccia del sito (defacement) o a controllare l’applicazione.

L’esempio degli attacchi RFI

Trattiamo ora le RFI, Remote File Inclusion, più nel dettaglio.

L’attaccante ha già appurato, tramite attenta analisi, che l’applicazione vittima consente di navigare l’albero dei file del server.

Sembra ragionevole chiedersi se per caso l’applicazione vulnerabile esegua ciecamente i file che vengono passati tramite parametro.
In caso affermativo, l’hacker può pensare di continuare con l’attacco in modo ancora più impattante.

Come già illustrato, le vulnerabilità che consentono le remote file inclusion consistono nell’eseguire file o path relativi passati da un parametro URL. Dunque, l’attaccante passa in parametro un indirizzo web dove sa che risiede un file eseguibile malevolo.

L’applicazione vulnerabile andrà ad eseguire tale file lato server. Si profila il rischio di Remote File Inclusion poiché nel file sono generalmente contenuti script che mirano alla creazione di web shell da cui poi si può puntare ad attacchi più strutturati.

Di partenza, una volta ottenuta con la forza la capacità di dettare al server i file da eseguire, l’attaccante può arrivare ad ottenere il totale controllo dell’applicazione. Da qui possono verificarsi vari scenari:

  • modifica o eliminazione di varie pagine, che andrebbero a compromettere l’usabilità e l’integrità dell’applicazione. Malintenzionati potrebbero anche sfruttare i server come host per servizi propri o di terzi.
  • Usando tecniche simili a quelle già viste, la possibilità che password e dati sensibili vengano trafugati non è da considerarsi remota.
  • Il server compromesso è in totale controllo dell’attaccante. Finché non verranno intrapresi interventi risolutivi, il terminale contribuirà alla riuscita di futuri attacchi DDoS lanciati dall’hacker.

Alternativamente, modificando i file che il server consegna al client, l’hacker ha l’opportunità di performare attacchi ai danni degli utenti finali, includendo ad esempio dei file javascript che verranno eseguiti dal browser.

Ma come fa l’applicazione ad eseguire file chiamati da un parametro?
E come si può evitare che ciò rappresenti una vulnerabilità?

Innanzitutto, molti linguaggi di scripting server side offrono la possibilità di includere tutta una serie di file all’interno di quello principale che andrà poi eseguito dal server.

Nell’intestazione del file principale c’è la chiamata ai file da includere, così le funzionalità importate potranno essere sfruttate nel codice successivo. Questa tecnica, se usata in modo adeguato e sicuro, contribuisce a scrivere codice più modulare e dunque più ordinato. Oppure, accade spesso che si includano dei file a seconda dell’interazione che un utente ha con l’applicazione.

Ad esempio, dalla home di un negozio online si clicca sull’icona di un prodotto, arrivando alla relativa pagina. Se questo passaggio viene effettuato ‘appoggiandosi’ all’url, ad esempio con [indirizzo]?page=file.estensione, probabilmente lo si fa per includere più facilmente i relativi file che racchiudono le funzionalità e i componenti necessari a navigare correttamente la pagina.

Per poter includere file senza rendere vulnerabile l’applicazione bisogna operare alcuni controlli sull’input e ricordare sempre il mantra:

“Never trust the User”.

Il problema principale, nel caso di RFI, è quindi che il proprietario dell’applicazione si aspetta che questa includa ed esegua solo i file previsti dai programmatori, mentre accade che ogni  file passato a parametro viene eseguito. La soluzione più diretta sembra essere quella di creare una whitelist di file accettati e verificare che quello chiamato dal parametro in Url rientri in quelli della lista.

Per rendere più stringente la condizione di controllo, si potrebbero decretare una lista di formati accettati piuttosto che limiti sulle dimensioni dei file.
In ultima analisi, dato che in tutti gli attacchi trattati vengono fornite stringhe con caratteri inusuali, risulta ragionevole limitare i caratteri usati per nominare i file ai soli alfanumerici (o un set stabilito a monte dai programmatori, purché non comprenda punti, forward slash, % o similari). L’obiettivo di questa limitazione è impedire di poter passare indirizzi web o stringhe con comandi (esempio canonico: Null Byte) in parametro.

Se si usa il sistema di inclusione (ES: include function in php) dei file e ci si deve appoggiare all’url, è possibile assegnare un alias per ogni file ed accettare solo quell’insieme di alias prestabilito. Ogni altra entità verrà rifiutata, specialmente file che hanno estensioni di un linguaggio di scripting.

Ad esempio, nell’URL invece di leggere […]/sezione?page=nome-file.[estensione] si avrà […]/sezione?page=[alias].

Si aggiunge, poi, un controllo di sessione per prevenire che l’utente, cambiando una cifra nell’URL, navighi in sezioni accessibili solo a privilegi più alti del suo. In questo modo si costruisce un’altra linea di difesa, sia contro malintenzionati che contro utenti “sbadati”.

È bene notare, infine, che queste pratiche di prevenzione rappresentano il livello minimo di sicurezza.
É preferibile implementarle sempre ma da sole non sono sufficienti. Possono essere un buon complemento a supporto di tecnologie specifiche di protezione, come ad esempio Firewall, implementate da professionisti.

Questi ultimi possono anche fornire un servizio di testing, andando a evidenziare delle criticità nella sicurezza delle applicazioni prima che si verifichino attacchi e danni.

Remote File Inclusion - RFI examples

Fonte: securityzines.com

Conclusioni

L’interazione tra utenti e applicazioni è fondamento dell’idea di web.

Questo strumento consente di fornire, visualizzare ed ottenere informazioni, connettendo milioni di utenti tra loro. L’idea di condivisione di informazioni ha però un risvolto pratico che può rivelarsi pericoloso: nel caso in cui un utente interagisca con un’applicazione (che è una macchina) può succedere, con dolo o meno, che qualcosa di non previsto accada, intaccando l’esperienza utente o peggio debilitando il sistema.

Per questo ed altri motivi, i programmatori adottano il mantra “Never Trust the User”: ogni interazione utente-app deve svolgersi su binari ben precisi e previsti in fase di progettazione.

Nel caso di vulnerabilità che agevolano Remote File Inclusion, abbiamo visto che sanificazione dell’input (scremare file accettati secondo formati e caratteri ben precisi) e validazione (analisi e test dei file accettati prima di eseguirli) offrono una buona prima linea di difesa, ma ci si può sempre rivolgere a professionisti del settore per effettuare dei test sulla robustezza dei propri prodotti web.

Cyberment Srl

Cyberment è un’azienda specializzata in consulenza di sicurezza informatica. Il nostro red team è composto da hacker etici e specialisti in cybersecurity che operano in questo settore da oltre 20 anni.

Ci occupiamo di identificare le vulnerabilità informatiche nei sistemi e nelle applicazioni web tramite servizi di Vulnerability Assessment e Penetration Test.

Siamo un’azienda di sicurezza informatica certificata ISO 9001, ISO 27001, nonché azienda etica. Abbiamo sede legale a Milano e sede operativa a Porto Mantovano, mentre Londra è il cuore del nostro reparto ricerca e sviluppo.

Se desideri conoscere in modo approfondito i nostri servizi di prevenzione dalle minacce informatiche, contattaci!