Esse repositório implementa uma ferramenta para verificar se os patches são garantidos até rastrear equivalência (Pate).
O objetivo é provar que os patches de segurança aplicados aos binários removem apenas comportamentos ruins ou os caracterizam com precisão para o desenvolvedor do patch. O verificador suporta binários PowerPC e AARCH32 (atualmente exigindo binários elfos estaticamente vinculados).
A maneira mais rápida de começar é construir a imagem do Docker e usar a ferramenta via Docker. Para instruções de construção mais detalhadas, consulte a seção de desenvolvimento abaixo.
Primeiro, construa a imagem do Docker com o comando:
Docker Build --platform Linux/AMD64. -t Pate
Em seguida, execute o verificador em um exemplo:
Docker Run - -rm -it --platform linux/amd64 -v "$ (pwd)"/tests/integration/packet/exe:/alvo Pate --original /target/packet.exe ---patched /target/packet.patched.exe -s parse_packet
O verificador aceita os seguintes argumentos da linha de comando:
-h,-ajude a mostrar este texto de ajuda
-o,-binário original exe original
-p,-binário remendado de remendado
-b,-Blockinfo FileName Block Information Relating Binários
-s,-startymbol arg inicia a análise da função com este símbolo
-D,-Nodiscovery não descobre dinamicamente os pares de funções com base em
chamadas.
-Solver arg o solucionador SMT para resolver a verificação
condições. Um de cvc4, yices ou z3
(Padrão: YICES)
--Geal-timeout Arg o tempo limite para verificar metas individuais em segundos
(Padrão: 300)
-HEURISTIC-TIM-TIMEOUT ARG o tempo limite para verificar os objetivos heurísticos em segundos
(Padrão: 10)
-Original-anvill-thints arg
Analisar uma especificação ANVILL para descoberta de código
dicas
-Arg
Analisar uma especificação ANVILL para descoberta de código
dicas
-ARGUS-PROBABILISTA DOBILISTA ARG
Analisar um arquivo json contendo função probabilística
Nome/endereço dicas
-Pontos de ponta de compra-de-probabilística arg
Analisar um arquivo json contendo função probabilística
Nome/endereço dicas
-ORiginal-CSV-função não arg
Analisar um arquivo CSV contendo nome/endereço da função
dicas
-AGRAGEM ARG
Analisar um arquivo CSV contendo nome/endereço da função
dicas
--original-bsi-tips arg analisando um arquivo json contendo nome/endereço da função
dicas
-Arg-bsi-bsi-t-thint Parse um arquivo JSON contendo nome/endereço da função
dicas
-Não-duras-dicas não extraem metadados das informações do anão
os binários
-V,-verbosidade arg a verbosidade da saída de log (padrão: informações)
-Save-MACAW-CFGS Dir Save MacAW CFGS no diretório fornecido
-Solver-interação de arquivo de arquivo
Salvar interações com o solucionador SMT durante o simbólico
execução neste arquivo
-Arquivo de Summary-Json
Um arquivo para salvar resultados de prova interessantes em json
formatar
-Log-file Arquivo Um arquivo para salvar logs de depuração para
-e,-ErrorMode Arg Verifier Modo de manuseio de erros
(Padrão: ThrowonanyFailure)
-R,-Rescobemode Arg variável Modo de manuseio de falhas de resgate
(Padrão: ThroneqRescopeFailure)
-SKIP-FUNCTIONS SPUNCIO
--SKIP DIVERGENTE-CONTROL-FLOW
<presecado>
--alvo-equiv-rregs Arg computam uma condição de equivalência suficiente para
estabelecer igualdade nos registros dados após o
TOPLEVEL ENTRADE RETURNS. <presecado>
--Ignore-segmentos Arg Skip segmentos (0-Indexados) Ao carregar o elfo
--json-Toplevel Run Toplevel no modo json-output (modo interativo
apenas)
-Read-somente-segmentos Arg Mark segmentos como somente leitura (0-Indexado) ao carregar
DUENDE
--Script FileName Salvar Macaw CFGS no diretório fornecido
--sUSMUMUM STACK-SCOPE Adicione suposições adicionais sobre o escopo da estrutura de pilha
Durante as chamadas de função (inseguro)
-Ignore-Warnings Arg não levanta nenhum dos tipos de aviso fornecidos
-sempre-classify-retorno sempre resolve falhas de classificador assumindo
A função retorna, se possível.
A seção de início rápido descreveu um comando para executar o verificador em um caso de teste usando o contêiner do docker. Esta seção abordará alguns comandos úteis para outros cenários.
Se você tiver um arquivo tar de uma imagem do Docker do verificador, poderá instalá -lo usando o comando:
Docker Load -i /path/to/pate.tar
Para executar o verificador via Docker depois disso:
Docker Run -RM -it -Linux/amd64 Pate -Help
Para usar o verificador com o Docker, é útil mapear um diretório no sistema de arquivos local no contêiner do Docker para poder salvar arquivos de saída. Supondo que seus binários originais e corrigidos sejam original.exe e patched.exe , respectivamente:
Mkdir VerifierData
cp original.exe patched.exe verifierdata/
Docker Run - -rm -it -Linux/amd64
-v `pwd`/verifierdata`:/verifierdata Pate
--original /verifierdata/original.exe
-Patiled /verifierdata/patched.exe
--proof-summary-json /verifierdata/report.json
--------ite /verifierdata/pate.log
-Save-MACAW-CFGS /VerifierData /CFGS
Este comando executará o verificador nos dois binários e o colocará em um loop de leitura de leitura-Eval, onde você pode explorar interativamente a saída do verificador.
Por padrão, o verificador começa a verificar no ponto de entrada formal do programa. Isso geralmente não é muito útil (e pode ser problemático para binários complexos com uma grande _start que causa problemas para nossa descoberta de código). Além disso, para alterações com um escopo de impacto conhecido (ou pelo menos esperado), analisar apenas as funções afetadas é significativamente mais rápido. Em vez disso, especificar um ponto de entrada de análise, passando a opção -s <function_symbol> iniciará a análise da função correspondente ao símbolo fornecido. Observe que isso requer que os símbolos da função sejam fornecidos para os binários (como símbolos de depuração incorporados ou separadamente em um dos formatos de dica).
Embora seja doentio, às vezes é útil tratar uma chamada de função como um não-operatório. Por exemplo, ignorar grandes funções que não mudaram e é improvável que tenham um efeito sobre a correção (por exemplo, grandes funções criptográficas de bibliotecas confiáveis) pode melhorar significativamente o desempenho. Para usar esse recurso, passe um arquivo de configuração para o verificador usando a opção --blockinfo , garantindo que o arquivo de configuração inclua as seguintes diretivas:
Ignore-original-functions = [<deed>, ...] ignorar funções de primeira linha = [<deed>, ...]
onde cada uma das listas é uma lista de endereços de funções para ignorar. Embora as duas listas sejam especificadas separadamente, elas quase certamente devem estar "alinhadas" entre os dois binários (ou seja, ignorar uma função no binário original provavelmente significa que a função correspondente no binário corrigida também precisa ser ignorada).
O verificador se beneficia dos metadados anões de duas maneiras:
Para injetar metadados anões em binários sem ela (por exemplo, binários despojados), recomendamos o uso da ferramenta anã-angustiante. Como exemplo de uso de dwarf-writer por meio de sua imagem do Docker, assumindo a existência de um alvo ( target-binary.exe ) e metadados no formato JSON anvill ( target-binary.exe.json ):
Docker Load -i anão-docker.tar
mkdir dwarfwriterdata
CP Target-Binary.exe Target-Binary.exe.json dwarfwriterdata/
Docker Run - -rm -it -v `pwd`/dwarfwriterdata:/dwarfwriterdata dwarf -writer
--anvill /dwarfwriterdata/target-binary.exe.json
/Dwarfwriterdata/target-binary.exe
/Dwarfwriterdata/target-binary-dwarf.exe
Isso produzirá uma versão do binário anotado com metadados anões em DwarfWriterData/target-binary-dwarf.exe .
Se você possui a ferramenta llvm-dwarfdump , poderá usá-la para inspecionar os metadados anões gerados. O verificador pate aproveitará automaticamente as dicas de metadados anões, a menos que seja direcionado para ignorá -los.
O verificador toma dois binários como entrada: um binário original e um binário corrigido. A suposição é que algum patch orientado à segurança foi aplicado ao binário original que preserva amplamente seu comportamento, mas pode corrigir alguns comportamentos indesejáveis. O verificador tenta provar que os dois binários exibem o mesmo comportamento observável; Se não puder, produz um resumo diferencial que descreve as condições sob as quais o binário remendado exibe comportamentos diferentes do original. Isso permite que os desenvolvedores do Patch entendam o impacto de seus patches na semântica do programa e avaliem se o impacto é restrito aos caminhos de execução que eles pretendiam.
O verificador não requer uma especificação fornecida manualmente dos usuários; Em vez disso, trata o programa original como a especificação comportamental desejada. Esse arranjo faz de Pate um verificador relacional , pois relaciona o binário corrigido ao original. O verificador é baseado em várias bibliotecas existentes para descoberta de código binário e execução simbólica de programas (incluindo programas de código de máquina). Aproximadamente, o verificador funciona por:
A ferramenta Pate é escrita em Haskell e requer o compilador GHC (testamos com 9,6) e a ferramenta de construção da CABAL para compilar. O edifício da fonte pode ser realizado por:
git clone [email protected]: galoisinc/Pate.git CD Pate Atualização do submódulo Git -Init CP Cabal.Project.Dist Cabal.Project Cabal Configurar PKG: Pate ./Pate.sh -Help
O verificador exige que um solucionador SMT esteja disponível no PATH . O padrão é yices - z3 e cvc4 também podem funcionar, mas não são testados regularmente com Pate.
Este material é baseado no trabalho apoiado pela Agência de Projetos de Pesquisa Avançada de Defesa (DARPA) e pelo Centro de Guerra de Informações Navais Pacífico (NIWC Pacific) sob o número do contrato N66001-20-C-4027. Quaisquer opiniões, descobertas e conclusões ou recomendações expressas neste material são as do (s) autor (s) e não refletem necessariamente as opiniões do Darpa & Niwc Pacific.