Supporter - Nibble Fabiano Furtado Posted October 26, 2018 at 01:23 PM Supporter - Nibble Share Posted October 26, 2018 at 01:23 PM 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 to comment Share on other sites More sharing options...
rcimatti Posted October 30, 2018 at 01:14 PM Share Posted October 30, 2018 at 01:14 PM 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 to comment Share on other sites More sharing options...
Supporter - Nibble Fabiano Furtado Posted October 30, 2018 at 04:51 PM Author Supporter - Nibble Share Posted October 30, 2018 at 04:51 PM 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 to comment Share on other sites More sharing options...
rcimatti Posted October 30, 2018 at 07:14 PM Share Posted October 30, 2018 at 07:14 PM 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 to comment Share on other sites More sharing options...
Supporter - Nibble Fabiano Furtado Posted October 31, 2018 at 12:48 AM Author Supporter - Nibble Share Posted October 31, 2018 at 12:48 AM 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 to comment Share on other sites More sharing options...
Supporter - Nibble Fabiano Furtado Posted October 31, 2018 at 08:58 PM Author Supporter - Nibble Share Posted October 31, 2018 at 08:58 PM 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 to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.