O design do Sandbox2 se baseia em tecnologias conhecidas e estabelecidas, uma estrutura de políticas e dois processos: o executor e o sandboxee.
Tecnologias envolvidas
As seções a seguir abordam as tecnologias que criam a camada de base para o Sandbox2.
Namespaces do Linux
Os namespaces do Linux são uma tentativa de fornecer virtualização no nível do sistema operacional. Embora vários espaços de usuário sejam executados aparentemente de forma independente uns dos outros, eles compartilham uma única instância de kernel. O Sandbox2 usa os seguintes tipos de namespaces:
- IPC
- Rede (a menos que seja explicitamente desativada chamando
PolicyBuilder::AllowUnrestrictedNetworking()
) - Montar (usando uma visualização personalizada da árvore do sistema de arquivos)
- PID
- Usuário
- UTS
Leia mais sobre namespaces do Linux na Wikipedia ou na página de manual relacionada.
IPC
O Sandbox2 permite a troca de dados arbitrários entre o executor do sandbox e o sandboxee não confiável. Ele é compatível com mensagens do tipo comprimento-valor (TLV, na sigla em inglês), transmissão de descritores de arquivo e troca de credenciais por tokens e identificadores.
Seccomp-BPF
O Sandbox2 depende do seccomp-bpf, que é uma extensão do modo de computação segura (seccomp) que permite usar regras do filtro de pacote Berkeley (BPF) para filtrar syscalls.
O seccomp é um recurso do kernel do Linux que restringe as chamadas de sistema de um processo para permitir apenas exit
, sigreturn
, read
e write
. Se um processo tentar
executar outra syscall, ele será encerrado. A extensão seccomp-bpf permite
mais flexibilidade do que o seccomp. Em vez de permitir um conjunto fixo de syscalls, o seccomp-bpf executa um programa BPF nos dados de syscall e, dependendo do valor de retorno do programa, pode executar a syscall, pular a syscall e retornar um valor fictício, encerrar o processo, gerar um sinal ou notificar o rastreador.
Ptrace
A syscall ptrace (rastreamento de processo) oferece funcionalidade que permite ao processo tracer observar e controlar a execução do processo tracee. O processo de rastreamento tem controle total sobre o rastreado depois de anexado. Leia mais sobre ptrace na Wikipedia ou na página de manual relacionada.
Política de sandbox
A política de sandbox é a parte mais importante de um sandbox, porque especifica as ações que o Sandboxee pode e não pode executar. Uma política de sandbox tem duas partes:
- Política de syscall
- Configuração de namespace
Política de syscall padrão
A política padrão bloqueia syscalls que são sempre perigosas e tem precedência sobre a política estendida fornecida pelo usuário.
Política de syscall estendida
A política de syscall estendida pode ser criada usando nossa classe
PolicyBuilder. Essa classe define várias regras de conveniência (por exemplo,
AllowStaticStartup
, AllowDynamicStartup
, AllowOpen
) que podem ser usadas para
melhorar a legibilidade da sua política.
Se você quiser restringir ainda mais as chamadas de sistema ou exigir regras mais complexas, especifique macros BPF brutas com AddPolicyOnSyscall
e AddPolicyOnSyscalls
. O exemplo de crc4 usa esse mecanismo para restringir argumentos para as chamadas de sistema read
, write
e close
.
Em geral, quanto mais restrita for a política de sandbox, melhor, porque a exploração de qualquer vulnerabilidade presente no código será limitada pela política. Se você conseguir especificar exatamente quais syscalls e argumentos são necessários para a operação normal do programa, qualquer invasor que explorar uma vulnerabilidade de execução de código também será restrito aos mesmos limites.
Uma política de sandbox muito restrita pode negar todas as chamadas de sistema, exceto leituras e gravações em descritores de arquivo de entrada e saída padrão. Nesse ambiente, um programa pode receber entradas, processá-las e retornar a saída. No entanto, se o processo tentasse fazer qualquer outra syscall, ele seria encerrado devido a uma violação da política. Portanto, se o processo for comprometido (execução de código por um usuário malicioso), ele não poderá fazer nada mais nefasto do que produzir uma saída ruim (que o executor e outros ainda precisam processar corretamente).
Configuração do namespace
O objeto PolicyBuilder também é usado para configurar uma visualização individual do Sandboxee do
sistema de arquivos. Arquivos únicos (AddFile
/ AddFileAt
), diretórios inteiros (AddDirectory
/ AddDirectoryAt
) e armazenamento temporário (AddTmpfs
) podem ser mapeados para o ambiente do Sandboxee. Além disso, AddLibrariesForBinary
pode ser usado para mapear automaticamente todas as bibliotecas necessárias pelo executável vinculado dinamicamente especificado.
Sinalizações de linha de comando
Qualquer política do Sandbox2 pode ser desativada especificando uma das seguintes flags de linha de comando. Essas flags são destinadas a testes, por exemplo, ao refinar a política de syscalls estendida.
--sandbox2_danger_danger_permit_all
--sandbox2_danger_danger_permit_all_and_log
Executor do sandbox
O Sandbox Executor é um processo que não está em sandbox. É o processo de rastreamento ptrace que se conecta ao Sandboxee (processo tracee ptrace). O Sandbox Executor também configura e executa uma instância do Monitor que rastreia o Sandboxee e fornece informações de status.
O Sandbox2 permite três modos de execução: independente, Sandbox2 Forkserver e Custom Forkserver. Se você usar um forkserver, o Sandboxee será criado como um processo filho do executor do sandbox. Esses modos são explicados em detalhes aqui.
Sandboxee
O Sandboxee é o processo executado no ambiente restrito e em sandbox definido pela política de sandbox. O executor do sandbox envia a política para o sandboxee via IPC. Em seguida, o Sandboxee aplica a política. Qualquer violação da política vai resultar na rescisão do processo, a menos que seja configurado de outra forma (consulte a Política de sandbox).