hacktricks/binary-exploitation/heap/large-bin-attack.md
2024-12-12 13:56:11 +01:00

5 KiB

Ataque ao Large Bin

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

Outras maneiras de apoiar o HackTricks:

Informação Básica

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

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

É possível encontrar um ótimo exemplo em how2heap - large bin attack.

Basicamente aqui você pode ver como, na última versão "atual" do glibc (2.35), não é verificado: P->bk_nextsize permitindo modificar um endereço arbitrário com o valor de um chunk de large bin se certas condições forem atendidas.

Nesse exemplo, você pode encontrar as seguintes condições:

  • Um chunk grande é alocado
  • Um chunk grande menor que o primeiro, mas no mesmo índice, é alocado
  • Deve ser menor para que vá primeiro no bin
  • (Um chunk para evitar a fusão com o chunk superior é criado)
  • Em seguida, o primeiro chunk grande é liberado e um novo chunk maior do que ele é alocado -> Chunk1 vai para o large bin
  • Em seguida, o segundo chunk grande é liberado
  • Agora, a vulnerabilidade: O atacante pode modificar chunk1->bk_nextsize para [target-0x20]
  • Em seguida, um chunk maior que o chunk 2 é alocado, então o chunk2 é inserido no large bin sobrescrevendo o endereço chunk1->bk_nextsize->fd_nextsize com o endereço do chunk2

{% hint style="success" %} Existem outros cenários potenciais, a ideia é adicionar ao large bin um chunk que seja menor que um chunk X atual no bin, para que ele precise ser inserido imediatamente antes dele no bin, e precisamos ser capazes de modificar o bk_nextsize de X, pois é onde o endereço do chunk menor será escrito. {% endhint %}

Este é o código relevante do malloc. Comentários foram adicionados para entender melhor como o endereço foi sobrescrito:

{% code overflow="wrap" %}

/* if smaller than smallest, bypass loop below */
assert (chunk_main_arena (bck->bk));
if ((unsigned long) (size) < (unsigned long) chunksize_nomask (bck->bk))
{
fwd = bck; // fwd = p1
bck = bck->bk; // bck = p1->bk

victim->fd_nextsize = fwd->fd; // p2->fd_nextsize = p1->fd (Note that p1->fd is p1 as it's the only chunk)
victim->bk_nextsize = fwd->fd->bk_nextsize; // p2->bk_nextsize = p1->fd->bk_nextsize
fwd->fd->bk_nextsize = victim->bk_nextsize->fd_nextsize = victim; // p1->fd->bk_nextsize->fd_nextsize = p2
}

{% endcode %}

Isso poderia ser usado para sobrescrever a variável global global_max_fast da libc para então explorar um ataque de fast bin com chunks maiores.

Você pode encontrar outra ótima explicação desse ataque em guyinatuxedo.

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

Outras maneiras de apoiar o HackTricks: