La progettazione di Sandbox2 si basa su tecnologie consolidate e ben note, un framework di policy e due processi: Sandbox Executor e Sandboxee.
Tecnologie coinvolte
Le sezioni seguenti riguardano le tecnologie che costituiscono il livello di base per Sandbox2.
Spazi dei nomi Linux
Gli spazi dei nomi Linux sono un tentativo di fornire la virtualizzazione a livello di sistema operativo. Sebbene più spazi utente vengano eseguiti in modo apparentemente indipendente l'uno dall'altro, condividono una singola istanza del kernel. Sandbox2 utilizza i seguenti tipi di spazi dei nomi:
- IPC
- Rete (a meno che non sia disabilitata esplicitamente chiamando
PolicyBuilder::AllowUnrestrictedNetworking()) - Montaggio (utilizzando una visualizzazione personalizzata dell'albero del file system)
- PID
- Utente
- UTS
Scopri di più sugli spazi dei nomi Linux su Wikipedia o nella pagina del manuale correlata.
IPC
Sandbox2 consente lo scambio di dati arbitrari tra Sandbox Executor e Sandboxee non attendibile. Supporta i messaggi di tipo lunghezza-valore (TLV), il passaggio dei descrittori di file e lo scambio di credenziali tramite token e handle.
Seccomp-BPF
Sandbox2 relies on seccomp-bpf, un'estensione della modalità di calcolo sicura (seccomp) che consente di utilizzare le regole del filtro di pacchetti Berkeley (BPF) per filtrare le chiamate di sistema.
seccomp è una funzionalità del kernel Linux che limita le chiamate di sistema di un processo per consentire solo exit, sigreturn, read e write. Se un processo tenta di eseguire un'altra chiamata di sistema, viene terminato. L'estensione seccomp-bpf offre maggiore flessibilità rispetto a seccomp. Anziché consentire un insieme fisso di chiamate di sistema, seccomp-bpf esegue un programma BPF sui dati della chiamata di sistema e, a seconda del valore restituito del programma, può eseguire la chiamata di sistema, saltarla e restituire un valore fittizio, terminare il processo, generare un segnale o notificare il tracer.
Ptrace
La chiamata di sistema ptrace (traccia del processo) fornisce funzionalità che consentono al processo tracer di osservare e controllare l'esecuzione del processo tracee. Una volta collegato, il processo tracer ha il controllo completo del processo tracee. Scopri di più su ptrace su Wikipedia o nella pagina del manuale correlata.
Policy sandbox
La Sandbox Policy è la parte più importante di una sandbox, in quanto specifica le azioni che Sandboxee può e non può eseguire. Una policy sandbox è composta da due parti:
- Policy di chiamata di sistema
- Configurazione dello spazio dei nomi
Policy di chiamata di sistema predefinita
La policy predefinita blocca le chiamate di sistema che sono sempre pericolose e ha la precedenza sulla policy estesa fornita dall'utente.
Policy di chiamata di sistema estesa
La policy di chiamata di sistema estesa può essere creata utilizzando la
PolicyBuilder. Questa classe definisce una serie di regole pratiche (ad es. AllowStaticStartup, AllowDynamicStartup, AllowOpen) che possono essere utilizzate per migliorare la leggibilità della policy.
Nella maggior parte dei casi, è preferibile iniziare con
DefaultPolicyBuilder
(sapi::Sandbox2Config::DefaultPolicyBuilder()), che restituisce un oggetto
PolicyBuilder preconfigurato con una policy di base per le librerie tipiche
a thread singolo e può essere ulteriormente personalizzato con regole aggiuntive
(ad es. .AllowDynamicStartup() e .AddLibrariesForBinary() durante la sandbox
di un file binario). In Sandboxed API (SAPI), DefaultPolicyBuilder() viene utilizzato da sapi::SandboxConfig::DefaultConfig() insieme a sapi::SandboxConfig::DefaultFlags(), sapi::SandboxConfig::DefaultEnvironmentVariables() e sapi::Sandbox2Config::DefaultLimits(). La creazione diretta di un oggetto PolicyBuilder deve essere utilizzata solo quando DefaultPolicyBuilder() non è possibile utilizzare o quando è necessaria una configurazione precisa.
Se vuoi limitare ulteriormente le chiamate di sistema o richiedere regole più complesse, puoi
specificare le macro BPF non elaborate con AddPolicyOnSyscall e AddPolicyOnSyscalls. L'
esempio crc4 utilizza questo
meccanismo per limitare gli argomenti per le chiamate di sistema read, write, e close.
In generale, più restrittiva è la policy sandbox, meglio è, perché lo sfruttamento di qualsiasi vulnerabilità presente nel codice sarà limitato dalla policy. Se riesci a specificare esattamente quali chiamate di sistema e argomenti sono necessari per il normale funzionamento del programma, qualsiasi utente malintenzionato che sfrutti una vulnerabilità di esecuzione di codice è limitato anche agli stessi limiti.
Una policy sandbox molto restrittiva potrebbe negare tutte le chiamate di sistema, ad eccezione delle letture e delle scritture sui descrittori del file di input e output standard. All'interno di questa sandbox, un programma potrebbe accettare input, elaborarlo e restituire l'output. Tuttavia, se il processo tentasse di effettuare qualsiasi altra chiamata di sistema, verrebbe terminato a causa di una violazione della policy. Pertanto, se il processo viene compromesso (esecuzione del codice da parte di un utente malintenzionato), non può fare nulla di più nefasto della produzione di output errato (che l'executor e altri devono comunque gestire correttamente).
Configurazione dello spazio dei nomi
L'oggetto PolicyBuilder viene utilizzato anche per configurare la visualizzazione individuale del file system di Sandboxee. I singoli file (AddFile / AddFileAt), le directory intere
(AddDirectory / AddDirectoryAt) e l'archiviazione temporanea (AddTmpfs)
possono essere mappati nell'ambiente di Sandboxee. Inoltre, AddLibrariesForBinary può essere utilizzato per mappare automaticamente tutte le librerie necessarie per l'eseguibile collegato dinamicamente specificato.
Flag della riga di comando
Qualsiasi policy Sandbox2 può essere disabilitata specificando uno dei seguenti flag della riga di comando. Questi flag sono destinati a scopi di test (ad es. durante la perfezionamento della policy di chiamata di sistema estesa).
--sandbox2_danger_danger_permit_all--sandbox2_danger_danger_permit_all_and_log
Sandbox Executor
Il Sandbox Executor è un processo che non è in sandbox. È il processo tracer ptrace che si collega a Sandboxee (processo tracee ptrace). Sandbox Executor configura ed esegue anche un' istanza Monitor che monitora Sandboxee e fornisce informazioni sullo stato.
Sandbox2 consente tre modalità di esecuzione: Stand-alone, Sandbox2 Forkserver e Custom Forkserver. Se utilizzi un forkserver, Sandboxee viene creato come processo figlio di Sandbox Executor. Queste modalità sono spiegate in dettaglio qui.
Sandboxee
Sandboxee è il processo che viene eseguito nell'ambiente con sandbox limitato definito dalla policy sandbox. Sandbox Executor invia la policy a Sandboxee tramite IPC. Sandboxee applica quindi la policy. Qualsiasi violazione della policy comporterà la terminazione del processo, a meno che non sia configurato diversamente (vedi Policy sandbox).