Il supporto per Windows Vista Service Pack 1 (SP1) termina il 12 luglio 2011. Per continuare a ricevere gli aggiornamenti della sicurezza per Windows, assicurarsi di utilizzare Windows Vista con Service Pack 2 (SP2). Per altre informazioni, consulta questa pagina Web Microsoft: Il supporto per alcune versioni di Windows sta per terminare.

Quando un'applicazione carica dinamicamente una DLL senza specificare un percorso completo, Windows prova a individuare la DLL effettuando una ricerca in un set di directory ben definito. Se un utente malintenzionato acquisisce il controllo di una delle directory, può forzare l'applicazione a caricare una copia dannosa della DLL invece della DLL prevista. Questi attacchi sono noti come "attacchi di precaricamento delle DLL" e sono comuni a tutti i sistemi operativi che supportano il caricamento dinamico delle librerie di DLL condivise. L'effetto di questi attacchi potrebbe essere che un utente malintenzionato possa eseguire codice nel contesto dell'utente che esegue l'applicazione. Quando l'applicazione viene eseguita come amministratore, questo può portare a un'elevazione dei privilegi locale. Sappiamo del rinnovato interesse per questi attacchi. Per limitare l'effetto di questo problema sui comuni clienti, rilasciamo questo documento alla community di sviluppatori per assicurarci che siano a conoscenza del problema e che siano disponibili gli strumenti necessari per risolvere il problema nelle loro applicazioni.

Riepilogo

Descrizione degli attacchi di precaricamento delle DLL

Attacchi basati su LoadLibrary

Quando un'applicazione carica dinamicamente una DLL senza specificare un percorso completo, Windows prova a individuare tale DLL effettuando una ricerca lineare in un set di directory ben definito, noto come Ordine di ricerca DLL. Se Windows individua la DLL nell'ordine di ricerca della DLL, la carica. Tuttavia, se Windows non trova la DLL in una delle directory nell'ordine di ricerca della DLL, restituirà un errore nell'operazione di caricamento della DLL. Di seguito è riportato l'ordine di ricerca DLL per le funzioni LoadLibrarye LoadLibraryEx,che vengono usate per caricare dinamicamente le DLL:

  1. La directory da cui è stata caricata l'applicazione

  2. Directory di sistema

  3. Directory di sistema a 16 bit

  4. Directory di Windows

  5. La directory di lavoro corrente

  6. Directory elencate nella variabile di ambiente PATH



Si consideri lo scenario seguente:


  • Un'applicazione carica una DLL senza specificare un percorso completo che prevede di trovare nel file CWD dell'applicazione.

  • L'applicazione è completamente preparata a gestire il caso quando non trova la DLL.

  • L'utente malintenzionato riconosce queste informazioni sull'applicazione e controlla il sito Web part.

  • L'utente malintenzionato copia la propria versione appositamente realizzato della DLL nel file CWD. Si presuppone che l'utente malintenzionato abbia l'autorizzazione per eseguire questa operazione.

  • Windows cerca nelle directory nell'ordine di ricerca della DLL e trova la DLL nel file CWD dell'applicazione.

In questo scenario, la DLL appositamente realizzato viene eseguita all'interno dell'applicazione e acquisisce i privilegi dell'utente corrente.

Consiglio Per evitare questo attacco, le applicazioni possono rimuovere la directory di lavoro corrente (CWD) dal percorso di ricerca dll chiamando
l'API SetDllDirectory usando una stringa vuota
(""). Se un'applicazione dipende dal caricamento di una DLL dalla directory corrente, ottenere la directory di lavoro corrente e usarla per passare un percorso completo di LoadLibrary.



Siamo anche consapevoli che alcuni sviluppatori usano LoadLibrary per verificare se una DLL specifica è presente per determinare quale versione di Windows viene eseguita dall'utente. Tenere presente che questo potrebbe rendere vulnerabile l'applicazione. Se la raccolta interessata non esiste effettivamente nella versione di Windows in cui l'applicazione è eseguita, un utente malintenzionato potrebbe introdurre in CWD una raccolta con lo stesso nome. Questa tecnica è sconsigliata. Usare invece le tecniche consigliate descritte nell'articolo in MSDN "Ottenere la versione del sistema".

Un'applicazione che carica plug-in di terze parti e che non può forzare i plug-in a usare un percorso qualificato per le chiamate LoadLibrary deve chiamare SetDllDirectory("") per rimuovere CWD e quindi chiamare SetDllDirectory("percorso di installazione del plug-in") per aggiungere la directory di installazione del plug-in al percorso di ricerca DLL.

Attacchi basati su SearchPath

