Apoiador Nibble Fabiano Furtado Postado Outubro 26, 2018 em 13:23 Apoiador Nibble Compartilhar Postado Outubro 26, 2018 em 13:23 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 More sharing options...
rcimatti Postado Outubro 30, 2018 em 13:14 Compartilhar Postado Outubro 30, 2018 em 13:14 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 Link para o comentário Compartilhar em outros sites More sharing options...
Apoiador Nibble Fabiano Furtado Postado Outubro 30, 2018 em 16:51 Autor Apoiador Nibble Compartilhar Postado Outubro 30, 2018 em 16:51 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 More sharing options...
rcimatti Postado Outubro 30, 2018 em 19:14 Compartilhar Postado Outubro 30, 2018 em 19:14 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 More sharing options...
Apoiador Nibble Fabiano Furtado Postado Outubro 31, 2018 em 00:48 Autor Apoiador Nibble Compartilhar Postado Outubro 31, 2018 em 00:48 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 More sharing options...
Apoiador Nibble Fabiano Furtado Postado Outubro 31, 2018 em 20:58 Autor Apoiador Nibble Compartilhar Postado Outubro 31, 2018 em 20:58 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 More sharing options...
Posts Recomendados
Arquivado
Este tópico foi arquivado e está fechado para novas respostas.