WWW2Exec - GOT/PLT
Last updated
Last updated
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
A Tabela de Deslocamento Global (GOT) é um mecanismo usado em binários vinculados dinamicamente para gerenciar os endereços de funções externas. Como esses endereços não são conhecidos até o tempo de execução (devido ao vínculo dinâmico), a GOT fornece uma maneira de atualizar dinamicamente os endereços desses símbolos externos uma vez que eles são resolvidos.
Cada entrada na GOT corresponde a um símbolo nas bibliotecas externas que o binário pode chamar. Quando uma função é chamada pela primeira vez, seu endereço real é resolvido pelo vinculador dinâmico e armazenado na GOT. Chamadas subsequentes para a mesma função usam o endereço armazenado na GOT, evitando assim a sobrecarga de resolver o endereço novamente.
A Tabela de Ligação de Procedimentos (PLT) trabalha em estreita colaboração com a GOT e serve como um trampolim para lidar com chamadas a funções externas. Quando um binário chama uma função externa pela primeira vez, o controle é passado para uma entrada na PLT associada a essa função. Esta entrada da PLT é responsável por invocar o vinculador dinâmico para resolver o endereço da função, caso ainda não tenha sido resolvido. Após o endereço ser resolvido, ele é armazenado na GOT.
Portanto, as entradas da GOT são usadas diretamente uma vez que o endereço de uma função ou variável externa é resolvido. As entradas da PLT são usadas para facilitar a resolução inicial desses endereços via o vinculador dinâmico.
Obtenha o endereço da tabela GOT com: objdump -s -j .got ./exec
Observe como após carregar o executável no GEF você pode ver as funções que estão na GOT: gef➤ x/20x 0xADDR_GOT
Usando o GEF você pode iniciar uma sessão de debugging e executar got
para ver a tabela got:
Em um binário, a GOT tem os endereços para as funções ou para a seção PLT que irá carregar o endereço da função. O objetivo desta escrita arbitrária é substituir uma entrada da GOT de uma função que será executada mais tarde com o endereço da PLT da função system
por exemplo.
Idealmente, você irá substituir a GOT de uma função que está prestes a ser chamada com parâmetros controlados por você (assim você poderá controlar os parâmetros enviados para a função system).
Se system
não for usado pelo binário, a função system não terá uma entrada na PLT. Nesse cenário, você precisará vazar primeiro o endereço da função system
e então sobrescrever a GOT para apontar para esse endereço.
Você pode ver os endereços da PLT com objdump -j .plt -d ./vuln_binary
A GOT da libc geralmente é compilada com RELRO parcial, tornando-a um bom alvo para isso, supondo que seja possível descobrir seu endereço (ASLR).
Funções comuns da libc vão chamar outras funções internas cujas GOT poderiam ser sobrescritas para obter execução de código.
Encontre mais informações sobre esta técnica aqui.
Em explorações de heap em CTFs, é comum conseguir controlar o conteúdo de chunks e em algum momento até sobrescrever a tabela GOT. Um truque simples para obter RCE se gadgets não estiverem disponíveis é sobrescrever o endereço GOT de free
para apontar para system
e escrever dentro de um chunk "/bin/sh"
. Dessa forma, quando esse chunk for liberado, ele executará system("/bin/sh")
.
Outra técnica comum é sobrescrever o endereço GOT de strlen
para apontar para system
, então se essa função for chamada com entrada do usuário, é possível passar a string "/bin/sh"
e obter um shell.
Além disso, se puts
for usado com entrada do usuário, é possível sobrescrever o endereço GOT de strlen
para apontar para system
e passar a string "/bin/sh"
para obter um shell porque puts
chamará strlen
com a entrada do usuário.
Uma maneira comum de obter RCE a partir de uma vulnerabilidade de heap é abusar de um fastbin para que seja possível adicionar a parte da tabela GOT no fast bin, assim sempre que esse chunk for alocado será possível sobrescrever o ponteiro de uma função, geralmente free
.
Então, apontando free
para system
e liberando um chunk onde foi escrito /bin/sh\x00
executará um shell.
É possível encontrar um exemplo aqui.
A proteção Full RELRO é destinada a proteger contra esse tipo de técnica resolvendo todos os endereços das funções quando o binário é iniciado e tornando a tabela GOT somente leitura após isso:
RelroAprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)