Divulgação pública do código da Apple que assina vulnerabilidade de terceiros
Ao contrário de alguns trabalhos anteriores, essa vulnerabilidade não requer direitos de administrador, não requer um código JIT ou corrupção de memória para ignorar a verificação de assinatura de código. Tudo o que você precisa é de um arquivo Fat / Universal corretamente formatado, e a verificação da assinatura do código mostrará um resultado válido.
Sumário
- Foi encontrado um desvio usado pela API de terceiros para assinar o código, permitindo que você apresente qualquer código assinado pela Apple.
- Todos os conhecidos fornecedores e projetos de código aberto são notificados (veja a lista abaixo). Patches estão disponíveis para eles.
- É possível que o problema afete outros programas de terceiros que usam as APIs oficiais de assinatura de código da Apple.
- Os desenvolvedores são responsáveis pelo uso adequado da API de assinatura de código. Existem ferramentas de hackers de demonstração (PoC) para testes.
- Aplica-se apenas ao macOS e versões mais antigas do OSX.
Fornecedores afetados
- VirusTotal - CVE-2018-10408
- Google - Papai Noel, molcodesignchecker - CVE-2018-10405
- Facebook - OSQuery - CVE-2018-6336
- Desenvolvimento de objetivos - LittleSnitch - CVE-2018-10470
- F-Secure - xFence (também LittleFlocker) CVE-2018-10403
- Visão objetiva - WhatsYourSign, ProcInfo, KnockKnock, LuLu, TaskExplorer (e outros) - CVE-2018-10404
- Yelp - OSXCollector - CVE-2018-10406
- Preto de carbono - Resposta Cb - CVE-2018-10407
A importância da assinatura de código e como ela funciona no macOS / iOS
A assinatura de código é uma construção de segurança que usa uma infra-estrutura de chave pública (PKI) para assinar digitalmente código compilado ou mesmo scripts para garantir que seja confiável e que o código seja autêntico. No Windows, você pode assinar criptograficamente quase tudo: de binários .NET a scripts do PowerShell. No macOS / iOS, a assinatura de código refere-se principalmente aos binários e pacotes de aplicativos Mach-O, para permitir que apenas códigos confiáveis sejam executados na memória.
Antivírus, sistemas de segurança e resposta a incidentes, além de ferramentas forenses analisam assinaturas para identificar códigos confiáveis entre os não confiáveis. A verificação de assinatura acelera a análise. Várias ferramentas usam informações de assinatura de código para implementar medidas de segurança: são listas de permissões, antivírus, resposta a incidentes e sistemas de busca de ameaças. Comprometer a assinatura do código em um dos SOs populares significa minar a construção básica da segurança, da qual dependem muitas operações rotineiras de segurança da informação.
Já foram encontrados problemas na assinatura do código (
1 ,
2 ,
3 ,
4 ,
5 ). Ao contrário de alguns trabalhos anteriores, essa vulnerabilidade não requer direitos de administrador, não requer um código JIT ou corrupção de memória para ignorar a verificação de assinatura de código. Tudo o que você precisa é de um arquivo Fat / Universal corretamente formatado, e a verificação da assinatura do código mostrará um resultado válido.
Detalhes da vulnerabilidade
A essência da vulnerabilidade é que o carregador Mach-O e a API de assinatura de código não são usados para verificar assinaturas de código incorretamente. Essa diferença pode ser explorada usando um binário Universal / Fat especialmente criado.
O que é um arquivo Fat / Universal?Fat / Universal é um formato binário que contém vários arquivos Mach-O (arquivo executável, dyld ou pacote), cada qual focado em uma arquitetura específica da CPU (por exemplo, i386, x86_64 ou PPC).
Pré-requisitos
- O primeiro Mach-O no arquivo Fat / Universal deve ser assinado pela Apple, pode ser um arquivo i386, x86_64 ou até um PPC.
- Um código binário ou estranho malicioso autoassinado deve ser compilado no i386 para o macOS x86_64.
- O CPU_TYPE no cabeçalho Fat do binário da Apple deve ser definido como um tipo de processador inválido ou que não seja nativo do chipset host.
Sem passar os
SecRequirementRef e
SecCSFlags relevantes, a interface do programa API de assinatura de código (
SecCodeCheckValidity ) verificará o primeiro binário no arquivo Fat / Universal quanto à origem da assinatura (por exemplo, Apple) e verifique se a assinatura é autêntica. Em seguida, a API verificará todos os outros binários no arquivo Fat / Universal quanto à conformidade dos identificadores de equipe e autenticidade da assinatura, mas
sem verificar a raiz da confiança da autoridade de certificação . A razão pela qual o código malicioso ou o código "não assinado" deve ser i386 é porque a API de assinatura de código está configurada por padrão para verificar a assinatura de código da arquitetura de CPU nativa (x86_64).
Uma das razões pelas quais o código autoassinado passa no teste com êxito é porque, mesmo nos principais binários da Apple, o campo TeamIdentifier está definido como
not set
. A ilustração abaixo mostra o binário Mach-O válido, assinado pela Apple (python.x64), próximo ao Mach-O autoassinado (ncat.i386). Ambos têm `TeamIdentifier = not set`.

