macOS Sandbox
Basic Information
O macOS Sandbox (inicialmente chamado de Seatbelt) limita as aplicações que estão rodando dentro do sandbox às ações permitidas especificadas no perfil do Sandbox com o qual o aplicativo está rodando. Isso ajuda a garantir que a aplicação acessará apenas os recursos esperados.
Qualquer aplicativo com a entitlement com.apple.security.app-sandbox
será executado dentro do sandbox. Binários da Apple geralmente são executados dentro de um Sandbox, e todos os aplicativos da App Store têm essa entitlement. Portanto, vários aplicativos serão executados dentro do sandbox.
Para controlar o que um processo pode ou não fazer, o Sandbox tem hooks em quase qualquer operação que um processo possa tentar (incluindo a maioria das syscalls) usando MACF. No entanto, dependendo das entitlements do aplicativo, o Sandbox pode ser mais permissivo com o processo.
Alguns componentes importantes do Sandbox são:
A extensão do kernel
/System/Library/Extensions/Sandbox.kext
O framework privado
/System/Library/PrivateFrameworks/AppSandbox.framework
Um daemon rodando em userland
/usr/libexec/sandboxd
Os containers
~/Library/Containers
Containers
Cada aplicação sandboxed terá seu próprio container em ~/Library/Containers/{CFBundleIdentifier}
:
Dentro de cada pasta de id de pacote, você pode encontrar o plist e o diretório de Dados do App com uma estrutura que imita a pasta Home:
Observe que, mesmo que os symlinks estejam lá para "escapar" do Sandbox e acessar outras pastas, o App ainda precisa ter permissões para acessá-las. Essas permissões estão dentro do .plist
em RedirectablePaths
.
Os SandboxProfileData
são os dados do perfil de sandbox compilados CFData escapados para B64.
Tudo criado/modificado por um aplicativo em Sandbox receberá o atributo de quarentena. Isso impedirá um espaço de sandbox ao acionar o Gatekeeper se o aplicativo em sandbox tentar executar algo com open
.
Perfis de Sandbox
Os perfis de Sandbox são arquivos de configuração que indicam o que será permitido/proibido nesse Sandbox. Ele usa a Linguagem de Perfil de Sandbox (SBPL), que utiliza a linguagem de programação Scheme.
Aqui você pode encontrar um exemplo:
Verifique esta pesquisa para verificar mais ações que podem ser permitidas ou negadas.
Note que na versão compilada de um perfil, o nome das operações é substituído por suas entradas em um array conhecido pelo dylib e pelo kext, tornando a versão compilada mais curta e mais difícil de ler.
Importantes serviços do sistema também são executados dentro de seu próprio sandbox personalizado, como o serviço mdnsresponder
. Você pode visualizar esses perfis de sandbox personalizados em:
/usr/share/sandbox
/System/Library/Sandbox/Profiles
Outros perfis de sandbox podem ser verificados em https://github.com/s7ephen/OSX-Sandbox--Seatbelt--Profiles.
Aplicativos da App Store usam o perfil /System/Library/Sandbox/Profiles/application.sb
. Você pode verificar neste perfil como direitos como com.apple.security.network.server
permitem que um processo use a rede.
SIP é um perfil de Sandbox chamado platform_profile em /System/Library/Sandbox/rootless.conf
Exemplos de Perfil de Sandbox
Para iniciar um aplicativo com um perfil de sandbox específico, você pode usar:
Observe que o software autorizado pela Apple que roda em Windows não possui precauções de segurança adicionais, como o sandboxing de aplicativos.
Exemplos de bypass:
https://desi-jarvis.medium.com/office365-macos-sandbox-escape-fcce4fa4123c (eles conseguem escrever arquivos fora do sandbox cujo nome começa com
~$
).
Rastreamento de Sandbox
Via perfil
É possível rastrear todas as verificações que o sandbox realiza toda vez que uma ação é verificada. Para isso, basta criar o seguinte perfil:
E então, basta executar algo usando esse perfil:
Em /tmp/trace.out
você poderá ver cada verificação de sandbox realizada toda vez que foi chamada (ou seja, muitos duplicados).
Também é possível rastrear o sandbox usando o -t
parâmetro: sandbox-exec -t /path/trace.out -p "(version 1)" /bin/ls
Via API
A função sandbox_set_trace_path
exportada por libsystem_sandbox.dylib
permite especificar um nome de arquivo de rastreamento onde as verificações de sandbox serão escritas.
Também é possível fazer algo semelhante chamando sandbox_vtrace_enable()
e, em seguida, obtendo os logs de erro do buffer chamando sandbox_vtrace_report()
.
Inspeção de Sandbox
libsandbox.dylib
exporta uma função chamada sandbox_inspect_pid que fornece uma lista do estado do sandbox de um processo (incluindo extensões). No entanto, apenas binários da plataforma podem usar essa função.
Perfis de Sandbox do MacOS e iOS
O MacOS armazena perfis de sandbox do sistema em dois locais: /usr/share/sandbox/ e /System/Library/Sandbox/Profiles.
E se um aplicativo de terceiros tiver a com.apple.security.app-sandbox concessão, o sistema aplica o perfil /System/Library/Sandbox/Profiles/application.sb a esse processo.
No iOS, o perfil padrão é chamado container e não temos a representação de texto SBPL. Na memória, esse sandbox é representado como uma árvore binária de Permitir/Negar para cada permissão do sandbox.
SBPL Personalizado em aplicativos da App Store
Pode ser possível para empresas fazerem seus aplicativos rodarem com perfis de Sandbox personalizados (em vez de com o padrão). Elas precisam usar a concessão com.apple.security.temporary-exception.sbpl
que precisa ser autorizada pela Apple.
É possível verificar a definição dessa concessão em /System/Library/Sandbox/Profiles/application.sb:
Isso irá avaliar a string após esta concessão como um perfil de Sandbox.
Compilando e descompilando um Perfil de Sandbox
A ferramenta sandbox-exec
utiliza as funções sandbox_compile_*
da libsandbox.dylib
. As principais funções exportadas são: sandbox_compile_file
(espera um caminho de arquivo, parâmetro -f
), sandbox_compile_string
(espera uma string, parâmetro -p
), sandbox_compile_name
(espera um nome de um contêiner, parâmetro -n
), sandbox_compile_entitlements
(espera um plist de concessões).
Esta versão revertida e open source da ferramenta sandbox-exec permite que sandbox-exec
escreva em um arquivo o perfil de sandbox compilado.
Além disso, para confinar um processo dentro de um contêiner, pode chamar sandbox_spawnattrs_set[container/profilename]
e passar um contêiner ou perfil pré-existente.
Depurar e Bypass Sandbox
No macOS, ao contrário do iOS, onde os processos são isolados desde o início pelo kernel, os processos devem optar por entrar no sandbox. Isso significa que no macOS, um processo não é restrito pelo sandbox até que decida ativamente entrar nele, embora os aplicativos da App Store estejam sempre isolados.
Os processos são automaticamente isolados do userland quando começam, se tiverem a concessão: com.apple.security.app-sandbox
. Para uma explicação detalhada desse processo, consulte:
Extensões de Sandbox
As extensões permitem conceder privilégios adicionais a um objeto e são concedidas chamando uma das funções:
sandbox_issue_extension
sandbox_extension_issue_file[_with_new_type]
sandbox_extension_issue_mach
sandbox_extension_issue_iokit_user_client_class
sandbox_extension_issue_iokit_registry_rentry_class
sandbox_extension_issue_generic
sandbox_extension_issue_posix_ipc
As extensões são armazenadas no segundo slot de rótulo MACF acessível a partir das credenciais do processo. A seguinte sbtool
pode acessar essas informações.
Observe que as extensões geralmente são concedidas por processos permitidos, por exemplo, tccd
concederá o token de extensão de com.apple.tcc.kTCCServicePhotos
quando um processo tentar acessar as fotos e for permitido em uma mensagem XPC. Então, o processo precisará consumir o token de extensão para que ele seja adicionado a ele.
Observe que os tokens de extensão são longos hexadecimais que codificam as permissões concedidas. No entanto, eles não têm o PID permitido codificado, o que significa que qualquer processo com acesso ao token pode ser consumido por múltiplos processos.
Observe que as extensões estão muito relacionadas às concessões também, então ter certas concessões pode automaticamente conceder certas extensões.
Verificar Privilégios de PID
De acordo com isso, as funções sandbox_check
(é um __mac_syscall
), podem verificar se uma operação é permitida ou não pelo sandbox em um certo PID, token de auditoria ou ID único.
A ferramenta sbtool (encontre-a compilada aqui) pode verificar se um PID pode realizar certas ações:
[un]suspend
Também é possível suspender e retomar a sandbox usando as funções sandbox_suspend
e sandbox_unsuspend
da libsystem_sandbox.dylib
.
Note que, para chamar a função de suspensão, algumas permissões são verificadas para autorizar o chamador a chamá-la, como:
com.apple.private.security.sandbox-manager
com.apple.security.print
com.apple.security.temporary-exception.audio-unit-host
mac_syscall
Essa chamada de sistema (#381) espera um primeiro argumento do tipo string que indicará o módulo a ser executado, e então um código no segundo argumento que indicará a função a ser executada. O terceiro argumento dependerá da função executada.
A chamada da função ___sandbox_ms
envolve mac_syscall
, indicando no primeiro argumento "Sandbox"
, assim como ___sandbox_msp
é um wrapper de mac_set_proc
(#387). Então, alguns dos códigos suportados por ___sandbox_ms
podem ser encontrados nesta tabela:
set_profile (#0): Aplica um perfil compilado ou nomeado a um processo.
platform_policy (#1): Impõe verificações de política específicas da plataforma (varia entre macOS e iOS).
check_sandbox (#2): Realiza uma verificação manual de uma operação específica da sandbox.
note (#3): Adiciona uma anotação a uma Sandbox.
container (#4): Anexa uma anotação a uma sandbox, tipicamente para depuração ou identificação.
extension_issue (#5): Gera uma nova extensão para um processo.
extension_consume (#6): Consome uma extensão dada.
extension_release (#7): Libera a memória vinculada a uma extensão consumida.
extension_update_file (#8): Modifica parâmetros de uma extensão de arquivo existente dentro da sandbox.
extension_twiddle (#9): Ajusta ou modifica uma extensão de arquivo existente (por exemplo, TextEdit, rtf, rtfd).
suspend (#10): Suspende temporariamente todas as verificações da sandbox (requer permissões apropriadas).
unsuspend (#11): Retoma todas as verificações da sandbox que foram suspensas anteriormente.
passthrough_access (#12): Permite acesso direto a um recurso, ignorando as verificações da sandbox.
set_container_path (#13): (apenas iOS) Define um caminho de contêiner para um grupo de aplicativos ou ID de assinatura.
container_map (#14): (apenas iOS) Recupera um caminho de contêiner do
containermanagerd
.sandbox_user_state_item_buffer_send (#15): (iOS 10+) Define metadados de modo usuário na sandbox.
inspect (#16): Fornece informações de depuração sobre um processo em sandbox.
dump (#18): (macOS 11) Despeja o perfil atual de uma sandbox para análise.
vtrace (#19): Rastreia operações da sandbox para monitoramento ou depuração.
builtin_profile_deactivate (#20): (macOS < 11) Desativa perfis nomeados (por exemplo,
pe_i_can_has_debugger
).check_bulk (#21): Realiza múltiplas operações
sandbox_check
em uma única chamada.reference_retain_by_audit_token (#28): Cria uma referência para um token de auditoria para uso em verificações de sandbox.
reference_release (#29): Libera uma referência de token de auditoria previamente retida.
rootless_allows_task_for_pid (#30): Verifica se
task_for_pid
é permitido (semelhante às verificaçõescsr
).rootless_whitelist_push (#31): (macOS) Aplica um arquivo de manifesto de Proteção de Integridade do Sistema (SIP).
rootless_whitelist_check (preflight) (#32): Verifica o arquivo de manifesto SIP antes da execução.
rootless_protected_volume (#33): (macOS) Aplica proteções SIP a um disco ou partição.
rootless_mkdir_protected (#34): Aplica proteção SIP/DataVault a um processo de criação de diretório.
Sandbox.kext
Note que, no iOS, a extensão do kernel contém todos os perfis codificados dentro do segmento __TEXT.__const
para evitar que sejam modificados. As seguintes são algumas funções interessantes da extensão do kernel:
hook_policy_init
: Ele conectampo_policy_init
e é chamado apósmac_policy_register
. Realiza a maioria das inicializações da Sandbox. Também inicializa o SIP.hook_policy_initbsd
: Configura a interface sysctl registrandosecurity.mac.sandbox.sentinel
,security.mac.sandbox.audio_active
esecurity.mac.sandbox.debug_mode
(se inicializado comPE_i_can_has_debugger
).hook_policy_syscall
: É chamado pormac_syscall
com "Sandbox" como primeiro argumento e um código indicando a operação no segundo. Um switch é usado para encontrar o código a ser executado de acordo com o código solicitado.
MACF Hooks
Sandbox.kext
usa mais de uma centena de hooks via MACF. A maioria dos hooks apenas verifica alguns casos triviais que permitem realizar a ação; caso contrário, chamarão cred_sb_evalutate
com as credenciais do MACF e um número correspondente à operação a ser realizada e um buffer para a saída.
Um bom exemplo disso é a função _mpo_file_check_mmap
que conecta mmap
e que começará a verificar se a nova memória será gravável (e se não, permitirá a execução), então verificará se está sendo usada para o cache compartilhado do dyld e, se sim, permitirá a execução, e finalmente chamará sb_evaluate_internal
(ou um de seus wrappers) para realizar verificações adicionais de permissão.
Além disso, dentre os centenas de hooks que a Sandbox usa, há 3 em particular que são muito interessantes:
mpo_proc_check_for
: Aplica o perfil se necessário e se não foi aplicado anteriormente.mpo_vnode_check_exec
: Chamado quando um processo carrega o binário associado, então uma verificação de perfil é realizada e também uma verificação que proíbe execuções SUID/SGID.mpo_cred_label_update_execve
: Isso é chamado quando o rótulo é atribuído. Este é o mais longo, pois é chamado quando o binário está totalmente carregado, mas ainda não foi executado. Ele realizará ações como criar o objeto sandbox, anexar a estrutura da sandbox às credenciais kauth, remover o acesso a portas mach...
Note que _cred_sb_evalutate
é um wrapper sobre sb_evaluate_internal
e essa função obtém as credenciais passadas e então realiza a avaliação usando a função eval
que geralmente avalia o perfil da plataforma que é, por padrão, aplicado a todos os processos e então o perfil de processo específico. Note que o perfil da plataforma é um dos principais componentes do SIP no macOS.
Sandboxd
A Sandbox também possui um daemon de usuário em execução expondo o serviço XPC Mach com.apple.sandboxd
e vinculando a porta especial 14 (HOST_SEATBELT_PORT
) que a extensão do kernel usa para se comunicar com ele. Ele expõe algumas funções usando MIG.
References
Last updated