Reading Time: 11 minutes

Sicurezza dei sistemi: Individuazione delle risorse da proteggere

Le azioni necessarie per innalzare il livello di sicurezza nell’uso delle applicazioni online non si esauriscono con l’attivazione di meccanismi di protezione delle informazioni in transito.

Ogni soluzione crittografica, applicata al singolo protocollo e/o servizio applicativo, per quanto robusta, risulta ben poco utile se i dati sensibili possono essere recuperati da un hacker, attaccando direttamente le stazioni in cui questi sono memorizzati (anche solo temporaneamente).

Piuttosto che catturare le informazioni spedite, magari codificate tramite un complesso algoritmo crittografico, un hacker può trovare più semplice attaccare direttamente gli host coinvolti nel processo di comunicazione.

Se riesce ad accedere in maniera fraudolenta ai dati memorizzati nella memoria o sui supporti fisici utilizzati da tali piattaforme può puntare a recuperare le informazioni che gli interessano con semplici operazioni di lettura senza dover applicare tecniche di crittoanalisi, in quanto nelle stazioni coinvolte nel servizio, anche i dati sensibili sono spesso memorizzati in chiaro.

Guadagnare un accesso al sistema remoto, può quindi rappresentare una valida alternativa alla cattura e decodifica dei dati sulla rete.

Per questo, ogni sistema connesso, sia che svolga funzione di server o di semplice client, deve essere protetto contro eventuali accessi indesiderati.

La protezione deve essere estesa anche a stazioni che non trattano direttamente dati sensibili, ma connesse alla stessa infrastruttura di rete delle altre.

In caso di compromissione, ciascun host può infatti essere manipolato opportunamente dall’hacker e divenire strumento per la conduzione di attacchi verso altre piattaforme.

Le possibili vie per condurre un attacco contro un host sono molteplici.

Se sulle piattaforme coinvolte esistono servizi sprovvisti di adeguati meccanismi di autenticazione e/o applicazioni software affette da bug di programmazione, un attaccante può cercare di sfruttare le vulnerabilità per accedere alle informazioni residenti sul sistema.

Oltre alle vulnerabilità associate alle componenti applicative, installate e utilizzate dagli utenti, esistono lacune di sicurezza connesse a bug relativi alle componenti software di più basso livello (parti del kernel del sistema operativo, librerie di sistema, driver per la gestione delle periferiche).

La possibilità di condurre un attacco può derivare anche da configurazioni poco accorte di funzioni e servizi sulle piattaforme locali (configurazioni di default molto aperte).

Per gli utenti locali e gli amministratori dei sistemi informativi aziendali garantire la sicurezza delle piattaforme di lavoro e dei server connessi alla rete è pertanto un compito critico (e molto complesso), che richiede di pianificare l’introduzione di misure atte a impedire che il proprio sistema offra possibili appigli ai malintenzionati.

Le misure da contrapporre consistono sia nella rimozione di eventuali componenti a rischio, sia nell’attivazione di componenti di sicurezza aggiuntivi (quali software Antivirus, meccanismi IDS).

Considerata la complessità del problema, per poter individuare la soluzione più adatta al proprio scenario di utilizzo e alle proprie competenze, occorre capire quali sono le risorse da proteggere e del ruolo per la continuità del servizio erogato da ciascuna piattaforma.

Indipendentemente dal ruolo della stazione (client o server), una lista di risorse da includere nella lista delle componenti a rischio è la seguente:

  • lista degli account definiti e abilitati ad accedere al sistema;
  • dati sensibili memorizzati nel filesystem locale o su altri dischi raggiungibili via rete;
  • altri dati memorizzati su supporti hardware (anche rimuovibili);
  • codice dei programmi eseguibili;
  • processi attivi;
  • buffer e altre aree di memoria allocate ai processi attivi;
  • CPU;
  • puntatori alle connessioni di rete (socket);
  • semafori e altri meccanismi di sincronizzazione tra processi.

A parte gli account e le informazioni memorizzate nel file system (a cui è dedicato un paragrafo a sé stante), nella precedente lista compaiono elementi poco noti, la cui inclusione tra le risorse a rischio di attacco può anche sorprendere.

Analizziamo i motivi per cui tali elementi sono stati inclusi nella lista dei componenti rilevanti la sicurezza dei sistemi.

Il codice di un programma è componente delicata che può risultare oggetto di attacchi per molteplici motivi.

