hacktricks/reversing-and-exploiting/linux-exploiting-basic-esp/stack-overflow/ret2dlresolve.md

5.4 KiB

Ret2dlresolve

{% 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)

Support HackTricks
{% endhint %}

Informações Básicas

Como explicado na página sobre GOT/PLT e Relro, binários sem Full Relro resolverão símbolos (como endereços para bibliotecas externas) na primeira vez que forem usados. Essa resolução ocorre chamando a função _dl_runtime_resolve.

A função _dl_runtime_resolve pega do stack referências a algumas estruturas que precisa para resolver o símbolo especificado.

Portanto, é possível falsificar todas essas estruturas para fazer a resolução dinâmica do símbolo solicitado (como a função system) e chamá-la com um parâmetro configurado (por exemplo, system('/bin/sh')).

Geralmente, todas essas estruturas são falsificadas fazendo uma cadeia ROP inicial que chama read sobre uma memória gravável, então as estruturas e a string '/bin/sh' são passadas para que sejam armazenadas pela leitura em um local conhecido, e então a cadeia ROP continua chamando _dl_runtime_resolve com o endereço para $'/bin/sh'.

{% hint style="success" %} Essa técnica é útil especialmente se não houver gadgets de syscall (para usar técnicas como ret2syscall ou SROP) e não houver maneiras de vazar endereços da libc. {% endhint %}

Você pode encontrar uma explicação melhor sobre essa técnica na segunda metade do vídeo:

{% embed url="https://youtu.be/ADULSwnQs-s?feature=shared" %}

Estruturas

É necessário falsificar 3 estruturas: JMPREL, STRTAB e SYMTAB. Você tem uma explicação melhor sobre como essas são construídas em https://ir0nstone.gitbook.io/notes/types/stack/ret2dlresolve#structures

Resumo do Ataque

  1. Escrever estruturas falsas em algum lugar
  2. Definir o primeiro argumento da system ($rdi = &'/bin/sh')
  3. Definir na pilha os endereços das estruturas para chamar _dl_runtime_resolve
  4. Chamar _dl_runtime_resolve
  5. system será resolvido e chamado com '/bin/sh' como argumento

Exemplo

Você pode encontrar um exemplo dessa técnica aqui contendo uma explicação muito boa da cadeia ROP final, mas aqui está o exploit final usado:

from pwn import *

elf = context.binary = ELF('./vuln', checksec=False)
p = elf.process()
rop = ROP(elf)

# create the dlresolve object
dlresolve = Ret2dlresolvePayload(elf, symbol='system', args=['/bin/sh'])

rop.raw('A' * 76)
rop.read(0, dlresolve.data_addr) # read to where we want to write the fake structures
rop.ret2dlresolve(dlresolve)     # call .plt and dl-resolve() with the correct, calculated reloc_offset

log.info(rop.dump())

p.sendline(rop.chain())
p.sendline(dlresolve.payload)    # now the read is called and we pass all the relevant structures in

p.interactive()

Referências

{% 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)

Support HackTricks
{% endhint %}