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

74 lines
8.8 KiB
Markdown

# Unsorted Bin Attack
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
Para mais informações sobre o que é um unsorted bin, consulte esta página:
{{#ref}}
bins-and-memory-allocations.md
{{#endref}}
Listas não ordenadas podem escrever o endereço em `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 poderá **escrever esse endereço em um endereço arbitrário**, o que pode ser útil para vazar endereços do Glibc ou contornar algumas defesas.
Basicamente, esse ataque permite **definir um grande número em um endereço arbitrário**. Esse grande número é um endereço, que pode ser um endereço de heap ou um endereço do Glibc. Um alvo típico é **`global_max_fast`** para permitir a criação de bins de fast bin com tamanhos maiores (e passar de um ataque de unsorted bin para um ataque de fast bin).
> [!TIP]
> D> ar uma olhada no exemplo fornecido em [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle) e usar 0x4000 e 0x5000 em vez de 0x400 e 0x500 como tamanhos de chunk (para evitar Tcache), é possível ver que **atualmente** o erro **`malloc(): unsorted double linked list corrupted`** é acionado.
>
> Portanto, esse ataque de unsorted bin agora (entre outras verificações) também requer ser capaz de corrigir a lista duplamente encadeada, para que isso seja contornado `victim->bk->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.
> [!CAUTION]
> Note que este ataque corrompe o unsorted bin (portanto, pequeno e grande também). Portanto, só podemos **usar alocações do fast bin agora** (um programa mais complexo pode fazer outras alocações e travar), e para acionar isso devemos **alocar o mesmo tamanho ou o programa travará.**
>
> Note que sobrescrever **`global_max_fast`** pode ajudar neste caso, confiando que o fast bin será capaz de cuidar de todas as outras alocações até que a exploração seja concluída.
O código de [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) explica isso muito bem, embora se você modificar os mallocs para alocar memória grande o suficiente para não acabar em um Tcache, você pode ver que o erro mencionado anteriormente aparece, impedindo essa técnica: **`malloc(): unsorted double linked list corrupted`**
## Unsorted Bin Infoleak Attack
Este é, na verdade, um conceito muito básico. Os chunks no unsorted bin terão ponteiros. O primeiro chunk no unsorted bin terá, na verdade, os links **`fd`** e **`bk`** **apontando para uma parte da arena principal (Glibc)**.\
Portanto, se você puder **colocar um chunk dentro de um unsorted bin e lê-lo** (use after free) ou **alocá-lo novamente sem sobrescrever pelo menos 1 dos ponteiros** para então **lê-lo**, você pode ter um **vazamento de informações do Glibc**.
Um [**ataque semelhante usado neste writeup**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html) 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 overflow de byte nulo em B foi usado para fazer C indicar que B estava não utilizado. 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, em seguida, os endereços vazados da libc foram escritos em B, de onde foram vazados.
## References & Other examples
- [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap**](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 que seja possível obter a flag e o PIE não está habilitado.
- É possível gerar chunks de tamanhos arbitrários e há um overflow de heap com o tamanho desejado.
- O ataque começa criando 3 chunks: chunk0 para abusar do overflow, chunk1 para ser transbordado e chunk2 para que o chunk superior não consolide os anteriores.
- Então, chunk1 é liberado e chunk0 é transbordado para que o ponteiro `bk` de chunk1 aponte para: `bk = magic - 0x10`
- Em seguida, chunk3 é alocado com o mesmo tamanho que chunk1, o que acionará o ataque de 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**](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 o mesmo, ela fará realloc sobre ele e, em seguida, liberará, mas retornará 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. Então, a **função de mesclagem é chamada com 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), o que **vazará um endereço da libc**.
- Como o binário tem proteções para alocar apenas tamanhos maiores que **`global_max_fast`**, nenhum fastbin é usado, um ataque de unsorted bin será usado para sobrescrever a variável global `global_max_fast`.
- Então, é 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, criar um novo chunk usará o endereço livre anteriormente comprometido (0x20) que **acionará o ataque de unsorted bin**, sobrescrevendo o `global_max_fast` com um valor muito grande, permitindo agora criar chunks em fast bins.
- Agora um **ataque de fast bin** é realizado:
- Primeiro de tudo, descobre-se que é possível trabalhar com fast **chunks de tamanho 200** na localização de **`__free_hook`**:
- <pre class="language-c"><code class="lang-c">gef➤ p &__free_hook
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook>
gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
<strong>0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200
</strong>0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
</code></pre>
- Se conseguirmos obter um chunk rápido de tamanho 0x200 nesta 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, assim obtemos um ponteiro para um chunk liberado de tamanho `0xfc*2 = 0x1f8` no fast bin.
- Em seguida, a função de edição é chamada neste chunk para modificar o endereço **`fd`** deste fast bin para apontar para a função anterior **`__free_hook`**.
- Então, um chunk com tamanho `0x1f8` é criado para recuperar do fast bin o chunk inútil anterior, de modo que outro chunk de tamanho `0x1f8` seja criado para obter um chunk de fast bin na **`__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 de 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**](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, em seguida, realizar um ataque de fast bin para sobrescrever o malloc hook com um endereço de one gadget.
- [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/)
- Só podemos alocar chunks de tamanho maior que `0x100`.
- Sobrescrever `global_max_fast` usando um ataque de Unsorted Bin (funciona 1/16 vezes devido ao ASLR, porque precisamos modificar 12 bits, mas devemos modificar 16 bits).
- Ataque de Fast Bin para modificar um array global de chunks. Isso fornece uma primitiva de leitura/escrita arbitrária, que permite modificar o GOT e definir algumas funções para apontar para `system`.
{{#include ../../banners/hacktricks-training.md}}