hacktricks/binary-exploitation/common-binary-protections-and-bypasses/libc-protections.md

12 KiB

Proteções Libc

{% hint style="success" %} Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

Aplicação de Alinhamento de Chunk

Malloc aloca memória em agrupamentos de 8 bytes (32 bits) ou 16 bytes (64 bits). Isso significa que o final dos chunks em sistemas de 32 bits deve alinhar com 0x8, e em sistemas de 64 bits com 0x0. O recurso de segurança verifica se cada chunk alinha corretamente nesses locais específicos antes de usar um ponteiro de um bin.

Benefícios de Segurança

A aplicação de alinhamento de chunk em sistemas de 64 bits melhora significativamente a segurança do Malloc ao limitar a colocação de chunks falsos a apenas 1 em cada 16 endereços. Isso complica os esforços de exploração, especialmente em cenários onde o usuário tem controle limitado sobre os valores de entrada, tornando os ataques mais complexos e difíceis de executar com sucesso.

  • Ataque Fastbin em __malloc_hook

As novas regras de alinhamento no Malloc também frustram um ataque clássico envolvendo o __malloc_hook. Anteriormente, os atacantes podiam manipular tamanhos de chunks para sobrescrever este ponteiro de função e ganhar execução de código. Agora, a exigência de alinhamento rigoroso garante que tais manipulações não sejam mais viáveis, fechando uma rota comum de exploração e melhorando a segurança geral.

Mistura de Ponteiros em fastbins e tcache

Mistura de Ponteiros é uma melhoria de segurança usada para proteger ponteiros Fd de fastbin e tcache em operações de gerenciamento de memória. Esta técnica ajuda a prevenir certos tipos de táticas de exploração de memória, especificamente aquelas que não requerem informações de memória vazadas ou que manipulam locais de memória diretamente em relação a posições conhecidas (sobrescritas relativas).

O núcleo desta técnica é uma fórmula de ofuscação:

New_Ptr = (L >> 12) XOR P

  • L é a Localização de Armazenamento do ponteiro.
  • P é o Ponteiro Fd de fastbin/tcache.

A razão para o deslocamento bit a bit da localização de armazenamento (L) por 12 bits para a direita antes da operação XOR é crítica. Essa manipulação aborda uma vulnerabilidade inerente à natureza determinística dos 12 bits menos significativos dos endereços de memória, que são tipicamente previsíveis devido a restrições da arquitetura do sistema. Ao deslocar os bits, a parte previsível é removida da equação, aumentando a aleatoriedade do novo ponteiro misturado e, assim, protegendo contra explorações que dependem da previsibilidade desses bits.

Esse ponteiro misturado aproveita a aleatoriedade existente fornecida pela Randomização de Layout de Espaço de Endereços (ASLR), que randomiza endereços usados por programas para dificultar a previsão do layout de memória de um processo pelos atacantes.

Desmistificar o ponteiro para recuperar o endereço original envolve usar a mesma operação XOR. Aqui, o ponteiro misturado é tratado como P na fórmula, e quando XORado com a localização de armazenamento inalterada (L), resulta na revelação do ponteiro original. Essa simetria na mistura e desmistificação garante que o sistema possa codificar e decodificar ponteiros de forma eficiente, sem sobrecarga significativa, enquanto aumenta substancialmente a segurança contra ataques que manipulam ponteiros de memória.

Benefícios de Segurança

A mistura de ponteiros visa prevenir sobrescritas parciais e totais de ponteiros na heap, uma melhoria significativa em segurança. Este recurso impacta técnicas de exploração de várias maneiras:

  1. Prevenção de Sobrescritas Relativas por Byte: Anteriormente, os atacantes podiam alterar parte de um ponteiro para redirecionar chunks da heap para diferentes locais sem conhecer endereços exatos, uma técnica evidente na exploração House of Roman sem vazamento. Com a mistura de ponteiros, tais sobrescritas relativas sem um vazamento da heap agora requerem força bruta, reduzindo drasticamente a probabilidade de sucesso.
  2. Aumento da Dificuldade de Ataques em Tcache Bin/Fastbin: Ataques comuns que sobrescrevem ponteiros de função (como __malloc_hook) manipulando entradas de fastbin ou tcache são dificultados. Por exemplo, um ataque pode envolver vazar um endereço da LibC, liberar um chunk no bin tcache e, em seguida, sobrescrever o ponteiro Fd para redirecioná-lo para __malloc_hook para execução de código arbitrário. Com a mistura de ponteiros, esses ponteiros devem ser corretamente misturados, necessitando de um vazamento da heap para manipulação precisa, elevando assim a barreira de exploração.
  3. Requisito de Vazamentos da Heap em Locais Não-Heap: Criar um chunk falso em áreas não-heap (como a pilha, seção .bss ou PLT/GOT) agora também requer um vazamento da heap devido à necessidade de mistura de ponteiros. Isso estende a complexidade de explorar essas áreas, semelhante ao requisito de manipular endereços da LibC.
  4. Vazar Endereços da Heap Torna-se Mais Desafiador: A mistura de ponteiros restringe a utilidade dos ponteiros Fd em fastbin e tcache como fontes para vazamentos de endereços da heap. No entanto, ponteiros em bins não ordenados, pequenos e grandes permanecem não misturados, portanto ainda utilizáveis para vazar endereços. Essa mudança empurra os atacantes a explorar esses bins em busca de informações exploráveis, embora algumas técnicas ainda possam permitir a desmistificação de ponteiros antes de um vazamento, embora com restrições.

