Jump to content

Fabiano Furtado

Apoiadores
  • Content Count

    29
  • Joined

  • Last visited

Posts posted by Fabiano Furtado


  1. Em 12/06/2019 em 13:39, Fernando Mercês disse:

    É nóis.

    Aproveitando, eu tive a ideia de extender o PEDA pra já tratar esses casos. Você - e quem mais quiser - poderia testar antes de eu enviar um possível patch pros caras? Meu fork tá em https://github.com/merces/peda

    Basicamente é carregar o binário, mesmo com símbolos removidos, e comandar start. Tem que parar na main() automagicamente. hehe

    Abraço!

    Fiz o teste com o seu PEDA, copiando o peda.py para o diretório do meu peda. Não deu muito certo.

    O resultado foi esse:

    $ gdb ./helloworld
    GNU gdb (GDB) 8.3
    Copyright (C) 2019 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
    Type "show copying" and "show warranty" for details.
    This GDB was configured as "x86_64-pc-linux-gnu".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
        <http://www.gnu.org/software/gdb/documentation/>.

    For help, type "help".
    Type "apropos word" to search for commands related to "word"...
    Reading symbols from ./helloworld...
    (No debugging symbols found in ./helloworld)
    gdb-peda$ start
    No unwaited-for children left.
    Display various information of current execution context
    Usage:
        context [reg,code,stack,all] [code/stack length]

    gdb-peda$

     

    O que estou fazendo de errado?

    Valeu.


  2. Oi Fernando... vou testar sim, mas tem que ser amanhã. Legal essa iniciativa! Vou lhe dar um retorno em breve.

    Bom... testei esse comando "info files" que você mencionou no video e deu certo, mas deu errado😞

    "Stripando" o binário com o strip, funciona, mas com o sstrip, não.

    O sstrip é um utilitário que vem no pacote elfkickers (http://www.muppetlabs.com/~breadbox/software/elfkickers.html). Enfim... parece que ele retira mais coisas do binário e o "info files" não consegue identificar o entry point. Usei o "readelf -a" para comparar e analisar os dois binários e não há nehhuma informação sobre os Section Headers no arquivo gerado pelo sstrip.

    Só para efeito comparativo, com o strip, o meu binário ficou com 6160 bytes. Com o sstrip ficou com 4144!

    Neste caso, há algum outro comando que possa ser usado no GDB?

    Valeu!


  3. Pessoal,

    preciso de uma ajuda com o GDB depurando arquivos binários stripped.

    Fiz um "Hello World!" básico em C, compilei ele com "gcc -Wall -z noseparate-code hw64.c -o hw64" e logo em seguida executei um sstrip em cima do binário.

    O parâmetro "-z noseparate-code" foi usado pra deixar o binário menor (leia o man deste parâmetro). Em tempo, o gcc compilou o binário com PIE habilitado, ou seja, a cada execução o SO aloca o programa em um endereço de memória diferente.

    Eu consegui fazer a depuração no GDB, mas precisei usar o Ghidra para descobrir os offsets do binário, uma vez que o objdump com o binário sstrip não mostra nada.

    Para isso, executei o GDB (estou usando a versão 8.3 com o peda 1.1):

       * starti --> ele executa a primeira instrução, no caso, uma instrução da lib ld-linux

       * info proc mappings --> para saber qual endereço de memória o programa foi alocado devido ao ASLR

       * breakpoint na main() --> depois de ter obtido o offset desta função com o Ghidra + informação do endereço de memória

       * continue --> fim da depuração

    Alguém conhece alguma técnica melhor que não precise do Ghidra (ou outro disassembly) para obtermos os offsets das funções?

    Desde já, agradeço.


  4. 23 horas atrás, Fernando Mercês disse:

    Beleza e você? Com funções naked? Não. 😕

    Tudo bem!

    Não precisa utilizar funções naked. Pode ser ofuscação utilizando outros métodos. Por exemplo, me lembro uma vez que você postou um artigo/comentário sobre substituição de uma insrtução call por outras equivalentes (push e jmp) para enganar o decompiler.... enfim... acho que você deve ter algum material bom sobre isso.

    Valeu!!!!


  5. Em 26/03/2019 em 05:01, Fernando Mercês disse:

    Interessante mesmo! Muito obrigado pelo post!

    Eu busquei por exemplos de uso do atributo naked, tipo de quando usar, sabe? Encontrei um caso no RTOS pra evitar salvar o contexto duas vezes, um exemplo de ofuscação meio fraco e alguns outros. Por acaso você tem alguns exemplos práticos de uso deste atributo? Tipo, em que situação eu usaria uma função pelada? 🤓

    Abraço!

    Fernando.... blza? Vc tem mais exemplos de ofuscação? Eu achei bem interessante, apesar de ser "meio fraco". :)


  6. 11 horas atrás, Fernando Mercês disse:

    Acho que por treino sim, pois realmente não vejo benefício prático do programa em si, mas posso estar perdendo algo também.

    Os compiladores inserem padding, em geral 0x00 ou 0x90 (NOP no x86) mesmo. O legal de fazer algo assim é que você vai precisar parsear o ELF, enumerar as funções e fazer seus patches. #include <elf.h> e segue o jogo. hehe

    Se fizer, posta os desenvolvimentos aqui pra gente acompanhar. 😀

    Abraço e boa sorte!

    Blza.... vou pesquisar sobre o assunto. Se sair algo, eu divulgo aqui. Obrigado!


  7. Pessoal,

    boa noite. Estava pensando em fazer um programa em C para inserir NOPs entre duas funções quaiquer da section .text de um binário ELF.

    Seria mais para fins de estudos mesmo, sem muito objetivo prático.

    Alguém já pesquisou sobre isso? Será que vale o esforço?

    Imagino que não seja algo muito fácil de se fazer, uma vez que temos várias referências de chamadas de funções dentro de um binário.

    Desde já, agradeço.


  8. Em 18/05/2019 em 08:09, fredericopissarra disse:

    Um artiguinho meu (e o follow up mostrando como montei o gráfico animado) - escritos em Agosto de 2017:

    https://bitismyth.wordpress.com/2017/08/23/estatisticamente-insignificante/

    https://bitismyth.wordpress.com/2017/08/25/o-grafico-animado-dos-sorteios-howto/

    Muito bom os artigos!!!! Realmente fica quase impossível adivinhar esses números diante de tantas possíveis combinações.


  9. Pessoal, desenvolvi recentemente 2 programas em C para gerar e filtrar números/combinações numéricas das loterias Dupla Sena e Lotofácil (eles podem ser adaptados facilmente para outros tipos de concursos, por exemplo).

    Gostaria de um feedback de vocês pois não sei se fiz da melhor forma possível. Achei a leitura do arquivo texto contendo as combinações um pouco lenta.

    Enfim... todas as críticas são bem-vindas pois tenho certeza que poderia ter feito ele de outra maneira mais otimizada.

    https://github.com/fabianofurtado/random-lottery-numbers

    Há, basicamente, duas formas de vocês o utilizarem:

    1) Através de um arquivo texto contendo as combinações (pode ser gerada no random.org)

    2) Através do parâmetro -n onde o sistema utilizará as funções srand() e rand() da libc.

    Valeu!


  10. Pessoal,

    estou estudando alguns tópicos do livro "Reversing: Secrets of Reverse Engineering" do Eldad Eilam, ano 2005, mais espeficificamente o capítulo "10- Antireversing Techniques".
    Neste capítulo há muito conteúdo, mas a dúvida é sobre o "Garbage Byte", técnica onde se coloca bytes em posições estratégias do binário para dificultar o disassembly, combinado com os métodos que os disassemblers utilizam para fazer o reversing de forma correta. O livro apresenta duas técnicas chamadas de Linear Sweep e Recursive Traversal. Segundo o autor, este exemplo do livro...

    _asm
    {
      mov eax, 2
      cmp eax, 3
      je Junk
      mov eax, After
      jmp eax
    Junk:
      _emit 0xf
    After:
      mov eax, [SomeVariable]
      push eax
      call AFunction
    }

    ... confunde os disassemblers, independentemente da técnica utilizada (Linear Sweep ou Recursive Traversal). "A razão pela qual esse truque funciona é bem trivial - porque o disassembler não tem idéia de que a sequencia mov eax, After, jmp eax é equivalente a jmp After...".

    Neste exemplo temos 2 "pegadinhas" para os disassemblers. A primeira é um jump condicional, que sempre será incondicional pois a comparação feita sempre será com constantes (2 e 3). A segunda é esse conjunto "mov eax, After, jmp eax", já citado anteriormente.

    Bem, implementar uma nova técnica de disassembler mais inteligente é muito complicado? Pelo menos uma técnica onde se consiga avaliar os saltos baseados em constantes, como no exemplo acima. Acredito que seja complexo pois este livro é de 2005 e até hoje os disassemblers não a implementaram. Alguém já teve alguma experiência com isso? Saberia me apontar a dificuldade em se implementar tal técnica?

    Em tempo, sugiro a leitura e estudo deste livro. Estou achando excelente o seu conteúdo.

    Desde já, agradeço.

    • Curtir 1

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

    • l33t 1

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

    • Curtir 1

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

    • Curtir 1

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

    • Agradecer 1
    • l33t 1

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

    • Curtir 4

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

    • Agradecer 2
    • Curtir 2
×
×
  • Create New...