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.
Scarica

Windows: la sicurezza inizia nel kernel