Un attacco simile si verifica quando un'applicazione usa l'API SearchPath per individuare una DLL e caricare dinamicamente il percorso restituito da SearchPath. Di seguito è riportato l'ordine di ricerca predefinito per l'API SearchPath:

  • La directory da cui è stata caricata l'applicazione

  • La directory di lavoro corrente

  • Directory di sistema

  • Directory di sistema a 16 bit

  • Directory di Windows

  • Directory elencate nella variabile di ambiente PATH

Questo modello non è consigliato perché non è sicuro. Non è consigliabile usare la funzione SearchPath come metodo per l'individuazione di un file DLL se l'uso previsto dell'output si trova in una chiamata alla funzione LoadLibrary. Questo può causare l'individuazione del file DLL errato perché l'ordine di ricerca della funzione SearchPath è diverso dall'ordine di ricerca usato dalla funzione LoadLibrary. Se è necessario individuare e caricare un file DLL, usare la funzione LoadLibrary.

ShellExecute e CreateProcess


Le varianti di questi problemi possono verificarsi anche quando gli sviluppatori chiamano funzioni simili come ShellExecutee CreateProcessper caricare eseguibili esterni. È consigliabile prestare attenzione agli sviluppatori durante il caricamento dei file binari e specificare il percorso completo. Questo dovrebbe presentare una minore complessità quando si carica un file binario invece di una raccolta.

Procedura consigliata per sviluppatori di software

È consigliabile eseguire le operazioni seguenti per gli sviluppatori:

  • Convalidare le applicazioni per le istanze di caricamenti di libreria non sicuri (esempi di ognuna di essi sono forniti più avanti in questo articolo). Sono inclusi i seguenti:

    • L'uso di SearchPath per identificare la posizione di una raccolta o di un componente.

    • L'uso di LoadLibrary per identificare la versione del sistema operativo.

  • Usare percorsi completi per tutte le chiamate a LoadLibrary, CreateProcess e ShellExecute, dove possibile.

  • Implementare chiamate a SetDllDirectory con una stringa vuota ("") per rimuovere la directory di lavoro corrente dall'ordine di ricerca dll predefinito in cui è necessario. Tenere presente che SetDllDirectory influisce sull'intero processo. È quindi consigliabile eseguire questa operazione una volta prima dell'inizializzazione del processo, non prima e dopo le chiamate a LoadLibrary. Poiché SetDllDirectory influisce sull'intero processo, più thread che chiamano SetDllDirectory con valori diversi potrebbero causare un comportamento indefinito. Inoltre, se il processo è progettato per caricare DLL di terze parti, sarà necessario eseguire test per determinare se l'esecuzione di un'impostazione a livello di processo causa incompatibilità. Un problema noto è che quando un'applicazione dipende Visual Basic, Applications Edition, un'impostazione a livello di processo può causare incompatibilità.

  • Usare la funzione SetSearchPathModeper abilitare la modalità di ricerca del processo sicuro per il processo. La directory di lavoro corrente viene spostata all'ultima posizione nell'elenco di ricerca di SearchPath per tutta la durata del processo.

  • Evitare di usare SearchPath per verificare l'esistenza di una DLL senza specificare un percorso completo, anche se è abilitata la modalità di ricerca sicura, perché ciò può comunque portare ad attacchi di precaricamento delle DLL.

Indicazioni sull'identificazione dei caricamenti di raccolta non sicuri

Nel codice sorgente gli esempi seguenti sono relativi al caricamento di librerie non sicure:

  • Nell'esempio di codice seguente l'applicazione cerca "schannel.dll" usando il percorso di ricerca meno sicuro. Se un utente malintenzionato può inserire schannel.dll contenuto in CWD, verrà caricato anche prima che l'applicazione esequie nelle directory di Windows la raccolta appropriata.

    DWORD retval = SearchPath(NULL, "schannel", ".dll", err, result, NULL); 
    HMODULE handle = LoadLibrary(result);
  • Nell'esempio di codice seguente l'applicazione prova a caricare la libreria dalle varie posizioni dell'applicazione e del sistema operativo descritte all'inizio del documento per la chiamata LoadLibrary(). Se esiste il rischio che il file non sia presente, l'applicazione può provare a caricare il file dalla directory di lavoro corrente. Questo scenario è leggermente meno pericoloso rispetto all'esempio precedente. Tuttavia, espone comunque l'utente dell'applicazione a rischi se l'ambiente non è del tutto prevedibile.

    HMODULE handle = LoadLibrary("schannel.dll");




