Jump to content

Fernando Mercês

Administrators
  • Posts

    1,523
  • Joined

  • Last visited

  • Days Won

    173

Everything posted by Fernando Mercês

  1. Version 1.7f

    14 downloads

    ImpRec (Imports Reconstructor) foi o mais popular reconstrutor de IAT por mais de uma década e é utilizado com executáveis PE de 32-bits até hoje, apesar de o Scylla ser o padrão atual.
  2. Maria, por favor leia: Aí edita o seu tópico pra se adaptar à essas boas práticas pra gente poder te ajudar. ?
  3. Breno, leia aqui e edite seu tópico de acordo por favor: Do contrário, vai ficar muito complicado te ajudar.
  4. Não consigo imaginar uma forma sem assinatura digital. O Zendesk teria que assinar a mensagem a meu ver, mas não sei se ele faz isso. ?
  5. Que pergunta boa. ? Eu só consigo responder de forma leviana pois tenho zero experiência na programação de compiladores, engines, etc. O que sei é que em JavaScript os arrays são objetos, logo, não são simplesmente tipos primitivos em sequência na memória como em C. Agora a parte que eu acho (por não conhecer os internals do JavaScript): Quando você declara um array em JS, você está criando um objeto (alocando memória para ele) da classe Array. Portanto, provavelmente quando você coloca nele algum elemento, você tá na real chamando um método dessa classe. A diferença é que o programador faz isso sem ver. Por exemplo: frutas = ['melão', 'maçã'] O código acima cria um objeto, uma instância da classe Array. Acredito que seja equivalente ao seguinte (passando os elementos para o método construtor): frutas = Array('melão', 'maçã') Poderia também usar o método push: frutas = Array() frutas.push('melão') frutas.push('maçã') No entanto, é mais comum utilizar a notação como no primeiro código, o que pode dar a ilusão de que o array é similar ao do C, mas não é. Em todos os casos, se você fizer typeof(frutas), vai ver que o retorno é object. Agora, os detalhes internos dessa implementação eu não faço ideia - e também imagino que depende do engine usado, porque poderia ser feito de diferentes maneiras, com diferentes estruturas de dados (listas encadeadas, hashmaps, etc) para armazenar o endereço dos tipos primitivos e objetos que são elementos do array. Aqui tem detalhes da classe Array, mas ainda não responde sua dúvida. Recomendaria você: Implementar, em C, um tipo Array que suporte push e pop de elementos. Pode ser só do tipo int ou só do tipo char* pra ficar mais legal. Você pode usar ponteiro para funções para simular os métodos. Buscar o código-fonte de algum engine de JavaScript pra ver como eles fazem. Certamente vai ser diferente de como você fez, mas o fato de você ter feito o seu próprio "gerenciador de arrays" vai te dar uma solidez no assunto, mesmo que você escolha caminhos pouco otimizados e tal. Isso pelo menos seria o que eu faria se eu quisesse entender isso profundamente, mas pode ser que alguém com conhecimento no assunto ajude mais aqui. De qualquer forma, adoraria ver aqui o teu progresso neste estudo, para todos podermos aprender contigo. ? Um abraço e boa sorte!
  6. No artigo anterior, mostrei como detectar overlays em executáveis PE. Se você não sabe o que é um overlay, é melhor ler o artigo anterior antes de seguir com esse. Hoje vamos incluir os usuários de Linux na brincadeira. ? Vamos então ver como fazemos a mesma coisa para executáveis - na verdade qualquer tipo de object file - ELF. A lógica é a mesma: primeiro, temos que descobrir como calcular o tamanho original de um executável ELF a partir de seus cabeçalhos. Então vamos dar uma olhada no executável do ls aqui, que tem 147176 bytes de tamanho: $ wc -c /bin/ls 147176 /bin/ls Claro que no seu ambiente o tamanho pode ser diferente. Agora vou criar um binário chamado novo que terá a mesma imagem, dale.jpg usada no artigo anterior, como overlay (ou seja, adicionado após o fim do arquivo). Isso pode ser feito com o comando cat, que concatena arquivos: $ cat /bin/ls dale.jpg > novo Perceba que o tamanho do arquivo novo é exatamente a soma dos tamanhos dos arquivos /bin/ls e dale.jpg: $ wc -c /bin/ls dale.jpg 147176 /bin/ls 4347 dale.jpg 151523 total $ wc -c novo 151523 novo Já temos então um ELF com overlay (dados além de seu tamanho original). Detectando overlays Para detectar um overlay no ELF, a lógica é bem similar à que usamos para os executáveis PE. A diferença é que no caso do ELF, existe um campo no cabeçalho que nos dá o offset no arquivo, ou seja, a posição no arquivo em disco, de onde começam os cabeçalhos das seções. Veja com a opção -h do readelf: $ readelf -h novo ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: DYN (Position-Independent Executable file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x6180 Start of program headers: 64 (bytes into file) Start of section headers: 145256 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 11 Size of section headers: 64 (bytes) Number of section headers: 30 Section header string table index: 29 Como nos binários ELF os cabeçalhos de seção vêm depois de seu conteúdo, é seguro assumir que o tamanho original do arquivo é calculado pela seguinte fórmula: início dos cabeçalhos de seção + tamanho do cabeçalho de seção * número de cabeçalhos de seção A mesma saída do readelf nos mostra o tamanho de cabeçalhos de seção (64) e o número de cabeçalhos de seção (30). Sendo assim, o tamanho original do arquivo é: 145256 + 64 * 30 = 147176 (0x23ee8) Logo, qualquer coisa além do byte 0x23ee7 é overlay. Dá até pra gente extrair o overlay com o dd, usando um block size (bs) do tamanho dele e a opção skip para pular exatamente um bloco: $ dd if=novo of=novo.overlay bs=147176 skip=1 0+1 records in 0+1 records out 4347 bytes (4.3 kB, 4.2 KiB) copied, 0.000570537 s, 7.6 MB/s O overlay extraído tem que ter exatamente o conteúdo de dale.jpg. Seu tamanho e hash comprovam o feito: $ wc -c novo.overlay dale.jpg 4347 novo.overlay 4347 dale.jpg 8694 total $ md5sum dale.jpg novo.overlay 84a33c81345eb161327696a8d305d728 dale.jpg 84a33c81345eb161327696a8d305d728 novo.overlay Dúvidas é só comentar. Bons estudos!
  7. Olá! Tem muitos erros que você precisa corrigir. Vamos por partes, ok? ? Você declara a variável aleatorio e a utiliza para ler a opção digitada pelo usuário, mas antes mesmo que ela assuma qualquer valor, você verifica se seu valor é menor que 1 ou maior que 6 e isso está errado. Você não pode comparar o valor de uma variável com nada antes de inicializá-la com algum valor. Te recomendo: Renomear essa variável para opcao, que faz mais sentido já que ela vai conter a opção digitada pelo usuário. Usar um bloco do...while ao invés de while. Na verdade você pês um do...while dentro de um while, o que também é desncessário neste caso. Tem muitos outros erros, mas é preciso corrigir um por vez. Aplica aí as sugestões no código e responde este tópico com o código atualizado que a gente segue. ? Boa sorte!
  8. Seria o caso de essa conta custom_123 não ter privilégios administrativos no Windows? A opção anterior deve utilizar a conta SYSTEM, que é de sistema e é usada pela maioria dos serviços. Eu imagino que o serviço do MySQL requeira privilégios administrativos. Por que não você não quer usar a opção anterior (Standard System Account)? Abraço!
  9. Davi, Dica: ao postar, você pode formatar o seu texto. Se for código, é legal formatar como código clicando no botão <>. Olha a diferença. Sem formatação como código: if (var) var = 10; Com formatação como código (mais realce em C): if (var) var = 10; É bem mais fácil que colar prints. ? O botão fica no editor: Outra dica: você pode editar sua mensagem original. Não precisa responder de novo. ? Abraço!
  10. Antes de começar, é necessário explicar o que é um overlay, já que este é um termo genérico empregado em diferentes contextos. Pois bem, na análise de malware o termo diz respeito a quaisquer dados adicionados ao final de um arquivo PE. Aqui, entenda o final do arquivo como o último byte dele. Por exemplo, tomemos o executável write.exe, do Wordpad no Windows 10. No caso aqui, criei uma cópia dele para a área de trabalho, para facilitar. Perceba que ele tem 11264 bytes: C:\Users\admin\Desktop>copy c:\Windows\System32\write.exe . 1 file(s) copied. C:\Users\admin\Desktop>dir write.exe 06/12/2019 18:29 11,264 write.exe 1 File(s) 11,264 bytes Agora vamos adicionar algo ao final do arquivo, ou seja, acrescentar algo, aumentando seu tamanho. Isso pode ser qualquer coisa. No contexto de malware, normalmente se acrescenta outros executáveis ou shellcodes, mas qualquer coisa para o nosso exemplo serve. Usarei uma imagem de 4347 bytes: C:\Users\admin\Desktop>dir dale.jpg 26/08/2022 15:40 4,347 dale.jpg 1 File(s) 4,347 bytes 0 Dir(s) 39,704,485,888 bytes free Apesar de existirem programas criados especificamente para isto chamados de binders, o próprio comando copy consegue adicionar um overlay com a opção /b e o separador +. No exemplo abaixo, crio um arquivo chamado novo.exe, que será formado pelo conteúdo do arquivo write.exe seguido do conteúdo do arquivo dale.jpg: C:\Users\admin\Desktop>copy /b write.exe + dale.jpg novo.exe write.exe dale.jpg 1 file(s) copied. O exectuável novo.exe funciona normalmente, pois possui uma cópia exata do original write.exe logo em seu início e somente depois do último byte é que começa o primeiro byte do arquivo dale.jpg. Se o write.exe possui 11264 bytes de tamanho, significa que seu conteúdo vai do byte 0 ao byte 11263. Depois disso, iniciando no byte 11264, há o conteúdo do dale.jpg, que é considerado um overlay pelas razões já explicadas. Perceba também que o tamanho do novo.exe é exatamente a soma dos tamanhos de write.exe e dale.jpg: C:\Users\admin\Desktop>dir write.exe dale.jpg 06/12/2019 18:29 11,264 write.exe 26/08/2022 15:40 4,347 dale.jpg 2 File(s) 15,611 bytes C:\Users\admin\Desktop>dir novo.exe 26/08/2022 15:44 15,611 novo.exe 1 File(s) 15,611 bytes Detectando overlays Vários softwares detectam a presença de overlays. Por exemplo, ao abrir o novo.exe no DIE, ele detecta o overlay, tornando o botão abaixo clicável: DIE habilita o botão Overlay quando há dados acrescentados num aquivo PE Existe mais de uma forma de detectar a presença de overlays. A mais famosa funciona assim: Busca-se a "última" seção do executável, ou seja, a que vem depois de todas as outras, que naturalmente estará mais perto do fim do arquivo que todas as outras. Uma vez que a última seção seja identificada, anota-se o offset dela no arquivo, ou seja, onde ela começa no arquivo (não é em memória, mas sim no arquivo em disco). O valor anterior é somado com o tamanho dessa seção (também em disco). O resultado é o tamanho original do arquivo. Qualquer coisa a mais no arquivo é considerado overlay. Por exemplo, para o executável novo.exe, vejamos as seções (dá no mesmo aqui olhar no write.exe) com o DIE: Informações das seções do arquivo novo.exe no DIE A seção que tiver o maior valor no campo PointerToRawData de seu cabeçalho é a última. Note que não necessiamente ela será a última seção na lista, mas normalmente é o que acontece. No caso deste binário PE, é a seção .reloc. Sendo assim, para obter o tamanho original do arquivo PE, basta somar o byte no arquivo onde a seção começa (valor de PointerToRawData) com seu tamanho no arquivo (valor de SizeOfRawData). Fazendo a conta: 0x2a00 + 0x200 = 0x2c00 (11264 em decimal) Portanto, qualquer coisa além do byte 0x2bff (que é 0x2c00 - 1) no arquivo é overlay. Exatamente por isso o DIE começa a exibir do byte 0x2c00 se você clicar no botão Overlay: DIE exibindo o overlay Executáveis contendo dados além de seu tamanho original podem levantar suspeitas, mas há usos legítimos para este recurso, como na assinatura digital. No entanto, fica a cargo da pessoa que analisa verificar o que tem no overlay e se o código do arquivo lê algo a partir de lá ou não. Quem usa YARA pode se beneficiar da sua capacidade de detectar overlays que adicionei na versão 3.6.0. Para deixar o assunto ainda mais fácil, gravei um vídeo resumindo e mostrando o que está neste artigo em ação: Bons estudos! ?
  11. Bela dica @Zemthos ? Um ponto importante que também pode abrir muitas portas é que o MSI é um OLE2, então todas essas ferramentas funcionam para abri-los e analisá-los. Abraços, pessoal!
  12. O que é Engenharia Reversa? Engenharia reversa de software é a técnica para entender como um trecho de código funciona sem possuir seu código-fonte. É aplicável em diversas áreas da tecnologia como: Análise de malware Reimplementação de software e protocolos Correção de bugs Análise de vulnerabilidades Adição/Alteração de recursos no software Proteções anti-pirataria Alguns termos e abreviações para a engenharia reversa incluem: RCE (Reverse Code Engineering), RE, e reversing. Como funciona? Quando um programa tradicional é construído, o resultado final é um arquivo executável que possui uma série de instruções em código de máquina para que o processador de determinada arquitetura possa executar. Com ajuda de software específicos, profissionais com conhecimentos dessa linguagem (em nosso caso, Assembly) podem entender como o programa funciona e, assim, estudá-lo ou até fazer alterações no mesmo. O curso Este curso é uma sólida introdução sobre Engenharia Reversa. Nele os estudantes aprendem, desde o zero e com a preocupação de entender o motivo de cada passo, como reverter programas básicos em Windows e Linux, adquirindo assim todo o conhecimento necessário para seguir seus estudos em desafios mais avançados na análise de malware e engenharia reversa de aplicações em geral. Cada tópico prático do curso é acompanhado de um ou mais exercícios para fixação do conteúdo. O que você vai aprender A Engenharia Reversa e Suas Aplicações Falando em Binário e em Hexadecimal Arquivos Arquivos Binários Cadeias de Texto ASCII e UNICODE Arquivos Executáveis Cabeçalhos e Campos Seções e Mapeamento em Memória Carregamento de Programas Introdução ao Assembly x86 Arquiteturas Registradores Instruções Básicas Funções e Pilha Debugging Básico Opcodes, Mnemônicos e Instruções Breakpoints de software e hardware Patching O instrutor @Fernando Mercês é Pesquisador de Ameaças na Trend Micro, onde atua como investigador de ciber crime, utilizando engenharia reversa e técnicas de inteligência de ameaças no time de Pesquisa de Ameaças Futuras (FTR). Criador de várias ferramentas livres na área, com frequência apresenta suas pesquisas nos principais eventos de segurança no Brasil e no exterior. É também professor e fundador da Mente Binária, uma instituição de ensino e pesquisa sem fins lucrativos comprometida com o ensino de computação no Brasil. Pré-requisitos Lógica de programação Computador próprio com: Placa de rede sem fio (na modalidade presencial). VMware Player ou Pro instalado A VM entregue é para arquitetura Intel, AMD, e compatíveis. Computadores com processadores ARM precisam emular a VM, o que deixa tudo muito lento. Se você só tiver acesso a computadores com processadores ARM, vai precisar criar sua própria VM de Windows. Capacidade para rodar uma VM de 4 GB de RAM e 60 GB de disco Última versão do Zoom (na modalidade online) Próximas turmas A confirmar
  13. Se forem válidos, é informação sensível. Pode até ser encarado como vulnerabilidade, mas possivelmente de baixo impacto. E não é de código em si né... Enfim, discutível. ?
  14. https://stniiomyjliimcgkvdszvgen3eaaoz55hreqqx6o77yvmpwt7gklffqd.onion/ Boa sorte. Espero que consigam recuperar sem precisar pagar. :( Valeu.
  15. Olá. Valeu por avisar. Não é um erro, é o comportamento padrão do editor de oferecer só os botões básicos em telas menores (celular, etc). No entanto, considerando que nosso conteúdo é técnico e muitas vezes terá código, pus o botão de código para todas as telas. ? Markdown foi um teste. Já desativei. Valeu!
  16. Olá. Não entendi sua dúvida. O que você quer exatamente? Valeu!
  17. Opa, O enunciado pede para tratar dois números inteiros. Você fez com um array (vetor) de inteiros e um inteiro. Consegue avaliar você mesmo se está de acordo ou não? Não posso responder por você. ? Abraço.
  18. Pelo que entendi aqui, basta que a função retorne o menor entre dois números inteiros, então não precisar tratar arrays? Valeu.
  19. Opa, se você precisar dos números que leu fora do loop que tá lendo, vai precisar colocá-los num array. ? Outra dica: por favor, indente seu código e use o botão se inserir código aqui do fórum. Olha a diferença: Sem indentação, nem formatação: for(i=1;i<=10;i++) { printf("\n%d\t%.2f",i,n); } m=t/u; sleep(2); return 0; Indentado e formatado como código: for(i=1;i<=10;i++) { printf("\n%d\t%.2f",i,n); } m=t/u; sleep(2); return 0; Fica bem melhor pra gente ler. ? Um abraço.
  20. Opa, tudo bem? Muito boas suas perguntas. ? Essas diretivas definem dados. Por exemplo, da documentação do FASM: Mas elas não estão limitadas apenas ao tamanho de um dado. Você também pode definir vários dados, que serão armazenados em sequência (conceito de array). Por exemplo, a seguinte diretiva define três bytes em sequência e associa o rótulo dados a ele (essa associação é como o nome de uma variável: só existe no código-fonte): dados: db 0x41, 0x42, 0x43 Outra sintaxe possível para definição dos mesmos três bytes é: dados: db 'A', 'B', 'C' Ou ainda: dados: db 'ABC' Ou: dados: db 'AB', 'C' Ou: dados: db 'AB', 0x43 E por aí vai... É o mesmo que, em C, fazer algo como: char *dados = "ABC"; Ou seja, o rótulo em Assembly será somente o endereço no segmento de dados do programa. Abraço!
×
×
  • Create New...