> For the complete documentation index, see [llms.txt](https://stacked-rwx.gitbook.io/public/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://stacked-rwx.gitbook.io/public/pwning/heap0-picoctf.md).

# Heap0 - PicoCTF

O desafio me forneceu dois arquivos e uma instância para fazer uma conexão remota.

* **chall** -> binário executável
* **chall.c** -> arquivo contendo o código fonte

Analisando o programa, é possível observar que o programa aloca duas variáveis (**input\_data** e **safe\_var**), na heap. A variável **input\_data** recebe a string "**pico**" e a **safe\_var** recebe "**bico**".

De acordo com o código, a ideia é modificar o conteúdo de safe\_var que modificará o conteúdo armazenado e será imprimido no terminal.

<figure><img src="/files/m8ZiXQtq2SlWmzEtDSov" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/52l6pPvWJWuYUKuGkVvK" alt=""><figcaption></figcaption></figure>

Agora, vamos analisar a função **check\_win** que declara a nossa vitória e dropa o que tem dentro do **flag.txt**.

<figure><img src="/files/tcJgTwlSa0h8S4Sroren" alt=""><figcaption></figcaption></figure>

Analisando o código, podemos notar a função **write\_buffer** que nos permite "inputar" que serão armazenados na variável **input\_data**:

<figure><img src="/files/aGPPdNbdZHJ9JY9VqTH3" alt=""><figcaption></figcaption></figure>

Para quem é do ramo de pwning, reversing, coisas do tipo e até mesmo quem programa em C a algum tempo, sabe que a função **scanf()** não possui **boundary checks** e isso permite que um **overflow** aconteça.

O **overflow** vai acontecer justamente na variável **input\_data**, e isso permitirá sobrescrever locais de memória adjacentes, incluindo principalmente a **safe\_var**.

Vou explicar isso em duas imagens:

Antes:

<figure><img src="/files/dn1dBfzyAGoyA9sB20o6" alt=""><figcaption></figcaption></figure>

Depois:

<figure><img src="/files/1gwx5RwaBK9Uiznc23V8" alt=""><figcaption></figcaption></figure>

E para saber o comprimento exato da string necessária para sobrescrever **safe\_var**? Precisamos analisar o layout da memória usando a função "**print heap**", que revela os endereços de heap de **input\_data** e **safe\_var**.

Vem comigo!

<figure><img src="/files/oTFeku6LqHXxbK2TvEI5" alt=""><figcaption></figcaption></figure>

Para isso, peguei os dois endereços e realizei uma subtração simples e obtive o endereço **0x20** em hexadecimal.

Logo após isso, fiz uma conversão rápida para decimal e obtive o valor de **32**.

Ou seja, para sobrescrever **safe\_var**, a string precisa ser maior do que **32** bytes, no **MÍNIMO** **33** bytes.

Então inserindo um sequência de **33** caracteres ou mais, nos permitirá substituir o "**bico**" de **safe\_var** para outra coisa. Isso fará com que a função **check\_win** imprima a nossa flag.

<figure><img src="/files/2axAxtxiDqCOnxAALO1T" alt=""><figcaption></figcaption></figure>

Perfeito!

Agora o meu objetivo é repetir esse mesmo processo, só que na instância remota do picoctf.

<figure><img src="/files/kNboJUcljGuKIMPlrP7b" alt=""><figcaption></figcaption></figure>

Vejam só! Dropamos a flag.

É isso, galera! Aqui é uma forma interessante de compreender como a heap funciona e como um overflow acontece nela.

Até mais.