Se il programma ha un ruolo di controllo sugli altri eseguibili che vengono lanciati all’interno di una piattaforma (come per esempio avviene con un programma Antivirus), è evidente il vantaggio che l’attaccante può conseguire se riesce a modificare/sostituire il codice di tale programma fasullo è in esecuzione, l’utente locale è indotto a credere di possedere adeguata protezione contro l’esecuzione di altri programmi ostili, illudendosi sulla sicurezza della propria piattaforma.

Problemi di sicurezza analoghi possono insorgere se viene manomesso il codice di programmi che erogano servizi via rete.

Per esempio un attaccante può sostituire il codice di un FTP Server in modo che non effettui alcuna procedura di autenticazione, o più semplicemente restituisca sempre un successo al termine di tale processo, consentendo l’accesso ai file anche quando l’utente ha specificato username e password non definiti nel sistema.

Per evitare che un software installato sull’host si trasformi in una componente ostile è necessario pertanto proteggere ogni forma di codice eseguibile memorizzata localmente.

Anche se di più complessa manipolazione, è necessario prevedere adeguata protezione anche al codice dei programmi che risultano attualmente in esecuzione.

Al fine di scongiurare la possibilità di lanciare in esecuzione involontariamente un programma manomesso può essere opportuno produrre, mantenere e verificare all’avvio una checksum crittografica di ogni file eseguibile presente sulla propria piattaforma.

Esistono numerosi tool software che sono in grado di calcolare tali digest (utilizzando funzioni quali MD5 o SHA) e memorizzarli in maniera sicura in aree di memoria non facilmente accessibili all’attaccante.

La tendenza attuale è includere questa funzione di controllo nei software Antivirus che vengono installati sugli host.

Generalmente, una stazione server è chiamata a eseguire numerosi processi contemporaneamente.

Questo richiede un sistema operativo, che consente di gestire molteplici programmi allo stesso tempo (sistema multitask) e un’architettura hardware veloce e affidabile.

Le stazioni client richiedono in genere prestazioni meno brillanti.

Anche se il numero di processi attivi su un client è limitato, le piattaforme sono provviste di sistemi operativi multitask.

I processi che sono attivi allo stesso momento su un generico host concorrono tra loro per l’uso di risorse hardware locali quali aree di memoria, CPU e PID (Process ID).

È fondamentale includere tali risorse nella lista degli elementi da proteggere.

Un attaccante potrebbe infatti utilizzare in maniera non idonea un processo fra quelli in esecuzione per cercare di esaurire tutta la memoria RAM disponibile o per sovraccaricare la CPU (attacco DoS).

Un altro possibile esercizio per l’attaccante potrebbe essere quello di mandare in esecuzione numerosi processi a cui vengono assegnati PID diversi fino a esaurire lo spazio di tutti i possibili identificativi assegnabili.

Forzare l’assegnazione di nuovi PID è relativamente semplice anche agendo da remoto. In un sistema operativo UNIX per esempio al momento in cui il server esegue una fork() generando un processo figlio, al nuovo processo viene assegnato un PID che viene comunicato al padre.

Una volta noto il PID di un processo si può usare tale identificativo per effettuare operazioni sul processo stesso.

Per esempio, noto il PID di un processo si può inviare allo stesso opportune chiamate di sistema per cercare di terminarlo (tramite il comando kill()).

La protezione di queste componenti è normalmente compito delle funzioni di sicurezza intrinseche del sistema operativo installato sulla singola piattaforma.

I sistemi operativi di derivazione UNIX da sempre posseggono meccanismi che consentono un qualche livello di protezione nell’uso della memoria, della CPU e dei puntatori ai processi., da azioni fraudolente promosse dagli utenti connessi.

Anche nei sistemi Microsoft Windows (diffusi sulla maggior parte dei PC client) si ha oggi la possibilità di limitare le azioni che possono essere svolte da un utente.

Tali meccanismi possono essere normalmente manipolati (ed eventualmente aggirati) solo da chi ha privilegi amministrativi sulla piattaforma locale.

Per evitare quindi che i programmi lanciati e le attività svolte dall’utente locale possano creare effetti DoS sulla piattaforma è considerato opportuno evitare sempre l’uso di account utente con privilegi superiori a quelli strettamente necessari allo svolgimento delle normali operazioni sull’host.

