hacktricks/binary-exploitation/heap/unsorted-bin-attack.md

11 KiB

Ataque ao Unsorted Bin

Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks:

Informações Básicas

Para mais informações sobre o que é um unsorted bin, consulte esta página:

{% content-ref url="bins-and-memory-allocations.md" %} bins-and-memory-allocations.md {% endcontent-ref %}

As listas não ordenadas são capazes de escrever o endereço para unsorted_chunks (av) no endereço bk do chunk. Portanto, se um atacante puder modificar o endereço do ponteiro bk em um chunk dentro do unsorted bin, ele poderia ser capaz de escrever esse endereço em um endereço arbitrário que poderia ser útil para vazar endereços de libc ou contornar algumas defesas.

Portanto, basicamente, esse ataque permite sobrescrever um endereço arbitrário com um número grande (um endereço que poderia ser um endereço de heap ou um endereço de libc) como algum endereço de pilha que poderia ser vazado ou alguma restrição como a variável global global_max_fast para permitir a criação de fast bin bins com tamanhos maiores (e passar de um ataque unsorted bin para um ataque fast bin).

{% hint style="success" %} Analisando o exemplo fornecido em https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle e usando 0x4000 e 0x5000 em vez de 0x400 e 0x500 como tamanhos de chunk (para evitar tcaches), é possível ver que atualmente o erro malloc(): unsorted double linked list corrupted é acionado.

Portanto, esse ataque ao unsorted bin agora (entre outras verificações) também requer ser capaz de corrigir a lista duplamente encadeada para que isso seja contornado victim->bck->fd == victim ou não victim->fd == av (arena). O que significa que o endereço onde queremos escrever deve ter o endereço do chunk falso em sua posição fd e que o fd do chunk falso está apontando para a arena. {% endhint %}

{% hint style="danger" %} Observe que esse ataque corrompe o unsorted bin (portanto, também o small e o large). Portanto, agora só podemos usar alocações do fast bin (um programa mais complexo pode fazer outras alocações e travar), e para acionar isso devemos alocar o mesmo tamanho ou o programa travará.

Observe que fazer global_max_fast pode ajudar nesse caso, confiando que o fast bin será capaz de lidar com todas as outras alocações até que a exploração seja concluída. {% endhint %}

O código de guyinatuxedo explica muito bem, embora se você modificar os mallocs para alocar memória grande o suficiente para não terminar em um tcache, você verá que o erro mencionado anteriormente aparece, impedindo essa técnica: malloc(): unsorted double linked list corrupted

Ataque de Vazamento de Informações do Unsorted Bin

Este é na verdade um conceito muito básico. Os chunks no unsorted bin terão ponteiros duplos para criar o bin. O primeiro chunk no unsorted bin terá na verdade os links FD e BK apontando para uma parte da arena principal (libc).
Portanto, se você pode colocar um chunk dentro de um unsorted bin e lê-lo (uso após liberação) ou alocá-lo novamente sem sobrescrever pelo menos 1 dos ponteiros para então ler ele, você pode ter um vazamento de informações da libc.

Um ataque semelhante usado neste artigo, foi abusar de uma estrutura de 4 chunks (A, B, C e D - D é apenas para evitar a consolidação com o chunk superior) então um estouro de byte nulo em B foi usado para fazer C indicar que B estava inutilizado. Além disso, em B os dados prev_size foram modificados para que o tamanho, em vez de ser o tamanho de B, fosse A+B.
Então C foi desalocado e consolidado com A+B (mas B ainda estava em uso). Um novo chunk de tamanho A foi alocado e então os endereços vazados da libc foram escritos em B de onde foram vazados.

Referências e Outros Exemplos

  • https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap
  • O objetivo é sobrescrever uma variável global com um valor maior que 4869 para ser possível obter a flag e o PIE não estar habilitado.
  • É possível gerar chunks de tamanhos arbitrários e há um estouro de heap com o tamanho desejado.
  • O ataque começa criando 3 chunks: chunk0 para abusar do estouro, chunk1 para ser estourado e chunk2 para que o chunk superior não consolide os anteriores.
  • Em seguida, o chunk1 é liberado e o chunk0 é estourado para que o ponteiro bk do chunk1 aponte para: bk = mágica - 0x10
  • Em seguida, o chunk3 é alocado com o mesmo tamanho que o chunk1, o que acionará o ataque ao unsorted bin e modificará o valor da variável global, tornando possível obter a flag.
  • https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html
  • A função de mesclagem é vulnerável porque se ambos os índices passados forem iguais, ele realocará nele e então o liberará, mas retornando um ponteiro para essa região liberada que pode ser usada.
  • Portanto, 2 chunks são criados: chunk0 que será mesclado consigo mesmo e chunk1 para evitar a consolidação com o chunk superior. Em seguida, a função de mesclagem é chamada com o chunk0 duas vezes, o que causará um uso após a liberação.
  • Em seguida, a função view é chamada com o índice 2 (que é o índice do chunk usado após a liberação), que irá vazar um endereço da libc.
  • Como o binário tem proteções para alocar apenas tamanhos maiores que global_max_fast para que nenhum fastbin seja usado, um ataque ao unsorted bin será usado para sobrescrever a variável global global_max_fast.
  • Em seguida, é possível chamar a função de edição com o índice 2 (o ponteiro usado após a liberação) e sobrescrever o ponteiro bk para apontar para p64(global_max_fast-0x10). Em seguida, criando um novo chunk usará o endereço de liberação comprometido anteriormente (0x20) e acionará o ataque ao unsorted bin sobrescrevendo o global_max_fast com um valor muito grande, permitindo agora criar chunks em fast bins.
  • Agora um ataque ao fast bin é realizado:
  • Primeiramente, é descoberto que é possível trabalhar com chunks fast de tamanho 200 na localização de __free_hook:
  • gef➤  p &__free_hook
    

$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook> gef➤ x/60gx 0x7ff1e9e607a8 - 0x59 0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200 0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000

  • Se conseguirmos obter um fast chunk de tamanho 0x200 nessa localização, será possível sobrescrever um ponteiro de função que será executado
  • Para isso, um novo chunk de tamanho 0xfc é criado e a função mesclada é chamada com esse ponteiro duas vezes, dessa forma obtemos um ponteiro para um chunk liberado de tamanho 0xfc*2 = 0x1f8 no fast bin.
  • Em seguida, a função edit é chamada nesse chunk para modificar o endereço fd desse fast bin para apontar para a função __free_hook anterior.
  • Depois, um chunk com tamanho 0x1f8 é criado para recuperar do fast bin o chunk inútil anterior, então outro chunk de tamanho 0x1f8 é criado para obter um chunk fast bin no __free_hook que é sobrescrito com o endereço da função system.
  • E finalmente um chunk contendo a string /bin/sh\x00 é liberado chamando a função delete, acionando a função __free_hook que aponta para system com /bin/sh\x00 como parâmetro.
  • CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html
  • Outro exemplo de abuso de um overflow de 1B para consolidar chunks no unsorted bin e obter um vazamento de informações da libc e depois realizar um ataque fast bin para sobrescrever o hook malloc com um endereço de one gadget
Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks: