Neste artigo, resolveremos a 24ª tarefa no site
pwnable.kr e aprenderemos sobre o empilhamento do quadro da pilha.
Informações OrganizacionaisEspecialmente 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 análise forense de computadores, 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.
Solução simples de trabalho de login
Continuamos 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 o login simples da assinatura. Nos é dado o endereço e a porta para conexão e o próprio programa.

Baixe tudo o que eles nos dão, verifique o binário.

Este é um elfo de 32 bits com canário instalado e pilha não executável. Nós descompilamos no IDA Pro.

No programa, os dados do usuário são decodificados a partir da base64. A variável v7 armazena o comprimento da sequência decodificada. A seguir, v7 é comparada com 12. Se o teste for aprovado, a sequência decodificada será copiada para a variável de entrada e a função de autenticação será chamada, na qual o comprimento da sequência decodificada será passado como parâmetro. E se passarmos a autenticação, a função correta será chamada. Vamos dar uma olhada na função de autenticação.

Parece um estouro de buffer. Dê uma olhada na pilha.

Não. Não podemos estourar o buffer, pois isso requer mais de 12 bytes. Os endereços em que o valor das variáveis são armazenadas são interessantes, especialmente a variável v4 na qual a cópia é executada.

Este é o endereço [ESP + 32]. Dê uma olhada no código para isso de forma desmontada.

As instruções a seguir são necessárias para salvar o quadro da pilha.
push ebp
mov ebp, espPara restaurar a pilha, use a instrução leave. Que realizamos as operações inversas.

O mais interessante é a terceira instrução
sub esp, 28h .
Assim, ocorre sobreposição: esp diminui em 40 e a variável v2 está localizada em esp + 32 e leva 12 bytes. Ou seja, depois de mover o valor de esp para ebp, o endereço dos últimos quatro bytes da variável v2 será salvo em ebp. Quando as instruções leave e retn são executadas, os últimos quatro bytes da variável v2 agora estarão no quadro alto da pilha.
Vamos verificar e fornecer a linha de entrada QUFBQUFBQUFCQkJC.

Se nossa suposição estiver correta, depois de executar retn na função auth, o topo da pilha será o endereço "BBBB".

Agora execute a licença.

Há "BBBB" no EBP e agora, após executar a licença na função principal main, o programa irá falhar. Assim, podemos diante do endereço do topo da pilha em que o endereço para o qual queremos ir será localizado. Então a carga será assim: 4 bytes + endereço para onde vamos + endereço até o início da carga.
Primeiro, escreva um modelo.
from pwn import * from base64 import * r = remote('pwnable.kr', 9003) r.recv() r.interactive()
Agora descobrimos o endereço para onde queremos ir - este é 0x8049284 dentro da função correta.

Este endereço será a segunda parte da nossa carga. A terceira parte da carga será o endereço da variável de entrada (endereço de carga).

Nós compomos a carga no código. Não esqueça de codificar em base64:
payload = "A"*4 + p32(0x8049284) + p32(0x811EB40) payload = b64encode(payload)
Código completo.
from pwn import * from base64 import * r = remote('pwnable.kr', 9003) r.recv() payload = "A"*4 + p32(0x8049284) + p32(0x811EB40) payload = b64encode(payload) r.send(payload+"\n") r.interactive()

E consiga seus pontos. Honestamente, essa tarefa não foi muito fácil para mim.

E continuamos: no próximo artigo - forense. Você pode se juntar a nós no
Telegram .