La regola base è sradicare l’abitudine degli utenti di loggarsi come Administrator o Superuser.

Nonostante i meccanismi di protezione inclusi nei sistemi operativi, un’area di memoria che risulta spesso critica è quella denominata Call Stack.

Questa è una struttura dati utilizzata per memorizzare temporaneamente informazioni su quali sono le subroutine attive di un programma.

Le informazioni vengono inserite (tramite operazioni Push) e tolte (tramite operazione Pop) dallo stack secondo una disciplina LIFO (Last In First Out).

Nel Call Stack viene memorizzato l’indirizzo di ritorno da utilizzare una volta terminata la subroutine attiva (Return Address).

L’indirizzo di ritorno dovrebbe puntare all’istruzione successiva, nel flusso del codice in esecuzione, a quella in cui era riferita la subroutine stessa.

Nello stack vengono anche memorizzati i parametri che sono passati alla subroutine.

Poiché la disciplina LIFO prevede di inserire i dati necessari alla esecuzione della subroutine dopèo aver scritto il Return Adress, è fondamentale che lo spazio riservato nello stack per tali parametri coincida con la massima dimensione che gli stessi dati possono assumere.

La mancanza di controlli sull’eventuale superamento di tale limite superiore può essere utilizzato da un attaccante per compromettere il sistema.

Se i dati passati eccedono infatti la dimensione del buffer loro riservato, è possibile andare a sovrascrivere l’area dello stack in cui è memorizzato il Return Address, sostituendovi un valore scelto opportunamente dall’attaccante, ottenendo quello che generalmente viene indicato come Stack Buffer Overlflow.

Per riuscire a sovrascrivere il Return Address con un valore casuale non occorre conoscere tutta la struttura dello stack.

È sufficiente inserire una stringa di dati opportunamente lunga per compromettere la possibilità di ritorno al codice principale del programma.

L’effetto in tal caso è normalmente quello di un attacco DoS.

Se l’hacker desidera sfruttare la tecnica di Stack Buffer Overflow per lanciare in esecuzione un opportuno blocco di codice, è necessario conoscere esattamente la profondità dell’area dello stack utilizzata.

In tal caso è possibile scrivere nel Return Address esattamente una sequenza prestabilita, scegliendo di fatto quale sarà la prossima istruzione eseguita una volta terminata la subroutine.

È possibile seguire due strategie:

  • inserire come nuovo Return Address il puntatore a una istruzione di una componente di codice attiva sulla piattaforma locale che si trova a un indirizzo noto;
  • inserire come nuovo Return Address il puntatore all’inizio del Call Stack dove sarà stato precedentemente inserito dall’attaccante un opportuno Shellcode.

Nel primo caso il salto diretto all’istruzione puntata può permettere all’attaccante di accedere a uno specifico servizio senza dover prima superare la procedura di autenticazione a esso associata.

Nel secondo scenario il nuovo Return Address punta semplicemente a un’area dello stack in cui l’attaccante ha scritto (specificando direttamente il codice in linguaggio assembler per la specifica piattaforma target) le istruzioni per aprire una backdoor e restituire una shell di comandi sull’host compromesso.

Lo spazio disponibile per scrivere questo Shellcode dipende dallo spazio reso disponibile dalla subroutine che presenta la vulnerabilità.

Oltre al Call Stack nei programmi possono esistere altri buffer che possono subire attacchi di tipo buffer overflow.

Queste vulnerabilità sono state utilizzate da numerosi Internet Worm per compromettere i sistemi, copiare il proprio codice e mandarlo fraudolentemente in esecuzione.

Esempi in tal senso sono i seguenti worm: Morris, Slammer, Blaster, Witty.

Le vulnerabilità di Buffer Overflow dipendono dalle funzioni utilizzate dai programmatori nella stesura del codice e dai controlli sulla lunghezza dei dati passati in input ai programmi.

Solo un’attenta analisi e revisione del codice di un programma può consentire l’individuazione delle istruzioni affette dal problema e suggerire la soluzione.

Un singolo utente può fare ben poco per risolvere in autonomia il problema, in quanto difficilmente ha tempo e conoscenze necessarie per effettuare il Security Assessment del codice.

Inoltre non sempre i sorgenti dei programmi utilizzati sono disponibili come Open Source per poterne effettuare il debug.

