Windows: la sicurezza inizia nel kernel Marco Russo DevLeap http://blogs.devleap.com/marco [email protected] Agenda Architettura kernel di Windows Modello a oggetti Security descriptor ACL – Access Control List Auditing Privilegi Architettura kernel di Windows Perché il kernel è importante Tutto il codice kernel viene eseguito in modalità full trusted Accesso completo a tutte le risorse Il codice in modalità kernel non ha vincoli di sicurezza L’implementazione della sicurezza è realizzata nel kernel attraverso codice che gira in modalità “full trusted” Il codice “utente” è controllato Modalità di esecuzione definita a livello di CPU Limiti nell’accesso alle risorse Implementazione fisica basata su caratteristiche CPU Impossibile da aggirare senza un appoggio da parte di altro codice trusted MS Windows NT: obiettivi del progetto Compatibilità applicazioni Win32, Win16, MS-DOS, OS/2, POSIX Portabilità Ieri: piattaforma Intel, RISC Oggi: x32, x64, IA-64 (Itanium) Xbox: kernel NT modificato Robustezza Estendibilità Prestazioni Compatibilità binaria, sorgente, file system Architettura di MS Windows NT Applications and Subsystems Software (User-Mode Instruction Set) Process Security Local Object Virtual Manager Monitor IPC Manager Memory Manager Kernel I/O Manager GDI USER Device Drivers HAL Hardware I/O Devices DMA/Bus Controller Timers Caches, Interrupts CPU Privileged Architecture Spazio di indirizzamento System Memory (2 GB) Non-paged Paged Per-Process Memory (2 GB) Physical Addressing Range Paged Memoria virtuale Process Address Space Physical Memory 2 GB Page Tables R e s e r v e d 0 Committed Pages Invalid Committed Pages Invalid Shared memory e copy on write Process 1 Virtual Memory Page 1 Committed Memory Page 2 Page 1 Page 2 Section Page 1 Process 2 Page 2 Copy Virtual Memory Page 2 Copy (Read-Write) La memoria in Windows Task Manager Process Explorer http://www.sysinternals.com/Utilities/ProcessExplorer.html Gli oggetti di NT (kernel objects) Process Access Token Mutex Thread Event Semaphore Section File Registry Perché gli oggetti kernel sono importanti L’accesso a oggetti kernel da parte di codice utente è sempre controllato Gli oggetti kernel possono far comunicare processi diversi tra loro Per accedere alle risorse della macchina bisogna sicuramente accedere a un oggetto kernel La garanzia di questo funzionamento è data dalle caratteristiche dei microprocessori Tutti gli accessi possono essere convalidati e monitorati Meccanismi di auditing grazie a primitive del kernel Object: struttura interna Condivisione ed eventule comunicazione tra processi Chi può farne cosa Reference counter Object Header Gerarchia di oggetti Object Name Object Directory Security Descriptor Quota Charges Open Handle Counter Open Handle Database Permanent/Temporary Kernel/User Mode Type Object Pointer Object Body Limite alla quantità di risorse disponibili al processo Type Object Security Detail Access Token Security ID: LEES Group IDs: TEAM1 TEAM2 LOCAL INTERACTIVE WORLD Privileges: None . . . Event Object . . Security Descriptor . . Access Control List Allow LEES Synchronize Modify State Allow TEAM1 Synchronize Allow TEAM2 Synchronize Modify State Processi Cosa è un Processo? Un’istanza di un programma in esecuzione Un processo possiede degli Oggetti Gli oggetti sono rappresentati dagli Handle Cosa distingue un processo da un altro? Handle table Memoria privata Windows Il processo è un insieme di thread, ed esiste fino a che contiene almeno un thread Perché un processo è importante? Definisce il perimetro di sicurezza delle risorse di un’applicazione Gli accessi a oggetti kernel sono controllati tramite Handle e rilasciati se il processo viene chiuso Il processo è assegnato a un “utente” al momento della sua creazione (Access Token) Win32-Based Process Model Access Token Virtual Address Space Description ... Process Object Table Available Objects Handle 1 Thread x Handle 2 File y Handle 3 Section z Ciclo di vita di un Processo Un processo viene creato associando sempre un file eseguibile (.EXE), che è mappato in memoria ed eseguito Creando un processo viene creato un thread Il primo thread di un processo può essere chiamato thread principale, anche se la sua chiusura non determina necessariamente la fine del processo La run-time library del C termina il processo corrente se si esce dalla funzione main() con return, indipendentemente dalla presenza di altri thread Interprocess Communication (IPC) IPC viene realizzata quando due o più processi condividono un oggetto Gli oggetti usati per IPC includono: Shared memory (section object) Files Semaphores Pipes / Mailslot Windows sockets I metodi di accesso condiviso sono gli stessi per molti oggetti di tipo diverso Condivisione di oggetti Gli oggetti condivisi sono handle diversi che puntano allo stesso oggetto kernel Process A Process B Kernel Objects Object Table Thread x Object Table Handle 1 Thread y Handle 1 Handle 2 File k Handle 2 Handle 3 Section z File w Handle 3 Gli oggetti nei processi Process Explorer http://www.sysinternals.com/Utilities/ProcessExplorer.html WinObj http://www.sysinternals.com/Utilities/WinObj.html Access Token Security Descriptor Cosa è un access token Documento d’identità di un utente, contiene: Identità dell’utente Gruppi a cui appartiene Privilegi dell’utente Associato a un processo (o a un thread) Non è modificabile da parte di codice utente Garanzia di integrità dei dati, salvo che un amministratore acceda alla macchina e ne cambi gli archivi. Access token Un access token comprende SID utente SID dei gruppi a cui l’utente appartiene Privilegi assegnati all’utente Account SID Group 1 SID Group n SID Privilege 1 Privilege 1 Access token e processi Process Explorer http://www.sysinternals.com/Utilities/ProcessExplorer.html Security Identifiers - SID Un Security Identifier (SID) identifica un attore nella security: Utenti, Gruppi, Computer, Domini Un SID è composto da: Livello revisione (es. 1) Identifier-authority (es. 5 = SECURITY_NT_AUTHORITY) Uno o più valori per subauthority SID sono lunghi quanto serve per essere statisticamente univoci Il setup assegna un SID al computer Utenti e gruppi della macchina locale hanno un SID derivato da quello del computer, con un RID (Relative Identifier) alla fine Alcuni utenti e gruppi hanno SID predefiniti (eg. World = S-1-1-0) RID parte da 1000 (numeri inferiori riservati a RID predefiniti) Security Descriptor Descrittori associati agli oggetti: file, chiavi di registry, definiti da applicazioni Hanno una lunghezza variabile Owner SID Primary Group DACL pointer SACL pointer DACL SACL Compatibilità con POSIX Creazione di un Security Descriptor Process Access Token Object Security Descriptor User SID Group SID Discretionary ACL Access Control Entry (Denied) ... Access Control Entry (Allowed) ... Owner SID Group SID 1) InitializeSecurityDescriptor() 2) SetSecurityDescriptorOwner() 3) SetSecurityDescriptorGroup() 4) InitializeAcl() 5) AddAccessDeniedAce() ... 6) AddAccessAllowedAce() ... 7) SetSecurityDescriptorDacl() Perché la DACL è importante Definisce i criteri di autorizzazione per l’accesso a un oggetto Una DACL “sbagliata” favorisce ingressi non autorizzati Capire il funzionamento consente di creare DACL corrette e di spiegare funzionamenti apparentemente oscuri Ci sono molti automatismi che per default favoriscono la sicurezza Alcuni programmatori creano involontariamente delle vulnerabilità lasciando “troppo accessibile” una risorsa DACL: Discretionary Access Control List Una DACL ha zero o più Access Control Entry (ACE) Un security descriptor senza DACL consente accesso completo a chiunque Un security descriptor con una DACL vuota (0 ACE) nega l’accesso a chiunque Un ACE può essere “allow” o “deny” ACE Type SID Access Mask Read, Write, Delete, ... Controllo accesso Le ACE nella DACL sono esaminate in ordine ACE con SID corrispondente a un SID del token? Se sì, gli accessi disponibili corrispondono a quelli desiderati? Se sì, che tipo di ACE è? Deny: restituisce ACCESS_DENIED Allow: consente l’accesso specificto e se non ci sono altri accessi da verificare restituisce ACCESS_ALLOWED Se si terminal la DACL e restano degli accessi da verificare, restituisce ACCESS_DENIED Esempio: Access granted Security Token Used ID: FredMgr Group Ids: Users Mgrs Everyone Privileges: None Desired access read/write (RW) File object Security descriptor AccessAllowed FredMgr Read (RX) ACE AccessAllowed Mgrs Special Access(RW) AccessAllowed Everyone Special Access(X) ACE Discretionary Access Control List ACE Esempio: Access denied Security Token Used ID: FredMgr Group Ids: Users Mgrs Everyone Privileges: None Desired access read/write (RW) File object Security descriptor AccessDenied Mgrs Read/Write (RW) ACE AccessAllowed FredMgr Read(RX) AccessAllowed Everyone Write(W) ACE Discretionary Access Control List ACE Ordinamento ACE L’ordine degli ACE è importante API a basso livello consentono la creazione di DACL con ACE in un ordine qualsiasi Tutte le interfacce utente e le API di più alto livello ordinano gli ACE facendo precedere i DENY dagli ALLOW Token Marco Authors DACL Developers Deny Privilege 1 Authors Privilege n Read Allow Marco All DACL Allow Marco All Access Request Read Deny Authors Read Casi speciali L’owner di un oggetto ha sempre i permessi WRITE_DACL and READ_DACL Un account con il privilegio “take ownership” può acquisire diventare owner di un oggetto Un account con il privilegio “backup” può aprire qualsiasi file in lettura Un account con il privilegio “restore” può aprire qualsiasi file in scrittura Ereditarietà ACE In NT 4.0, gli oggetti possono ereditare gli ACE solo da un contenitore padre (es. Directory o registry) quando sono creati Nessuna distinzione tra ACE ereditati e non ereditati Non c’è prevenzione dell’ereditarietà In Windows 2000 l’ereditarietà è controllabile SetNamedSecurityInfoEx / SetSecurityInfoEx Applicazione di nuovi ACE ereditabili a tutti gli oggetti figli (subkey, file) ACE specificati direttamente hanno la precedenza su ACE ereditati ACL sul file system Windows Explorer Privilegi Specifica quali azioni sul sistema può eseguire un processo (o un thread) Privilegi associati a utenti o gruppi Set di privilegi predefiniti associati a gruppi standard (System, Administrators, …) Esempio di privilegi: Backup/Restore Shutdown Debug Take ownership Privilegi disabilitati per default, vanno abilitati con una API Privilegi elevati Alcuni privilegi possono dare a un utente il controllo completo della macchina: Debug: può aprire qualsiasi processo, incluso System, per: Iniettare e/o modificare codice Leggere dati sensibili Take Ownership: può accedere a qualsiasi oggetto sul sistema Sostituzione file di sistema Cambiamenti alla security Restore: può sostituire qualsiasi file Load Driver I driver bypassano tutta la security Create Token Può creare utenti locali fittizi Richiede uso di API Windows non documentate Trusted Computer Base (Act as Part of Operating System) Può creare una nuova sessione di logon con un SID arbitrario nel token Privilege SeCreateTokenPrivilege SeAssignPrimaryTokenPrivilege SeLockMemoryPrivilege SeIncreaseQuotaPrivilege SeMachineAccountPrivilege SeTcbPrivilege SeSecurityPrivilege SeTakeOwnershipPrivilege SeLoadDriverPrivilege SeSystemProfilePrivilege SeSystemtimePrivilege SeProfileSingleProcessPrivilege SeIncreaseBasePriorityPrivilege SeCreatePagefilePrivilege SeCreatePermanentPrivilege SeBackupPrivilege SeRestorePrivilege SeShutdownPrivilege SeDebugPrivilege SeAuditPrivilege SeSystemEnvironmentPrivilege SeChangeNotifyPrivilege SeRemoteShutdownPrivilege SeUndockPrivilege SeSyncAgentPrivilege SeEnableDelegationPrivilege Local System X X X X Local Service Network Service X X X X X X X X X X X X X X X X X X X X X X X X X Auditing Impersonation Auditing Log accesso agli oggetti Necessario abilitare auditing Un amministratore può abilitarlo con Local Security Policy Editor (secpol.msc) Security log visualizzabile con Event Log Viewer SACL specifica log abilitati Struttura analoga a DACL elenco di ACE) Processa solo ACE corrispondenti all’accesso richiesto Owner SID Primary Group DACL pointer SACL pointer DACL SACL Perché l’auditing è importante Consente di tracciare le autorizzazioni (concesse e negate) di accesso a un oggetto Autorizzazione concessa: importante per avere log in sistemi ad alta sicurezza Autorizzazione negata: importante per individuare tentativi di accesso non autorizzate e per motivi di debug e/o troubleshooting Abilitazione dell'Auditing 1. Abilitare la categoria di auditing nelle policy 2. Abilitare l'auditing sugli oggetti (file, etc.) Auditing Local Security Policy Event Viewer Impersonation Consente a un’applicazione di adottare il profilo di security di un altro utente Usato da applicazioni lato server Impersonation implementata a livello di thread Il process token è il “primary token” che resta sempre accessibile Ogni thread può impersonare un client diverso Diverse API per impersonation (named pipes, RPC, DCOM) Client Process Server Process Server Threads Object Perché impersonation è importante Implementano la sicurezza di un sistema Le credenziali dell’utente sono quelle che definiscono il livello di accesso a una risorsa Può dare problemi di scalabilità Richieste brevi e provenienti da client sempre diversi possono dare un alto overhead di chiamata Va usata solo in server “trusted” Un processo con bassi privilegi potrebbe fare leva su un utente con privilegi più alti per accedere a informazioni riservate Per questo su Reporting Services è sconsigliabile impersonare l’utente nell’accesso verso il server dati Delegation (default disabilitata) Utenti che hanno il privilegio di impostare delegation (default = administrators) Delegation per localsystem Delegation per un utente Strutture security di processi e thread Security descriptor definiti per processi / thread / access token Come ogni oggetto kernel Thread 2 ha un token di impersonation Thread 1 ha il token di default del processo Security descriptor Security descriptor Access token Process Security descriptor Thread 1 Security descriptor Thread 2 Security descriptor Access token Access Token PView (da Platform SDK) Conclusioni In Windows la sicurezza nasce nel kernel Qualsiasi oggetto del kernel ne è soggetto Le applicazioni in modalità utente devono sempre essere autorizzate per qualsiasi operazione Solo i driver sono “full trusted” ACL pervasive in tutto il sistema Non solo nel file system Auditing controllabile su ogni accesso Utile anche per debug Privilegi assegnati agli utenti Attenzione ai privilegi elevati © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.