Desmistificando Ponteiros com um Vazamento da Heap

{% hint style="danger" %} Para uma melhor explicação do processo verifique o post original aqui. {% endhint %}

Visão Geral do Algoritmo

A fórmula usada para misturar e desmistificar ponteiros é:

New_Ptr = (L >> 12) XOR P

Onde L é a localização de armazenamento e P é o ponteiro Fd. Quando L é deslocado para a direita por 12 bits, expõe os bits mais significativos de P, devido à natureza do XOR, que produz 0 quando os bits são XORados consigo mesmos.

Passos Chave no Algoritmo:

  1. Vazamento Inicial dos Bits Mais Significativos: Ao XORar o L deslocado com P, você efetivamente obtém os 12 bits superiores de P porque a parte deslocada de L será zero, deixando os bits correspondentes de P inalterados.
  2. Recuperação dos Bits do Ponteiro: Como o XOR é reversível, conhecer o resultado e um dos operandos permite que você calcule o outro operando. Essa propriedade é usada para deduzir todo o conjunto de bits para P ao XORar sucessivamente conjuntos conhecidos de bits com partes do ponteiro misturado.
  3. Desmistificação Iterativa: O processo é repetido, cada vez usando os novos bits descobertos de P do passo anterior para decodificar o próximo segmento do ponteiro misturado, até que todos os bits sejam recuperados.
  4. Tratamento de Bits Determinísticos: Os últimos 12 bits de L são perdidos devido ao deslocamento, mas são determinísticos e podem ser reconstruídos após o processo.

Você pode encontrar uma implementação deste algoritmo aqui: https://github.com/mdulin2/mangle

Guarda de Ponteiro

A guarda de ponteiro é uma técnica de mitigação de exploração usada no glibc para proteger ponteiros de função armazenados, particularmente aqueles registrados por chamadas de biblioteca como atexit(). Essa proteção envolve embaralhar os ponteiros XORando-os com um segredo armazenado nos dados da thread (fs:0x30) e aplicando uma rotação bit a bit. Esse mecanismo visa impedir que atacantes sequestram o fluxo de controle sobrescrevendo ponteiros de função.

Contornando a Guarda de Ponteiro com um vazamento

  1. Entendendo as Operações da Guarda de Ponteiro: O embaralhamento (mistura) de ponteiros é feito usando o macro PTR_MANGLE, que XORa o ponteiro com um segredo de 64 bits e, em seguida, realiza uma rotação à esquerda de 0x11 bits. A operação reversa para recuperar o ponteiro original é tratada por PTR_DEMANGLE.
  2. Estratégia de Ataque: O ataque é baseado em uma abordagem de texto conhecido, onde o atacante precisa conhecer tanto a versão original quanto a misturada de um ponteiro para deduzir o segredo usado para a mistura.
  3. Explorando Textos Conhecidos:
  • Identificando Ponteiros de Função Fixos: Ao examinar o código-fonte do glibc ou tabelas de ponteiros de função inicializadas (como __libc_pthread_functions), um atacante pode encontrar ponteiros de função previsíveis.
  • Calculando o Segredo: Usando um ponteiro de função conhecido, como __pthread_attr_destroy, e sua versão misturada da tabela de ponteiros de função, o segredo pode ser calculado girando para trás (rotação à direita) o ponteiro misturado e, em seguida, XORando-o com o endereço da função.
  1. Textos Alternativos: O atacante também pode experimentar misturar ponteiros com valores conhecidos, como 0 ou -1, para ver se esses produzem padrões identificáveis na memória, potencialmente revelando o segredo quando esses padrões são encontrados em dumps de memória.
  2. Aplicação Prática: Após calcular o segredo, um atacante pode manipular ponteiros de maneira controlada, essencialmente contornando a proteção da Guarda de Ponteiro em uma aplicação multithreaded com conhecimento do endereço base da libc e a capacidade de ler locais de memória arbitrários.

Referências

{% hint style="success" %} Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}