BR102018077436A2 - método de execução forçada de integridade de controle de fluxo em um binário monolítico usando análise estática - Google Patents

método de execução forçada de integridade de controle de fluxo em um binário monolítico usando análise estática Download PDF

Info

Publication number
BR102018077436A2
BR102018077436A2 BR102018077436-0A BR102018077436A BR102018077436A2 BR 102018077436 A2 BR102018077436 A2 BR 102018077436A2 BR 102018077436 A BR102018077436 A BR 102018077436A BR 102018077436 A2 BR102018077436 A2 BR 102018077436A2
Authority
BR
Brazil
Prior art keywords
privilege
functions
function
node
binary
Prior art date
Application number
BR102018077436-0A
Other languages
English (en)
Inventor
Vladimir PORTELA PARENTE
Alexandre PRADO TELES
Original Assignee
Samsung Eletrônica da Amazônia Ltda.
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Samsung Eletrônica da Amazônia Ltda. filed Critical Samsung Eletrônica da Amazônia Ltda.
Priority to BR102018077436-0A priority Critical patent/BR102018077436A2/pt
Priority to US16/376,579 priority patent/US11003430B2/en
Publication of BR102018077436A2 publication Critical patent/BR102018077436A2/pt

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/52Binary to binary
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F16/00Information retrieval; Database structures therefor; File system structures therefor
    • G06F16/90Details of database functions independent of the retrieved data types
    • G06F16/901Indexing; Data structures therefor; Storage structures
    • G06F16/9024Graphs; Linked lists
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/50Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
    • G06F21/52Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems during program execution, e.g. stack integrity ; Preventing unwanted data erasure; Buffer overflow
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/50Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
    • G06F21/57Certifying or maintaining trusted computer platforms, e.g. secure boots or power-downs, version controls, system software checks, secure updates or assessing vulnerabilities
    • G06F21/577Assessing vulnerabilities and evaluating computer system security
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/43Checking; Contextual analysis
    • G06F8/433Dependency analysis; Data or control flow analysis
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/44Encoding
    • G06F8/443Optimisation
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/54Link editing before load time
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/30Arrangements for executing machine instructions, e.g. instruction decode
    • G06F9/32Address formation of the next instruction, e.g. by incrementing the instruction counter
    • G06F9/322Address formation of the next instruction, e.g. by incrementing the instruction counter for non-sequential address
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/50Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
    • G06F21/55Detecting local intrusion or implementing counter-measures
    • G06F21/556Detecting local intrusion or implementing counter-measures involving covert channels, i.e. data leakage between processes
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/60Protecting data
    • G06F21/604Tools and structures for managing or administering access control systems
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/44Arrangements for executing specific programs

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • General Engineering & Computer Science (AREA)
  • Software Systems (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Computer Security & Cryptography (AREA)
  • Computer Hardware Design (AREA)
  • Databases & Information Systems (AREA)
  • Data Mining & Analysis (AREA)
  • Computing Systems (AREA)
  • Storage Device Security (AREA)
  • Executing Machine-Instructions (AREA)

Abstract

A presente invenção se refere a um método de execução forçada de Integridade de Fluxo de Controle (CFI) para um binário monolítico usando análise estática que compreende as etapas de: marcar algumas funções avaliadas como funções de núcleo por uma heurística escolhida ou empiricamente; gerar o gráfico de chamadas de binário; - se o gráfico de chamadas de binário de análise estática estiver incompleto, então: definir o privilégio 2 para funções com estimativa incompleta; definir o privilégio ad hoc para funções especificas; - gerar a política; - agrupar todos os nós de função das funções de núcleo como um nó de privilégio superior (conjunto 0); - agrupar todas as funções leaf em um nó sem privilégio (conjunto n); - agrupar todos os nós sem privilégios que alcançam funções de privilégio i e definir o privilégio do nó agrupado como i + 1; - verificar se existe um nó sem privilégio além da função trivial; em caso positivo, retornar para a etapa anterior de agrupar todos os nós sem privilégio e configurar o privilégio do nó agrupado como i + 1; em caso negativo, definir o privilégio das funções triviais como i + 2.

Description

MÉTODO DE EXECUÇÃO FORÇADA DE INTEGRIDADE DE CONTROLE DE FLUXO EM UM BINÁRIO MONOLÍTICO USANDO ANÁLISE ESTÁTICA Campo da Invenção
[0001] O método da presente invenção se refere à execução forçada da Integridade de fluxo de Controle (visa evitar o ataque de reutilização de código) de uma forma mais rigorosa, mas, ao mesmo tempo, mantém o desempenho de um binário monolítico em um nível aceitável. Além disso, esta execução forçada tem o objetivo especifico de proteger as funções de núcleo do sistema. Uma vez que estas funções de núcleo gerenciam aspectos críticos do sistema, tais como credenciais de privilégio e execução de inicialização (init), por exemplo, tal execução forçada de Integridade de Fluxo de Controle (Control Flow Integrity - CFI) é essencial para diminuir a superfície de ataque sem comprometer as funcionalidades e o desempenho dos sistemas.
[0002] O método da presente invenção pode ser usado individualmente de modo a forçar a execução de uma CFI e também pode ser usado em conjunto com métodos de CFI complementares, tal como Clang CFI de chamadas indiretas usado no Android P, que verifica o protótipo de função.
Antecedentes
[0003] Na última década, os invasores têm explorado vulnerabilidades ao usar uma corrupção de memória e, portanto, sobrescrever o endereço de retorno de uma função para apontá-la para um código desejado por eles. Este código foi, em um grande número de vezes, introduzido em uma região que deveria conter apenas os dados usados pelo programa tal como, por exemplo, um buffer vulnerável (um invasor poderia escrever no mesmo).
[0004] Com o advento do recurso W © X, a memória somente poderia ser marcada como gravável ou executável ao mesmo tempo, mas não em ambos. Portanto, um invasor pode sobrescrever o endereço de retorno de uma função, mas não pode mais introduzir um código arbitrário em um buffer de modo a ser executado quando o retorno ocorrer, uma vez que a região de memória especificada para este buffer foi marcada como gravável e não executável.
[0005] Sem a introdução de código, a ideia natural para um invasor era usar o código já disponível no sistema, uma vez que a sobrescrita do endereço de retorno ainda era possível, mesmo com algumas defesas implantadas contra ele, tal como o Canary. Este tipo de ataque é conhecido como Ataque de Reutilização de Código (Code Reuse Attack - CRA). Um exemplo de violação, neste caso, seria que um invasor poderia criar um endereço de retorno simplesmente ao apontar para system/bin/sh. Este tipo de CRA especifico que tem como destino principalmente funções da libc é conhecido como ret21ibc. Ele desvia o fluxo de programa para outro para chamar uma função libc de destino. Ao restringir o fluxo de controle de funções libc, este ataque se tornou mais difícil de ser implantado.
[0006] A Programação Orientada para Retorno (Return Oriented Programming - ROP) foi o próximo passo na evolução da violação. Ela é um ataque mais complexo capaz de criar um Conjunto de Turing Completo ou, em outras palavras, realizar qualquer cálculo desejado para o adversário (criar uma Máquina de Turing). Neste cenário, primeiro, o invasor identifica os gadgets, os quais geralmente são pequenos blocos de códigos que terminam em uma instrução de retorno. Em segundo, o invasor constrói sua cadeia de ataque escolhendo os gadgets apropriados para serem usados. Finalmente, o invasor cria a carga útil que será colocada sobre a pilha. Para conter este tipo de ataque, similar ao Ret21ibc, é necessário forçar a execução para que o programa siga seu fluxo de controle correto.
[0007] O próximo passo na evolução do ataque foi a Programação Orientada a Salto (Jump Oriented Programming -JOP) . De uma maneira simples, em vez de usar instruções de retorno para desviar o fluxo do programa, a JOP usa instruções de salto explicitas para encadear os gadgets. Similar ao caso da ROP, a melhor defesa contra este ataque é forçar a execução do fluxo de controle.
[0008] Um aspecto importante é que a Randomização de Layout de Espaço de Endereço (ASLR) é uma ótima ferramenta de defesa que funciona contra inserções de código e contra ataques de reutilização de código. Em sua versão simples, ela adiciona um deslocamento aleatório ao endereço de inicialização do programa. Com este recurso, é mais difícil para um invasor usar as funções de uma biblioteca especifica e encontrar os gadgets executáveis adequados. No entanto, no sistema de 32 bits, a entropia disponível para randomizar o espaço de endereço não é muito alta e um invasor pode usar uma pesquisa de força bruta para revelar os endereços de destino. Além disso, se um único endereço de uma variável global for descoberto, toda a randomização feita pela ASLR será frustrada. Além disso, mesmo que apenas uma variável local tenha seu endereço revelado, o invasor já tem o layout, por exemplo, de uma lib inteira, o que facilita a violação. Portanto, a ASLR aumenta a segurança, mas não pode ser a única defesa implementada contra estes ataques. Alguns outros métodos ortogonais devem ser usados.
[0009] Teoricamente, a ROP/JOP e sua variante podem ser defendidas simplesmente ao seguir o fluxo de programa correto e esperado. No entanto, estimar corretamente o gráfico de chamadas de um programa, o qual é necessário para a execução forçada, é um problema de difícil decisão conhecido. Portanto, algumas flexibilizações ou suposições precisam ser feitas para tornar este problema solucionável neste contexto.
[0010] Embora, mesmo que o gráfico de chamadas correto e completo (ou uma boa aproximação) estivesse disponível, a execução forçada de fluxo de controle seria muito dispendiosa, todas as alterações no fluxo de programa teriam de ser analisadas através de pesquisa em uma estrutura de dados grande. Esta abordagem poderia comprometer o desempenho, o que tornaria a implantação de tal solução de segurança indesejável e impossível em um mercado de dispositivos competitivo, tal como o de smartphones.
[0011] Concluindo, uma solução que force a execução do fluxo de programa que seja mais restrita possível para manter a segurança do dispositivo e, ao mesmo tempo, manter o desempenho em níveis aceitáveis, é essencial para se defender contra o tipo de ataque ROP/JOP.
[0012] No atual estado da técnica, há soluções e tecnologias que visam alcançar o mesmo objetivo da presente invenção, o qual é forçar a execução da CFI de um programa.
[0013] O artigo intitulado: "ACES: Automatic Compartments for Embedded Systems" (USENIX 2018) descreve um novo compilador com base em Máquina Virtual de Baixo Nivel (Low Level Virtual Machine - LLVM) que cria compartimentos em um sistema bare-metal (sem sistema operacional) para impor seu isolamento com base no menor privilégio. Ele foca em dispositivos ARMv7-M.
[0014] Para criar os componentes, o Gráfico de Dependência de Programa (Program Dependency Graph - PDG) foi usado. O isolamento dos componentes foi feito não apenas para transições entre eles, mas também para acesso aos recursos do sistema.
[0015] Embora a ideia de separar as funções por conjuntos esteja próxima de um dos conceitos da invenção, sua geração se baseia no PDG, em vez do gráfico de chamadas. Além disso, sua política não é feita para isolar funções, mas recursos do sistema em geral. Portanto, uma verificação mais complexa deve ser feita em um grande número de situações. Com isto, a sobrecarga da solução é consideravelmente grande, o que é inadequado para sistemas com fortes restrições, tal como o consumo de bateria.
[0016] O artigo intitulado "DROP THE ROP FINE-GRAINED CONTROL-FLOW INTEGRITY FOR THE LINUX KERNEL" (Black Hat Asia 2017) cria um método de execução forçada de CFI para o kernel do Linux (binário monolítico) ao verificar se o protótipo de função da função chamada corresponde com aquela esperada como parte chamada.
[0017] Para criar uma CFI mais restrita, é usada uma técnica denominada Separação de Gráfico de Chamadas (Call Graph Detaching - CGD) . Ela simplesmente evita o uso de chamadas diretas para gerar a política permitida para protótipos.
[0018] A política, neste caso, é feita com foco em protótipos de função e, possivelmente, uma pesquisa em uma estrutura de dados é necessária para verificar se o fluxo deve ser permitido ou não. Isto pode comprometer o desempenho, conforme mostrado pelos experimentos executados. Além disso, o uso da CGD é contra o conceito de proteger as funções de núcleo, pois oculta quem está realmente acessando-as.
[0019] A ARM Pointer Authentication (descrita no site da Qualcomm, https://www.qualcomm.com/media/documents/files/whitepaper-pointer-authentication-on-armv8-3.pdf) é um método disponível para a variante ARMv8.3-A que visa torná-la mais difícil para um invasor modificar ponteiros protegidos. Ao criptografar o ponteiro com a cifra QARMA com a chave contida em um registro reservado não acessível a ELO, o ponteiro se torna inutilizável, disponível apenas para leitura. Com isto, o fluxo de controle é forçado pela manutenção da chamada original pretendida do conteúdo do ponteiro.
[0020] Este método funciona apenas para execução no espaço do usuário, uma vez que o registro usado para conter a chave deve estar em um nível de exceção com privilégios superiores. Além disso, este método deve ser usado em ponteiros que não são usados com frequência para evitar sobrecargas de desempenho. Além disso, esta é uma maneira de manter o fluxo de programa em um comportamento não malicioso. Concluindo, as abordagens de execução forçada de CFI da invenção podem funcionar ortogonalmente com este mecanismo para melhorar a segurança.
[0021] Muitas soluções (tal como, por exemplo, o artigo intitulado "DROP THE ROP FINE-GRAINED CONTROL-FLOW INTEGRITY FOR THE LINUX KERNEL AND CLANG CFI FOR INDIRECT CALLS USED IN ANDROID P") forçam a execução de CFI ao verificar se o protótipo da função chamada (em tempo de execução) coincide com o protótipo esperado. Em poucas palavras, a execução forçada da presente invenção verifica se uma chamada para uma função de núcleo é permitida ou não, independentemente do protótipo. Portanto, ambas as verificações são diferentes e ortogonais. Concluindo, elas poderiam ser executadas no mesmo binário para verificar se o fluxo está correto.
[0022] Algumas soluções como a patente US 2017/0140148 Al, publicada em 18 de maio de 2 017, e a Proteção de Ataque de Retorno (Return Attack Protection -RAP, da PaX) funcionam ao criptografar o endereço de retorno no prólogo da função e descriptografá-lo antes de retornar para a parte que faz a chamada. O método da invenção para impedir a ROP, neste caso, ocorreria como uma verificação adicional de modo a evitar a violação se este tipo de mecanismo fosse ignorado.
[0023] Concluindo, as tecnologias existentes não usam o conceito de funções de núcleo e de criar uma política para restringir o acesso às mesmas. Portanto, a invenção tem uma diferença significativa quando comparada com as tecnologias mais próximas existentes.
Sumário da Invenção
[0024] A presente invenção está relacionada ao campo de segurança da tecnologia. Especificamente, ela descreve um modo para execução forçada de Integridade de Controle de Fluxo (CFI) para um binário monolítico genérico (autocontido) através de análise estática apenas, embora o uso de análise dinâmica aumente a confiabilidade do gráfico de controle de fluxo usado.
[0025] O método de execução forçada da presente invenção tem dois objetivos principais. O primeiro é proteger as funções de núcleo consideradas do sistema. De modo a ser considerada essencial, uma função é avaliada por uma heurística escolhida ou empiricamente. Neste contexto, por exemplo, o binário analisado poderia ser o kernel do Linux e as funções de núcleo poderiam ser todas as funções relacionadas às credenciais de uma linha de execução (thread). O segundo objetivo é manter o funcionamento (semântica) do binário inalterado. Desta forma, mesmo que um invasor seja capaz de chamar algumas funções do binário, ele não terá acesso à parte critica que lhe fornece os recursos desejados do sistema.
[0026] A ideia principal é que cada função de núcleo é critica para o funcionamento do sistema (de um ponto de vista especifico) e uma chamada errada (pode ser de um invasor) para elas pode comprometer todo o sistema. Portanto, todas elas devem ser agrupadas como um componente principal com acesso restrito. Após agrupar as funções de núcleo, deve-se observar que qualquer função que possa acessar diretamente este componente principal, o qual tem acesso restrito agora, é o novo alvo de um invasor. No entanto, a mesma ideia pode ser aplicada recursivamente e uma execução forçada de CFI para todo o binário é criada. Desta forma, o primeiro objetivo de proteger as funções de núcleo do sistema é alcançado. O segundo objetivo é alcançado ao evitar o uso de uma estrutura de dados grande para manter as relações entre as funções (quando misturadas, os componentes) em virtude do custo de pesquisa. Isto é feito ao usar uma relação transitiva simples entre elas que é facilmente avaliada.
[0027] Especificamente, a presente invenção se refere a um método de execução forçada de Integridade de Fluxo de Controle (CFI) para um binário monolítico usando análise estática compreendendo as etapas de: marcar algumas funções avaliadas como funções de núcleo por uma heurística escolhida ou empiricamente; gerar o gráfico de chamadas binário; se o gráfico de chamadas binário estiver incompleto, então: criar um gráfico de chamadas a partir de análise estática; definir o privilégio 2 para funções com estimativa incompleta; definir o privilégio ad hoc para funções especificas; gerar a política; - agrupar todos os nós de função das funções de núcleo como um nó de privilégio superior (conjunto 0); - agrupar todas as funções leaf em um nó sem privilégio (conjunto n); - agrupar todos os nós sem privilégios que alcançam funções de privilégio i e definir o privilégio do nó agrupado como i + 1; - verificar se existe um nó sem privilégio além da função trivial; em caso positivo, retornar para a etapa anterior de agrupar todos os nós sem privilégio e configurar o privilégio do nó agrupado como i + 1; em caso negativo, definir o privilégio das funções triviais como i + 2.
[0028] Este método não apenas evita a JOP, mas cria novas camadas de segurança que restringem o acesso às funções essenciais (de núcleo) relacionadas à segurança de todo o sistema. Se um invasor quiser acessar uma função de núcleo, ele precisará criar uma cadeia mais longa e mais complexa.
[0029] Este método não requer um gráfico de chamadas completo do binário. Ele pode funcionar apenas com o uso de análise estática, mesmo se o gráfico de chamadas estiver incompleto. O uso de análise dinâmica apenas melhora a precisão do gráfico de chamadas o que, no final, também melhora a segurança.
[0030] Este método pode ser aplicado a binários de uma grande variedade de arquiteturas (incluindo ARM, x86) com alguns pequenos ajustes.
[0031] Uma vez que este método instrumenta cada chamada de função em parte ao adicionar o privilégio da função após a instrução responsável pela chamada (direta ou indireta), é obrigatório que somente instruções alinhadas possam ser usadas para chamar uma função ou retorno. É altamente improvável que um invasor consiga encontrar uma chamada não intencional ou uma instrução de retorno antes de um privilégio de chamada válido. Em resumo, este método ajuda a evitar a JOP e a ROP em um ISA desalinhado ao diminuir o número de instruções não intencionais.
[0032] A CFI do programa é aplicada de uma maneira que está mais próxima da melhor CFI do que outras soluções, ao mesmo tempo em que mantém o desempenho.
[0033] Além disso, a presente invenção ajuda a evitar ataques ROP ao verificar se o fluxo reverso está correto usando a mesma política gerada.
[0034] Em resumo, o método da presente invenção força a execução de uma CFI que protege funções essenciais e, ao mesmo tempo, mantém o comportamento e o desempenho do binário. Se usado, por exemplo, no kernel do Linux, o qual é executado em um privilégio mais alto e é um alvo de um grande número de ataques, ele aumentaria a segurança de sistemas com base neste kernel tal como, por exemplo, o Android.
Breve Descrição dos Desenhos
[0035] Os objetivos e vantagens da presente invenção se tornarão mais evidentes através da descrição detalhada do exemplo a seguir e figuras não limitativas apresentadas ao final do presente documento.
[0036] A Figura 1 ilustra um exemplo de cadeia de ataque que começa na função vulnerável f_n e vai até commit_creds(prepare_creds(0)) ser executado.
[0037] A Figura 2 ilustra a mesma cadeia de ataque da Figura 1, mas com a diferença de que f_n-l chamar f_n-2 não é mais permitido pela execução forçada de CFI.
[0038] A Figura 3 ilustra uma situação exemplar na qual o invasor tem como chamada de destino f_0, ele já tem uma cadeia formada, mas tem necessariamente de passar por f_1.
[0039] A Figura 4 ilustra uma situação similar à Figura 3, mas com duas camadas de segurança antes de chamar f_0.
[0040] A Figura 5 ilustra o caso geral das Figuras 3 e 4 com n camadas de segurança.
[0041] A Figura 6 ilustra a política de chamada indireta da presente invenção.
[0042] A Figura 7 ilustra um fluxograma do método de Geração de Políticas.
[0043] A Figura 8 ilustra como o conjunto 1 é construído.
[0044] A Figura 9 ilustra um exemplo do algoritmo de agrupamento para o conjunto 1 antes do agrupamento real.
[0045] A Figura 10 ilustra um exemplo do algoritmo de agrupamento para o conjunto 1 após o agrupamento real.
[0046] A Figura 11 ilustra um exemplo do algoritmo de agrupamento para o conjunto de folhas antes do agrupamento real.
[0047] A Figura 12 ilustra um exemplo do algoritmo de agrupamento para o conjunto leaf após o agrupamento real.
[0048] A Figura 13 ilustra o fluxograma do algoritmo de Geração de Políticas com o gráfico de chamadas incompleto.
[0049] A Figura 14 ilustra uma visão do binário monolítico com todas as camadas de segurança e com o conjunto de núcleo localizado no centro.
Descrição Detalhada
[0050] Na Programação Orientada a Saltos (JOP), o invasor tentará executar gadgets em uma cadeia para executar a violação. O invasor simplesmente sobrescreve o conteúdo de um registrador que aponta direta ou indiretamente para um endereço de função. Para evitar isto, uma primeira linha de defesa é feita ao forçar a execução de uma instrução destinada a chamar uma função somente possa ser usada se o endereço estiver de fato apontando para o inicio de uma função.
[0051] No entanto, conforme mostrado pela Figura 1, uma cadeia de ataque simples pode ser construída por um invasor de modo a ter, por exemplo, o privilégio root ao chamar commit_creds(prepare_creds(0)) ao nível do kernel do Linux. Deve-se notar que esta cadeia começa a partir de uma função vulnerável que é violada e uma cadeia de ataque é criada para realizar a chamada. Para o invasor, não importa se o fluxo de programa está correto ou não, contanto que o objetivo de violação seja cumprido. Portanto, duas coisas podem ser concluídas. Primeiro, a violação ainda é possível usando a JOP, apenas o número de gadgets disponíveis foi reduzido. Em segundo, é mais fácil para o invasor construir esta cadeia a partir da função f_n se ele tem um grande número de funções f_n-l possíveis que podem ser usadas na cadeia em etapas intermediárias.
[0052] A Figura 2 descreve a mesma cadeia de funções usada, mas, desta vez, a execução forçada de CFI não permite que f_n-l chame f_n-2 e, portanto, o ataque é evitado. Neste cenário, o invasor teria que procurar outra função para usar, o que aumenta a complexidade geral do ataque.
[0053] A Figura 3 ilustra uma cadeia de ataque no cenário que funciona a partir do conjunto 0, o alvo do ataque, somente pode ser chamado por funções do conjunto 1. Neste caso, o invasor terá de construir uma cadeia e adicionar necessariamente uma função do conjunto 1 e uma função do conjunto 0. A Figura 4 ilustra uma situação similar, mas com três conjuntos obrigatórios, o que adiciona outra camada de complexidade para o invasor.
[0054] A Figura 5 descreve uma situação similar quando comparado com as Figuras 3 e 4. Neste caso geral, o invasor deve criar uma cadeia, mas deve passar por todas as n funções (n conjuntos) para atingir seu destino (conjunto 0) . Este conjunto de destino final possivelmente tem funções criticas do binário. Por exemplo, se o binário analisado fosse o kernel, este conjunto poderia ter funções relacionadas a credenciais de processos. Portanto, este conjunto 0 será chamado como o conjunto de função de núcleo o qual, logicamente, tem funções de núcleo. Na mesma Figura 5 é mostrado que, se o invasor tentar saltar da função f_n (conjunto n, menos privilegiado) para a função f_2 (conjunto 2, mais privilegiado), então, a execução é interrompida e um erro é gerado.
[0055] A Figura 6 descreve o método de acordo com uma concretização da presente invenção. Todas as funções de núcleo são empiricamente marcadas e agrupadas no conjunto 0. Este conjunto tem o maior privilégio e pode acessar (chamar) uma função de qualquer outro nivel de privilégio. O próximo conjunto (conjunto 1) tem privilégio para acessar o conjunto de núcleo e todas as funções abaixo deste acesso privilegiado (todos os privilégios maiores do que 0). O conjunto 2 segue O mesmo padrão, ele tem acesso ao conjunto 1 e a todos os conjuntos abaixo, incluindo ele mesmo, mas não tem acesso ao conjunto O. Isto ocorre para todo conjunto até que o último conjunto seja formado apenas por funções leaf que não tenham direitos de acesso. Em resumo, a regra de acesso é que o conjunto mais privilegiado que uma função de nível I de privilégio pode acessar é aquele de privilégio I - 1 (ele também pode acessar funções com privilégio maior do que ou igual a I) . Por exemplo, uma função com privilégio 5 pode chamar funções com privilégio 4 ou superiores (o que inclui seu próprio nível, 5, e todos os níveis maiores do que 5). Para que isto ocorra, todas as chamadas indiretas são instrumentadas com esta verificação de privilégios. Além disso, ao aplicar o fluxo reverso da Figura 6, uma proteção contra ROP é feita com os mesmos conjuntos. Uma observação importante sobre o acesso privilegiado é que, embora os conjuntos 0 e 1 possam acessar exatamente os mesmos conjuntos, o conjunto 0 pode ser acessado somente pelo conjunto 1 e por si mesmo, enquanto que o conjunto 1 pode ser acessado pelos conjuntos 0, 1 e 2. Portanto, o conjunto 1 atua como uma primeira camada de proteção para o conjunto 0.
[0056] O problema, neste ponto, é como definir a qual conjunto cada função pertence ou, em outras palavras, a política que deve ser aplicada. A Figura 7 descreve o algoritmo de Geração de Políticas. Dado o gráfico de chamadas do binário e todas as funções de núcleo marcadas, é verificado recursivamente quais funções chamam o conjunto de destino naquele instante (iniciando em 0 e incrementando a cada etapa) até que existam apenas funções leaf com o menor privilégio de acesso. É importante observar que algumas funções devem ter algumas chamadas não instrumentadas em geral para manter as funcionalidades binárias. Isto ocorre quando a função de parte chamadora foi implementada de uma forma que as instruções usadas para chamar uma função possam ser usadas em um contexto em que o endereço de destino esteja no meio de uma função, em vez do ponto de entrada. Este cenário provavelmente ocorrerá se algumas funções forem escritas diretamente em Assembly. Portanto, elas são autorizadas a manter chamadas diretas não instrumentadas. Conforme mostrado pela Figura 8, uma vez que uma função com uma chamada não instrumentada pode ir para qualquer função, os componentes do conjunto 1 são feitos de funções que podem acessar o núcleo direta ou indiretamente em qualquer contexto (instrumentado ou não). O algoritmo de agrupamento usado na Geração de Políticas é mostrado na Figura 9 (antes) e na Figura 10 (depois) para o conjunto 1 e na Figura 11 (antes) e Figura 12 (depois) para as funções leaf definidas.
[0057] Um problema com o algoritmo de Geração de Políticas é que ele depende do gráfico de chamadas do binário, o qual pode estar incompleto. A fim de resolver este problema e manter as funcionalidades de binário conforme esperado, uma extensão é feita na Geração de Políticas, conforme descrito na Figura 13. O primeiro incremento é que todas as funções com estimativa incompleta detectada que não acessam nenhuma função de núcleo sejam colocadas no conjunto 2. O segundo é que as regras ad hoc sejam inseridas. Com isto, as funcionalidades de binário são mantidas, uma vez que uma função do conjunto 1 pode acessar qualquer outra, o que mantém as funcionalidades de binário independentemente do gráfico de chamadas e, de maneira similar, uma função do conjunto 2 pode acessar qualquer outra, exceto do conjunto 0. Neste caso, se uma função classificada incorretamente do conjunto 2 realmente acessa uma função do núcleo, então, seu privilégio é aumentado para 1 na fase de inserção ad hoc. No entanto, esta é uma situação improvável, uma vez que o acesso às funções de núcleo possivelmente é supervisionado. Portanto, este aperfeiçoamento na Geração de Políticas torna este método de execução forçada viável.
[0058] A Figura 14 descreve como o binário é visto com todas as camadas de segurança adicionadas. As funções de núcleo estão no centro apenas disponíveis para serem chamadas por elas mesmas e pela camada anterior.
[0059] De modo a forçar a política para a proteção contra JOP, o binário é instrumentado da seguinte maneira: antes de cada ponto de entrada de função, seu privilégio é inserido e, antes de cada chamada indireta instrumentada, este mesmo privilégio é colocado depois. Uma observação importante é que é possível que as funções de núcleo não tenham seu privilégio antes do ponto de entrada para evitar qualquer chamada indireta. Na chamada instrumentada, duas coisas são feitas. A primeira é verificar se a parte chamadora pode realmente chamar a parte chamada. Caso contrário, é gerado um erro. A segunda é colocar o endereço de retorno no local adequado, se necessário. Para a proteção contra ROP, é necessário inserir o privilégio depois após cada chamada de função e instrumentar as instruções de retorno. Isto é necessário pelo fato de que, quando uma função retorna, ela não sabe se a chamada foi direta ou indireta. Além disso, é inserido o privilégio de função após a instrução de retorno instrumentada. Uma vez que, em geral, na instrução de retorno apenas o destino é mantido como informação, é necessário reservar um registrador para manter o endereço da parte chamadora e, portanto, verificar se o retorno é permitido pela política.
[0060] A ideia original da CFI é verificar se cada tupla da parte chamadora - parte chamada (origem e destino) são válidas. No entanto, se nenhum relaxamento for usado, esta abordagem terá um alto custo, pois é necessário pesquisar em tempo de execução (runtime) em uma estrutura de dados por uma tupla especifica. Portanto, uma CFI mais viável é necessária se o aprimoramento de segurança é desejado.
[0061] Ao empregar o método da presente invenção, o desempenho do binário é mantido, uma vez que a verificação de política é simples; ela pode ser apenas uma verificação se o privilégio de parte chamadora for menor do que ou igual ao privilégio da parte chamada mais um. Portanto, a pesquisa dispendiosa em uma estrutura de dados no tempo de execução é evitada ao inserir instruções indefinidas (dados) no binário.
[0062] Embora a presente invenção tenha sido descrita em relação a determinadas concretizações preferidas, deve ser entendido que não se pretende limitar a invenção a tais concretizações particulares. Pelo contrário, pretende-se abranger todas as alternativas, modificações e equivalências possíveis dentro do espirito e escopo da invenção, conforme definido pelas reivindicações anexas.

Claims (5)

  1. Método para forçar a execução de Integridade de Fluxo de Controle (CFI) em um binário monolítico usando análise estática caracterizado pelo fato de que compreende as etapas de:
    • - marcar algumas funções avaliadas como funções de núcleo por uma heurística escolhida ou empiricamente;
    • - gerar o gráfico de chamadas binárias;
    • - se o gráfico de chamadas binário da análise estática estiver incompleto, então:
    definir o privilégio 2 para funções com estimativa incompleta;
    definir o privilégio ad hoc para funções específicas;
    • - gerar a política;
    • - agrupar todos os nós de função das funções de núcleo como um nó de maior privilégio (conjunto 0);
    • - agrupar todas as funções leaf em um nó sem privilégio (conjunto n);
    • - agrupar todos os nós sem privilégios que alcançam funções de privilégio i e definir o privilégio do nó agrupado para i + 1;
    • - verificar se existe um nó sem privilégio além da função trivial;
    em caso positivo, retornar para a etapa anterior de agrupar todos os nós sem privilégio e configurar o privilégio do nó agrupado para i + 1;
    em caso negativo, definir o privilégio das funções triviais como i + 2.
  2. Método, de acordo com a reivindicação 1, caracterizado pelo fato de que o privilégio de função é colocado após cada chamada direta ou indireta.
  3. Método, de acordo com a reivindicação 1, caracterizado pelo fato de que um registrador reservado é usado se a proteção contra ROP for usada.
  4. Método, de acordo com a reivindicação 1, caracterizado pelo fato de que o privilégio de cada função é colocado antes de seu ponto de entrada.
  5. Método, de acordo com a reivindicação 1, caracterizado pelo fato de que ainda compreende a etapa de verificar se o fluxo reverso está correto usando a mesma política gerada.
BR102018077436-0A 2018-12-28 2018-12-28 método de execução forçada de integridade de controle de fluxo em um binário monolítico usando análise estática BR102018077436A2 (pt)

Priority Applications (2)

Application Number Priority Date Filing Date Title
BR102018077436-0A BR102018077436A2 (pt) 2018-12-28 2018-12-28 método de execução forçada de integridade de controle de fluxo em um binário monolítico usando análise estática
US16/376,579 US11003430B2 (en) 2018-12-28 2019-04-05 Method of enforcing control flow integrity in a monolithic binary using static analysis

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
BR102018077436-0A BR102018077436A2 (pt) 2018-12-28 2018-12-28 método de execução forçada de integridade de controle de fluxo em um binário monolítico usando análise estática

Publications (1)

Publication Number Publication Date
BR102018077436A2 true BR102018077436A2 (pt) 2020-07-07

Family

ID=71124777

Family Applications (1)

Application Number Title Priority Date Filing Date
BR102018077436-0A BR102018077436A2 (pt) 2018-12-28 2018-12-28 método de execução forçada de integridade de controle de fluxo em um binário monolítico usando análise estática

Country Status (2)

Country Link
US (1) US11003430B2 (pt)
BR (1) BR102018077436A2 (pt)

Families Citing this family (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US11336680B2 (en) * 2020-03-05 2022-05-17 Oracle International Corporation Tailored security configuration of least-privilege applications
US11537372B2 (en) * 2020-03-25 2022-12-27 ManyCore Corporation Generating compilable machine code programs from dynamic language code
US11537374B1 (en) * 2021-06-03 2022-12-27 Oracle International Corporation System and method for hot method call graph analysis

Family Cites Families (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US9177147B2 (en) * 2012-09-28 2015-11-03 Intel Corporation Protection against return oriented programming attacks
US8997256B1 (en) * 2014-03-31 2015-03-31 Terbium Labs LLC Systems and methods for detecting copied computer code using fingerprints
US10289842B2 (en) 2015-11-12 2019-05-14 Samsung Electronics Co., Ltd. Method and apparatus for protecting kernel control-flow integrity using static binary instrumentation

Also Published As

Publication number Publication date
US11003430B2 (en) 2021-05-11
US20200210161A1 (en) 2020-07-02

Similar Documents

Publication Publication Date Title
Almakhdhub et al. $\mu $ RAI: Securing Embedded Systems with Return Address Integrity
US11089016B2 (en) Secure system on chip
Mashtizadeh et al. CCFI: Cryptographically enforced control flow integrity
Seshadri et al. Pioneer: verifying code integrity and enforcing untampered code execution on legacy systems
Burow et al. Cfixx: Object type integrity for c++ virtual dispatch
US7308576B2 (en) Authenticated code module
BRPI0608821A2 (pt) inicialização segura
US20040151319A1 (en) Method and apparatus for managing a hierarchy of nodes
US20100146295A1 (en) Trusted Computing Entities
BR102018077436A2 (pt) método de execução forçada de integridade de controle de fluxo em um binário monolítico usando análise estática
US10303861B2 (en) Software diversification in external contexts
Kallenberg et al. Defeating signed bios enforcement
Silberman et al. A comparison of buffer overflow prevention implementations and weaknesses
US10866908B2 (en) System and method for probabilistic defense against remote exploitation of memory
US11194899B2 (en) Apparatus and methods for transitioning between a secure area and a less-secure area
CN115391235B (zh) 一种硬件辅助的软件安全防护方法、设备及介质
Lee et al. Demystifying Android’s Scoped Storage Defense
US11361070B1 (en) Protecting devices from remote code execution attacks
Tsantekidis et al. Efficient Monitoring of Library Call Invocation
Almakhdhub et al. uRAI: Return Address Integrity for Embedded Systems.
Ferri et al. Towards the Hypervision of Hardware-based Control Flow Integrity for Arm Platforms.
Ochoa et al. Reasoning about probabilistic defense mechanisms against remote attacks
Sahita et al. PROTECTING CRITICAL APPLICATIONS ON MOBILE PLATFORMS.
Aquilino Relevance of security features introduced in modern Windows OS
CN113742789B (zh) 数据处理方法及数据处理装置

Legal Events

Date Code Title Description
B03A Publication of a patent application or of a certificate of addition of invention [chapter 3.1 patent gazette]
B08F Application dismissed because of non-payment of annual fees [chapter 8.6 patent gazette]

Free format text: REFERENTE A 3A ANUIDADE.

B08G Application fees: restoration [chapter 8.7 patent gazette]