Parte 1: http://blogs.ugidotnet.org/raffaele/archive/2009/01/27/windows-vista-integrity-levels-parte-1.aspx
Parte 2: http://blogs.ugidotnet.org/raffaele/archive/2009/01/29/windows-vista-integrity-levels-parte-2.aspx
Parte 3: http://blogs.ugidotnet.org/raffaele/archive/2009/02/03/windows-vista-integrity-levels-parte-3.aspx
Lo Shatter Attack
Nel 2005 Fabio Santini ed io abbiamo tenuto il Security Roadshow in giro per l'Italia. Una delle demo di Fabio consisteva nello Shatter Attack, un tipo di Luring Attack che più generalmente sono attacchi di tipo "Elevation of Privilege". Questo attacco mostrava quanto fosse pericoloso girare come administrator in Windows XP.
Fabio avviava un "malware" di sua creazione con credenziali di normale utente allo scopo di limitare i danni che il malware avrebbe potuto fare.
Il malware in questione mandava una serie di "click" del mouse da codice verso Explorer.exe (la shell di Windows) lanciando così un comando "distruttivo" come potrebbe essere format: "Start, run, format " .... Ok format è solo un esempio di 'effetto' ma se ci pensiamo un attimo non si fa fatica a disastrare una macchina quando si hanno i privilegi di administrator.
Il processo malware, avendo ricevuto un token da normale utente grazie a runas, non avrebbe mai avuto i privilegi per eseguire un format e avrebbe ricevuto un "access denied".
Il processo malware però poteva mandare una serie di WM_LBUTTONDOWN verso il processo Explorer.exe che aveva il token di administrator in quanto l'utente (Fabio nella demo, non nella vita reale) si loggava con privilegi di amministratore. La command che lanciava l'operazione di Format ereditava il token da Explorer.exe e di conseguenza riceveva il token di administrator.
Il gateway all'elevazione di privilegi
Il motivo per cui è possibile realizzare uno Shatter Attack è che gli oggetti di windowing (USER) e grafici (GDI) non sono soggetti a security per ovvi problemi di performance. Pensate cosa significherebbe eseguire un controllo di security per ogni Pen, Brush, CreateWindow, SetWindowText, LineTo, Draw, ... eseguita nel sistema. A distanza di diciotto anni, considero giusta questa scelta che Microsoft fece con Windows NT.
L'introduzione di UIPI in Vista
Il meccanismo di User Interface Privilege Isolation (UIPI) è strettamente legato agli Integrity Levels. UIPI ha il compito di impedire ad un processo di comunicare con un altro che abbia Integrity Level più elevato.
Per esempio un processo con Integrity Level Medium (normale user) non riuscirà a fare una serie di cose verso un altro processo con Integrity Level High (Administrator) o System (servizi e web application):
- Usare SendMessage / PostMessage di messaggi considerati potenzialmente pericolosi.
Windows mantiene una blacklist di messaggi tra cui tutti quelli superiori a WM_USER, tipicamente usati dalle applicazioni come meccanismo di comunicazione privato. Questi messaggi vengono filtrati da Windows. - Eseguire un thread hook
- Monitorare con i journal hook
- Iniettare dll
In pratica UIPI impedisce, grazie agli Integrity Level, gli Shatter Attack che erano fatali in Windows XP. Aggiungerei che UIPI è un meccanismo indispensabile, senza il quale sarebbe facile bypassare il blocco agli oggetti offerto dal meccanismo degli Integrity Levels visto nei precedenti post.
Application Compatibility
Parlando di Application Compatibility, UIPI è certamente un fattore di primo piano in quanto molte applicazioni eseguono una comunicazione tra processi utilizzando l'API RegisterWindowMessage e comunicando con messaggi custom (WM_USER+...).
Per permettere alle applicazioni di modificare il filtro esiste l'API ChangeWindowMessageFilter:
- MSGFLT_ADD. Permette al processo che invoca la API di ricevere il messaggio
- MSGFLT_REMOVE. Nega al processo che invoca la API la ricezione del messaggio
I processi con Integrity Level <= Low non possono usare questa API.
Con una semplice call a questa API i problemi di comunicazione tra processi via WM_xxx sono risolti.
Accessibility
Sembra tutto risolto e invece c'è un problema di primaria importanza: le applicazioni per l'accessibilità. In Windows esiste per esempio la "On-Screen Keyboard" che permette di simulare la tastiera usando solo il mouse. Molte altre applicazioni esistono per i portatori di handicap che permettono di facilitare il canale di I/O tra computer e persona.
Non è perciò improbabile avere la on-screen keyboard che gira come normale user (Integrity Level Low) che devono pilotare applicazioni ad Integrity Level superiore, magari una command prompt amministrativa. Purtroppo UIPI impedisce tutto questo e rende impossibile l'uso di queste applicazioni.
Microsoft non si è affatto dimenticata di questo problema e ha introdotto il flag UIAccess che bypassa UIPI. Questo flag viene letto dal manifest dell'eseguibile e conservato nel token associato al processo.
Visto che questo flag può essere usato per bypassare il meccanismo di protezione da parte di un malware, esiste una policy (abilitata per default) per cui il flag ha effetto solo se l'exe è stato installato in una di queste cartelle:
- in una sottocartella di "Program Files" o "Program Files (x86)"
- in una sottocartella di Windows\System32
Poiché la scrittura in queste cartelle è possibile solo ad un adminstrator, solo una applicazione installata da un token elevato può usare UIAccess.
Per sapere se un token di processo ha abilitato o meno il flag UIAccess, si usa GetTokenInformation passando TokenUIAccess. Il valore di ritorno è 0 (disabilitato) o 1 (abilitato).
Integrity Levels e UIPI sono quindi in primo piano per quello che riguarda i problemi di "Application Compatibility" nei sistemi operativi dalla 6.0 in su (cioè da Vista/2008 in avanti).
Valeva la pena di introdurre queste novità a scapito della piena compatibilità delle vecchie applicazioni? A mio avviso si, senza alcun dubbio perché sottolineo che presto gli antivirus non serviranno più a nulla.