-
Content Count
36 -
Joined
-
Last visited
Content Type
Forums
Calendar
Treinamentos
Notícias
Artigos
Gallery
Downloads
Everything posted by Fabiano Furtado
-
Oi Fernando... primeiramente, obrigado pelo retorno. Acho que ainda não tenho essa capacidade para fazer tal análise, ainda mais de dentro da ld-linux. 😞 Quem sabe um video sobre o assunto no seu canal do YouTube? O máximo que consegui foi tirar algumas informações do dump que foi gravado: $ coredumpctl list Hint: You are currently not seeing messages from other users and the system. Users in groups 'adm', 'systemd-journal', 'wheel' can see all messages. Pass -q to turn off this notice. TIME PID UID GID SIG COREFILE EXE Wed 2018-11-14 15:56:57 -02 17737 1000 988 11 present /usr/lib/ld-2.28.so $ coredumpctl info 17737 Hint: You are currently not seeing messages from other users and the system. Users in groups 'adm', 'systemd-journal', 'wheel' can see all messages. Pass -q to turn off this notice. PID: 17737 (ld-linux-x86-64) UID: 1000 (fabianofurtado) GID: 988 (users) Signal: 11 (SEGV) Timestamp: Wed 2018-11-14 15:56:56 -02 (5min ago) Command Line: /lib64/ld-linux-x86-64.so.2 /tmp/hw64 Executable: /usr/lib/ld-2.28.so Control Group: /user.slice/user-1000.slice/session-6.scope Unit: session-6.scope Slice: user-1000.slice Session: 6 Owner UID: 1000 (fabianofurtado) Boot ID: ***** Machine ID: ***** Hostname: PC-107204 Storage: /var/lib/systemd/coredump/core.ld-linux-x86-64.1000.******.*****.lz4 Message: Process 17737 (ld-linux-x86-64) of user 1000 dumped core. Stack trace of thread 17737: #0 0x00007f293c068bc3 _dl_relocate_object (/usr/lib/ld-2.28.so) #1 0x00007f293c061397 dl_main (/usr/lib/ld-2.28.so) #2 0x00007f293c076090 _dl_sysdep_start (/usr/lib/ld-2.28.so) #3 0x00007f293c05f088 _dl_start (/usr/lib/ld-2.28.so) #4 0x00007f293c05e008 _start (/usr/lib/ld-2.28.so) Esse programa foi um "Hello World" feito em NASM.
-
Fernando, tudo bem? Tenho uma dúvida em relação a esse procedimento de hook relacionada a segurança. Muito básica, diga-se. Para que esse LD_PRELOAD foi implementado na GLIBC se, ao meu ver, só há desvantagens em relação a segurança? Quais os benefícios de se ter implementado isso? Achei muito interessante esse recurso, mas a segurança fica comprometida com ele ativado. Outra... usei o ldd para ver as dependências e a maioria das aplicações Linux linkadas dinamicamente utiliza a ld-linux-x86-64.so.2 para funcionar/carregar o binário ELF. Lendo mais sobre o assunto (1), e também demonstrado por você no artigo ( $ LD_PRELOAD=$PWD/hook.so ./ld-linux-x86-64.so.2 ./ola ), é possível executar um binário sem o bit de execução habilitado. Não entendi o motivo disso. Fiz um teste com o ld-linux-x86-64.so.2 em um binário sem dependências (linkado estaticamente) e, independentemente do estado do bit de execução, o binário não roda. Tenho um Segmentation Fault. Eu só queria uma opinião mesmo sobre essas implementações pois acho que a segurança fica muito comprometida desta maneira. Desde já agradeço. Referências: * (1) https://superuser.com/questions/341439/can-i-execute-a-linux-binary-without-the-execute-permission-bit-being-set
-
Artigo EXCELENTE! Sempre aprendo algo novo por aqui! Vou postar um comentário, pois estou com algumas dúvidas. Valeu!
-
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á.
-
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!
-
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.
-
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.
-
Curso de Engenharia Reversa Online (CERO)
Fabiano Furtado reviewed Fernando Mercês's treinamento in Treinamentos
Fala Fernando... tudo bem? Estou acompanhando de perto esse curso e deixo aqui meus parabéns! Se você pudesse falar um pouco sobre o IDA, agradeceria. Depois que vi aquele seu video, "Interagindo com o IDA / CTF Shellterlabs / Sorteio Roadsec Rio" - https://www.youtube.com/watch?v=KjQMOByFt9A, fiquei muito empolgado pois trata-se de um software muito poderoso e queria mais informações. No mais, continue com essa didática. Valeu! -
Pessoal, tudo bem? Estou estudando esse universo chamado C e desenvolvi uma aplicação simples que é um gerador genérico de chaves para um aplicativo qualquer. Ele soma os valores ASCII do array de caracteres gerado aleatoriamente e gera a chave baseado nesta soma. Bem simples. Gostaria de opiniões, críticas e sugestões. Link: https://github.com/fabianofurtado/my_keygen Agradeço desde já.
-
Gostei muito do curso, mas acho que poderia abordar mais um pouco da linguagem, através de mais videos. De qualquer maneira, recomendo este curso para todos.
-
Pessoal, acredito que todos já saibam disso pois faz parte da matemática básca, mas é interessante pensar sobre: na matemática, só existe SOMA! Eu considero que a subtração, a multiplicação e a divisão são "alias" (ou atalhos) para a soma. Por exemplo: * quando fazemos 3 - 2 = 1, estamos fazendo uma soma pois, na verdade, estamos fazendo 3 + (-2) = 1 (soma de um número positivo com um número negativo) * quando multiplicamos 3 * 2 = 6, estamos fazendo várias somas pois, na verdade, estamos fazendo 2 + 2 + 2 = 6 (estamos somando N vezes um número) Uma coisa interessante... sabemos que o resultado de 3 * 2 = 2 * 3, mas em nível de processamento, é diferente: 3 * 2 = 2 + 2 + 2 e 2 * 3 = 3 + 3 * quando dividimos 6 / 3 = 2, estamos fazendo soma pois, na verdade, estamos somando quantas vezes 3 "cabe dentro" de 6. (ou podemos pensar que a subtração é o contrário da multiplação e que a multiplicação é uma soma) Mas e daí? Qual a relação disso com a computação? Se pensarmos em um microprocessador moderno, sabemos que ele possui instruções específicas para somar e subtrair, por exemplo. Entretanto, conseguiríamos desenvolver um microprocessador mais simples somente com a instrução de soma e chegaríamos no mesmo resultado. Como dizia o Fernando Mercês, o computador é uma máquina de calcular gigante! (e que só faz soma!) É isso. Será que estou errado em pensar assim? Desde já, obrigado.