Ir para conteúdo

Protetores de Binários


Fabiano Furtado

Posts Recomendados

  • Apoiador Nibble

Pessoal,

bom dia. Estou estudando algumas técnicas de proteção de binários, me baseando no video do Fernando Mercês do Roadsec 2017 https://www.youtube.com/watch?v=cpU9U0sqzh4

Mais especificamente, em 27'29", o Fernando mostra como substituir algumas instruções por outras equivalentes, para dificultar a análise do binário.

Fiz exatamente isso, mas o programa da um Segmentation Fault após a alteração, e eu não tenho idéia do que pode ser. Alguma ajuda?

Segue o programa exemplo em C que fiz para alterar o JMP:

#include <stdio.h>
int main(void) {
  int c = 0;
  c++;
  
  if ( c == 1 ) {
    __asm__("nop");
    __asm__("nop");
    __asm__("nop");
    __asm__("nop");
    goto end;
  }

  do {
    puts("Dentro do while");
    goto end;    
  } while (1);

  puts("antes do Fim");
  
end:
  puts("Fim");
  
  return 0;
}

Compilei ele com: gcc -Wall -m32 -O0 salto.c -o salto

Seguem as linhas originais:

    11b5:       83 7d f4 01             cmp    DWORD PTR [ebp-0xc],0x1                                                    
    11b9:       75 06                   jne    11c1 <main+0x34>                                                           
    11bb:       90                      nop                                                                               
    11bc:       90                      nop                                                                               
    11bd:       90                      nop                                                                               
    11be:       90                      nop                                                                               
    11bf:       eb 13                   jmp    11d4 <main+0x47>                                                           

    11c1:       83 ec 0c                sub    esp,0xc                                                                    
    11c4:       8d 83 08 e0 ff ff       lea    eax,[ebx-0x1ff8]                                                           
    11ca:       50                      push   eax                                                                        
    11cb:       e8 60 fe ff ff          call   1030 <puts@plt>                                                            
    11d0:       83 c4 10                add    esp,0x10                                                                   
    11d3:       90                      nop                                                                               
    11d4:       83 ec 0c                sub    esp,0xc                                                                    
    11d7:       8d 83 18 e0 ff ff       lea    eax,[ebx-0x1fe8]

Seguem as linhas alteradas:

    11b9:       75 06                   jne    11c1 <main+0x34>                                                           
    11bb:       68 d4 11 00 00          push   0x11d4                                                                     
    11c0:       c3                      ret                                                                               

    11c1:       83 ec 0c                sub    esp,0xc                                                                    
    11c4:       8d 83 08 e0 ff ff       lea    eax,[ebx-0x1ff8]                                                           
    11ca:       50                      push   eax                                                                        
    11cb:       e8 60 fe ff ff          call   1030 <puts@plt>                                                            
    11d0:       83 c4 10                add    esp,0x10                                                                   
    11d3:       90                      nop                                                                               
    11d4:       83 ec 0c                sub    esp,0xc                                                                    
    11d7:       8d 83 18 e0 ff ff       lea    eax,[ebx-0x1fe8]

Alguma ajuda?

Desde já, agradeço.

Link para o comentário
Compartilhar em outros sites

  • Apoiador Nibble
3 horas atrás, rcimatti disse:

Bom dia Fabiano,

 

Fiz o teste por aqui e funcionou sem problemas, será que o endereço do push está correto? Estou anexando o print do hte mostrando a parte modificada (e funcionando), se quiser o binário me avisa.

 

Att,

Rafael

Oi Rafael, primeiramente, obrigado pelo retorno.

Você pode colocar os opcodes que você usou para as novas intruções?

Repeti o processo e ainda estou com o "Segmentation Fault".

Desde já, agradeço.

Link para o comentário
Compartilhar em outros sites

Claro, segue abaixo a saída do gdb do programa original:

   0x08048427 <+28>:    83 7d f4 01    cmp    DWORD PTR [ebp-0xc],0x1
   0x0804842b <+32>:    75 06    jne    0x8048433 <main+40>
   0x0804842d <+34>:    90    nop
   0x0804842e <+35>:    90    nop
   0x0804842f <+36>:    90    nop
   0x08048430 <+37>:    90    nop
   0x08048431 <+38>:    eb 11    jmp    0x8048444 <main+57>

   0x08048433 <+40>:    83 ec 0c    sub    esp,0xc

