hacktricks/binary-exploitation/basic-stack-binary-exploitation-methodology
2024-12-14 21:30:33 +00:00
..
tools Translated ['.github/pull_request_template.md', 'LICENSE.md', 'android-f 2024-12-14 21:30:33 +00:00
elf-tricks.md Translated ['.github/pull_request_template.md', 'LICENSE.md', 'android-f 2024-12-14 21:30:33 +00:00
README.md Translated ['.github/pull_request_template.md', 'LICENSE.md', 'android-f 2024-12-14 21:30:33 +00:00

Metodologia Básica de Exploração Binária

{% hint style="success" %} Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Suporte ao HackTricks
{% endhint %}

Informações Básicas sobre ELF

Antes de começar a explorar qualquer coisa, é interessante entender parte da estrutura de um binário ELF:

{% content-ref url="elf-tricks.md" %} elf-tricks.md {% endcontent-ref %}

Ferramentas de Exploração

{% content-ref url="tools/" %} tools {% endcontent-ref %}

Metodologia de Stack Overflow

Com tantas técnicas, é bom ter um esquema de quando cada técnica será útil. Note que as mesmas proteções afetarão diferentes técnicas. Você pode encontrar maneiras de contornar as proteções em cada seção de proteção, mas não nesta metodologia.

Controlando o Fluxo

Existem diferentes maneiras de você acabar controlando o fluxo de um programa:

  • Stack Overflows sobrescrevendo o ponteiro de retorno da pilha ou o EBP -> ESP -> EIP.
  • Pode ser necessário abusar de um Integer Overflows para causar o overflow.
  • Ou via Arbitrary Writes + Write What Where to Execution.
  • Format strings: Abuse printf para escrever conteúdo arbitrário em endereços arbitrários.
  • Array Indexing: Abuse de um indexação mal projetada para conseguir controlar alguns arrays e obter uma escrita arbitrária.
  • Pode ser necessário abusar de um Integer Overflows para causar o overflow.
  • bof para WWW via ROP: Abuse de um buffer overflow para construir um ROP e conseguir obter um WWW.

Você pode encontrar as técnicas de Write What Where to Execution em:

{% content-ref url="../arbitrary-write-2-exec/" %} arbitrary-write-2-exec {% endcontent-ref %}

Laços Eternos

Algo a ser levado em conta é que geralmente apenas uma exploração de uma vulnerabilidade pode não ser suficiente para executar um exploit bem-sucedido, especialmente algumas proteções precisam ser contornadas. Portanto, é interessante discutir algumas opções para tornar uma única vulnerabilidade explorável várias vezes na mesma execução do binário:

  • Escrever em uma cadeia ROP o endereço da função main ou o endereço onde a vulnerabilidade está ocorrendo.
  • Controlando uma cadeia ROP adequada, você pode ser capaz de realizar todas as ações nessa cadeia.
  • Escrever no endereço exit no GOT (ou qualquer outra função usada pelo binário antes de terminar) o endereço para voltar à vulnerabilidade.
  • Como explicado em .fini_array, armazene 2 funções aqui, uma para chamar a vulnerabilidade novamente e outra para chamar __libc_csu_fini que chamará novamente a função de .fini_array.

Objetivos de Exploração

Objetivo: Chamar uma Função Existente

  • ret2win: Há uma função no código que você precisa chamar (talvez com alguns parâmetros específicos) para obter a flag.
  • Em um bof regular sem PIE e canary, você só precisa escrever o endereço no endereço de retorno armazenado na pilha.
  • Em um bof com PIE, você precisará contorná-lo.
  • Em um bof com canary, você precisará contorná-lo.
  • Se você precisar definir vários parâmetros para chamar corretamente a função ret2win, você pode usar:
  • Uma cadeia ROP se houver gadgets suficientes para preparar todos os parâmetros.
  • SROP (caso você possa chamar essa syscall) para controlar muitos registradores.
  • Gadgets de ret2csu e ret2vdso para controlar vários registradores.
  • Via um Write What Where, você poderia abusar de outras vulnerabilidades (não bof) para chamar a função win.
  • Pointers Redirecting: Caso a pilha contenha ponteiros para uma função que será chamada ou para uma string que será usada por uma função interessante (system ou printf), é possível sobrescrever esse endereço.
  • ASLR ou PIE podem afetar os endereços.
  • Uninitialized variables: Você nunca sabe.

Objetivo: RCE

Via shellcode, se nx desativado ou misturando shellcode com ROP:

  • (Stack) Shellcode: Isso é útil para armazenar um shellcode na pilha antes ou depois de sobrescrever o ponteiro de retorno e então pular para ele para executá-lo:
  • Em qualquer caso, se houver um canary, em um bof regular você precisará contorná-lo (leak).
  • Sem ASLR e nx, é possível pular para o endereço da pilha, pois ele nunca mudará.
  • Com ASLR, você precisará de técnicas como ret2esp/ret2reg para pular para ele.
  • Com nx, você precisará usar algum ROP para chamar memprotect e tornar alguma página rwx, a fim de então armazenar o shellcode lá (chamando read, por exemplo) e depois pular para lá.
  • Isso misturará shellcode com uma cadeia ROP.

Via syscalls

  • Ret2syscall: Útil para chamar execve para executar comandos arbitrários. Você precisa ser capaz de encontrar os gadgets para chamar a syscall específica com os parâmetros.
  • Se ASLR ou PIE estiverem habilitados, você precisará derrotá-los para usar gadgets ROP do binário ou bibliotecas.
  • SROP pode ser útil para preparar o ret2execve.
  • Gadgets de ret2csu e ret2vdso para controlar vários registradores.

Via libc

  • Ret2lib: Útil para chamar uma função de uma biblioteca (geralmente de libc) como system com alguns argumentos preparados (por exemplo, '/bin/sh'). Você precisa que o binário carregue a biblioteca com a função que você gostaria de chamar (libc geralmente).
  • Se compilado estaticamente e sem PIE, o endereço de system e /bin/sh não vão mudar, então é possível usá-los estaticamente.
  • Sem ASLR e sabendo a versão da libc carregada, o endereço de system e /bin/sh não vão mudar, então é possível usá-los estaticamente.
  • Com ASLR mas sem PIE, sabendo a libc e com o binário usando a função system, é possível ret para o endereço de system no GOT com o endereço de '/bin/sh' no parâmetro (você precisará descobrir isso).
  • Com ASLR mas sem PIE, sabendo a libc e sem o binário usar a função system:
  • Use ret2dlresolve para resolver o endereço de system e chamá-lo.
  • Contorne ASLR e calcule o endereço de system e '/bin/sh' na memória.
  • Com ASLR e PIE e não sabendo a libc: Você precisa:
  • Contornar PIE.
  • Encontrar a versão da libc usada (leak de alguns endereços de função).
  • Verificar os cenários anteriores com ASLR para continuar.

Via EBP/RBP

  • Stack Pivoting / EBP2Ret / EBP Chaining: Controle o ESP para controlar RET através do EBP armazenado na pilha.
  • Útil para off-by-one stack overflows.
  • Útil como uma maneira alternativa de acabar controlando EIP enquanto abusa de EIP para construir o payload na memória e então pulando para ele via EBP.

Diversos

  • Pointers Redirecting: Caso a pilha contenha ponteiros para uma função que será chamada ou para uma string que será usada por uma função interessante (system ou printf), é possível sobrescrever esse endereço.
  • ASLR ou PIE podem afetar os endereços.
  • Uninitialized variables: Você nunca sabe.

{% hint style="success" %} Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Suporte ao HackTricks
{% endhint %}