Poiché le vulnerabilità di tipo Buffer Overflow sono legate agli specifici programmi utilizzati e alle librerie del proprio sistema operativo la sola contromisura efficace, applicabile per ridurre l’esposizione al rischio della propria piattaforma, è monitorare costantemente i siti che pubblicano nuove vulnerabilità per verificare se il software è a rischio.

In caso affermativo è consigliabile contattare il vendor del software e installare eventuali patch di sicurezza da esso rilasciate.

Altri potenziali bersagli di un hacker sono infine rappresentati dai puntatori alle connessioni per la comunicazione tra processi, tradizionalmente utilizzate per il passaggio dati tra processi locali e/o remoti (pipe, socket), e dai meccanismi implementati per sincronizzare questo scambio dati.

Un discorso a parte va poi fatto per le risorse hardware da proteggere.

Oltre alle componenti logiche precedentemente descritte, contribuiscono a determinare il fattore di rischio complessivo del target anche gli elementi hardware utilizzati dagli host.

Una corretta policy di sicurezza aziendale dovrebbe prevedere misure idonee per assicurare la protezione di componenti come: dischi, modem, interfacce di rete, dispositivi di backup.

In alcune organizzazioni, i sistemi informatici e gli apparati di comunicazione risultano così numerosi da rendere estremamente complesso anche solo produrre un inventario delle componenti hardware incluse nel perimetro da difendere.

Talvolta lo scenario delle installazioni presenti in azienda muta così rapidamente da rendere subito obsoleto ogni inventario condotto manualmente.

Per questo, per mantenere informazioni sui propri sistemi e sulle componenti hardware da questi utilizzate, si ricorre a tecniche e strumenti software (installati a bordo delle piattaforme), che consentono un inventario automatico, aggiornato ogni qual volta una nuova risorsa viene introdotta o rimossa.

Lo sforzo associato alla creazione e al mantenimento di un database aggiornato delle risorse a rischio non è un processo fine a se stesso.

Non è raro infatti che, in seguito a un’azione di Auditing, si individuino componenti hardware (come schede di rete e/o modem) di cui non si era a conoscenza.

Ognuna di queste componenti, rappresentando di fatto una modalità di accesso al target, può essere considerata una potenziale vulnerabilità per la sicurezza complessiva dell’infrastruttura.

Molto frequentemente l’analisi rileva che, non tutte le risorse associate a una piattaforma sono necessarie e/o compatibili con le regole stabilite dalla propria politica di sicurezza.

Per evitare che i sistemi possano essere compromessi è generalmente necessario provvedere alla loro immediata rimozione.

Dischi e dispositivi di backup devono altresì essere protetti in quanto elementi utilizzati per la memorizzazione dei file e dei dati sensibili.

Altro reale pericolo da fronteggiare consiste nella possibilità che, in assenza dell’utente autorizzato, un intruso utilizzi le periferiche della stazione per raccogliere informazioni contenute sul disco, per accedere a uno specifico applicativo e/o per tentare un attacco verso le altre postazioni, mascherando la propria identità.

Per scongiurare questi attacchi, tutte le moderne stazioni sono provviste di appositi meccanismi per proteggere la postazione in assenza dell’utente legittimo.

Una corretta policy aziendale dovrebbe prescrivere l’obbligo di utilizzo di tali strumenti per migliorare la protezione fisica della piattaforma.

Lo strumento standard per evitare l’uso illegittimo delle periferiche locali è avviare uno screensaver con password.

Lo screensaver blocca l’uso della tastiera e delle altre periferiche.

Tale accorgimento protegge le periferiche dall’uso illegittimo da parte di intrusi occasionali.

Questo meccanismo offre però una debole resistenza alle azioni di attaccanti debitamente attrezzati. È sufficiente un dispositivo elettronico di basso costo, per emulare la tastiera e per provare in maniera esaustiva tutte le possibili combinazioni di password in pochi secondi.

Con un simile dispositivo, ogni screensaver può essere rapidamente aggirato.

Inoltre, se è consentito l’accesso pubblico all’area dove si trova la stazione, un intruso può facilmente asportare i supporti fisici che interessano (esempio dischi), farne una copia e rimettere tutto a posto il mattino successivo.

error: Content is protected !!

Complimenti! Ti sei iscritto alla nostra Newsletter

C'è stato un errore durante l'invio della richiesta. Per favore riprova.

Computer Security will use the information you provide on this form to be in touch with you and to provide updates and marketing.