E do programa alterado:

   0x08048427 <+28>:    83 7d f4 01    cmp    DWORD PTR [ebp-0xc],0x1
   0x0804842b <+32>:    75 06    jne    0x8048433 <main+40>
   0x0804842d <+34>:    68 44 84 04 08    push   0x8048444
   0x08048432 <+39>:    c3    ret    

   0x08048433 <+40>:    83 ec 0c    sub    esp,0xc
 

Aproveitei pra anexar os binários aqui no post também.

 

Abs,

Rafael

salto

salto-original

Link para o comentário
Compartilhar em outros sites

  • Apoiador Nibble
5 horas atrás, rcimatti disse:

Claro, segue abaixo a saída do gdb do programa original:

.........

Aproveitei pra anexar os binários aqui no post também.

Abs,

Rafael

salto

salto-original

Rafael, descobri o que estava fazendo de errado, graças aos seus binários!!!

Estava compilando com o PIE ativado! E como o PIE é para suportar randomização de espaço de endereço (ASLR) em arquivos executáveis, coloquei um "-no-pie" na linha de compilação do gcc (gcc -Wall -no-pie -m32 -O0 salto.c -o salto) e deu certo!

Como o endereçamento é dinâmico, a probabilidade de dar um Segmentation Fault é altíssima! Desabilitando isso, resolve.

Obrigado!

Link para o comentário
Compartilhar em outros sites

  • Apoiador Nibble

Pessoal... eu queria poder utilizar essa técnica com o ALSR ativado. Então, continuando a pesquisa sobre o assunto, descobri que precisaria do valor do EIP para fazer o "jump" para o endereço randomizado. Lendo sobre isso em https://stackoverflow.com/questions/8333413/why-cant-you-set-the-instruction-pointer-directly, descobri que não tem como ler diretamente ou escrever para o EIP usando os opcodes normais. Somente as instruções JMP, CALL ou RET é que podem alterar o EIP. Desta forma, criei uma função get_eip() para alterar o EIP para fazer o JMP incondicional.

Segue o programa em C modificado:

#include <stdio.h>

void get_eip(void) {
  return;
}

int main(void) {
  int c = 0;
  c++;
  
  if ( c == 1 ) {
    get_eip(); // faz o JMP para 'end:' (goto end;)
    //goto end; // Comentei pois estou forcando o jump dentro da get_eip()
  }

  do {
    puts("Dentro do while");
    goto end;    
  } while (1);

  puts("antes do Fim");
  
end:
  puts("Fim");
  
  return 0;
}

Depois de compilar com "gcc -Wall -m32 -O0 salto.c -o salto" (utilizando ALSR), o programa ficou assim:

0000118d <get_eip>:                                                                                                  
    118d:       55                      push   ebp                                                                   
    118e:       89 e5                   mov    ebp,esp                                                               
    1190:       e8 6f 00 00 00          call   1204 <__x86.get_pc_thunk.ax>                                          
    1195:       05 6b 2e 00 00          add    eax,0x2e6b                                                            
    119a:       90                      nop                                                                          
    119b:       5d                      pop    ebp                                                                   
    119c:       c3                      ret                                                                          

0000119d <main>:                                                                                                     
    119d:       8d 4c 24 04             lea    ecx,[esp+0x4]                                                         
.....
    11c9:       75 05                   jne    11d0 <main+0x33>                                                      
    11cb:       e8 bd ff ff ff          call   118d <get_eip>                                                        
    11d0:       83 ec 0c                sub    esp,0xc                                                               
    11d3:       8d 83 08 e0 ff ff       lea    eax,[ebx-0x1ff8]
.....
Após a alteração dos opcodes, a função get_eip() ficou assim:

0000118d <get_eip>:                                                                                                  
    118d:       58                      pop    eax                               ; Retira o endereco do IP da pilha e o copia em  EAX
    118e:       05 13 00 00 00          add    eax,0x13       ; Soma o IP com 0x13 para fazer o salto de 19 instruções

    1193:       50                      push   eax                          ; Joga o novo endereço do IP na pilha
    1194:       c3                      ret                                      ; Altera o EIP e altera o fluxo para a label "end" do programa em C

Bom, resumindo, a bagaça funcionou.

Entretanto, gostaria de saber se há alguma forma mais simples de se manipular o EIP e fazer essa operação sem o uso de call.

Alguém mais experiente poderia ajudar nisso?

Obrigado desde já.

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

  • Quem Está Navegando   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.
×
×
  • Criar Novo...