Hook na GOT

Introdução

Estarei explicando na prática como funciona o hook na GOT, como a challenge que estarei usando de exemplo é sobre heap exploitation então será necessário um conhecimento básico sobre alocação dinâmica e conhecimento básico sobre a tabela GOT

Sem mais delongas vamos primeiro analizar o source code:

Vou dar uma breve explicação sobre o código, ele está fazendo uma struct que vai guardar um inteiro e um char, na main ele define essa struct para *i1 e *i2, para a i1 ele aloca na heap o tamanho da heapStructure, depois define o ponteiro para priority como 1, logo em seguida aloca mais 8 bytes na heap para o ponteiro name, o mesmo ocorre com i2. O strcpy não está verificando o tamanho, por conta disso o código fica vulnerável a exploração

Perceba que no final da execução da main é chamado um printf() sem formatação o compilador automatiza o printf() para puts(), perceba também que winner() não foi chamada em nenhum lugar do código, então a ideia aqui é redirecionar o fluxo para winner(), faremos isso da seguinte forma: => Vamos estourar o primeiro strcpy até chegar no ponteiro para o i2->name => Vamos sobrescrever o ponteiro com a GOT da puts com o endereço da winner, porque quando o último puts() for executado ele chamará a winner()

Vamos ver como fazemos isso, primeiramente vou ver em que lugar da heap está nosso input:

É necessário definir esse breakpoint para que o programa não encerre sua execução, agora vou executar: r AAAA BBBB

Se você estiver usando o gdb-peda use find AAAA Enfim, nosso primeiro input está em: 0xf7e69018 Vou pegar umas 30 ocorrências apartir desse endereço:

Agora chega a parte legal, perceba que em 0xf7e902c(0xf7e9028 + 0x4) temos 0xf7e6938, que é um ponteiro para o nosso segundo input, perceba que ele aponta para 0xf7e69038 que tem justamente o nosso BBBB(segundo input)

Agora vamos ver com quantos byes chegamos até esse ponteiro a conta é bem fácil só subtrair: 0xf7e902c – 0xf7e69018 = 0x14 (20 bytes) lembrando que 0xf7e69018 é o endereço do nosso primeiro input

Então com 20 bytes chegamos até o ponteiro qualquer coisa que escrevemos depois dos 20 bytes está sobrescrevendo o ponteiro

Comando executado: r $(python -c “print ‘A’*20”) $(python -c “print ‘B’*4”) Você pode notar que 0x41 são nossos A’s, e o ponteiro 0xf7e69000 aponta para os nossos B’s que são 0x42

A hook da GOT começa aqui, vamos substituir o ponteiro para puts@got, pois assim ele vai apontar para puts@got e lá sobrescrevemos para o endereço da winner(), assim quando o último printf() for executado ele irá chamar a winner(), vamos ver isso na prática

Primeiro vamos localizar o endereço da puts@got e da winner():

Vamos rodar isso: r $(python -c “print ‘A’*20 + ‘\x08\x04\xc1\x40′[::-1]”) $(python -c “print ‘\x08\x04\x88\x91′[::-1]”) obs: [::-1] é para inverter o endereço já que estamos lidando com little endian recapitulando: mandamos os A’s até chegar no ponteiro, sobrescrevemos ele com a puts@got, lá vamos sobrescrever com o endereço da winner(), ele vai resolver o endereço da winner() e da próxima vez que chamar a printf() vai chamar a nossa winner(), pois ela que foi resolvida

Então como foi dito veja que o ponteiro aponta para a puts@got elá está justamente o endereço da winner, agora quando o puts foi executado novamente ele vai chamar a winner

Exploit

Last updated