Jump to content
  • News

    • Fernando Mercês
      Uma engenheira de software de Reykjavík, na Islândia, não curtiu muito quando o Twitter encerrou o suporte ao app oficial para macOS. O limite de caracteres dos posts na plataforma foi dobrado, de 140 para 280 caracteres em Setembro do ano passado, mas o app para macOS não recebeu essa atualização. Foi então que Alva fez engenharia reversa no aplicativo do Twitter e simplesmente mudou o limite imposto pelo software de 140 caracteres para 240. Como a plataforma já aceitava os tweets maiores, ela só precisava contornar este limite no software mesmo. O patch foi feito com um disassembler chamado Hopper, que Alva diz ser seu preferido para disassemblar binários escritos em Objective C, a linguagem padrão para aplicativos Apple. Mais detalhes você encontra no blogpost dela, em Inglês: Reclaim your abandonware.
      Nós aqui do Mente Binária ficamos muito felizes de ver a engenharia reversa sendo utilizada com fins criativos. Parabéns, Alva! 

    • No dia 26 de fevereiro o usuário de nick Sai Lay publicou em seu Twitter um cheat sheet sobre segmentação de memória para o Linux :

       
      Afinal, o que é um cheat sheet? Basicamente um “guia rápido”, uma “folha de consulta” para possíveis dúvidas que você possa ter sobre o assunto abordado. Este tipo de guia pode abordar diversos assuntos, desde comandos/scripts específicos para pentest até definições rápidas sobre registradores e alinhamento de memória (que é o nosso caso).
      A quantidade de informações disponíveis em um cheat sheet é enorme, mas não há sentido em ter tanta informação se não entendermos de fato o que é aquilo. Tendo em vista isto detalharemos um pouco mais um ponto em específico deste guia, deixando o resto para a sua curiosidade
      Que tal darmos uma breve olhada em uma seção? Considere o código abaixo:
      #include <stdio.h> int main(void){ printf("Isto eh um teste\n"); return 0; } Se utilizarmos o comando readelf --sections test veremos que a seção .data(seção de dados inicializados), por exemplo, tem apenas 16 bytes (em hexa):
      ... [22] .got PROGBITS 0000000000200fd8 00000fd8 0000000000000028 0000000000000008 WA 0 0 8 [23] .got.plt PROGBITS 0000000000201000 00001000 0000000000000020 0000000000000008 WA 0 0 8 [24] .data PROGBITS 0000000000201020 00001020 0000000000000010 0000000000000000 WA 0 0 8 [25] .bss NOBITS 0000000000201030 00001030 0000000000000008 0000000000000000 WA 0 0 1 … Podemos verificar o que tem nestes bytes com objdump -d -j .data test:
      test: file format elf64-x86-64 Disassembly of section .data: 0000000000201020 <__data_start>: ... 0000000000201028 <__dso_handle>: 201028: 28 10 20 00 00 00 00 00 (. ..... Mas e se nosso código fosse da seguinte forma:
      #include <stdio.h> int a = 10; int main(void){ printf("Isto eh um teste\n"); return 0; } Note que o tamanho da seção aumentou em 4 bytes, que “coinscidentemente” é o tamanho de uma variável do tipo inteiro na arquitetura onde os testes foram feitos :
      ... [23] .got.plt PROGBITS 0000000000201000 00001000 0000000000000020 0000000000000008 WA 0 0 8 [24] .data PROGBITS 0000000000201020 00001020 0000000000000014 0000000000000000 WA 0 0 8 [25] .bss NOBITS 0000000000201034 00001034 0000000000000004 0000000000000000 WA 0 0 1 [26] .comment PROGBITS 0000000000000000 00001034 … Se olharmos o que há na seção veremos o seguinte resultado:
      test: file format elf64-x86-64 Disassembly of section .data: 0000000000201020 <__data_start>: ... 0000000000201028 <__dso_handle>: 201028: 28 10 20 00 00 00 00 00 (. ..... 0000000000201030 <a>: 201030: 0a 00 00 00 .... Agora temos um valor de 4 bytes disponível para nossa variável a que possui o valor 0a em hexa (ou seja, 10 como declarado anteriormente).
       
      Caso a variável fosse, por exemplo, long long a = 10 o resultado seria:
      est: file format elf64-x86-64 Disassembly of section .data: 0000000000201020 <__data_start>: ... 0000000000201028 <__dso_handle>: 201028: 28 10 20 00 00 00 00 00 (. ..... 0000000000201030 <a>: 201030: 0a 00 00 00 00 00 00 00 .....… 8 bytes disponíveis, exatamente o valor que sizeof(long long) representa nesta arquitetura. Não ficou satisfeito ainda? Você também pode olhar as seções com o gdb(GNU Debugger) utilizando o comando maintenance info sections:
      ... [22] 0x00201000->0x00201020 at 0x00001000: .got.plt ALLOC LOAD DATA HAS_CONTE---Type <return> to continue, or q <return> to quit--- NTS [23] 0x00201020->0x00201038 at 0x00001020: .data ALLOC LOAD DATA HAS_CONTENTS [24] 0x00201038->0x00201040 at 0x00001038: .bss ALLOC [25] 0x00000000->0x0000001c at 0x00001038: .comment READONLY HAS_CONTENTS ... É extremamente interessante ir a fundo em cheat sheets como este, mais interessante ainda é montar um você mesmo, seja para uso particular ou para disponibilizar para todos. Espera, não entendeu direito os comandos, ordenação dos bytes ou algo desta notícia? Que tal assistir ao curso do CERO? A última aula fala justamente sobre o formato ELF (executáveis Linux) e sua especificação.
      Agora que sua curiosidade foi instigada, que tal aplicar seus conhecimentos sobre arquitetura de computadores e mostrar pra gente?

    • Em março do ano passado, pesquisadores da Trend Micro descobriram que o malware Winnti utilizava o Github para baixar um arquivo de configuração de seu servidor de Comando & Controle (C&C, ou C2). Mais para o fim do ano, a empresa Sucuri analisou um caso onde um minerador de criptomoeadas foi encontrado na plataforma. Agora é a vez de malware brasileiro entrar na brincadeira.
      Disfarçado seu malware de "notafiscal" como muitos outros criadores de malware brasileiros, o usuário w3afkli1001 hospedou um .rar e um .exe num repositório chamado nfiscal. Ironicamente, foi escolhida uma licença livre Apache.

      Usando a ferramenta repoget, que fiz exatamente para casos como esse, baixei todo o conteúdo de todos os repositórios deste usuário (mas só havia um mesmo):
      $ python2.7 repoget.py w3afkli1001 Creating ./w3afkli1001 directory... Cloning repositories... w3afkli1001/nfiscal Cloning gists repositories... $ cd w3afkli1001/nfiscal $ md5 * MD5 (ET78G4B6GTY8H6GFB5XCSRY846HGFB15XRHTYD46HGFB5X1HDY468HDFGB15DHY46HFB51HYD846HDBFG5.PDF.exe) = 778351a3953ed0cc081fef0a5da53358 MD5 (ET78G4B6GTY8H6GFB5XCSRY846HGFB15XRHTYD46HGFB5X1HDY468HDFGB15DHY46HFB51HYD846HDBFG5.PDF.rar) = b97861be214d9a4643571090ee8740e9 MD5 (LICENSE) = 86d3f3a95c324c9479bd8986968f4327 MD5 (Nota_Fiscal.exe) = 679dd0f68e9f25b4c57bd5bc332fb952 Olhando o log dos commits, percebe-se que o autor utilizou a interface web do Github para fazer uploads dos arquivos. Mais fácil que aprender a usar o git né? 
      $ git log commit 5e0d647a5356b861102b8fe4eacbf13d3f9c1eef (HEAD -> master, origin/master, origin/HEAD) Author: w3afkli1001 <35973712+w3afkli1001@users.noreply.github.com> Date: Thu Feb 15 14:28:19 2018 -0200 Add files via upload commit 61792bc7a8591291d2467333a5cecfc6d9505c5e Author: w3afkli1001 <35973712+w3afkli1001@users.noreply.github.com> Date: Mon Feb 5 20:14:25 2018 -0200 Add files via upload commit f03d7491f2c5369d4d6be9353d04faa8564c60dc Author: w3afkli1001 <35973712+w3afkli1001@users.noreply.github.com> Date: Mon Feb 5 20:13:00 2018 -0200 Delete ET78G4B6GTY8H6GFB5XCSRY846HGFB15XRHTYD46HGFB5X1HDY468HDFGB15DHY46HFB51HYD846HDBFG5.PDF.exe Mas por que afinal, é perigoso hospedar malware em sites como Github, Google Drive, Dropbox, etc? Acontece que muitas soluções de segurança não bloqueiam as requisições para estes sites, pois são conhecidamente sites benignos. A responsabilidade da segurança é deles, mas reconheço que é um desafio.

    • Em 2015 foi criado o projeto Kaitai Struct. Mantido até hoje o projeto engloba toda uma estrutura para trabalhar com a ideia de parsing de arquivos, tanto em disco quanto em memória.
      O segredo disto é a linguagem descritiva criada pelo projeto. O Kaitai utiliza um arquivo de texto com extensão .ksy para definir um formato. Este arquivo, após ser compilado pelo seu próprio compilador (ksc) gera um código em qualquer uma das linguagens aceitas para parsear o formato(CPP/STL, C#, Graphviz, Java, JavaScript, Perl, PHP, Python, Ruby e JSON).
      Ficou confuso? Aqui está um exemplo de um arquivo nesta linguagem descritiva:
      meta: id: microsoft_pe title: Microsoft PE (Portable Executable) file format application: Microsoft Windows endian: le ks-version: 0.7 doc-ref: http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx seq: - id: mz1 type: mz_placeholder - id: mz2 size: mz1.header_size - 0x40 - id: pe_signature contents: ["PE", 0, 0] - id: coff_hdr type: coff_header - id: optional_hdr type: optional_header size: coff_hdr.size_of_optional_header - id: sections repeat: expr repeat-expr: coff_hdr.number_of_sections type: section enums: pe_format: 0x107: rom_image 0x10b: pe32 0x20b: pe32_plus types: mz_placeholder: seq: - id: magic contents: "MZ" … Neste exemplo o arquivo está descrevendo os campos do formato PE (executáveis Windows). Alguns campos foram omitidos pois a especificação do formato PE é grande. Todos estes campos e suas definições podem ser encontrados na documentação oficial.
      Segue a definição de alguns campos:
      id: usado para identificação.
      doc-ref: usado para indicar a documentação do formato
      endian: usado para indicar o endianess (ordem dos bytes. Little-Endian no exemplo).
      seq: usado para indicar uma sequência de atributos e a ordem que serão lidos ou escritos.
       
      Sem mais delongas vamos ao que interessa, a prática. O exemplo abaixo usa a versão web do projeto:

      Para analisar um arquivo PE (que é o nosso exemplo) primeiro devemos ir no lado esquerdo onde há vários tipos de formatos em ksy, selecionar a pasta kaitai.oi/formats/executables e clicar duas vezes em microsoft_pe.ksy:

      Logo de cara podemos ver o arquivo .ksy, mas ainda não fizemos o parser. Para de fato conseguir analisar o nosso binário precisamos carregá-lo e isto é feito no botão abaixo de “Local Storage” (lugar este onde ficam os arquivos que carregamos). Há três botões, o primeiro cria um arquivo .ksy, o segundo carrega um arquivo seu para análise e o terceiro baixa um arquivo do repositório do KS:

      Aqui carreguei o Putty.exe (um binário PE) e olha só o resultado: uma árvore ao meio com todos os campos parseados e o dump do arquivo em disco à direita. Se clicarmos duas vezes em algum campo , como, por exemplo, ImageBase, podemos ver sua localização exata no arquivo, no dump:

      Legal, não é mesmo? Mais legal ainda é o fato dele gerar o código fonte usado para o parser e isso na linguagem que você escolher dentre das suportadas. No caso, escolhi C++:

      Aqui foram apresentadas apenas algumas funcionalidades deste projeto, mas fica claro o quanto isso é útil tanto para análises quanto para estudos de diversos formatos: executáveis, logs, cabeçalhos de protocolos e até mesmo arquivos .pcap.
      O Kaitai Struct também funciona em linha de comando em: Linux, Windows e macOS. Caso queira você também pode baixar o código direto do repositório do projeto e trabalhar como quiser, seja para engenharia reversa ou para aprender como programar um parser.

    • No final de 2015 o programador Mahdi Safsafi decidiu listar todas as instruções da Intel e da AMD e colocar num repositório no github vários conjuntos de instruções, incluindo SSE5 e 3DNow! Estas  estão listadas em formato XML. Segundo o autor a ideia principal é justamente essa, ter um repositório com uma lista de fácil parsing, ou seja, simples de ser lida por um script ou programa.
       
      A documentação é extremamente simples e de fácil entendimento. Foram usadas algumas notações da própria Intel para indicar, por exemplo, se uma instrução suporta certo modo de operação. Exemplo:
       
      V - Supported. I - Not supported. N.E- Indicates an instruction syntax is not encodable in 64-bit mode (it may represent part of a sequence of valid instructions in other modes).  
      Pode ser que essa notícia soe um pouco estranha pra você, que pode se perguntar: Qual seria a utilidade de uma lista parseável de instruções? Um exemplo onde esta lista pode ser útil é num script que pode analisar estes dados e ti prover informações da propria documentação em um piscar de olhos. Para exemplificar isto fiz um código em Python que simplesmente abre o arquivo XML, lê seus campos e imprime seus valores na tela de uma forma -organizada-. Veja:
      import xml.etree.ElementTree as x tree = x.parse('AZ.xml') root = tree.getroot() for child in root.iter('ins'): attr1 = child.attrib.get('x32m', None) attr2 = child.attrib.get('x64m', None) opc = child.attrib.get('openc', None) m = child.find('mnem').text arg = child.find('args').text dsc = child.find('dscrp').text print '32 bits Mode: ' + format(attr1) print '64 bits Mode: ' + format(attr2) print 'Mnemonic: ' + format(m) print 'Args: ' + format (arg) print 'Openc: ' + format(opc) print 'Description: ' + format(dsc) print '----------------------------'  
      A saída ficaria mais ou menos assim:
       
      ... 32 bits Mode:V 64 bits Mode:RVM Mnemonic:VPSRLD Args:ymm1,ymm2,xmm3/m128 Openc:None Description:Shift doublewords in ymm2 right by amount specified in xmm3/m128 while shifting in 0s. ---------------------------- 32 bits Mode:V 64 bits Mode:VMI Mnemonic:VPSRLD Args:ymm1,ymm2,imm8 Openc:None Description:Shift doublewords in ymm2 right by imm8 while shifting in 0s. ---------------------------- 32 bits Mode:V 64 bits Mode:RVM Mnemonic:VPSRLQ Args:ymm1,ymm2,xmm3/m128 Openc:None Description:Shift quadwords in ymm2 right by amount specified in xmm3/m128 while shifting in 0s. ---------------------------- 32 bits Mode:V 64 bits Mode:VMI Mnemonic:VPSRLQ Args:ymm1,ymm2,imm8 Openc:None Description:Shift quadwords in ymm2 right by imm8 while shifting in 0s. ---------------------------- 32 bits Mode:V 64 bits Mode:V Mnemonic:PSUBB Args:mm,mm/m64 Openc:None Description:Subtract packed byte integers in mm/m64 from packed byte integers in mm. ---------------------------- 32 bits Mode:V 64 bits Mode:V Mnemonic:PSUBB Args:xmm1,xmm2/m128 Openc:None Description:Subtract packed byte integers in xmm2/m128 from packed byte integers in xmm1. ---------------------------- 32 bits Mode:V 64 bits Mode:V Mnemonic:PSUBW Args:mm,mm/m64 Openc:None Description:Subtract packed word integers in mm/m64 from packed word integers in mm. ---------------------------- ...
      Isso me lembrou uma ferramenta escrita pelo Fernando chamada bashacks(mais especificamente a função bh_asminfo), onde a ideia é a mesma.
      Infelizmente o projeto que contém esta lista foi descontinuado agora no fim de 2017, mas o autor já foi rápido e iniciou um novo chamado opcodesDB, que pelo visto suporta JSON. Já pensou no tanto de coisas que poderíamos fazer com estes bancos de dados parseáveis?
       
       

    • Nesta sexta-feira a desenvolvedora de software Hex-Rays atualizou a versão do IDA, seu disassembler. A versão gratuita do IDA não era atualizada desde a versão 5.0, enquanto a versão paga seguiu passando pela 6.0, 6.5, etc até chegar à versão 7.0 atual. Como este software tem um custo alto, esta é uma notícia muito boa para estudantes e entusiastas em engenharia reversa que querem ter um gostinho de como funciona este poderoso analisador estático (ok, sabemos que o IDA também pode depurar, mas sua principal função é disassemblar código 🙂). 
      O IDA freeware está disponível para Windows, Linux e macOS e pode ser baixado aqui.
      Em breve faremos alguns vídeos sobre o uso desse disassembler, mas até lá, você já não tem desculpa pra não baixar e começar a conhecê-lo!


    • Dados os ocorridos recentes sobre vazamento de dados como o caso da Netshoes, resolvi compartilhar mais uma ferramenta, desta vez um programa em Python que recebe um endereço de e-mail como argumento e busca por leaks que o envolvam. Adicionalmente, de posse de alguma senha vazada, é possível testar o reuso de credenciais em diferentes serviços.
      O nome do software é Cr3dOv3r, disponibilizado sob a licença livre MIT. Aqui encontrei uma minha de Instagram (que não utilizo), que possui uma senha vazada anteriormente, conforme visto na imagem. Vale a pena conferir seus e-mails aí!

×
×
  • Create New...