Di seguito sono riportati alcuni esempi di caricamento di raccolta più sicuro e migliore:

  • Nell'esempio di codice seguente la raccolta viene caricata direttamente usando un percorso completo. L'utente malintenzionato non rischia di introdurre codice dannoso, a meno che non abbia già le autorizzazioni di scrittura per la directory di destinazione dell'applicazione.

    HMODULE handle = LoadLibrary("c:\\windows\\system32\\schannel.dll");



    Nota Per informazioni su come determinare la directory di sistema, vedere le risorse seguenti:

    GetSystemDirectory

    http://msdn.microsoft.com/en-us/library/ms724373%28VS.85%29.aspxSHGetKnownFolderPath

    http://msdn.microsoft.com/en-us/library/bb762188%28v=VS.85%29.aspx

  • Nell'esempio di codice seguente la directory di lavoro corrente viene rimossa dal percorso di ricerca prima di chiamare LoadLibrary. In questo modo il rischio si riduce in modo significativo, perché l'utente malintenzionato dovrebbe controllare la directory dell'applicazione, la directory di Windows o tutte le directory specificate nel percorso dell'utente per usare un attacco con precaricamento delle DLL.

    SetDllDirectory ("");
    HMODULE handle = LoadLibrary("schannel.dll");
  • In tutti i sistemi che hanno installato l'aggiornamento della sicurezza 963027 (descritto in MS09-014),il codice seguente sposterà definitivamente CWD nell'ultimo punto dell'ordine di ricerca. Le chiamate successive alla funzione SetSearchPathMode dall'interno del processo che provano a cambiare la modalità di ricerca non verranno effettuate.

    SetDllDirectory ("");
    HMODULE handle = LoadLibrary("schannel.dll");
  • Nell'esempio di codice seguente la directory di lavoro corrente viene rimossa dal percorso di ricerca prima di chiamare LoadLibrary. In questo modo il rischio si riduce in modo significativo, perché l'utente malintenzionato dovrebbe controllare la directory dell'applicazione, la directory di Windows o tutte le directory specificate nel percorso dell'utente per usare un attacco con precaricamento delle DLL.

    SetSearchPathMode (BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT );
    HMODULE handle = LoadLibrary("schannel.dll");

Uso di Process Monitor per rilevare in modo dinamico i caricamenti non sicuri

Microsoft pubblica uno strumento denominato Monitoraggio processo. Questo strumento consente a sviluppatori e amministratori di tenere traccia attentamente del comportamento di un processo in esecuzione. Process Monitor può essere usato per rilevare dinamicamente se una delle applicazioni può essere vulnerabile a questo tipo di problema.

  • Per scaricare Process Monitor, visitare la pagina Web Microsoft seguente:

    http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx

  • Provare ad avviare l'applicazione usando CWD impostato su una directory specifica. Ad esempio, fare doppio clic su un file con estensione il cui gestore di file è assegnato all'applicazione.

  • Configurare Process Monitor con i filtri seguenti:



    testo alternativo

  • Se viene raggiunto un percorso vulnerabile, verrà visualizzato un messaggio simile al seguente: testo alternativoLa chiamata alla condivisione file remota per caricare una DLL indica che si tratta di un programma

    vulnerabile.

Ulteriori informazioni

Per altre informazioni, visitare le pagine Web Microsoft seguenti:

Ordine di ricerca di Dynamic Link Library

http://msdn.microsoft.com/library/ms682586(VS.85).aspxDocumentazione MSDN sulla funzione SearchPath

http://msdn.microsoft.com/library/aa365527(VS.85).aspxDocumentazione di MSDN sulla funzione LoadLibrary

http://msdn.microsoft.com/library/ms684175(VS.85).aspxDocumentazione msdn sulla funzione SetDllDirectory

http://msdn.microsoft.com/library/ms686203(VS.85).aspxDocumentazione msdn sulla funzione SetSearchPathMode

http://msdn.microsoft.com/library/dd266735(VS.85).aspxPost di blog di David Leblanc, Principal Security Engineer con Microsoft Office

http://blogs.msdn.com/b/david_leblanc/archive/2008/02/20/dll-preloading-attacks.aspxPost di blog di Andrew Roths, team di progettazione MSRC su attacchi di precaricamento DLL

http://blogs.technet.com/b/srd/archive/2009/04/14/ms09-014-addressing-the-safari-carpet-bomb-vulnerability.aspx

Risorse aggiuntive

Serve aiuto?

Amplia le tue competenze
Esplora i corsi di formazione
Ottieni in anticipo le nuove caratteristiche
Partecipa a Microsoft Insider

Queste informazioni sono risultate utili?

Grazie per il feedback!

×