Por exemplo, assinei o binário usando o ID do desenvolvedor e tentei no lipo combiná-lo com o binário da Apple em um arquivo Fat / Universal. Este tipo de assinatura de código falha.

Meu PoC inicial é ncat (do nmap), que chamei de ncat.frankenstein. Aqui, o arquivo Fat resultante contém o binário python x86_64 assinado pela Apple e o binário ncat i386 autoassinado (adhoc). Um binário autoassinado é facilmente criado com
codesign -s - target_mach-o_or_fat_binary
. Aqui está o que parece no MachOView:

Se você executar este arquivo, o python x86_64 será iniciado:

E a assinatura do código está sendo verificada:

Como eu executei o binário autoassinado ncat?
Isso é feito configurando um tipo CPU_Type inválido ou uma CPU não nativa (por exemplo, PPC). Em seguida, o carregador do Mach-O ignora o binário do Mach-O com uma assinatura válida e executa o código malicioso (não assinado pela Apple):

Em seguida, o ncat.frankenstein é executado e o resultado da validação será
valid
:
Publicamos o ncat.frankenstein e quatro outros exemplos para que os desenvolvedores possam verificar vulnerabilidades em seus produtos.
Recomendações
Na linha de comandoDepende de como você verifica o código assinado. Se você usa o codesign, provavelmente conhece os seguintes comandos:
codesign –dvvvv
- despejo da autoridade de certificação e TeamIdentifier (ID do desenvolvedor)codesign –vv
- verificação rigorosa de todas as arquiteturas
Mas, para verificar corretamente esse tipo de abuso, você precisa adicionar o requisito de certificado âncora com os seguintes
comandos :
codesign -vv -R='anchor apple' ./some_application_or_mach-o
# para código assinado pela Applecodesign -vv -R='anchor apple generic' ./some_application_or_mach-o
# para código assinado pela Apple e Apple
Esse comando mostrará um erro ao verificar o código com a assinatura de outra pessoa:

Você pode usar o comando
spctl
, mas requer uma análise cuidadosa da saída do comando. Por exemplo, o binário Mach-O com a assinatura da Apple (/ bin / ls) e o Safari retorna o seguinte:

E aqui está o resultado de um aplicativo assinado pela Apple:

Observe a linha "(o código é válido, mas não parece ser um aplicativo)" para / bin / ls, que não passa no teste. Para comparação, eis o resultado do arquivo Fat / Universal ncat.frankenstein:

O arquivo ncat.frankenstein Fat / Universal não mostra que o código é válido. Portanto, não posso recomendar o
spctl
para verificar manualmente os binários Mach-O offline. Basta usar o código de sinalização com os sinalizadores apropriados.
Para desenvolvedoresNormalmente, os desenvolvedores verificam os binários Mach-O ou Fat / Universal usando as
APIs SecStaticCodeCheckValidityWithErrors () ou
SecStaticCodeCheckValidity () com os seguintes sinalizadores:
Esses sinalizadores devem garantir que todo o código carregado na memória no arquivo Mach-O ou Fat / Universal seja assinado criptograficamente. No entanto, essas APIs não fornecem validação adequada por padrão; portanto, desenvolvedores de terceiros precisam isolar cada arquitetura no arquivo Fat / Universal e verificar se as identidades correspondem e são criptograficamente robustas.
A melhor maneira de testar cada arquitetura aninhada no arquivo Fat / Universal é chamar
SecRequirementCreateWithString primeiro com o requisito "apple âncora", depois
SecStaticCodeCheckValidity com o
kSecCSDefaultFlags | kSecCSCheckNestedCode | kSecCSCheckAllArchitectures | kSecCSEnforceRevocationChecks com referência ao requisito; conforme mostrado no código-fonte corrigido do
WhatsYourSign .
Passando a “maçã âncora” para a função SecRequirmentCreateWithString, essa chamada funciona de maneira semelhante ao comando
codesign -vv -R='anchor apple'
, exigindo a presença da cadeia de confiança Apple Software Signing para todos os binários aninhados no arquivo Fat / Universal. Além disso, passando sinalizadores e o requisito para SecStaticCodeCheckValidity, todas as arquiteturas são verificadas quanto a esse requisito e verificações de revogação são aplicadas.
Manifestações
Ferramenta de
codesign
de
codesign
da Apple e a necessidade de usar o sinalizador
-R
.

LittleSnitch - a verificação do arquivo Fat / Universal no disco não funciona, mas o LittleSnitch verifica corretamente o processo na memória.


LittleFlocker - a F-Secure comprou o LittleFlocker e agora se chama xFence.

F-Secure xFence (anteriormente LittleFlocker)

Ferramentas de visão de objetivo
Taskexplorer


WhatsYourSign

O Facebook OSquery é o resultado de amostras de malware e / bin / ls como um exemplo válido.

Emissão do Google Santa - Fileinfo mostra que ncat.frankenstein está na lista de permissões:

Negar a execução ncat (não assinada) e a permissão de execução ncat.frankenstein:

Log Santa.log mostrando eventos do exemplo anterior:

Resposta ao negro de fumo

VirusTotal - exemplo de bash_ppc_adhoc antes de instalar o patch no VirusTotal:

Datas de divulgação
22/02/2018: Um relatório e um PoC foram enviados à Apple para contornar os sistemas de segurança de terceiros.
01/01/2018: A Apple respondeu que os desenvolvedores de terceiros devem usar kSecCSCheckAllArchitectures e kSecCSStrictValidate com a API SecStaticCodeCheckValidity, e a documentação do desenvolvedor será atualizada de acordo.
06/06/2018: um relatório e um PoC foram enviados à Apple para contornar as bandeiras e verificar rigorosamente o
codesign
.
16/03/2018: informações adicionais enviadas à Apple.
20/03/2018: A Apple disse que não via isso como um problema de segurança que deveria ser resolvido diretamente.
29/03/2018: A Apple afirmou que a documentação pode ser atualizada, mas "[...] desenvolvedores de terceiros devem fazer um trabalho adicional para verificar se todas as identidades no binário universal são iguais se quiserem apresentar um resultado significativo".
02/04/2018: primeiro contato com o CERT / CC e subsequente colaboração para esclarecer o escopo e o impacto da vulnerabilidade.
09/09/2018: todos os desenvolvedores de terceiros conhecidos afetados pela vulnerabilidade são notificados em coordenação com o CERT / CC.
18/04/2018: último contato com o CERT / CC com uma recomendação de que divulgar publicamente informações em um blog é melhor para notificar outros desenvolvedores de terceiros que usam a API de assinatura de código da Apple em particular.
05/05/2018: contato final com os desenvolvedores antes da publicação.
12/06/2018: divulgação de informações.
Em conclusão
Agradecemos a todos os desenvolvedores terceirizados por seu trabalho duro e profissionalismo na solução desse problema. As vulnerabilidades de assinatura de código são bugs especialmente desmoralizantes, especialmente para empresas que estão tentando fornecer segurança melhor que a padrão no sistema operacional.
AÇÃO GMO GlobalSign Rússia para assinantes da Habr

Você pode obter informações adicionais entrando em contato com o gerente da GlobalSign pelo telefone: +7 (499) 678 2210, ou preencha o
formulário no site, indicando o código promocional CS002HBFR.