Reversão MIPS e Golang - o básico do reverso. Resolvendo problemas para reverter com r0ot-mi. Parte 2

imagem

Neste artigo, trataremos da descompilação do binário MIPS em Ghidra e reverteremos o programa escrito em golang na AID.

Parte 1 - C, C ++ e DotNet descompilam.

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 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.

MIPS ELF


imagem

Faça o download e verifique o arquivo.

imagem

Este é um arquivo executável de 32 bits para os processadores da arquitetura MIPS. Para resolver esse problema, usaremos o Ghidra. Abra a hidra, crie um novo projeto e adicione-o ao nosso arquivo executável.

imagem

Agora abra o arquivo investigado e vá para a janela Symbol Tree. Na pesquisa, digite main para encontrar o ponto de entrada do programa.

imagem

Quando você seleciona uma função, ela é aberta imediatamente no descompilador.

imagem

Vamos converter o código.

imagem

Vemos que 64 bytes são lidos na variável local_54, vamos renomeá-la para input (tecla de atalho L) e criar uma matriz de caracteres de 64 caracteres (tecla de atalho Ctrl + L). Você também pode renomear a variável sVar1.

imagem

imagem

Após alguma conversão, o código começou a parecer um pouco mais bonito.

imagem

Analisamos o código. A string que inserimos deve ter 19 caracteres. Em que posição qual caractere deve ficar claro no código. Nesse caso, do dia 8 ao dia 17, deve ser o símbolo 'i'. Nós recuperamos, passamos a senha.

Golang basic


imagem

Nesta tarefa, somos fornecidos com um arquivo executável escrito em Go. Você pode até descobrir qual versão. Eu jogo a IDA. Deve-se dizer imediatamente que a função principal não é chamada principal, mas chamada main_main. Portanto, realizamos uma pesquisa por função e vamos para a real principal.

imagem

Vamos analisar o código. Vamos começar do começo.

imagem

Existem definições de a, key, input. O bloco esquerdo é responsável por concluir a função main_main. Considere o bloco esquerdo.

imagem

A função fmt_Scanln foi projetada para ler uma linha do console. Também observamos os dados main_statictmp_2 já salvos no programa.

imagem

Em seguida, a função runtime_stringtoslicebyte é chamada, de acordo com o código, podemos assumir que ele recebe os primeiros 6 bytes da próxima linha.

imagem

Key.ptr irá apontar para o início desta fatia. Vamos ver o que vem a seguir.

imagem

Dependendo da comparação do registro nulo r9 e do registro rsi, onde está localizado o comprimento da entrada do usuário. A partir disso, podemos concluir que r9 provavelmente será um contador. Vamos olhar para o bloco direito, para onde o controle irá, após a venda na linha que inserimos.

imagem

A função bytes_Compare é chamada e, dependendo do resultado da comparação, exibe uma das linhas.

imagem

imagem

Nós descobrimos a saída do programa, agora vamos ver as quebras de linha (no ramo esquerdo).

imagem

O caractere da entrada do usuário é inserido no registro r10 e, em seguida, há um monte de códigos complexos para comparações para controlar exceções como divisão de pânico e índice de pânico. Eu destaquei o ramo de execução do programa.

imagem

Assim, um byte de uma string especificada estaticamente é colocado no EDX e briga com r10, onde é o byte da fatia. Em seguida, o contador r9 aumenta. Provavelmente são necessários dois blocos adjacentes do meio para controlar o comprimento do corte.

Vamos combinar tudo: a linha inserida está contaminada com uma fatia e comparada com uma linha especificada estaticamente. Vamos usar o proxy para descobrir a senha correta.

imagem

Nós obtemos a resposta. A complexidade do reverso dos binários Go é que existem fatores complicadores, como a ausência de um caractere nulo no final das linhas, a apresentação de seus tipos, o coletor de lixo, etc.

Por enquanto é tudo. Para continuar ... Você pode se juntar a nós no Telegram . Lá, você pode propor seus próprios tópicos e votar na escolha de tópicos para os seguintes artigos.

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


All Articles