Jump to content
Não é incomum encontrar capturas de tela do Detect It Easy (DIE) em relatórios e publicações sobre análise de malware. Isso se deve a um fato: ele funciona muito bem. Mas o que talvez você não saiba é que existe um trabalho nos bastidores de criação e atualização de assinaturas que ajuda nessa eficiência. Há também, obviamente, o excepcional trabalho do @horsicq (sim, ele é membro aqui!) no desenvolvimento deste software que mudou o paradigma da detecção de compiladores, linkers, packers e protectors utilizados em arquivos executáveis. Neste artigo vou mostrar como melhorei uma assinatura existente do DIE, na esperança de te encorajar a fazer o mesmo quando se deparar com desafios similares. Partiu? 😎
Uma breve história da detecção de packers
O ano era 2001 quando snake e Qwerton, dois hackers (na época, crackers - como eram / ainda são chamadas as pessoas s que faziam engenharia reversa), liberaram a versão 0.7 Beta do PEiD. O nome vem de Portable Executable (PE) iDentifier. Ou seja, um software identificador para arquivos PE capaz de detectar se um packer fora utilizado para comprimir, ou um protector para proteger, o executável de Windows que você estava analisando. O PEiD não foi o primeiro, mas ganhou espaço e cresceu em popularidade na década de 2000. O software vinha com um banco de dados interno de assinaturas de packers e protectors, mas também permitia o uso de um arquivo externo chamado userdb.txt onde você poderia armazenar suas próprias assinaturas (e compartilhar com a galera depois). Tais assinaturas seguiam um padrão como a seguir:
[nome do packer/protector] signature = 50 E8 ?? ?? ?? ?? 58 25 ?? F0 FF FF 8B C8 83 C1 60 51 83 C0 40 83 EA 06 52 FF 20 9D C3 ep_only = trueOs bytes no campo signature eram buscados no entrypoint do binário PE caso a opção ep_only estivesse presente e configurada como true. Do contrário, a sequência de bytes era buscada em todo o binário. Os dois caracteres "??" formavam um coringa que significava "qualquer byte". Se você usa o YARA (ou o YARA-X), deve soar familiar.
Rapidamente, outros hackers começaram a popular e distribuir seus bancos de dados de assinaturas personalizadas, populando-os ao analisar binários compilados em várias linguagens, mas também binários comprimidos ou protegidos. Obviamente isso gerou uma infinidade de versões de userdb.txt pelo mundo afora e uma grande disputa para saber qual era o mais completo. Resumindo, o caos. 🤪
Por volta de 2006, surge o RDG Packer Detector v0.6.4, criado por uma pessoa conhecida por RDGMax. Rapidamente o software ganhou espaço por ter um banco de dados interno de assinaturas de muito boa qualidade.
Para suportar assinaturas personalizadas, o RDG suporta ler um userdb.txt, ou seja, ele suporta assinaturas do PEiD, um movimento bastante inteligente para que as pessoas que tinham seus próprios bancos de assinaturas criado para o PEiD pudessem reaproveitá-las no RDG, caso as assinaturas padrão dele não detectassem o que se esperava ou para casos específicos.
A última versão pública parece ter sido liberada em 2021, mas há rumores de que o desenvolvimento continua e pode ser que vejamos uma nova versão do RDG Packer Detector num futuro próximo! 😊
Em paralelo ao sucesso do RDG, em janeiro de 2013, surge a primeira versão pública do Detect It Easy (DIE). Não tenho certeza sobre as primeiras versões, mas hoje o DIE conta com modernidades interessantíssimas. Um bom exemplo é o fato de ser multiplataforma, uma vez que a onipresença do Windows ficou no passado já que nos últimos anos muitas pessoas migraram para - ou já "nasceram" usando - sistemas operacionais GNU/Linux ou macOS. Outro fator importante para o sucesso do DIE foram as assinaturas. Além de serem boas, são todas abertas, então nós podemos ver todas as assinaturas que já vêm com o software e, claro, criar as nossas baseadas nelas. Além disso, o motor é simples de usar e a linguagem para criar as assinaturas é turing-complete, ou seja, podemos declarar variáveis, fazer repetições, condicionais, cálculos, etc. Ela é implementada com QT Script/QJSEngine, o que na prática nos permite escrever assinaturas em JavaScript e isso certamente contribui para a popularização do DIE. O autor foi para o GitHub e aceita contribuições de novas assinaturas ou modificações nas existentes por lá, que é o tema deste artigo. Vamos agora ver como melhorei uma assinatura do DIE, mas este artigo também te dá as bases para criar assinaturas novas se você precisar.
O desafio
Normalmente você precisa de uma nova assinatura ou precisa modificar uma existente quando o DIE não detecta alguma característica de um binário de seu interesse. Num caso recente, usei o DIE para identificar um binário PE e ele não detectou o compilador. Suspeitei que algo estava errado e olhei a estrutura do binário. Uma das coisas que me chamou atenção no binário foi a presença das seções .pdata e .xdata, pouco comuns na minha experiência, como mostra a Figura 1:

Figura 1 - Seções do binário não detectado pelo DIE
Além disso, no binário haviam algumas ocorrências de strings bastante sugestivas, mostradas na Figura 2:

Figura 2 - Strings intrigantes no binário
Tais strings me lembraram da existência do MinGW, uma suíte de aplicativos GNU para Windows. De fato, MinGW é uma abreviação de Minimalist GNU for Windows. Na prática, você pode escrever código em C/C++ e utilizar o GCC para compilar seu programa para Windows. Compilei então um "hello, world" em C com a última versão do MinGW. A estrutura de seções ficou parecida. Testei a detecção com o DIE e o resultado foi o mesmo com o meu binário inicial: o DIE não conseguiu detectar o compilador (Figura 3).

Figura 3 - DIE não detectou o compilador do meu "hello, world" com MinGW
Decidi então investigar e tentar resolver este problema.
Inspecionando a assinatura existente
Fui na pasta do DIE e em db\PE\MinGW.4.sg encontrei a assinatura que deveria detectar o MinGW:
// DIE's signature file init("compiler","MinGW"); includeScript("FPC"); // -- corte -- function detect(bShowType,bShowVersion,bShowOptions) { if(PE.getMajorLinkerVersion()==2) { if(!bFPC&&(PE.getMinorLinkerVersion()<=30||PE.getMinorLinkerVersion()==36||PE.getMinorLinkerVersion()==56)) { if(PE.compare("'MZ'90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21'This program cannot be run in DOS mode.\r\r\n$'00000000000000'PE'0000")) { if(!PE.section[".rsrc"]) { bDetected=1; } else { var nOffset=PE.section[".rsrc"].FileOffset; var nSize=PE.section[".rsrc"].VirtualSize; if(!PE.isSignaturePresent(nOffset+nSize-512,512,"'Microsoft Corp.'")) { bDetected=1; } } } } } // -- corte -- return result(bShowType,bShowVersion,bShowOptions); }Cortei alguns trechos de código em favor da brevidade, mas o importante é saber que a função detect() é a responsável por detectar (dã!) o compilador y otras cositas más. No final, o return result() vai retornar as informações detectadas, mas estas só serão utilizadas se bDetected, que parece ser uma variável global, for true. Restava saber então qual fluxo este código estava seguindo que não chegava numa das linhas que ligava a bDetected.
Depurando a assinatura
Graças à escolha da Qt, o DIE integrou um depurador (ou debugger, se você preferir a palavra em inglês) completo para encontrar problemas na assinatura. Para acessá-lo, basta:
Clicar no botão Signatures.
Escolher a assinatura que quer depurar no menu da esquerda.
Clicar no botão Debug.
Olha que belezinha:

Figura 4 - Depurando a assinatura MinGW.4.sg do DIE no QT Script Debugger integrado
É possível colocar breakpoints, usar Step Over (F10), Step Into (F11), etc. Assim ficou fácil perceber que, com o meu binário "hello, world", a condição do segundo if não resultava em verdadeiro: (!bFPC && (PE.getMinorLinkerVersion() <= 30 || PE.getMinorLinkerVersion() 36 || PE.getMinorLinkerVersion() 56).
Essa função PE.getMinorLinkerVersion pega o campo MinorLinkVersion do cabeçalho opcional do PE, que no caso precisa ter um valor menor que 30 ou igual a 36 ou 56 para a variável bDetected ser true. Fui verificar no meu binário inicial e o valor dele neste campo era 41. Já no "hello, world" que gerei, era 44. Gerei mais alguns binários usando versões diferentes do MinGW e usei o readpe (projeto nosso! 💚) para filtrar todos os valores possíveis:
$ ls *.exe hello_cygwin32.exe hello_mingw64_ucrt.exe hello_w64devkit_x64.exe nfuncs.exe hello_cygwin64.exe hello_mingw_from_linux.exe hello_w64devkit_x86.exe hello_mingw64_msvcrt.exe hello_mingw_from_linux_stripped.exe hello_winlib_x64.exe $ (for i in *.exe; do readpe -H "$i" | grep Linker; done) | sort -u Linker major version: 2 Linker minor version: 41 Linker minor version: 44Então o caminho parecia ser esse: expandir a assinatura para cobrir os valores 41 e 44 de LinkerMinorVersion. 🤞
Atualizando a assinatura
Só um pouquinho de programação básica foi necessário para modificar a assinatura. Criei uma variável minor para não precisar chamar PE.getMinorLinkerVersion() múltiplas vezes e atualizei a condição assim:
// -- corte -- function detect(bShowType,bShowVersion,bShowOptions) { if(PE.getMajorLinkerVersion()==2) { var minor=PE.getMinorLinkerVersion(); if(!bFPC&&(minor<=30||minor==36||minor==41||minor==44||minor==56)) { // -- corte -- return result(bShowType,bShowVersion,bShowOptions); }O resultado causou aquela liberação de dopamina. Como mostrado na Figura 5, o DIE detectou o MinGW, sua versão, linguagem e tudo mais.

Figura 5 - DIE detectando corretamente o compilador MinGW usado no "hello, word"
Aproveitei e adicionei na assinatura uma informação adicional, pois percebi que quando você usa o comando strip, os dados no overlay (dados que não pertencem à nenhuma seção ou cabeçalho, após o "fim" do arquivo), são removidos. Então adicionei mais um condicional no fim:
if(bDetected) { sVersion=getMinGWVersion(); if (!PE.isOverlayPresent()) sVersion+=", stripped"; }Testei e tudo funcionou bem. Era só enviar a contribuição no GitHub né? Será? 🤔
Enviando o patch
Para minha surpresa, quando cheguei no GitHub, a assinatura estava um pouco diferente da que eu tinha em meu computador com o DIE 3.10. Acontece que o DIE está em pleno desenvolvimento e depois do release da versão 3.10, as assinaturas foram atualizadas e a API mudou um pouco (para melhor). Por sorte, o autor deixa disponível uma versão beta que usa as últimas assinaturas do GitHub. Tratei de estudar a nova assinatura e, no fim, enviei um pull request que acabou corrigindo um pequeno problema com ela: um zero a menos na comparação da PE.compare(). O PR foi aceito (obrigado, @horsicq!) com a correção e as melhorias simples que fiz para detecção do MinGW.
Conclusão
A detecção de compilador e linker é uma parte importante da engenharia reversa porque te dá um norte de que ferramentas usar, como estarão as funções (convenção de chamadas, etc), como estarão as strings (.NET usa, na maioria dos casos, UTF-16-LE por exemplo). Além disso, saber se um compressor (packer) foi utilizado ou um protector já te prepara para o que você vai encontrar no entrypoint. É uma informação útil na inteligência de ameaças também. Portanto, ter um bom software de detecção à mão é essencial. Além disso, se o software permitir, você pode melhorá-lo. Exige algum esforço, algum estudo, mas as coisas boas exigem mesmo. E há prazer em fazer tais coisas, posso te garantir.
Por fim, fica meu agradecimento a todas as pessoas que trabalharam em softwares de detecção do tipo nos últimos anos. Espero que você compartilhe dessa gratidão também. Na próxima vez que o DIE detectar corretamente o que foi usado no seu binário, agradeça a quem o desenvolveu, mas também às suas alternativas como o RDG e o PEiD. Há um trabalho comunitário grande nos bastidores para que você possa dar um duplo-clique e ter sua resposta rapidinho. E de graça.
Ah, e se por acaso seu binário tiver sido compilado pelo MinGW e o DIE detectar corretamente, agradeça a quem criou a primeira versão do MinGW.4.sg e a quem já melhorou essa assinatura que, a partir de agora, inclui a Mente Binária também. 💚

  • 561 views
Este artigo é de autoria de Thomas Lange e foi traduzido e reproduzido com autorização do autor. Link para o artigo original aqui.
TL;DR
É difícil encontrar a imagem de instalação certa do Debian. Existem milhares de arquivos ISO e imagens usadas em ambientes de nuvem, suportando múltiplas arquiteturas de CPU e vários métodos de download. A estrutura de diretórios do servidor principal de imagens é como um labirinto e as páginas da web para download também são confusas.
Fatos mais importantes deste post
https://cdimage.debian.org/cdimage
A ISO netinst mais recente
A imagem do Debian testing live com GNOME mais recente imagem do Debian testing com GNOME
Não há ISO oficial do Debian stable usando o kernel backports
O serviço web FAIme cria imagens personalizadas usando o Debian stable com um kernel mais recente
A imagem mais antiga: Other-Maybe-Official - Debian-i386 2.1 Disc 1.iso
O Labirinto do Debian
Você já procurou por uma imagem específica do Debian que não fosse a ISO netinst padrão para amd64? Quanto tempo levou para encontrá-la?
O projeto Debian é muito bom em esconder suas imagens para download ao oferecer uma enorme quantidade de versões e variantes diferentes, além de múltiplos métodos para baixá-las. O Debian também possui várias páginas na web para
Download do Debian
Instalando o Debian pela internet
Mídia de instalação do Debian USB, CD, DVD
Instalação via rede a partir do menor USB ou CD possível
Imagens de instalação live
Baixando imagens de USB/CD/DVD do Debian via HTTP/FTP
Baixando imagens de USB/CD/DVD do Debian via BitTorrent
Baixando imagens de USB/CD/DVD do Debian via jigdo
Instalando com o Debian-Installer
Este é o labirinto secreto de imagens do Debian. Atualmente, ele está repleto com mais de 8.700 imagens ISO diferentes e outros 34.000+ arquivos (raw e qcow2) para as imagens para ambientes de nuvem (cloud images).
A URL principal do servidor que hospeda todas as imagens do Debian é https://cdimage.debian.org/cdimage/
Lá você vai encontrar imagens do tipo installer, live e cloud.
Vamos tentar encontrar a imagem certa para o que você precisa
Existem três tipos diferentes de imagens:
installer: podem ser inicializadas em um computador sem nenhum sistema operacional e, em seguida, o instalador do Debian pode ser iniciado para realizar uma instalação do Debian.
live: inicializam um desktop Debian sem instalar nada nos discos locais. Você pode experimentar o Debian e, se gostar, pode usar o instalador gráfico Calamares para instalá-lo no disco local.
cloud: destinadas a executar uma máquina virtual com Debian usando QEMU, KVM, OpenStack ou na nuvem da Amazon AWS ou Microsoft Azure.
Imagens para a versão estável
Quase sempre você provavelmente está procurando a imagem para instalar a versão estável mais recente. A URL https://cdimage.debian.org/cdimage/release/ mostra:
12.9.0 12.9.0-live current current-livemas o que você não vê é que dois dos diretórios acima são na verdade links simbólicos:
current -> 12.9.0/ current-live -> 12.9.0-live/Nestes diretórios você encontrará as imagens do tipo installer e live para a versão estável (atualmente Debian 12, codinome bookworm).
Se você escolher https://cdimage.debian.org/cdimage/release/12.9.0/, verá uma lista de arquiteturas de CPU suportadas:
amd64 arm64 armel armhf i386 mips64el mipsel ppc64el s390x source trace(Em tempo, source e trace não são arquiteturas de CPU)
O usuário típico não se preocupará com a maioria das arquiteturas porque seu computador quase sempre precisará de imagens da pasta amd64.
Vamos ver o que há na pasta amd64:
bt-bd bt-cd bt-dvd iso-bd iso-cd iso-dvd jigdo-16G jigdo-bd jigdo-cd jigdo-dlbd jigdo-dvd list-16G list-bd list-cd list-dlbdUau. Isso é confuso e não há descrição do que todos essas pastas significam.
bt = BitTorrent, um protocolo de compartilhamento de arquivos ponto-a-ponto
iso = diretórios contendo arquivos ISO
jigdo = uma opção de download muito especial apenas para especialistas que sabem que realmente querem isso
list = contém listas dos nomes dos arquivos .deb que estão incluídos nas imagens
Os três primeiros são diferentes métodos de como baixar uma imagem. Use iso quando uma única conexão de rede for rápida o suficiente para você. Usar bt pode resultar em um download mais rápido porque baixa via um protocolo de compartilhamento de arquivos ponto-a-ponto. Você precisa de um programa de torrent adicional para usar essa opção.
Em seguida, temos essas variantes:
bd = disco Blu-ray (tamanho até 8GB)
cd = imagem de CD (tamanho até 700MB)
dvd = imagens de DVD (tamanho até 4.7GB)
16G = para um pen drive USB de 16GB ou maior
dlbd = disco Blu-ray de camada dupla
As imagens 16G e dlbd estão disponíveis apenas via jigdo. Todas as pastas iso-xx e bt-xx fornecem as mesmas imagens, mas com um método de acesso diferente.
Aqui estão exemplos de imagens:
iso-cd/debian-12.9.0-amd64-netinst.iso
iso-cd/debian-edu-12.9.0-amd64-netinst.iso
iso-cd/debian-mac-12.9.0-amd64-netinst.iso
Felizmente, a pasta explica em detalhes as diferenças entre essas imagens e também o que você encontra lá. Você pode ignorar os arquivos SHA... se não souber para que eles servem. Eles não são importantes para você. Esses arquivos ISO são pequenos e contêm apenas o núcleo do instalador do Debian e um pequeno conjunto de programas. Se você quiser instalar um ambiente de desktop, os outros pacotes serão baixados da internet no final da instalação.
As pastas bt-dvd e iso-dvd contêm apenas o arquivo debian-12.9.0-amd64-DVD-1.iso ou o arquivo torrent apropriado. Em bt-bd e iso-bd você encontrará apenas debian-edu-12.9.0-amd64-BD-1.iso. Essas imagens grandes contêm muito mais pacotes do Debian, então você não precisará de uma conexão de rede durante a instalação.
Para as outras arquiteturas de CPU (diferentes de amd64), o Debian fornece menos variantes de imagens, mas ainda muitas. No total, temos 44 arquivos ISO (ou torrents) para o lançamento atual do instalador do Debian para todas as arquiteturas. Ao usar jigdo, você pode escolher entre 268 imagens.
E estas são apenas as imagens do instalador para a versão estável. Nenhuma versão mais antiga ou mais recente é contada aqui.
Dê uma respirada antes de mergulharmos nas...
As imagens live
As imagens live em release/12.9.0-live/amd64/iso-hybrid/ estão disponíveis apenas para a arquitetura amd64, mas para versões mais recentes do Debian haverá imagens também para arm64.
Temos 7 imagens live diferentes contendo um dos ambientes de desktop mais comuns e uma com apenas a interface de texto (standard).
debian-live-12.9.0-amd64-xfce.iso debian-live-12.9.0-amd64-mate.iso debian-live-12.9.0-amd64-lxqt.iso debian-live-12.9.0-amd64-gnome.iso debian-live-12.9.0-amd64-lxde.iso debian-live-12.9.0-amd64-standard.iso debian-live-12.9.0-amd64-cinnamon.iso debian-live-12.9.0-amd64-kde.isoO nome da pasta iso-hybrid refere-se à tecnologia que permite usar esses arquivos ISO tanto para gravá-los em um CD/DVD/BD quanto num pen drive USB. Já bt-hybrid fornece os arquivos torrent para baixar essas mesmas imagens usando um programa cliente de torrent.
Claro! Aqui está a tradução completa do trecho:
Imagens installer e live mais recentes (também conhecidas como testing)
Para versões mais novas das imagens, atualmente temos estas pastas:
daily-builds weekly-builds weekly-live-builds trixie_di_alpha1Sugiro usar a pasta weekly-builds, porque nela você encontra uma estrutura similar e todas as variantes de imagens assim como no diretório release. Por exemplo:
weekly-builds/amd64/iso-cd/debian-testing-amd64-netinst.iso
E o mesmo vale para as imagens live:
weekly-live-builds/amd64/iso-hybrid/debian-live-testing-amd64-kde.iso weekly-live-builds/amd64/iso-hybrid/debian-live-testing-amd64-lxde.iso weekly-live-builds/amd64/iso-hybrid/debian-live-testing-amd64-debian-junior.iso weekly-live-builds/amd64/iso-hybrid/debian-live-testing-amd64-standard.iso weekly-live-builds/amd64/iso-hybrid/debian-live-testing-amd64-lxqt.iso weekly-live-builds/amd64/iso-hybrid/debian-live-testing-amd64-mate.iso weekly-live-builds/amd64/iso-hybrid/debian-live-testing-amd64-xfce.iso weekly-live-builds/amd64/iso-hybrid/debian-live-testing-amd64-gnome.iso weekly-live-builds/amd64/iso-hybrid/debian-live-testing-amd64-cinnamon.iso weekly-live-builds/arm64/iso-hybrid/debian-live-testing-arm64-gnome.isoAqui você vê uma nova variante chamada debian-junior, que é um blend do Debian. Arquivos BitTorrent não estão disponíveis para as builds semanais.
A estrutura da pasta daily-builds é diferente e fornece apenas as ISOs pequenas de instalação via rede (netinst), mas com várias versões dos últimos dias. Atualmente há 55 arquivos ISO disponíveis lá.
Se quiser usar a imagem de instalação mais recente, baixe esta:
https://cdimage.debian.org/cdimage/daily-builds/sid\_d-i/arch-latest/amd64/iso-cd/debian-testing-amd64-netinst.iso
Debian estável com kernel backports
Infelizmente, o Debian não fornece nenhuma mídia de instalação usando a versão estável com kernel backports para hardware mais recente. Isso ocorre porque o ambiente do instalador é uma mistura bastante complexa de ferramentas especiais (como o anna) e versões .udeb de pacotes.
No entanto, o serviço web FAIme, do meu projeto FAI, pode criar uma imagem de instalação personalizada usando o kernel backports. Você pode escolher um ambiente desktop, um idioma e adicionar pacotes se quiser. Depois selecione o Debian 12 (bookworm) e ative o repositório backports, incluindo o kernel mais recente. Em alguns segundos você poderá baixar sua própria imagem de instalação.
Lançamentos antigos
Geralmente, você não deve usar versões antigas para uma nova instalação. Em nosso repositório, a pasta https://cdimage.debian.org/cdimage/archive/ contém 6.163 arquivos ISO, começando do Debian 3.0 (primeiro lançamento em 2002) e incluindo todos os point releases subsequentes.
A imagem completa em DVD do oldstable (Debian 11.11.0 com firmware non-free) está aqui:
https://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/archive/latest-oldstable/amd64/iso-dvd/firmware-11.11.0-amd64-DVD-1.iso
A imagem menor, de instalação via rede (netinst), é:
https://cdimage.debian.org/cdimage/archive/11.10.0/amd64/iso-cd/debian-11.10.0-amd64-netinst.iso
A imagem ISO mais antiga que consegui encontrar é de 1999, usando o kernel 2.0.36:
Other-Maybe-Official - Debian-i386 2.1 Disc 1.iso
Ainda não consegui inicializá-la no KVM.
ATUALIZAÇÃO: obtive um kernel panic porque minha VM tinha 4GB de RAM. Reduzindo para 500MB (até 8MB funcionam), o instalador do Debian 2.1 iniciou sem problemas.
Mais alguma coisa?
Neste post, ainda não cobrimos a pasta ports (com suporte não oficial para arquiteturas de hardware antigas), que contém cerca de 760 arquivos ISO, nem a pasta unofficial (1.445 arquivos ISO), que também fornecia ISOs com firmwares non-free no passado.
Além disso, há mais de 34.000 imagens cloud. Mas, bem... não há arquivos ISO envolvidos aí. Isso pode ser assunto para uma nova publicação.
Este artigo é de autoria de Thomas Lange e foi traduzido e reproduzido com autorização do autor. Link para o artigo original aqui.
  • 945 views
Havia anos que não mexia com eletrônica, mas recentemente tirei as ferramentas da maleta e montei minha bancada de novo. Não sou especialista no assunto, mas ainda sei cortar uns fios. 🙂
Neste artigo conto como consertei uma campainha tipo gongo de alta potência, aquelas muito utilizadas em pátios de escolas. Não é bem hardware hacking né? Ou é? Bem, deixo para você decidir. O objetivo de compartilhar essa empreitada é inspirar que você faça pequenos reparos também (ou pequenos hacks, se assim preferir), economize e gere menos lixo. Afinal, numa época onde  tudo é descartável, pouco é reciclável e quase nada é reciclado, o costume de "jogar fora e comprar novo" é demasiado perigoso. Quem separa o lixo, sabe o quanto de plástico entra em casa, por exemplo. É assustador. E quase toda nova compra significa novos plásticos jogados no lixo. Além disso, tem aquele mito de que "não vale a pena consertar porque custa quase o preço de um novo". Não é sempre assim, como você verá adiante.
A campainha parou de funcionar de repente e não faço ideia do que tenha causado o problema. Fiquei curioso para entender o mecanismo dela e a abri para ver.
Para minha surpresa, a campainha tinha um circuito que, de acordo com as inscrições na placa, parecia converter 127VAC (corrente alternada) para 12VDC (corrente contínua). Eu não sabia que dava para fazer isso com um circuito tão pequeno. De qualquer forma, estava claro que um circuito integrado na placa havia fritado:

Placa original da campainha. No canto inferior esquerdo tem um Circuito Integrado (CI) partido ao meio!
A primeira coisa que fiz foi testar o motor para ver se ainda funcionava e se realmente era alimentado com 12VDC. Funcionou. Então procurei identificar o CI destruído. Era um SM7055-12, mas não o encontrei em São Paulo para comprar. Se tivesse achado, o custo do conserto seria menor que R$ 5,00, mas não rolou. Minha ideia então foi buscar a fonte de 12V (doze volts) mais barata que eu conseguisse afim de remover a placa e substituir a da campainha. Precisava ser pequena também, para caber no chassi da campainha. Achei uma de 3A por R$ 17,73 na internet que parecia ser uma boa candidata.
Testei o motor com a fonte nova de 12V e ele funcionou. Abri o chassi, removi a placa, dessoldei os terminais conectados aos plugues que vão na tomada e soldei dois fios no lugar. Então dessoldei o par de fios que iam para  a saída da fonte (para o plugue) e conectei o motor ali, como mostra a imagem a seguir.

Chassi plástico da campainha com a placa da nova fonte conectada ao motor (mas ainda não fixada no chassi)
A placa da fonte comprada era aproximadamente três vezes maior que a placa original (como conseguiram um conversor AC/DC tão pequeno?), então tive que improvisar. Com uma furadeira e uma broca bem fina, fiz um furo no plástico e pus um parafuso num orifício já existente na placa para fixá-la no compartimento plástico. Ficou firme, então fiquei tranquilo. O funcionamento você pode conferir no vídeo a seguir:
A campainha ganhou um LED azul porque não me dei o trabalho de removê-lo do circuito da placa da fonte nova, mas ficou por dentro, invisível de fora e deu um toque de gambiarra que gosto. 😄
Gastei apenas R$ 17,73 para comprar a fonte. Já uma campainha dessa nova, não sairia por menos de R$ 110,00 (exclui o frete em ambos os preços). Significou uma economia de R$ 92,97 ou 84% e menos plástico jogado fora.
Claro que eu utilizei ferramentas e materiais que eu já tinha disponíveis como:
Multímetro
Ferro de solda
Sugador de solda
Estanho
Furadeira
Fonte 12VDC (para testar o motor antes de comprar uma fonte nova)
Tais itens não entraram na conta, mas eles já foram comprados há tempos e fazem parte da pequena bancada para consertos que tenho aqui. 🙂
Um outro ponto que acho interessante de consertar as coisas: mantém nossa mente afiada e nos força a fazer algo fora da tela, o que é muito bom para nossa saúde mental também. Portanto, sempre que puder, tente um conserto. Só não se arrisque ao mexer com eletricidade sem orientação/estudo prévio. Pode ser perigoso, especialmente em altas tensões.
Happy hacking? 😄 

 
 
  • 1,588 views
Este artigo explora o funcionamento interno do sistema operacional Windows, especificamente o manipulador de syscall nt!KiSystemCall64. Nele, explico como chamadas do sistema são mecanismos cruciais que concedem ao sistema operacional solicitar serviços do kernel, permitindo operações que o próprio sistema operacional não pode executar diretamente, como a criação de arquivos no disco rígido.
O artigo investiga a distinção entre Modo Usuário (user mode) e Modo Kernel (kernel mode), ilustrando como as syscalls (abreviação de System Calls ou chamadas de sistema) preenchem a lacuna de comunicação entre esses dois modos. Por meio da análise detalhada e desmontagem do manipulador KiSystemCall64, o artigo examina a transição do modo de usuário para o modo kernel, o papel da instrução swapgs e o uso de registradores específicos de modelo (Model Specific Registers - MSRs) no processo. O estudo ainda fornece informações sobre a estrutura KUSER_SHARED_DATA, destacando sua importância na redução das mudanças de contexto. As descobertas contribuem para uma compreensão mais profunda dos componentes internos do Windows, oferecendo um guia básico para iniciantes neste campo.
Quando comecei minha jornada de estudos sobre o Windows, uma das curiosidades que eu tinha era saber como o sistema manipulava e lidava com as syscalls. Antes de falar do manipulador, vamos definir alguns conceitos básicos.
O que são as chamadas de sistema?
As chamadas de sistema são um mecanismo fornecido pelo sistema operacional para a realização de algum serviço que o sistema operacional por si só não pode realizar. Por exemplo, criar um arquivo no disco rígido. Quando um usuário clica em “Criar um novo arquivo de texto” no Windows, por trás, o que acontece é que o SO usa uma syscall para pedir ao kernel que realize o serviço. De certa forma, isso existe para proteger o SO de atividades que poderiam causar danos se o usuário viesse a operar manualmente. Falando em proteção, vamos abordar os anéis (rings) de proteção do processador, que definem o modo usuário (ring 0) e o modo kernel (ring 3).
Modo Usuário e Modo Kernel
Quando falamos em modo usuário e modo kernel, estamos nos referindo aos anéis de proteção do processador. Estes anéis existem como forma de controle de privilégio do que pode ser acessado e operado. O sistema operacional atua no anel 3, ou em ring 3, que é um anel de proteção com poucos privilégios. É por este motivo que o sistema operacional não pode simplesmente criar um arquivo no disco rígido. O kernel, por sua vez, atua em ring 0, o anel com maiores privilégios. Nele, o kernel consegue interferir e interagir com outros dispositivos da máquina diretamente.
O mecanismo de syscall existe exatamente para realizar a comunicação entre ring 3 (sistema operacional) e ring0 (kernel). Quando uma chamada de sistema é realizada, uma interrupção de software é gerada e o controle do programa passa a ser do kernel, que por sua vez realiza a tarefa solicitada e devolve o controle do programa para o sistema operacional, em ring 3.
A figura 1 ilustra o fluxo de uma chamada de sistema no Windows, iniciando na camada de modo usuário. O processo começa com a chamada a uma função da API do Windows, que, por sua vez, utiliza a ntdll.dll para realizar a transição para o modo kernel por meio de uma instrução de sistema (syscall). Nesse exemplo, a função 'CreateFile' da API do Windows é usada como referência, sendo internamente mapeada para a função 'NtCreateFile' da ntdll.dll, responsável por invocar o interrupt handler no modo kernel.

Figura 1 - Fluxograma da CreateFile()
O manipulador de syscall do Windows
O nt!KiSystemCall64 é o manipulador de syscall do Windows. Ele é responsável pela entrada no modo kernel quando uma syscall é realizada.
Quando uma chamada de sistema é realizada em um sistema de 64-bits, a instrução “syscall” é executada. Vamos olhar no WinDBG o stub da “NtCreateFile” para fins de entendimento.
Na figura 2, a função NtCreateFile é destrinchada em linguagem assembly, permitindo a compreensão detalhada do fluxo de execução. Inicialmente, o argumento localizado em RCX é movido para R10, alinhando-se à convenção de chamada esperada pelo kernel. Em seguida, o índice correspondente ao serviço na Tabela de Serviços do Sistema (SSDT) é carregado no registrador EAX. No caso da NtCreateFile, o índice utilizado é 55h. Esse índice será processado pelo kernel durante a transição para o modo kernel, que ocorre por meio da instrução syscall. O Windows possui duas instruções que podem ser utilizadas para executar a syscall: a instrução “syscall”, representada pelo opcode “0f05” e a instrução “int 2Eh”, que possui o opcode “cd2e”. Ambas são utilizadas para causar a interrupção e alcançar o manipulador de syscall do Windows, o “nt!KiSystemCall64”, no caso da instrução “syscall” ou o “nt!KiSystemCall”, se a instrução for a “int 2Eh”. Antes da execução dessas instruções, um teste é realizado pelo próprio código da syscall para verificar se o sistema é x64 ou x86 (falarei mais deste teste em breve), como podemos ver na figura 2.

Figura 2 - Trecho de código da função NtCreateFile na ntdll.dll
Quando a instrução syscall é executada no modo usuário, o valor armazenado no registrador MSR IA32_LSTAR é carregado no registrador RIP, transferindo a execução para o kernel. Este valor é um endereço conhecido como o ponto de entrada do Kernel RIP para syscalls. Em outras palavras, ele é o endereço do manipulador de syscall, nt!KiSystemCall64.
O nt!KiSystemCall64 é o manipulador Kernel RIP Syscall em modo longo (64 bits). Quando a instrução syscall é executada, o código salta para a rotina do modo kernel cujo endereço é apontado por um MSR, acessado por meio das instruções rdmsr (leitura) e wrmsr (escrita).
KUSER_SHARED_DATA
A estrutura KUSER_SHARED_DATA é uma estrutura utilizada para que o kernel compartilhe informações com os processos do lado do user-mode, evitando assim uma troca de contexto de user-mode para kernel-mode constante. Você pode procurar ver mais detalhes sobre essa estrutura na documentação da Microsoft em KUSER_SHARED_DATA.
O sistema acessa a estrutura KUSER_SHARED_DATA que possui um endereço fixo mapeado para os processos no modo usuário 0xfffff78000000000. Na instrução TEST, um deslocamento com offset de 0x308 alcança o campo “SystemCall” da estrutura e o código testa se o valor dele é 1. Se for, significa que o sistema é baseado em x64 e ele a próxima instrução executada será a syscall . Caso contrário, ele pula para o endereço 0x00007ffe7756db55 que possui a instrução INT 2Eh. Ou seja, em sistemas baseados em x86, a instrução para gerar a interrupção é a INT 2Eh. Já na arquitetura x64, a instrução é a SYSCALL.
Ainda sobre a estrutura, de acordo com a documentação da Microsoft, o campo SystemCall é, em x64, inicializado para um valor diferente de zero se o sistema operar com uma exibição alterada do mecanismo de chamada de serviço do sistema.
Em x64, o membro SystemCall da estrutura KUSER_SHARED_DATA indica o mecanismo de chamadas de sistema em uso e é configurado com um valor diferente de zero, refletindo que o sistema está utilizando o modelo baseado em instruções otimizadas, como syscall. Em sistemas x86, esse membro permanece como zero, indicando que o modelo tradicional de chamadas de sistema, como int 2Eh ou sysenter, está em uso.
Quando a instrução syscall é executada, o valor de IA32_LSTAR é recuperado e colocado no registrador RIP do kernel. Chamamos isso de Kernel RIP Syscall. Após isso, o modo kernel passa a executar o manipulador de syscall nt!KiSystemCall64.
Desmontagem do manipulador de syscall
Desmontando o manipulador KiSystemCall64, vemos que a primeira instrução a ser executada é “swapgs”, como mostra a figura 3.

Figura 3 - Instrução swapgs no início do manipulador de syscall
Na verdade, existem dois manipuladores syscall diferentes, com e sem a palavra-chave ‘Shadow’. A palavra “Shadow” vem do recurso chamado de Kernel Virtual Address Shadow que visa corrigir o bug Meltdown.
A swapgs é uma instrução privilegiada usada para trocar o valor atual do registrador base GS pelo valor residente no endereço MSR C0000102H (IA32_KERNEL_GS_BASE). Explico: o valor do registro base GS é igual ao valor contido no MSR IA32_GS_BASE. Em sistemas Windows x64, os valores são:
IA32_KERNEL_GS_BASE — Ponteiro para Processor Control Region(PCR) atual, especificamente a região de controle do processador do kernel (KPCR) IA32_GS_BASE — Ponteiro para thread de execução atual da TEB Assim, no modo longo x64, o segmento GS sempre aponta para o thread atual TEB no modo usuário, enquanto no modo kernel aponta para o PCR do processador atual.
A próxima instrução mov qword ptr gs:[10h],rsp salva o ponteiro da pilha do modo usuário. O objetivo de salvar o ponteiro da pilha de modo usuário (RSP) durante a transição do modo usuário para o modo kernel é garantir que, quando o controle for devolvido ao modo usuário, a execução do programa possa continuar de maneira correta, mantendo o contexto da thread do usuário intacto.
Conclusão
Neste artigo, exploramos o papel das chamadas de sistema no Windows, com foco no manipulador de chamadas de sistema (syscalls) !KiSystemCall64. As syscalls são fundamentais para que o sistema operacional se comunique com o kernel e execute tarefas críticas que não podem ser realizadas diretamente em modo usuário, como criar arquivos, por exemplo. Também vimos como a transição entre os modos usuário e kernel ocorre de forma eficiente com a instrução swapgs e o uso da estrutura KUSER_SHARED_DATA, que permite uma comunicação rápida e eficaz entre o kernel e os processos. Discutimos como o sistema mantém o contexto da execução do programa, permitindo que a execução continue corretamente quando o controle retorna ao modo usuário. Qualquer dúvida ou sugestão, é só comentar abaixo. 🙂
  • 1,694 views
Talvez você conheça o Hiew (abreviação de Hacker's View), um poderoso editor hexadecimal que reconhece formatos de executáveis como PE e ELF e é capaz de editar suas características, disassemblar código em x86 e ARM e muito mais. Se ainda não conhece, comenta aí que num momento oportuno volto para falar mais dele. 😉
Neste artigo apresento o Hiewix, um novo programa feito pelo mesmo desenvolvedor do Hiew, Eugeny Suslikov, mais conhecido por seu nick SEN. Nesta leitura, você vai descobrir:
Para que serve o Hiewix e o problema que ele vem resolver. Os poderes e limitações do Hiewix. Se vale a pena ou não comprá-lo. 💸 O Hiewix é para os momentos em que você não conhece a estrutura de determinado arquivo binário. Logo, seu intuito não é servir para editar arquivos PE, ELF ou Mach-O. Na real, a versão atual nem é capaz de modificar arquivos abertos, mas sim de trabalhar para reconhecer, com a sua ajuda, arquivos desconhecidos.
Nada melhor que um exemplo para entender o poder do Hiewix. Recomendo acompanhar o artigo baixando a versão demo do Hiewix no site oficial e a ISO do Math Invaders para extrair o GAME.PAK que vamos utilizar como exemplo.
Considere um formato de arquivo binários, ou seja, cuja estrutura e conteúdo não sejam facilmente deduzíveis, utilizado num jogo qualquer. O nome do nosso arquivo é GAME.PAK, então vamos chamá-lo de arquivo PAK, mas não conhecemos sua estrutura ainda. A figura 1 mostra a tela do Hiewix v1.10.633 ao abrir o arquivo pela primeira vez.

Figura 1 - Tela inicial do Hiewix ao abrir o arquivo GAME.PAK
O Hiewix nos dá algumas opções iniciais para carregar o arquivo:
Main parser é o parser principal. O padrão é Binary(internal), que não faz nenhuma análise no arquivo. É nossa única opção numa primeira vez. Base address configura o primeiro endereço mostrado na tela do Hiewix para o conteúdo do arquivo. Por exemplo, se você digitar "10" (sem aspas), o primeiro byte do arquivo começará no endereço 0x10 e todos os comandos do Hiewix vão trabalhar a partir deste endereço base. Codesize permite configurar, se o arquivo contiver bytecode, (bytes que representam instruções para a CPU) o tipo de código para 16, 32 ou 64-bits. O Hiewix assume a arquitetura x86. Para arquivos de dados, a opção é Data. Second parser permite carregar um segundo parser além do principal para rodar sobre o arquivo. Mais sobre parsers em breve. Ao clicar em OK com as opções padrão selecionadas somos apresentados a uma tela bem parecida com a de um editor hexadecimal comum, mostrada na figura 2.

Figura 2 - arquivo GAME.PAK aberto no Hiewix
 NOTA: Se ao bater o olho nos bytes deste arquivo você achou esse formato familiar, provavelmente já fez engenharia reversa em jogos antigos ou assistiu a um dos vídeos sobre a engenharia reversa que fiz no jogo Math Invaders (veja a parte 1 e a parte 2). Na parte 1, usei o Kaitai Struct e o Hiew. Já na parte 2, utilizei também o ImHex editor. Na época ainda não tinha Hiewix. 😄
O Hiewix criou um segmento padrão de dados de tamanho 0x15EB759, que no caso é o tamanho total do arquivo (22,984,537 bytes). Este segmento, assim como outros que porventura sejam criados, só fazem sentido na interface do Hiewix e servem para organizar diferentes segmentos de dados ou código que você descubra. Nada no arquivo é alterado com a criação deles. Alías, lembre-se: o Hiewix abre o arquivo com permissão de leitura somente.
Uma vez o arquivo aberto, cabe a nós entender sua estrutura. Isso pode ser feito diretamente para formatos simples, mas formatos mais complexos podem exigir a engenharia reversa do executável que abre o arquivo analisado. Conforme formos compreendendo os dados no arquivo, vamos dando comandos no Hiewix que reflitam o que entendemos sobre tais dados.
Comandos do Hiewix
Os comandos são para você descrever o tipo de dado no qual o cursor se encontra. Por exemplo, por conta da análise deste arquivo PAK que já fiz, sei que os primeiros quatro bytes deste arquivo representam uma DWORD (double word), ou seja, um número de 4 bytes que nos diz quantos arquivos existem neste .PAK (o .PAK é uma espécie de sistema de arquivos rústico implementado num único arquivo que contém vários arquivos). Para descobrir como cheguei a esta conclusão, assista os vídeos de engenharia reversa no Math Invaders. 😉
Se os primeiros quatro bytes são uma DWORD, eu dou um clique no primeiro byte da DWORD (0x56 na figura 3) e clico no pequeno botão de um balãozinho com as lestras dd (de define dword) para produzir o efeito mostrado na figura 3.

Figura 3 - Primeira DWORD definida com o Hiewix no GAME.PAK
Perceba o efeito: O Hiewix pula uma linha na visualização após o fim da DWORD (ou seja, após o quarto byte) e muda a representação na coluna da direita para "dd 00000056", que indica que ela é uma DWORD e seu valor é 0x56 em little-endian.
Ao definir números, é possível ter algum controle sobre sua representação. Por exemplo, posso selecionar os mesmos quatro bytes da minha DWORD e clicar novamente no botão dd para definir um array de um elemento com representação decimal. Dessa forma, o valor é apresentado em decimal na coluna da direita, como mostra a figura 4.

Figura 4 - DWORD redefinida como array de um elemento com visualização em decimal
A ideia é que você vá descrevendo os conjuntos de bytes do arquivo com os comandos disponíveis no Hiewix, o que me lembra bastante o IDA, da Hex-Rays.
Os principais comandos disponíveis no Hiewix estão a seguir (o texto do ícone de cada botão, quando existe, está entre parênteses):
Name (ab), define um nome para o byte, que aparecerá na aba Names, mostrada como Names(0) na Figura 2. Code (add), diz que o byte deve ser interpretado como código. Está desabilitado pois estamos num segmento de dados. Byte (db), define um byte. Word (dw), define uma WORD de dois bytes. Dword (dd), define uma DWORD de quatro bytes. Qword (dq), define uma QWORD de oito bytes. Float (df), define o tipo de dados float para números reais. Double (dF), define o tipo de dados double para números reais. Dump, ainda não entendi. 😄 Byteline, define um conjunto de bytes sem interpretação. Asciiz (a), define uma string ASCII. Unicode, define uma string Unicode. Comment line, insere um comentário acima da linha. Comment on line, insere um comentário à direita da linha (na coluna da direita). A figura 5 mostra as três primeiras entradas do arquivo PAK totalmente definidas e com comentários e nomes criados.

Figura 5 - Definições dos campos da estrutura do PAK
O texto em vermelho descreve o tipo de definição que usei, ou seja, os botões que apertei para definir os dados. Como também usei nomes, a aba Names à esquerda mostra os quatro nomes que defini. A ideia é poder dar um duplo-clique no endereço do nome (coluna address) para que o Hiewix navegue direto para lá.
Também é possível marcar pontos como favoritos no arquivo que serão mostrados na aba Bookmarks. Para isso, basta selecionar o byte desejado clicar à esquerda da linha.
Com estes poderes, o Hiewix nos permite ter uma visualização muito melhor do conteúdo do arquivo. Algo similar aos Templates no 010 Editor ou às structs do Kaitai Struct. A diferença é que o Hiewix nos permite criar a estrutura interativamente e não só programaticamente.
Criando parsers
Na versão paga, você até pode salvar o estado atual (com suas definições feitas) para este arquivo específico e depois carregá-lo. No entanto, se uma definição se repete muito (como é o caso das 86 entradas neste arquivo PAK) ou se você precisar abrir outros arquivos com a mesma estrutura, não faria sentido ter que definir todos os campos manualmente. Para estes casos, o Hiewix oferece o recurso de criação de parsers, ou seja, de pequenos programas que irão entender o conteúdo do arquivo para você. O software oferece duas APIs, uma em C e outra em Lua para tal. O pacote da versão paga vem com um exemplo em C++ um pouco difícil de entender e um esqueleto em Lua, sem um exemplos completo. Com alguma luta, consegui escrever um parser em C/C++ e compilá-lo com o Visual Studio 2022. O código basicamente automatiza o que fizemos na mão, mas com algumas ressalvas. A principal função é a ParseFile(), que mostro abaixo:
/* * Math Invaders' PAK file parser for Hiewix * Author: mer0x36 * Date: December 2024 * * Compile with: * cl pak.cpp /link /out:pak.hwx32 kernel32.lib Hiewix32.lib /dll /subsystem:windows * * Then copy te pak.hwx32 to Hiewix root folder and load the PAK file * You can download the GAME.PAK file from * https://archive.org/details/MathInvaders (it's in the ISO file) */ #include <fcntl.h> #include <inttypes.h> #include <io.h> #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <sys/types.h> #include "HiewixExport.h" // API version: 110 #define NAME_LEN 64 // Compile with: // cl pak.cpp /link /out:pak.hwx32 kernel32.lib Hiewix32.lib /dll /subsystem:windows long __stdcall DllMain(void *hModule, unsigned long reason, void *lpReserved) { return 1; } HWX_EXPORT int ApiVersionUsed() { return HWX_API_VERSION; } HWX_EXPORT unsigned long HwxID() { return 0; } HWX_EXPORT const wchar_t *HwxTitle() { return L"Math Invaders PAK"; } HWX_EXPORT unsigned long HwxFlags() { return 0; } // PAK entry struct typedef struct { char name[NAME_LEN]; uint32_t offset; } entry; HWX_EXPORT bool IKnowThisFile(HWX_PREFILE_DATA *p_hwx_prefile_data) { p_hwx_prefile_data->_decode_engine = decode_engine_none; return true; } HWX_EXPORT bool ParseFile(HWX_FILE_DATA *p_hwx_file_data) { uint32_t nentries = 0; __int64 addr = 0; struct _stat st; const int file_index = p_hwx_file_data->_file_index; // Read the first DWORD from the file as it contains its number of entries int fd = ::_wopen(p_hwx_file_data->_filename, _O_RDONLY); if (fd == -1) return false; if ( ::_read(fd, &nentries, sizeof(nentries)) != sizeof(nentries) ) return false; // We'll use st.st_size to get the filesize if (::_fstat(fd, &st) != 0) return false; ::_close(fd); // Adds a data segment for the PAK header const __int64 headerSize = (nentries + 1) * sizeof(entry) + sizeof(uint32_t); HwxFileAddDataSegment(file_index, 0, 0, headerSize, 0); HwxFileSegmentName(file_index, 0, L"PAK_Header"); HwxFileSegmentCollapse(file_index, 0, false); // Adds a data segment for the PAK contents (right after header) HwxFileAddDataSegment(file_index, headerSize, headerSize, st.st_size-headerSize, 0); HwxFileSegmentName(file_index, headerSize, L"PAK_Contents"); HwxFileSegmentCollapse(file_index, headerSize, false); // Add a comment above the first line HwxFileCommentline(file_index, 0, L"PAK file start"); // Set number format to decimal HwxFileMakeDec(file_index); // Define a Dword HwxFileMakeDword(file_index, addr); // Set number format back to hex (default) HwxFileMakeHex(file_index); HwxFileCommentOnline(file_index, addr, L"number of entries"); addr += sizeof(uint32_t); // Loop that defines the entries for (int i=0; i < nentries; i++) { // Define a string, a comment, then advances 16 bytes HwxFileMakeStringAsciiz(file_index, addr, NAME_LEN); HwxFileCommentOnline(file_index, addr, L"file path"); addr += NAME_LEN; // Define a DWORD, a comment, then advances 4 bytes HwxFileMakeDword(file_index, addr); HwxFileCommentOnline(file_index, addr, L"file offset"); addr += sizeof(uint32_t); } return true; } O código completo será disponibilizado em breve.
Após compilado, o arquivo é uma DLL com extensão .hwx32 que deve ser colocado no diretório raiz do Hiewix. Dessa forma, ao abrir um novo arquivo, será possível escolher o nosso parser personalizado como mostra a figura 6.

Figura 6 - Nosso parser personalizado para escolha ao carregar um novo arquivo
O resultado você vê na figura 7. O arquivo é totalmente parseado (sim, um neologismo - e por que não?), dois segmentos são criados e vários comentários feitos.

Figura 7 - PAK parseado com nosso parser personalizado
Neste parser optei por não criar nomes para o código ficar menor. Ao invés de nomes, criei um segundo segmento, algo que só parece ser possível através da API por enquanto.
Já dá para perceber o poder que o Hiewix tem. Imagine que você pode criar parsers para qualquer tipo de arquivo que desejar. Se somar o poder o Kaitai Struct (que emite parsers em C++), fica mais poderoso ainda. No entanto, o Hiewix ainda está em desenvolvimento e é possível que muitas coisas mudem, inclusive na API, então recomendo segurar sua peteca antes de sair por aí criando parsers.
Vale a pena comprar?
O software me pareceu muito bom, mas há alguns pontos que requerem atenção na minha opinião, embora as coisas possam mudar muito em breve. São eles:
Prós
Velocidade. O Hiewix é escrito em C/C++ como tudo o que o SEN faz. E tudo acontece muito rápido no software. Isso é algo que eu valorizo muito, especialmente depois da invasão destes apps escritos em JavaScript para desktop que são uma carroça. Há quatro opções para marcar um endereço: nome, comentário acima da linha, comentário à direita da linha e favorito (bookmark). Muito legal essa versatilidade e muito similar ao Hiew, com o comentário acima talvez inspirado no IDA? Possibilidade de rodar um segundo parser, deixando ainda mais versátil. A API também sugere parsers reentrantes, mas não encontrei muita informação a respeito. A criação de tabelas (abas na parte de baixo da janela), que não mostrei aqui, mas é exibida na captura de tela aqui (abas Header, Dir, Sections, etc). Para um software pago, o preço é razoável: 50 dólares (aproximadamente R$ 300,00) por um ano e você renova se quiser as atualizações depois deste período. Para quem trabalha com arquivos desconhecidos com frequência, pode justificar o investimento. Contras
Em minha opinião, o software ainda vai amadurecer. Há um pequeno bug na visualização das colunas e não dá para controlar o tamanho da janela inicial do software (basta ir no menu Options e clicar em Save as default), por exemplo. Outros recursos dos quais senti a falta: Criação de novos segmentos através da interface gráfica. Possibilidade de exportar os bytes, como no Hiew. Redefinir uma Dword como decimal pela API como fiz na interface gráfica. Bem, pode ser que haja uma maneira, mas ainda não descobri (basta usar HwxFileMakeDec() e depois voltar para hexadecimal com a HwxFileMakeHex()). Suporte a outras arquiteturas além de x86 para segmentos de código. A API, por enquanto, me pareceu um pouco difícil de usar e não há documentação além de um arquivo de cabeçalho com os protótipos das funções da API. Como todos os outros softwares do SEN, o Hiewix é nativo para Windows, mas consegui rodá-lo no Ubuntu com Wine sem problemas aparentes. Espero que este artigo tenha sido útil para conhecer esta nova ferramenta e/ou como uma introdução no conceito de parsing de arquivos binários. Como sempre, fique junto e lembre-se que você pode apoiar a Mente Binária para que artigos como esse continuem sendo publicados. Um abraço e happy hacking!
Atualização em 10/12/2024: O autor do software leu o artigo e entrou em contato explicando alguns dos "contras".
 
  • 1,359 views
Downloads via torrent são feitos desde 2001. Como resultado, pessoas ao redor do mundo começaram a compartilhar seus arquivos favoritos, como músicas, filmes, imagens e vídeos, mesmo estando em locais distantes. Isso acabou abalando a indústria da música nos anos 2000, pois já não era mais necessário pagar para ter acesso a qualquer música, álbum, CD ou imagem, que antes só podiam ser obtidos mediante pagamento.
Esses compartilhamentos de arquivos de músicas, vídeos, imagens, etc., são feitos por meio da arquitetura de rede P2P (peer-to-peer / ponto-a-ponto).
Para realizar um download por P2P, basta baixar um arquivo torrent, por exemplo, “ubuntu-23.04-desktop-amd64.iso.torrent”, e adicioná-lo a um aplicativo como o uTorrent. Em seguida, o download começará.
Os arquivos “.torrent” contêm informações sobre o arquivo a ser baixado, como nome, tamanho, metadados adicionais (data de criação, informações do criador, descrição, hash, etc.).
De forma simplificada, conectamos ao IP do fornecedor do arquivo para iniciar o download. O fornecedor precisa saber nosso IP para saber para onde enviar o arquivo compartilhado. No entanto, isso pode ser um problema…
Aplicativos como BitTorrent, uTorrent e qBittorrent, por exemplo, usam o protocolo BitTorrent, que faz parte da arquitetura de rede P2P. Nessa rede descentralizada, todos os usuários são servidores e clientes ao mesmo tempo, expondo seus IPs “obrigatoriamente” para que outros usuários saibam para qual computador deva ser realizado o upload ou download de um arquivo.
O conhecimento do IP por si só pode não ser um problema tão grande em termos de segurança da informação, a menos que se envolva em downloads ilegais, como pirataria ou pornografia ilegal.
No entanto, é desconfortável que outras pessoas saibam seu IP, pois a privacidade é importante, e ninguém deseja que outros conheçam sua localização geográfica.
Assim, se alguém sabe seu IP para enviar um arquivo, e você sabe o IP dessa pessoa para receber o arquivo, o que poderia ser feito com essas informações?
Qualquer pessoa pode consultar um histórico de downloads torrent feito por outro usuário, desde a pessoa mais leiga em informática até a mais experiente pode fazer isso.
Um desses serviços de rastreamento de downloads via torrent é o iknowwhatyoudownload.com, que, traduzido, significa “eu sei o que você baixa”.
Ao informar um IP aleatório da faixa de IPs de uma VPN, por exemplo, é possível ver todos os downloads feitos pelo usuário desse IP.
O site lista o histórico de downloads do IP informado, incluindo o nome do arquivo baixado, a data e o horário completos, o tamanho do arquivo, o IP do usuário que baixou e outras informações.

A página retorna colunas com as datas dos arquivos, categoria, título e tamanho.
Observação: Na captura de tela, até mesmo um download de um vídeo pornô, um arquivo “XXX”, é mencionado na última linha.
O site oferece uma API na guia “API”. Ao criar uma conta gratuita, é possível até mesmo saber, por meio da resposta JSON da API, se um determinado IP baixou pornografia infantil ou pornografia legalizada. No exemplo fornecido, consta que não houve download de pornografia infantil, mas houve download de pornografia pelo IP informado.
Observação: O IP informado é de uma VPN, portanto, não é o IP “real” de um usuário.

A resposta JSON da API também fornece dados completos sobre os downloads torrent do IP informado.

Na guia “About”, o site informa o seguinte:

Confira o texto original em: https://iknowwhatyoudownload.com/en/contacts/
Em “Track downloads”, você pode gerar um link e enviá-lo para alguém. Quando essa pessoa clicar no link gerado, você poderá ver os downloads feitos por ela.


Lembre-se de que um ISP (provedor de internet, por exemplo) pode atribuir um único IP para mais de um usuário.
Outros sites oferecem serviços semelhantes. Além disso, é possível criar um bot capaz de pesquisar sites de filmes piratas por meio do Google, baixar torrents, ler informações como título do arquivo, data, hash, etc., iniciar o download para rastrear as conexões de upload e download e identificar os participantes desses downloads. O bot também pode interagir com peers, que são usuários que compartilham e recebem dados em aplicativos P2P como o uTorrent, permitindo obter seus endereços IP e descobrir o que cada usuário está baixando. Dessa forma, não seria necessário consultar um site como o iknowwhatyoudownload.com. Existem também técnicas mais avançadas que poderíamos abordar em outro artigo, caso você tenha interesse.
Observação: É importante ressaltar que o uso desses sites de monitoramento de torrents pode levantar questões de privacidade, pois eles obtêm informações sobre downloads de torrents e endereços IP. Sempre considere as leis e regulamentos locais ao utilizar esses serviços e tome as medidas necessárias para proteger sua privacidade online.
  • 9,509 views
A corrida tecnológica dos últimos anos continua trazendo benefícios para as operações das empresas mas, ao mesmo tempo, potencializando os prejuízos com ataques cibernéticos por uma série de motivos que incluem, de forma especial, o aumento das fronteiras dos negócios e da complexidade das operações neste novo cenário de adoção de ambientes em nuvem e outras tecnologias, novas conexões com clientes e fornecedores e outros fatores.
Um relatório divulgado recentemente - o Cost of a Data Breach, produzido pelo Ponemom Institute - dá uma ideia do tamanho dos prejuízos enfrentados pelas empresas atualmente; segundo o report, em 2022 o custo médio por incidente envolvendo o vazamento de dados de organizações - custo este que inclui questões legais, regulatórias, técnicas e danos à marca - foi de US$ 4,35 mi. Trata-se de uma média 2,6% maior do que a média do ano anterior.
Como consequência deste cenário, os investimentos em cibersegurança devem ultrapassar os US$ 219 bi em 2023, aumento de cerca de 12% em relação a 2022. No entanto, mesmo com o aumento dos investimentos, não são poucas as empresas que enfrentam uma grande dificuldade em obter visibilidade aos riscos a que estão expostas.
Visibilidade é questão essencial para a cibersegurança
Ter visibilidade do ponto de vista da segurança da informação significa, entre outras coisas, saber que dispositivos estão conectados ao ambiente e quais os riscos a que estes dispositivos estão expostos, além de saber quais vulnerabilidades estão afetando minha estrutura, que dados estão trafegando, etc. 
Existe uma série de serviços de consultoria de segurança que permitem obter, de forma ágil, uma maior visibilidade das vulnerabilidades afetando sistemas e aplicativos que podem ser exploradas por atacantes, sejam elas brechas na segurança da rede, erros de configuração, falhas de software, entre tantas outras.
Dentre estes serviços estão os testes automatizados de segurança, as auditorias/testes de compliance e pentests. Cada um destes serviços, no entanto, possui características e objetivos próprios. 
Neste blogpost traremos um pouco das particularidades destes serviços.
Testes de Auditoria ou Compliance
Com o aumento de regulamentações destinadas à proteção dos dados de cidadãos e clientes de empresas, sejam elas leis aplicadas pelos governos como a LGPD no Brasil ou a GDPR na Europa, sejam normas regulatórias criadas por setores específicos da economia para regular e normatizar seus mercados, empresas de todos os setores precisam estar atentas ao fluxo de dados e informações trafegando nos seus ambientes, evitando acesso não autorizado, exfiltração de dados e outras violações.
Testes de Auditoria e de Compliance verificam o nível de segurança das tecnologias envolvidas na operação, bem como das rotinas de coleta, processamento e armazenamento de dados a partir de um checklist. Importante destacar que este checklist se restringe ao escopo da auditoria em questão. 
Por exemplo: uma auditoria que irá verificar a aderência das operações a uma regulação específica de um setor não irá garantir que a empresa esteja em conformidade com outras leis ou regulamentações, nem mesmo irá medir o grau de maturidade da organização. Ou seja, trata-se de um teste cujo objetivo é basicamente checar se as regras determinadas pela regulação estão sendo seguidas.
Testes Automatizados ou scans de vulnerabilidades
Testes automatizados utilizam uma série de ferramentas capazes de verificar falhas e vulnerabilidades no ambiente, seja em endpoints, seja na infraestrutura de rede, servidores, etc. Estes testes vem ganhando popularidade por oferecerem uma série de benefícios que incluem: 
Eficiência: o uso de ferramentas automatizadas permite identificar uma série de vulnerabilidades em uma ampla gama de dispositivos em um curto espaço de tempo.
Custo-benefício e continuidade: o custo reduzido destes testes permite manter uma rotina de scans a baixos custos.
Escala: mesmo com o aumento de estrutura e com a adoção de novas tecnologias, testes automatizados podem ser facilmente conduzidos.
Mas apesar dos benefícios é preciso deixar claro que testes automatizados não representam uma solução completa para identificar todas as falhas e vulnerabilidades  presentes no negócio.
Testes automatizados não conseguem identificar, por exemplo, se existe algum gap de segurança nas regras do negócio - se em um processo de compra de um e-commerce há problemas no processo de validação de dados de pagamento, por exemplo. Da mesma forma não são capazes de identificar cenários de fraude
A título de exemplo, neste contexto de fraude, vamos considerar as falhas humanas. 
O relatório Data Breach Investigation Report, produzido pela Verizon, coloca entre os principais vetores para as violações o uso de credenciais roubadas (BEC), o phishing e a exploração de vulnerabilidades, nessa ordem - 74% de todas as violações incluem o elemento humano, com pessoas envolvidas por meio de erro, uso indevido de privilégios, uso de credenciais roubadas ou engenharia social.   
Identificar falhas que envolvam a operação depende de um entendimento do negócio, seu contexto e as relações e conexões entre pessoas, processos e tecnologias. Testes automatizados não são capazes de fazer esta avaliação ou conduzir simulações de ataques de engenharia social que poderiam identificar gaps de conhecimento entre os colaboradores.
Pentests ou Testes de Intrusão
Pentests, ou testes de intrusão, consistem em simular um ataque em uma rede, aplicação ou sistema para identificar vulnerabilidades e avaliar a efetividade das medidas de segurança existentes na organização. 
São aplicados por profissionais qualificados e fazem uso de táticas, técnicas e ferramentas similares às que atacantes reais usariam contra o negócio, ou seja, buscam simular cenários de ataque que irão considerar não apenas as vulnerabilidades na estrutura tecnológica, mas também no escopo único de cada empresa, sua operação, as pessoas envolvidas e, claro, as tecnologias usadas.
Pentests possuem uma série de modalidades e aplicações que incluem mas não se limitam a:
External – tem como objetivo entrar no ambiente corporativo de TI ou obter acesso a dados ou sistemas críticos a partir da Internet
Internal – avalia as proteções do ambiente corporativo de TI sob o ponto de vista da rede interna
Mobile Application – visa encontrar vulnerabilidades ou discrepâncias de programação que possam ser usadas em um ataque
Web Application – avalia resiliência de aplicações web
Wi-Fi – verifica a possibilidade de comprometer ambientes corporativos a partir de redes Wi-Fi
Testes no Ambiente de Rede – verifica vulnerabilidades neste ambiente e em seus dispositivos
Testes de Software ou aplicação de desktop – identifica falhas que possam levar ao controle do dispositivo, injeção ou interceptação de dados, etc.
Testes de Hardware – verifica vulnerabilidades diretamente ao hardware do dispositivo alvo. 
Em conclusão…
Testes de compliance, automatizados ou pentest possuem, cada um, a devida importância. Sua aplicação deve ser guiada pelo contexto específico de cada companhia.
Metaforicamente, assim como ir a um médico e realizar um exame específico quando aparece um dado sintoma não reduz a importância de realizar check ups completos e periódicos para avaliar a saúde como um todo, cada um dos testes que apresentamos neste artigo cumprem um papel importante na saúde da segurança de uma empresa. 
Diferenciais do Pentest da Tempest
Com início das operações em 2001, o Pentest da Tempest conta com a experiência e conhecimento do maior time técnico da América Latina  (SOC, Threat Hunting, Incident Response, Software Engineering, Red Team,  Vulnerability Management e  Threat Intelligence) para entregar um serviço de alta profundidade, com resultados robustos, tecnicamente sofisticados e efetivamente aderentes  aos desafios e necessidades dos nossos clientes. 
Recentemente produzimos o Guia do Comprador de Pentest da Tempest, onde você conhece melhor cada um dos tipos de pentest disponíveis atualmente e também tem acesso a uma série de dicas. Nele também apresentamos os seis elementos essenciais que irão ajudar a avaliar um fornecedor  para encontrar a solução mais adequada para sua situação.
Download do guia completo
Contar com o parceiro certo faz a diferença na proteção dos dados em qualquer ambiente
A Tempest Security Intelligence é uma empresa brasileira com atuação global. É a maior companhia brasileira especializada em cibersegurança e prevenção a fraudes digitais. 
Sediada no Recife, a Tempest conta também com escritórios em São Paulo e Londres, com mais de 600 colaboradores. 
Ao longo de seus 23 anos, a Tempest ajudou a proteger mais de 600 empresas de todos os portes e setores, dentre elas companhias do setor financeiro, varejo, e-commerce, indústria e healthcare, atuando em clientes nacionais e internacionais atendidos tanto pelo time no Brasil quanto no Reino Unido. 
Em 2020, a Tempest conquistou um parceiro de peso para continuar na vanguarda da cibersegurança, recebendo um grande aporte da Embraer, companhia brasileira de engenharia aeroespacial, o qual resultou em um dos maiores investimentos já realizados na história do setor de cibersegurança na América Latina. 

 
  • 3,733 views
Você conhece o pev, nosso kit de ferramentas para análise de binários PE (usados no Windows)? Se conhece, acho que vai se identificar com essa história. Se não conhece, vai conhecê-lo muito bem agora. Nesse artigo vou passear brevemente sobre a inspiração que deu origem ao projeto, o que foi feito desde então e o que vem por aí. De modo cronolagicamente organizado, começamos por um passado de mais de uma década. Partiu embarcar nessa viagem no tempo? ⌛
Passado 💭
Lá em 2010 eu queria fazer um programa que lesse a string de versão “File version” de executáveis PE. Essa que aparece quando você vai nas Propriedades de um executável .exe no Windows:

Essa informação só poderia estar no arquivo .exe, mas eu não sabia exatamente onde. Depois de muito estudo, consegui entender que essa informação fica numa estrutura chamada VS_FIXEDFILEINFO que, por sua vez, pertence a uma estrutura chamada VS_VERSIONINFO. Dava para encontrar essa estrutura por nome no binário em uma string UTF-16-LE na seção de recursos .rsrc:
$ strings -tx -el putty.exe | grep VS_VERSION_INFO 15a2c6 VS_VERSION_INFO $ hd -s 0x15a2c6 -n64 putty.exe 0015a2c6 56 00 53 00 5f 00 56 00 45 00 52 00 53 00 49 00 |V.S._.V.E.R.S.I.| 0015a2d6 4f 00 4e 00 5f 00 49 00 4e 00 46 00 4f 00 00 00 |O.N._.I.N.F.O...| 0015a2e6 00 00 bd 04 ef fe 00 00 01 00 4d 00 0a 00 00 00 |..........M.....| 0015a2f6 00 00 4d 00 00 00 00 00 00 00 0b 00 00 00 00 00 |..M.............| 0015a306 Mas onde estava o 0.77.0.0 ninguém me contava... Bem, segundo a documentação, a estrutura é definida assim:
typedef struct tagVS_FIXEDFILEINFO { DWORD dwSignature; DWORD dwStrucVersion; DWORD dwFileVersionMS; DWORD dwFileVersionLS; DWORD dwProductVersionMS; DWORD dwProductVersionLS; DWORD dwFileFlagsMask; DWORD dwFileFlags; DWORD dwFileOS; DWORD dwFileType; DWORD dwFileSubtype; DWORD dwFileDateMS; DWORD dwFileDateLS; } VS_FIXEDFILEINFO; Para facilitar a visualização dos campos de interesse dessa estrutura no dump hexa, coloquei comentários nela usando o rehex (parte integrante do nosso retoolkit) :

De acordo a documentação, o primeiro membro, chamado dwSignature, deve conter o valor 0xfeef04bd. Considerando o ensianness em little-endian, essa assinatura tá no dump hexa em 0x15a2e8, logo após a string VS_VERSION_INFO em UTF-16-LE. A missão então era achar como o número de “File version” era gerado, no exemplo aqui, a string 0.77.0.0. Vamos em frente.
Logo depois da dwSignature tem a dwStrucVersion de quatro bytes, seguida da dwFileVersionMS, que também é uma DWORD (Double WORD) de quatro bytes. Nesta última, temos os bytes 4D 00 (destacados em verde) e 00 00 (laranja). Lendo a documentação, descobri que A WORD mais significativa, tomando este número em little-endian, é o nosso primeiro zero da string "0.77.0.0", destacado em laranja. Já a WORD menos significativa é o 77 (0x4D), destacado em verde. O próximo membro é a dwFileVersionLS (amarelo e rosa), que segue a mesma lógica, formando o "0.0" final.
Na época, fiz um script em Python para buscar esse número de versão e chamei de pev.py (pev vem de “PE Version”). Não tenho mais o script, mas hoje seria algo nessa linha:
import sys if len(sys.argv) < 2: print("Usage: pev.py <pefile>") sys.exit(1) with open(sys.argv[1], "rb") as f: d = f.read() vinfo = "VS_VERSION_INFO".encode("utf-16-le") # Busca a string nos conteúdo do arquivo pos = d.find(vinfo) # Avança para depois da string vinfo + 4 pos += len(vinfo) + 4 sig = int.from_bytes(d[pos:pos+4], "little") if sig != 0xfeef04bd: print(f"Signature not found at {pos:#x}") sys.exit(1) pos += 8 # Avança para o dwFileVersionMS # Lê a word mais significativa major1 = int.from_bytes(d[pos+2:pos+2], "little") # Lê a word menos significativa major2 = int.from_bytes(d[pos:pos+2], "little") # Avança para o dwFileVersionLS pos += 4 # Lê a word mais significativa minor1 = int.from_bytes(d[pos+2:pos+2], "little") # Lê a word menos significativa minor2 = int.from_bytes(d[pos:pos+2], "little") print(f"{major1}.{major2}.{minor1}.{minor2}") Assim como o script da época, este script funciona:
$ python pev.py putty.exe 0.77.0.0 Mas sem dúvida, pode ser melhor por vários motivos. O principal, é que ele é lento, especialmente para arquivos grandes pois ele busca a string VS_VERSION_INFO no binário inteiro. É a famosa “marretada” em programação...

Era lento, não tinha jeito. Resolvi então estudar a documentação do PE e cheguei num código muito maior, mas que rodava muito mais rápido, porque eu lia todos os cabeçalhos do PE necessários para encontrar a posição no arquivo da estrutura VS_VERSION_INFO e, por consequência, da VS_FIXEDFILEINFO. O código não envolvia busca. Ao contrário, ele ia direto ao ponto. O pev 0.22 implementava esse algoritmo em aproximadamente 300 linhas de código em C. Lançado em 2010 no extinto Google Code, era assinado pelo Coding 40º, um grupo de programação que criei na faculdade com mais três amigos (@Francivan Bezerra, Thiago e Eduardo). No ano seguinte, o Coding 40º teve uma breve vida como hackerspace na Tijuca, no Rio de Janeiro, onde inclusive o @julio neves foi nos visitar. 💚
O projeto andou, mas em algum momento pensei: se eu passo por todos os cabeçalhos do PE, por que não imprimir os valores dos campos também? Isso transformaria o pev num parser de PE completo! E foi o que fizemos. Aí o projeto cresceu mais, ganhou relevância na área de segurança (era o único parser de PE livre e multiplataforma do planeta) e atraiu colaboradores do Brasil e de fora. A ponto do meu empregador na época ficar preocupado de eu estar recebendo dinheiro de outra empresa por conta do pev (como sempre, a p***a do capitalismo na nossa cola). Mas eu estava só aprendendo mesmo.
Na versão 0.50 eu segui a dica do @bsdaemon de “quebrar” o pev em programas menores, onde cada um cumpriria uma função. Assim, o pev virou um kit de ferramentas. E tivemos que aprender a lidar com tanto código, depois veio o Git e o GitHub e tivemos até uma sessão presencial onde vários colaboradores do projeto se uniram para estudar Git:

(Da esquerda para a direita, Álvaro Justen, Renato Augusto, Álvaro Rios, Thiago Bordini, @Felipe Esposito, Jan Seidl, Igor Rincon, @l0gan, @Gustavo Roberto, Slayer, @Fernando Mercês, Rogy e unk)
Dentre as muitas pessoas que colaboraram, teve o @jweyrich que reescreveu a libpe (na qual o pev se baseia) quase toda, corrigiu muito código, adicionou recursos e levou o projeto para outro nível. Junto com várias pessoas que reportaram e corrigiram bugs, implementaram recursos e testaram o pev, lançamos várias versões até chegarmos na atual 0.8x. 🙃
Presente 🎁
Hoje com aproximamente 30.000 linhas de código, o pev está estabelecido. Está presente em vários tutorias sobre análise de malware, e forense e em praticamente todas as distribuições Linux, incluindo Debian, Kali, Ubuntu, etc. Tem builds para Windows também. Veja alguns dos lugares onde você encontra o pev:
Pacote no Debian (eu fui o primeiro mantenedor, depois deixei o pacote órfão e o time do Debian assumiu! 💗):
Pacote no Ubuntu:
Incluso no Kali Linux por padrão:
Incluso no REMnux por padrão:
Incluso no Tsurugi Linux por padrão:
Paper Process Injection Techniques and Detection using the Volatility Framework no vx-underground:

Tem também pev no Arch Linux, Void Linux, vários tutoriais em português, inglês, chinês.. Em algum ponto eu até parei de monitorar. 😄 
Neste ínterim, tive a oportunidade de aprender com programadores incírveis que puseram código no pev. Só para citar alguns: @jweyrich, @Jan Seidl, Marcelo Fleury, @fredericopissarra e muitos outros que não conseguiria nomear aqui (mas estão todos na lista de colaboradores do projeto no GitHub). Muito obrigado! 💚
Muito tempo passou e muitos projetos livres similares surgiram, sendo o principal deles a pefile, que habilitou programadores e programadoras em Python a "parsear" binários PE facilmente. O mundo mudou, minhas prioridades mudaram, as prioridades dos colaboradores do pev mudaram também. Decidi então passar o bastão para quem tivesse interesse e em 28 de janeiro de 2022 comuniquei a comunidade que o projeto precisava de uma nova pessoa para mantê-lo. Surgiram algumas perguntas, alguns e-mails, até que em dezembro do mesmo ano, uma programadora da Alemanha entrou em contato informando do seu interesse em manter o projeto.
Conversa vai, conversa vem e é isso. O pev tem uma nova mantenedora! 🥳
Futuro 🔮
A nova mantenedora usa o apelido GoGoOtaku. Embora eu não a conheça, ela se mostrou bastante confiável e corrigiu vários bugs no pev já. Penso que é quase mágico o fato de alguém, bem longe de mim física e socialmente, tenha encontrado o pev e tenha tido o interesse em mantê-lo. São coisas que só o software livre, aliado a linguagens universais como C, idiomas universais como o inglês, e redes sociais como o GitHub, conseguem realizar. Acho isso muito incrível! 🙌
Em conversas com a nova mantenedora, expressei meu desejo que de o que pev voltasse a ser um programa só, mas com sub-comandos. Sugeri que usássemos o nome readpe, já que este é o programa mais usado do toolkit do pev e sugere um belo contraste com a ferramenta readelf do GNU Binutils. Ela gostou da ideia, afinal, o pev não tem mais nada a ver com “PE Version”. O mantenedor do pacote no Debian nos alertou  que mudar de nome é um processo delicado, especialmente porque o pev já é bastante conhecido, mas eu insisti. Minha ideia é que o readpe tenha sub-comandos que implementam a função dos programas separados hoje. Algo nessa linha:
Exibir a ajuda:
readpe help Imprimir os campos e valores dos cabeçalhos do PE (funcionalidade provida pelo readpe que seria dividida em sub-comandos):
readpe headers <pefile>          # todos os cabeçalhos readpe headers dos <pefile>      # somente o cabeçalho do DOS Exibir strings no PE (funcionalidade provida pelo pestr, que viraria um sub-comando do readpe):
readpe strings <pefile> # todas as strings readpe strings ascii -s <pefile> # somente strings ASCII exibindo as seções às quais elas pertencem readpe strings unicode <pefile> # somente strings UNICODE E por aí vai. Por hora, movi o pev para um repositório “embaixo” da Mente Binária, que chamei de readpe e dei todas as permissões para a nova mantenedora nele. Ela que vai decidir sobre o futuro do projeto. Talvez ela aceite minha sugestão de transformar o pev num único programa readpe. Talvez não. A mágica disso é que agora a decisão dela, afinal, filho a gente cria pro mundo e não pra gente né? 😄
Estou muito feliz que o pev tenha encontrado uma nova mantenedora (que já lançou a versão 0.82 com várias correções de bugs!). E que ele tem ajudado pessoas interessadas em "parsear" PEs pelo mundo afora durante seus 13 anos de existência.
Vou seguir acompanhando o projeto de perto e, quem sabe, até programando um pouquinho (se a nova mantenedora aceitar meus patches), mas acima de tudo, sou grato a todo mundo que contribuiu, usou e apoiou o pev durante todos esses anos. Ele continua sendo um dos poucos parsers livres de PE de linha de comando, multiplataforma, super versátil (com saídas em XML, JSON, HTML, etc), com recursos únicos (é o único livre que extrai certificados do PE, por exemplo) e claro, com raízes brasileiras. Foi o maior projeto de software livre da minha vida e eu continuo vibrando a cada commit que vejo nele. 😭
 
  • 4,485 views
Introdução
No vasto glossário de termos associados à segurança da informação o SOC - acrônimo em inglês para Centro de Operações de Segurança - talvez seja um dos mais mencionados, especialmente quando empresas se encontram diante de algum desafio relacionado com a proteção de sua estrutura.
Afinal, os SOCs representam, no imaginário de muitos, a solução definitiva para as mais complexas questões relacionadas à cibersegurança; algo muito próximo a uma bala de prata que combina profissionais altamente treinados e tecnologia de ponta para criar uma barreira de proteção intransponível pelo mais competente dos adversários.
E aqui começam os equívocos relacionados ao SOC. É verdade que os SOCs, quando bem estruturados e bem conduzidos, representam uma combinação dos pilares fundamentais da segurança: pessoas, processos e tecnologias. 
No entanto, um SOC só é tão eficiente quanto a soma das suas partes. 
Fatores que contribuem para seu sucesso incluem seu correto dimensionamento, decisões sobre quais tecnologias serão usadas, se haverá terceirização ou não de parte da operação e, principalmente, um conhecimento profundo do negócio por parte do time envolvido e a correta adequação do SOC à realidade da operação.
Um SOC, no fim das contas, não é um plugin, um serviço “one size fits all”. 
Tirar o máximo proveito deste tipo de estrutura depende em primeiríssimo lugar do entendimento do que é um SOC (e o que ele não é) e o que exatamente se espera dele.
Neste post você conhecerá alguns conceitos básicos envolvendo o SOC.
O que é e para que serve um SOC
Em uma definição generalista, SOCs, ou Centros de Operações de Segurança, são estruturas centralizadas compostas de tecnologias, pessoas e processos com o objetivo de monitorar e incrementar a postura de segurança de uma organização de forma contínua. Suas atribuições gerais são: prevenir, detectar, analisar e responder a incidentes de segurança cibernética.
Não é incomum os SOCs serem confundidos com monitoração de ameaça que é apenas um dos seus aspectos. Na verdade, o foco do SOC é mais amplo: a própria defesa do negócio. Segundo o diretor de MSS da Tempest, Renato Bezerra, “em uma operação bem sucedida do SOC não se quantifica apenas quantas ameaças foram detectadas, mas o quão eficazmente elas foram respondidas”.
Tão importante quanto monitorar e detectar anomalias é saber o que fazer após a revelação de uma ameaça/incidente. O sucesso da operação de um SOC depende de quão ágil a operação é na contenção, mitigação e erradicação do incidente cibernético detectado.
Elementos do SOC
Nesse sentido, e de forma bastante resumida, os SOCs operam segundo uma série de disciplinas que incluem, como vimos, a monitoração, identificação e resposta a ameaças e incidentes. E estas disciplinas são executadas com base em três elementos: 
Pessoas: A operação de um SOC depende de diferentes perfis de profissionais sem os quais os sistemas mais sofisticados não serão capazes de entregar os resultados esperados de um Centro de Operações de Segurança. Como visto, o exercício do SOC passa por monitorar, detectar e responder ameaças e, para isto, uma equipe multidisciplinar é essencial, desde profissionais especialistas em red team, blue team, até especialistas em cloud security, engenharia de detecção e engenharia de software, especialistas em resposta a incidentes e computação forense, inteligência de ameaças, entre outros.
Processos: O funcionamento do SOC depende de processos pré-definidos que servirão de guia para os seus operadores. Tais processos definem que ações serão tomadas, seja na rotina seja em situações de incidente cibernético. Processos incluem rotinas de monitoramento de redes e assets, de vulnerabilidades, de logs, gerenciamento de dados sensíveis da empresa e de clientes, políticas e procedimentos de resposta a incidentes, entre outros.
Tecnologias: a escolha das tecnologias dependerá da estrutura do negócio; mas além disso é fundamental que haja uma perfeita integração entre elas a fim de oferecer aos operadores uma visão completa dos riscos ao negócio. Algumas das tecnologias envolvidas em um SOC dizem respeito à segurança de estrutura e dados em nuvem, scanners de vulnerabilidade, firewalls, proteção de endpoints (EPP ou EDR) e de aplicações, entre outras.
Funções do SOC
O atual cenário de alta complexidade tecnológica coloca uma crescente gama de organizações diante da necessidade de contar com soluções de segurança integradas, capazes de lidar com desafios que envolvem desde a detecção precoce até a resposta efetiva e ágil a ameaças cibernéticas. 
Nesse sentido, o SOC se apresenta como uma solução robusta que envolve duas funções básicas:
Monitoramento e detecção de ameaças: Os SOCs contam com ferramentas e especialistas capazes de varrer a estrutura, buscando atividades suspeitas e rastreando vulnerabilidades que possam representar riscos ao negócio. Essa função envolve ainda o tratamento de um incidente dentro de parâmetros pré-estabelecidos, sua tratativa e mitigação, análise de malwares, etc.
Resposta a incidentes: uma das principais funções de um SOC, responder a um eventual incidente de forma ágil e efetiva (contenção, mitigação, resposta e erradicação), é a garantia de que um ataque não se tornará um evento fatal para o negócio. Mais do que isso, a resposta a um incidente envolve a recuperação dos assets envolvidos para que a operação volte à normalidade. A cada resposta a incidente também é trabalho do SOC aprender e registrar os processos tomados durante todas as suas fases, a fim de que eles possam ser aplicados nas melhorias necessárias para que este incidente não se repita, pelo menos não com o mesmo impacto, fechando o ciclo de resposta.
Um SOC não é um NOC (mas NOCs são importantes para os SOCs)
Um equívoco que ainda é comum é a confusão entre os papéis de um SOC e de um NOC. Um SOC não é um NOC, no entanto um NOC tem papel importante na operação de um SOC.
Enquanto o SOC se ocupa da monitoração, detecção e resposta a incidentes, NOCs, ou Centros de Operação de Rede, são estruturas pelas quais os administradores de TI supervisionam, monitoram e mantêm suas redes de comunicações, ou seja, as informações geradas por um NOC são integralmente consumidas por um SOC e podem determinar se um incidente está em curso ou não.
Dimensionamento do SOC é uma decisão de negócios
Como vimos, a operação de um SOC envolve uma combinação complexa de pessoas, processos e tecnologias e ao possibilitar essa combinação os SOCs surgem como um aliado poderoso tanto do ponto de vista tático – oferecendo o instrumental para enfrentar novas e mais complexas ameaças –  quanto do ponto de vista estratégico – possibilitando conectar a segurança da informação às prioridades e à visão estratégica da empresa. 
E aqui chegamos a um ponto vital para o sucesso do SOC.
Para ser realmente efetivo, o SOC deve ser dimensionado sempre de forma estratégica com foco no negócio. Os times envolvidos, a escolha das tecnologias e os processos que guiarão as operações precisam estar orientados pelo Mapa Estratégico e de Riscos da companhia, de modo que as prioridades dos seus projetos correspondam às prioridades do negócio.
Refletir sobre isso é fundamental inclusive para a decisão sobre terceirização (ou não) das operações do SOC, em parte ou em sua totalidade.
Quando terceirizar o SOC (ou partes dele)
Como vimos, o dimensionamento de um SOC (as pessoas, processos e tecnologias que dele farão parte) é uma decisão de negócios. Passa por uma análise profunda do negócio, sua operação e deve ser guiado por seu Mapa Estratégico e de Riscos. 
Inicialmente é preciso ter uma visão clara dos riscos ao negócio: seu tamanho, seu mercado, suas operações são cruciais para identificar quais os riscos a que ele está exposto. Um exemplo simples: a operação de uma padaria certamente não é tão complexa, do ponto de vista dos riscos de cibersegurança, quanto a operação de um grande escritório de advocacia. Essa reflexão é crucial para definir o escopo do SOC.
Uma vez definido o escopo do SOC é possível identificar quais elementos poderão (ou mesmo preferencialmente serão) terceirizados e quais farão parte de uma operação interna - lembrando que não há uma resposta correta aqui, trata-se de uma decisão que depende da realidade do negócio.
Em boa parte dos casos, o Orçamento é um fator determinante para essa decisão. Além das tecnologias necessárias para sua operação, os SOCs devem funcionar em um regime 24x7 operado por uma equipe multidisciplinar. Montar esse time depende de uma grande capacidade de retenção de profissionais (em um cenário de escassez de mão de obra especializada em segurança).
A terceirização pode trazer uma série de vantagens como:
Aumento na eficácia na detecção e resposta a incidentes: empresas que fornecem serviços terceirizados de SOC contam com profissionais altamente treinados e experientes nesta operação.
Redução nos Custos: terceirizar parte ou a totalidade da operação significa evitar os custos envolvidos na manutenção do SOC
Reduz a carga das equipes de segurança internas: se sua empresa já conta com um time de segurança, terceirizar a operação do SOC pode reduzir o tempo gasto com monitoração e gerenciamento de incidentes, permitindo seu time focar em outras tarefas. 
 Em contrapartida, montar uma estrutura de SOC internalizada em sua totalidade garante que a operação seja completamente voltada à realidade da corporação.
Ter a real noção do dimensionamento do SOC, seus objetivos e a capacidade de investimento neste segmento tornará mais clara a resposta para o "quando (ou quanto) terceirizar".
Conheça o Intelligence Driven SOC da Tempest
A fim de ajudar as organizações a lidar com os desafios apresentados neste artigo, a Tempest desenvolveu o Intelligence Driven SOC, oferecendo às empresas a oportunidade de contar com um Centro de Operações de Segurança completo que combina, entre outras características: 
Conexão com o mapa de riscos existente, trazendo contexto de negócio; A mais avançada Engenharia de Detecção de Ameaças, fornecendo  indicadores de cobertura através do mapeamento com base no MITRE ATT&CK™; Governança e acompanhamento com base em indicadores de desempenho ligados a casos de uso extraídos a partir da compreensão do mapa de riscos; A mais alta tecnologia e inteligência voltada para Cibersegurança, aliando equipe capacitada, plataforma de compartilhamento e bases de informação geolocalizadas.
Para saber mais sobre o Intelligence Driven SOC baixe o ebook Um novo SOC para os novos desafios de segurança.
Contar com o parceiro certo faz a diferença na proteção dos dados em qualquer ambiente
A Tempest Security Intelligence é uma empresa brasileira com atuação global. É a maior companhia brasileira especializada em cibersegurança e prevenção a fraudes digitais. 
Sediada no Recife, a Tempest conta também com escritórios em São Paulo e Londres, com mais de 600 colaboradores. 
Ao longo de seus 23 anos, a Tempest ajudou a proteger mais de 600 empresas de todos os portes e setores, dentre elas companhias do setor financeiro, varejo, e-commerce, indústria e healthcare, atuando em clientes nacionais e internacionais atendidos tanto pelo time no Brasil quanto no Reino Unido. 
Em 2020, a Tempest conquistou um parceiro de peso para continuar na vanguarda da cibersegurança, recebendo um grande aporte da Embraer, companhia brasileira de engenharia aeroespacial, o qual resultou em um dos maiores investimentos já realizados na história do setor de cibersegurança na América Latina.
  • 3,863 views
Você acessa o portal mente binária e, ao invés de preencher aqueles formulários gigantescos de login apenas pressiona logar-se com a sua conta Google. Escolhe seu nome de usuário e, sem inserir nenhuma senha ou outra informação você está logado na plataforma. A tecnologia utilizada para essa integração geralmente é o padrão OAuth 2.0, que permite que uma aplicação tenha acesso a alguns dados de um usuário registrado em sistemas terceiros, como o Google, sem a necessidade de conhecer as credenciais desse usuário.
É justamente essa possibilidade de não compartilhar credenciais para obter acesso à informação que contribui para a popularização da tecnologia. Imagine ter acesso a todas as informações necessárias do usuário e deixar que plataformas muito mais consolidadas cuidem da autorização, parece um caminho muito mais seguro, né?
A resposta é: depende. Como tudo na área de tecnologia, é muito importante configurar as soluções a serem utilizadas de maneira correta para evitar problemas que coloquem em risco a segurança da aplicação. Para entender alguns dos problemas que podem resultar de uma configuração insegura deste protocolo, vamos dar um passo atrás e entender como essa tecnologia funciona. Caso queira dar mais um passo para trás e ler um pouco sobre autenticação primeiro, aqui mesmo na Mente Binária tem o artigo Autenticação e Ataques Relacionados, do @Andre Smaira.
Conhecendo o protocolo OAuth 2.0
OAuth 2.0 é um protocolo de autorização que permite não só o compartilhamento de dados com aplicações de terceiros mas também o controle de quais informações serão compartilhadas. Dessa forma, após o usuário conceder a uma aplicação (como o portal Mente Binária) algumas de suas informações (nesse caso, as disponíveis em sua conta Google), é possível interagir com o portal sem a necessidade de se autenticar na aplicação.
A figura a seguir demonstra uma visão geral de como esse processo acontece, conforme apresentada na RFC 6749:

Na figura acima, é possível perceber a existência de três agentes no funcionamento desse protocolo:
O cliente (Client). Representado em cinza na figura, representa a Mente Binária ou a aplicação que estamos utilizando, e que deseja utilizar mais informações do usuário. O usuário que possui os dados (Resource Owner). Esse é você, que possui o poder de compartilhar ou não as suas informações. A aplicação que possui seus dados (Authorization Server e Resource Server). Embora em alguns casos a aplicação tenha um sistema de autenticação separado do servidor que possui esses dados (por isso a divisão na imagem), é essa aplicação que possui a informação que será compartilhada através do protocolo OAuth 2.0. Embora essa imagem represente bem como essa comunicação ocorre de maneira geral, deixa um pouco a desejar em caráter mais técnico, visto que abstrai demais o funcionamento do protocolo. Inspirado no excelente artigo da Salt Labs sobre o tema, construí a seguinte imagem para auxiliar no entendimento do processo:

A primeira etapa ocorre quando o usuário Breno decide se cadastrar ou se autenticar no site (caso já esteja cadastrado). O site, no entanto, necessita de uma prova de que Breno é quem diz ser, e pede para que ele solicite ao Google um token aleatório que o identifique na aplicação OAuth 2.0. Isso ocorre no momento em que o usuário pressiona o botão, quando uma nova janela é aberta com uma URL análoga à seguinte:
https://accounts.google.com/o/oauth2/v2/auth/oauthchooseaccount?access_type=offline&client_id=152067940327-ma5q9tjenci55tfs3mck9fe7npphvek4.apps.googleusercontent.com&response_type=code&redirect_uri=https%3A%2F%2Fwww.mentebinaria.com.br%2Foauth%2Fcallback%2F&state=STATE&code_challenge=CODE_CHALLENGE&code_challenge_method=CODE_CHALLENGE_METHOD&scope=profile%20email&service=lso&o2v=2&flowName=GeneralOAuthFlow Nessa URL, alguns valores são essenciais para o funcionamento do OAuth:
client_id: Este parâmetro identifica o cliente que solicita a informação. Na URL compartilhada, esse valor corresponde ao identificador atrelado ao portal Mente Binária. response_type: Define o conteúdo que será retornado na resposta. Esse valor é relevante para sabermos quais problemas de segurança podem ocorrer na aplicação. redirect_uri: Após a autenticação, o token gerado será enviado por meio de um redirecionamento à página informada neste parâmetro. A forma como essa página é configurada também é relevante para a segurança da aplicação. state: Salva um estado da aplicação. Geralmente é usado como uma medida de segurança secundária. Dessa forma, se um token é devolvido à aplicação com um estado que não é conhecido por ela, ela pode considerar que algo de errado aconteceu e interromper o processo sem obter as informações do usuário. scope: Este campo especifica quais informações serão compartilhadas através do protocolo OAuth. Após se autenticar e autorizar a aplicação a obter acesso a essa página, o usuário recebe um código complexo (etapas 3 e 4), identificado como authorization grant na primeira figura. Esse valor é então enviado diretamente à Google pela aplicação, que valida o usuário e as permissões aos quais esse token está atrelado, retornando esses dados a aplicação solicitante (etapas 6 e 7).
Após todo esse processo, a aplicação pode atrelar esse valores à sessão do usuário e até armazená-los no banco de dados, possibilitando a autenticação de um visitante na página sem a necessidade de digitar, ou até mesmo possuir, uma senha para a aplicação.
Problemas de segurança associados ao uso de OAuth 2.0
A ideia é muito boa, mas deve ser implementada com cuidado, visto que a utilização errada da aplicação pode levar a graves incidentes de segurança. A seguir, eu listo alguns problemas associado ao uso ou configuração insegura da tecnologia.
Pre-account Takeover
Embora a prática de se utilizar o OAuth para se autenticar nas aplicações tenha se difundido, ela raramente substitui por completo a existência de uma autenticação oferecida pela aplicação. Dessa forma, é preciso dobrar também a cautela durante a implementação. A imagem a seguir demonstra como o portal Mente Binária permite ambas as formas de se registrar:

O aumento na complexidade de uma aplicação também resulta em mais cuidados de segurança. Para este cenário, suponha que você se registrou no portal utilizando o e-mail de um conhecido, que ainda não se registrou no ambiente, usando uma senha de sua escolha. No entanto, como você não tem acesso ao conteúdo do endereço de e-mail, você é incapaz de confirmar a identidade (através do recurso de confirmação de e-mail) e começar a utilizar a plataforma. Caso a aplicação não tenha sido configurada de maneira correta, como demonstra esse report da HackerOne, se a vítima um dia decidir se autenticar no ambiente utilizando o OAuth como opção, o ambiente automaticamente irá validar o acesso criado usando o endereço de email, possibilitando que o atacante consiga acessar a conta da vítima através da senha que foi previamente configurada. Portanto, é necessário sempre ter atenção sobre as diferenças e implicações dos dois mecanismos paralelos de registro e autenticação na plataforma para garantir que o ambiente fique realmente seguro.
Open Redirects
Outro fator que pode levar a diversos problemas de segurança na aplicação é a configuração insegura das validações do parâmetro redirect_uri. Conforme comentado durante a explicação do protocolo, após se registrar com sucesso na aplicação, o usuário é redirecionado para a página presente neste parâmetro e, junto com esse redirecionamento, o token de acesso é enviado através do fragmento de hash presente na URL.
Se não houver validações suficientemente seguras desse parâmetro, um atacante pode enviar à vítima um link da página de login OAuth porém substituindo o conteúdo do parâmetro por um endereço controlado pelo atacante. Dessa forma, ao realizar o login, o token de authorization grant será enviado à uma página controlada pelo atacante e não à página que espera este parâmetro na aplicação. Este cenário pode ser observado nesse report. É preciso se atentar também ao fato de que, mesmo que haja validação do domínio da URL no parâmetro, o diretório para o qual essa URL aponta também deve ser validado, visto que se a página possuir um open redirect em algum outro diretório, um atacante poderá abusar desse comportamento para substituir o parâmetro para uma página em que ele é capaz de forçar um redirecionamento e, assim, obter também acesso ao conteúdo do token. O artigo da Salt Labs mencionando anteriormente demonstra de maneira muito bem explicada como esse ataque pôde ser realizado na aplicação do Booking. Já neste outro report da HackerOne, é possível visualizar que permitir o uso de outros subdomínios do site principal nesse parâmetro também pode facilitar que um atacante encontre e abuse de um open redirect para roubar tokens válidos no ambiente. Por fim, neste report super bem explicado, outro membro do ELT, @caioluders (twitter.com/caioluders), demonstra como é preciso estar atento a forma como essa validação é feita, para que o atacante não encontre uma forma de evadir esse mecanismo de segurança.
Leakando a URL
Mesmo que não haja possibilidade de se obter o token de acesso através do abuso do parâmetro redirect_uri, um atacante pode encontrar outras formas de obtê-lo diretamente através da URL. Neste report, por exemplo, o pesquisador utilizou do próprio design da aplicação para roubar tokens, visto que um usuário poderia criar uma página com seu próprio Google Analytics, que registra o conteúdo da página. Vale lembrar que, conforme descrito durante a explicação do protocolo, embora muitas vezes esse token tenha funcionamento único, o atacante pode utilizar um valor que não será aceito como parâmetro state. Dessa forma, ao receber o token, a aplicação tentará validar seu estado e o recusará devido ao valor inesperado. Assim, o atacante será capaz de, através do meio encontrado para vazar esse valor, utilizá-lo de maneira válida.
PostMessage
Versões mais recentes do OAuth 2.0 utilizam o método postMessage() como uma forma considerada segura de realizar o envio e recebimento dos tokens de uma aplicação. Neste report, um pesquisador demonstra que se deve tomar cuidado ao se designar a qual página será enviado o token obtido pelo OAuth. Ainda no mesmo report, o pesquisador percebe que o token é sempre enviado ao opener desse endereço e abusa desse comportamento genérico para tornar sua página o opener através da chamada windows.open() para o endereço vulnerável.
Além disso, Frans Rosén escreveu um excelente artigo sobre como alguns métodos postMessage() de bibliotecas de terceiros podem resultar no vazamento do token OAuth.
Cookie Bomb
Esta é uma vulnerabilidade que ocorre quando o atacante descobre uma forma de inserir cookies arbitrários no navegador de um usuário. Dessa forma, um atacante é capaz de inserir cookies muito grandes para um usuário, resultando em uma negação de serviço temporária deste usuário à aplicação devido ao envio de um conteúdo muito grande nas requisições. Nesta publicação, o pesquisador filedescriptor discute como essa vulnerabilidade pode ser abusada através de um XSS para impedir que a página presente no parâmetro redirect_uri de uma autenticação OAuth seja acessada e, dessa forma, o atacante possa obter acesso a esse token através do XSS, visto que o cookie bomb impediu o uso do token pela aplicação.
Para se aprofundar mais
Para ir além no assunto, veja esse artigo de um pesquisador contando como explorou o OAuth do facebook para conseguir roubar contas de usuários e confira também os write-ups de exploração de vulnerabilidades em OAuth neste repositório no GitHub. 😉
 
  • 5,834 views
Seja para tornar suas operações mais eficientes, seja para atender novas demandas de clientes ou fornecedores,, a adoção de novas tecnologias pelas organizações, acelerada nos últimos 3 anos, colaborou para o aumento da complexidade do ambiente corporativo. 
Dentre as muitas consequências destes processos - que incluem a migração de processos e aplicações para a nuvem, adoção de novos regimes de trabalho, entre outros -  destacam-se o aumento sem precedentes das fronteiras do negócio e a dificuldade de se obter visibilidade absoluta dos riscos a que ele está exposto. 
Esta visibilidade depende, entre outras coisas, de saber que dispositivos estão conectados ao ambiente e quais os riscos a que estes dispositivos estão expostos, além de saber quais vulnerabilidades estão afetando minha estrutura, que dados estão trafegando, etc. 
Neste cenário, os serviços de consultoria de segurança (security consulting), mais especificamente o Pentest, ajudam as empresas a identificar vulnerabilidades em seus sistemas e aplicativos que podem ser exploradas por cibercriminosos, sejam elas brechas na segurança da rede, erros de configuração, falhas de software, entre tantas outras. 
Mas nem todo pentest é igual; existem inúmeras aplicações para estes testes, e para ajudar as empresas a encontrar a solução ideal para cada caso a Tempest desenvolveu o Guia do Comprador de Pentest.
Pentest, ou Teste de Intrusão: o que é e como escolher o melhor para cada situação
Pentest, ou teste de intrusão, consiste em simular um ataque em uma rede, aplicação ou sistema para identificar vulnerabilidades e avaliar a efetividade das medidas de segurança existentes na organização, permitindo que as empresas aprimorem suas estratégias e garantam maior visibilidade no que estão protegendo.
Eles são de extrema utilidade seja para avaliar o compliance de uma empresa frente a regras de mercado ou regulamentações, seja para avaliar se um software ou aplicação está sendo desenvolvido com segurança.
Porém, há muitos tipos de pentest no mercado de diferentes fornecedores, cada um com um escopo e descrição, proporcionando ao comprador diversas possibilidades de escolha. Neste cenário, é preciso avaliar um conjunto de recursos para poder qualificar uma solução aderente ao negócio.
No Guia do Comprador de Pentest da Tempest você conhece melhor cada um dos tipos de pentest disponíveis atualmente, também tem acesso a uma série de dicas e conhece os seis elementos essenciais que irão ajudar a avaliar um fornecedor  para encontrar a solução mais adequada para sua situação.
Faça o download do Guia
Diferenciais do Pentest da Tempest
Com início das operações em 2001, o Pentest da Tempest conta com a experiência e conhecimento do maior time técnico da América Latina  (SOC, Threat Hunting, Incident Response, Software Engineering, Red Team,  Vulnerability Management e  Threat Intelligence) para entregar um serviço de alta profundidade, com resultados robustos, tecnicamente sofisticados e efetivamente aderentes  aos desafios e necessidades dos nossos clientes. 
Toda essa expertise é aplicada a diversas modalidades de pentest que incluem testes aplicados a aplicações web, dispositivos IoT, redes wi-fi ou até mesmo testes de estruturas físicas.
Contar com o parceiro certo faz a diferença na proteção dos dados em qualquer ambiente
A Tempest Security Intelligence é uma empresa brasileira com atuação global. É a maior companhia brasileira especializada em cibersegurança e prevenção a fraudes digitais. Sediada no Recife, a Tempest conta também com escritórios em São Paulo e Londres, com mais de 600 colaboradores. 
Ao longo de seus 23 anos, a Tempest ajudou a proteger mais de 600 empresas de todos os portes e setores, dentre elas companhias do setor financeiro, varejo, e-commerce, indústria e healthcare, atuando em clientes nacionais e internacionais atendidos tanto pelo time no Brasil quanto no Reino Unido. 
Em 2020, a Tempest conquistou um parceiro de peso para continuar na vanguarda da cibersegurança, recebendo um grande aporte da Embraer, companhia brasileira de engenharia aeroespacial, o qual resultou em um dos maiores investimentos já realizados na história do setor de cibersegurança na América Latina.
  • 849 views
Neste artigo vamos descrever como funciona a criptografia de curvas elípticas. Para isso é preciso saber como funciona aritmética modular. O artigo Introdução ao RSA, do @c4v0k, tem tudo que precisamos saber, então dá um pulo lá se não entender muito sobre a operação mod. Ao invés de estudar como implementar um esquema de curvas elípticas de forma segura e sua matemática por trás, vamos entender neste artigo a essência do assunto. 🙂
Curvas Elípticas
Uma curva elíptica é definida por uma equação cúbica. Exemplos de curvas incluem Weierstrass, Montgomery e Edwards. Essas três têm uma relação chamada equivalência birracional, então existe uma forma de transformar uma curva e todas as suas propriedades de um tipo para outro. Vamos usar a curva de Weierstrass na forma curta como exemplo pois é a mais simples de entender. A equação da curva é definida como:
y² = x³ + ax + b
Ao plotar a curva no plano cartesiano com a = -2 e b = 4, temos esse gráfico:

Curva definida pela equação y² = x³ - 2x + 4
Um grupo, em matemática, é uma estrutura algébrica que tem uma operação binária (no sentido de dois operadores). Nossa curva vai ser um grupo, então precisamos definir uma operação nela: a operação de soma. Peguemos dois pontos A e B da curva, totalmente aleatórios. Se traçarmos uma reta entre esses dois pontos, teremos um terceiro ponto que a reta vai cruzar. Esse terceiro ponto vai ser o espelho (no eixo x) do ponto que representa A + B. Veja a imagem para entender melhor:

Soma dos pontos A e B
Se repetirmos essa operação de soma com pontos da curva várias vezes, sempre teremos um ponto diferente como resultado. Mas, e se acontecer de aleatoriamente termos os pontos A e B iguais, como fica a soma de A + A? Para resolver essa soma, traçamos a reta tangente ao ponto A e o segundo ponto que a reta tocar na curva será o espelho de A + A:

Duplicação de um ponto A
Achou complicado esse negócio de tangente? Na verdade, é só imaginar que o ponto B está muito pertinho do ponto A, então a operação de soma acaba sendo a mesma essencialmente, só o cálculo dela que muda. Para terminar a definição do grupo na nossa curva, precisamos também de um inverso da soma. Vamos chamar de "menos" com o sinal "-", então o ponto -A será o inverso do ponto A. O inverso é mais tranquilo: só espelhar o ponto na coordenada x, logo se o ponto A é (x, y) o ponto -A é (x, -y).
Para facilitar a notação, quando somarmos dois pontos iguais, vamos chamar de 2A. Assim, se somarmos mais um A, teremos 3A e assim sucessivamente. Imagine agora que somemos A "n" vezes. Cada vez que a gente soma A, o resultado é um ponto diferente na nossa curva, logo seria complicado sabermos quantas vezes somamos A. Nosso "n" pode ser então um segredo, já que é difícil descobri-lo. Olhe a imagem abaixo e tente descobrir o "n":

Tente descobrir o valor de "n" na imagem
Só de olhar a imagem é difícil saber né? Eu sei que "n" é 17 porque fui eu que escolhi esse número. Mas quem vê de fora não descobre sem eu contar. Logo, "n" vai será a chave privada da nossa criptografia e "nA" será a chave pública. Mas tem um problema aí: se usarmos ponto flutuante, vai acabar acumulando erros na hora de somar todas essas vezes. Por isso, vamos tirar o mod de um primo p grandão, aí nossa equação da curva vai ficar assim:
y² = x³ + ax + b mod p
Com esse mod p grandão, teremos muitos pontos possíveis para somar! Eu garanto que a operação de soma e inverso funcionam muito bem nessa equação também. Além disso, será melhor para armazenar nossas chaves, pois todos os números são inteiros e conseguimos representá-los sem precisar de bits extras de precisão.
Um outro problema...
Imagina que eu escolha o número 17 para minha chave privada. Seria muito fácil qualquer um encontrá-la... Só tentar 1, 2, 3… até 17. Então, como p é um número grande, também podemos escolher nossa chave privada como um número grande, deixando-a mais difícil de ser descoberta! Vamos supor que o número tenha 256 bits, isso dá 78 dígitos. Para calcular nossa chave privada vamos precisar somar A o mesmo número de vezes que alguém que quer descobrir nossa chave precisa. Então, precisamos pensar numa forma de somar A "n" vezes rápido.
Lembra quando eu falei de grupo na matemática? Então, além da definição de soma, também temos as seguintes leis neste grupo:
Quando somamos qualquer dois pontos A + B = C, então C sempre vai estar no grupo também. O grupo tem associatividade, ou seja, a soma (A + B) + C para quaisquer pontos vai ser igual a A + (B + C). Existe um elemento neutro O, de forma que A - A = O. Provar que isso é verdade para curvas elípticas é um pouco complicado, no entanto. Se quiser saber mais sobre, veja no livro "Introdução à Criptografia com Curvas Elípticas", na seção 4.1.2, escrito por Sally Andria, Rodrigo Gondim e Rodrigo Salomão e publicado pelo IMPA.
Tá bom, mas o que isso tem a ver com somar A "n" vezes rápido? Bom, por causa dessa associatividade, A + 3A é igual a 2A + 2A. Então dá para representar nosso "n" em binário e aí duplicamos o ponto A várias vezes. Isso vai trocar a complexidade do problema para quantos bits o "n" tem e não para quanto ele vale em decimal. Vamos ver um exemplo com "n" sendo 315. A representação desse número em binário é 100111011, nessa tabela abaixo podemos ver as potências de 2 referente a cada posição:
 

Então podemos somar A 315 vezes como se fosse dessa forma:
28A + 25A + 24A + 23A + 21A + 20A
Com isso, vamos usar bem menos operações que 315.
Já sobre o elemento neutro O, imagine o que acontece quando somamos um ponto com o inverso dele, ou seja A + (-A). Ao traçar a reta entre esses dois pontos, teremos uma reta vertical, ou seja, paralela ao eixo y e que não corta a curva em nenhum outro ponto. Existe uma outra lei da geometria projetiva, aliás essa é a geometria que a gente tá vendo aqui, que diz que duas retas paralelas se encontram no infinito. Dito isso, vamos chamar esse ponto O de ponto no infinito e ele sempre será o elemento neutro, como o 0 (zero) na soma ou o 1 (um) na multiplicação.

A representado na nossa curva definida anteriormente
Troca de chaves
Um dos principais usos da criptografia de curvas elípticas é na troca de chaves. No protocolo TLS, a primeira coisa que acontece, criptograficamente falando (na maioria das vezes) é uma troca de chaves antes de o protocolo prosseguir com um esquema de criptografia simétrica para troca de dados segura entre o servidor e o cliente. Veremos agora como funciona um esquema de troca de chaves aplicável a qualquer grupo matemático. O esquema se chama Diffie-Hellman.
Vamos pensar em duas pessoas que querem ter uma chave secreta em comum. Chamaremo-os de Aline e Bernardo. Aline vai criar uma chave privada "n" e Bernardo vai criar uma chave privada "m", então os dois vão estabelecer um ponto de partida, que é o ponto A que vimos anteriormente. Já que os dois têm um mesmo ponto de partida, eles podem enviar a chave pública um para o outro, então Aline vai enviar "nA" para Bernardo e Bernardo envia "mA" para Aline. Já que os dois possuem as chaves públicas, então eles podem chegar em um acordo de chave multiplicando a chave privada na chave recebida.
Aline recebe "mA" e soma esse ponto "n" vezes, então ela vai ter "nmA". Já Bernardo recebe "nA" e soma esse ponto "m" vezes, então ele vai ter "nmA". A chave compartilhada vai ser "nmA" e eles podem seguir um canal secreto de comunicação. Veja a imagem para tentar entender melhor, nela eu usei "n" igual a 5 e "m" igual a 3.

Esquema Diffie-Hellman de troca de chaves, usando ECC
Criptografia
O mais comum de se ver no dia a dia, entre duas entidades, é primeiro um esquema de troca de chaves e depois a troca de dados por meio de um esquema simétrico de criptografia, como por exemplo o AES. Mesmo assim, veremos na prática um esquema um pouco diferente que não depende da troca de chaves. Esse esquema chama-se El Gamal. Aline e Bernardo serão os protagonistas de novo. 🙂
Aline será a pessoa que receberá a mensagem de Bernardo. Então ela precisa enviar a chave pública para Bernardo encriptar a mensagem que ele quer enviar, logo, Aline cria uma chave privada "n" e uma chave pública "P = nA". Ela envia a chave pública e o ponto de partida A para Bernardo. Bernardo tem uma mensagem "M" que quer enviar para Aline, então precisará gerar um número aleatório "k" e criar a sua própria chave "K = kA". Não só isso, Bernardo também vai enviar "C = kP + M" para Aline. Quando Alice receber esses dois pontos (C, K), basta que ela compute "C - nK" para recuperar a mensagem. Veja a imagem com a prova para tentar entender melhor:

Esquema Elgamal de criptografia usando ECC
Se gostou desse assunto você pode ver meu writeup de um desafio de CTF que envolve curvas elípticas. O CryptoHack também é um ótimo site para aprender sobre criptografia de curva elíptica (ECC, no acrônimo em inglês). Bons estudos!
  • 5,053 views
Prefácio
Este artigo abordará um recurso do sistema de arquivos NTFS, muito pouco conhecido e mal documentado, que leva o nome de Alternate Data Stream ou simplesmente ADS. O artigo apresenta conceitos, usos, formas de identificação e maneiras de lapidar a técnica. Embora essa técnica de ocultação de cargas maliciosas em sistemas de arquivos seja considerada antiga, seu uso ainda é muito relevante nos dias atuais.
O que é Alternate Data Stream (ADS)?
O Alternate Data Stream (ADS) é um recurso do sistema de arquivos NTFS, implementado pela primeira vez no Windows NT 3.1, com o intuito de permitir a compatibilidade com os sistemas de arquivos MAC HFS (Macintosh Hierarchical File System). De maneira sucinta, esse recurso permite que os arquivos contenham mais de um fluxo de dados. 
Os arquivos em NTFS têm ao menos um fluxo de dados visível. Em ambientes Windows, esse fluxo de dados padrão é chamado de atributo MFT :$DATA ou fluxo de dados sem nome.
Experimentação
Para entendermos melhor como funciona esse fluxo de dados, vamos abrir o Prompt de Comando para fazer alguns testes. Primeiramente, vamos começar criando um arquivo de texto com a string Mente Binária:

Observe o tamanho do arquivo gerado. Como segundo passo, vamos inserir um segundo fluxo de dados dentro desse arquivo:

Note que ao realizar o processo de listagem, o arquivo mentbin.txt permanece com 18 bytes, não sendo possível notar qualquer diferença aparente. Para verificar a existência de um ADS precisamos utilizar da flag /r para exibir o fluxo de dados alternados, como help do programa sugere:

Agora sim parece que acendemos a luz e conseguimos ver o hf.txt  dentro do arquivo mentbin.txt:

Ao abrir o arquivo com o Bloco de Notas, com o comando type ou Windows Explorer apenas o fluxo de dados principal é exibido em tela. 
Para ler o conteúdo de um fluxo, podemos utilizar os comandos more ou sort:

Caso de uso
Mas agora surge a pergunta, porque bulhufas isso é utilizado? Bom, acredito que conseguimos responder essa pergunta com uma demonstração prática. Quando baixamos arquivos da internet usando um browser por exemplo é criado um $DATA para identificar de onde esse arquivo foi baixado.
Demonstração
Vamos baixar a imagem do gatinho do post de Detectando overlays em executáveis ELF do @Fernando Mercês:

Salvamos a imagem:


Só pra garantir, verificamos o tipo de arquivo com o comando file:

Ao listar os arquivos com dir /r, é possível ver a existência de um ADS chamado Zone.Identifier:

Verificando seu conteúdo conseguimos extrair a informação de onde essa imagem foi baixada. Legal né?

Ocultando binários no fluxo de dados
Com esse recurso podemos esconder qualquer tipo de dado usando o ADS, então que tal começarmos escondendo o binário da calculadora? Analise:

Utilizando do wmic vamos executar o binário oculto.
A ferramenta Windows Management Instrumentation Command-line (WMIC) é uma interface de script e linha de comando que simplifica o uso do Windows Management Instrumentation (WMI) e dos sistemas gerenciados através do WMI. Embora no site da Microsoft exista um aviso informando que esse recurso foi preterido a partir do Windows 10 versão 21H1, sendo substituído pelo utilitário Windows PowerShell para WMI, ele continua presente em versões mais atuais do sistema. Vamos usá-lo:

calc.mp4 Mágicaaaaaa! 🪄
Relevância Forense 
Do ponto de vista forense, os fluxos de dados alternativos do NTFS têm implicações graves para a anti-forense, uma vez que invasores podem ocultar arquivos incriminadores ou cargas maliciosas por meio de fluxos de dados ocultos em outros arquivos além da possibilidade de utilizar dessa técnica para exfiltração de dados. Demonstrarei agora como é feito o processo de identificação.
Identificação
Como mencionado no prefácio, essa técnica de esconder dados usando ADS já é bem manjada, de modo que o Windows Defender e vários antivírus já conseguem fazer esse mapeamento. Além disso,  um administrador de sistemas ou um analista forense poderiam facilmente achar esses arquivos usando simples linhas de comando. Por exemplo:

Explicação da sintaxe
% implementa um foreach ? coloca uma condição where gi forma curta de Get-Item gci forma curta Get-Childitem ne Not Equal (Não é Igual) Lapidando a técnica
E se eu te falar que existe uma forma de lapidar essa técnica dificultando sua identificação, com o uso de nomes reservados no Windows? 🙂
Alguns nomes de uso reservado no Windows são: CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LP6, LPT7, LPT8 e LPT9.
Vamos olhar o que acontece quando tentamos criar qualquer tipo de arquivo, usando algum desses nomes reservados:

O arquivo não é criado. 😟
Pulo do 🐈 
Existe uma forma de realizar o bypass da verificação de nomes reservados. Utilizando os prefixos "\\?\" ou "\\.\"  é possível informar às APIs do Windows para desabilitar toda a análise de cadeia de caracteres enviado a cadeia que a segue diretamente para o sistema de arquivo possibilitando dessa forma criar arquivos com esses nomes.
Demonstração

Opa, opa, olha só, conseguimos criar o arquivo.
Agora vamos analisar o que acontece quando colocamos um fluxo de dados dentro de um arquivo com nome reservado.

Espera ai, cadê o ADS do arquivo COM.TXT?

Esse é o pulo do gato, o Windows não consegue mais detectar o ADS do arquivo, apenas quem criou o arquivo e sabe o nome pode ver/executar seu conteúdo.

Olha o que acontece quando tentamos buscar por esse arquivo usando os comandos demonstrados anteriormente:

Observação
Existe uma única solução chamada LADS que consegue identificar o fluxo de arquivo em nomes reservados, no entanto essa ferramenta não recebe mais atualização desde 2015.

Referências
https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file https://www.sans.org/blog/alternate-data-streams-overview/ https://owasp.org/www-community/attacks/Windows_alternate_data_stream https://www.deepinstinct.com/blog/the-abuse-of-alternate-data-stream-hasnt-disappeared https://github.com/codejanus/ToolSuite/blob/master/lads.exe
  • 3,322 views
Introdução 
Olá pessoal! Este é mais um artigo da série onde falo sobre técnicas de anti-engenharia reversa. Neles compartilho um pouco dos tutoriais práticos que desenvolvi ao longo das minhas pesquisas e estudos. No primeiro artigo, falei sobre a categoria de anti-debugging TLS Callback. Agora vou falar um pouco sobre as técnicas da categoria que utilizam flags de depuração do próprio processo para detectar o debugger. Antes de mais nada, vale entender o que são essas flags. 
 
O que são flags de depuração?
Estas flags são valores presentes dentro do espaço de endereço do processo, permanecendo na memória até o encerramento deste programa. A presença e/ou determinado valor destes bits podem indicar que o processo está em um ambiente de depurador. Como estas técnicas são válidas apenas para o ambiente Windows, seu significado e valores são definidos na documentação oficial do SO (WinAPI) [1], entretanto algumas flags podem não ser documentadas e, neste caso, somente se encontra informação em livros como o Windows Internals [2].
A primeira que vamos analisar é a NtGlobalFlag, desenvolvida na época do antigo Windows NT. Esta flag é definida no cabeçalho do Process Environment Block (PEB) de todos processos no sistema e é usada especificamente para indicar se o processo está executando ou não em depurador.
Antes de aprofundar nas particularidades desta flag, precisamos entender o que é a PEB, que foi citada anteriormente. De forma resumida, é uma estrutura que existe em cada processo do Windows e é apontada por outra estrutura chamada TEB (Thread Environment Block), que por sua vez contém informações em relação às threads do processo.
O código da PEB é composto por uma struct e sua versão para 32 bits no header windows.h ou winternl.h é a seguinte:
typedef struct _PEB {    BYTE                          Reserved1[2];    BYTE                          BeingDebugged;    BYTE                          Reserved2[1];    PVOID                         Reserved3[2];    PPEB_LDR_DATA          Ldr;    PRTL_USER_PROCESS_PARAMETERS  ProcessParameters;    PVOID                         Reserved4[3];    PVOID                         AtlThunkSListPtr;    PVOID                         Reserved5;    ULONG                         Reserved6;    PVOID                         Reserved7;    ULONG                         Reserved8;    ULONG                         AtlThunkSListPtr32;    PVOID                         Reserved9[45];    BYTE                          Reserved10[96];    PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;    BYTE                          Reserved11[128];    PVOID                         Reserved12[1];    ULONG                         SessionId;  } PEB, *PPEB; *O 3º byte desta estrutura é o campo BeingDebugged e este é definido pelo Windows para todo binário que está sendo executado, sendo 0 (padrão) para indicar que o processo não está sendo depurado e 1 para depurado. Este byte é avaliado na técnica abordada no Curso de Engenharia Reversa Online (CERO) através da função IsDebuggerPresent() e por conta disto esta técnica não será abordada neste artigo.
A Aula 24 - Anti-debug, do CERO, aborda a PEB de forma prática. Uma referência completa sobre a PEB também pode ser acessada em [3].
NtGlobalFlag
Esta flag também é um campo da PEB e se encontra no offset 0x68 em ambientes 32 bits, ou offset 0xBC em 64 bits, contados a partir do seu início. Esta flag é usada para rastreamento e depuração de programas. Seu valor é 0 por padrão, indicando que não há depurador no ambiente.
Caso se inicie o programa primeiro e depois de já iniciado, se analise seu processo no depurador, os campos da NtGlobalFlag não são alterados, deixando esta abordagem sem efeito. No entanto, caso se execute o programa diretamente  em um depurador, as seguintes flags serão definidas:    
FLG_HEAP_ENABLE_TAIL_CHECK    (0x10)     FLG_HEAP_ENABLE_FREE_CHECK    (0x20)     FLG_HEAP_VALIDATE_PARAMETERS  (0x40)  
A presença de um depurador no ambiente é confirmada ao se verificar o valor 0x70 resultante da operação OR entre estas flags.
Disassemble de processo 32 Bits:
mov eax, fs:[30h]     // acessa a PEB no registrador de segmento mov al, [eax+68h]    // a partir da PEB acessa a flag NtGlobalFlag and al, 70h           // soma as flags FLG_HEAP_* cmp al, 70h           // verifica se o valor da soma é 0x70 call  being_debugged  // caso positivo, avisa sobre depuração  
Disassemble de processo 64 Bits:
mov rax, gs:[60h]     // acessa a PEB no registrador de segmento mov al, [rax+BCh]     // a partir da PEB acessa a flag NtGlobalFlag and al, 70h cmp al, 70h call  being_debugged Disassemble de processo WOW64 (64 Bits que aceita também 32 bits):
mov eax, fs:[30h]     // acessa a PEB no registrador de segmento mov al, [eax+10BCh]   // a partir da PEB acessa a flag NtGlobalFlag and al, 70h cmp al, 70h call  being_debugged  
Código de exemplo:
#include <windows.h> #include <iostream> using namespace std; // define o valor das flags #define FLG_HEAP_ENABLE_TAIL_CHECK   0x10 #define FLG_HEAP_ENABLE_FREE_CHECK   0x20 #define FLG_HEAP_VALIDATE_PARAMETERS 0x40 // executa a operação OR entre o valor de todas as flags #define NT_GLOBAL_FLAG_DEBUGGED (FLG_HEAP_ENABLE_TAIL_CHECK | FLG_HEAP_ENABLE_FREE_CHECK | FLG_HEAP_VALIDATE_PARAMETERS) // se não for 64 bits #ifndef _WIN64 PVOID pPeb = (PVOID)__readfsdword(0x30);    // PEB DWORD dwNtGlobalFlag = *(PDWORD)((PBYTE) pPeb + 0x68); // flag #else // o mesmo procedimento para 64 bits PVOID pPeb = (PVOID)__readgsqword(0x60); DWORD dwNtGlobalFlag = *(PDWORD)((PBYTE)pPeb + 0xBC); #endif // _WIN64 // função que acusa depurador e sai void being_debugged() {     std::cout << "Stop debugging program!" << std::endl;     exit(-1); } int main() { // se em ambiente de depurador chama função de saída     if (dwNtGlobalFlag & NT_GLOBAL_FLAG_DEBUGGED)         being_debugged();     eles  // senão segue normalmente         std::cout << "Hello World!\n";     return 0; } Desabilitando a Técnica
Para desviar desta verificação, basta definir o campo NtGlobalFlag da estrutura PEB com 0 antes que este valor seja verificado pela proteção anti-depuração. Abaixo são alguns exemplos de como zerar esta flag:
No x64dgb com o plugin ScyllaHide: 
Plugins → ScyllaHide → Options -> NtGlobalFlag  [x]
 
Manualmente no x64dbg:
1. Ctrl+G → peb()+0x68 (32 bits) ou Ctrl+G → peb()+0xBC (64 bits)
2. Trocar o valor do byte de 0x70 para zero
 
No OllyDbg com o plugin Command Line:
1. Plugins → Command Line →  Command Line
2. dump fs:[30]+0x68 (32 bits) ou dump gs:[60]+0xBC (64 bits)
3. No painel dump de memória selecionar o 1º byte → Binary → Fill with 00's
*Também é possível usar o plugin Olly-Advanced 
 
Bom, iniciei aqui uma nova categoria de técnicas Anti-Debug, a das flags de depuração, iniciando com a flag NtGlobalFlag. No próximo artigo vou falar sobre uma técnica que usa 2 flags em conjunto, a Heap Flags e a ForceFlags.
 
Espero que tenham gostado. 
Forte abraço & até o próximo!
 
Referências:
[1] https://docs.microsoft.com/en-us/windows/win32/apiindex/windows-api-list
[2] https://docs.microsoft.com/en-us/sysinternals/resources/windows-internals
[3] https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/pebteb/peb/index.htm
 
  • 1,648 views
Paranoia - Fonte: www.clipartguide.com
 
No último dia 24 de agosto (2022), funcionários da empresa Google anunciaram através dessa postagem, dos autores Pedro Barbosa, Engenheiro de Segurança da Google e Vice-Capitão do time de CTF Epic Leet Team (ELT), e Daniel Bleichenbacher, Engenheiro de Software da Google, seu novo projeto de criptografia chamado Paranoid (paranoia em tradução livre para o português).
Ela cita o repositório GitHub do projeto. É importante dizer que apesar de a biblioteca ter sido criada e ser mantida por membros do time de Segurança da Informação da Google, ele não é um produto oficial da Google.
Nesse artigo vamos verificar o que é e para que serve esse projeto através de uma tradução comentada da postagem acima citada.
 
O que é o Projeto Paranoid ?

Fonte: istockphoto.com
 
Paranoid é um projeto usado para detecção de vulnerabilidades conhecidas em artefatos criptográficos, como chaves públicas e assinaturas digitais. Isso é importante pois tais artefatos às vezes são gerados por implementações desconhecidas e/ou que não tenham código aberto para inspeção, as chamadas "caixas pretas" (ou do inglês black Boxes).

Black Box - Fonte: www.nsoftware.com
 
Em 2019, pensando na vunerabilidade ROCA, os autores da Paranoid se perguntaram se outras fraquezas não poderiam existir em artefatos gerados por caixas pretas e o que eles poderiam fazer para detectá-los e mitigá-los. Foi daí que surgiu a ideia de criar a Paranoid, uma biblioteca capaz de checar uma grande quantidade de artefatos criptográficos.
Ela foi criada baseando-se na literatura preexistente, que mostra que a geração de artefatos nem sempre é perfeita. A seguir temos quatro dessas referências:
Arjen K. Lenstra, James P. Hughes, Maxime Augier, Joppe W. Bos, Thorsten Kleinjung, and Christophe Wachter. (2012). Ron was wrong, Whit is right. Cryptology ePrint Archive, Paper 2012/064; Nadia Heninger, Zakir Durumeric, Eric Wustrow, and J. Alex Halderman. (2012). Mining Your Ps and Qs: Detection of Widespread Weak Keys in Network Devices. USENIX Associations; Daniel J. Bernstein, Yun-An Chang, Chen-Mou Cheng, Li-Ping Chou, Nadia Heninger, Tanja Lange, and Nicko van Someren. (2013). Factoring RSA keys from certified smart cards: Coppersmith in the wild. Cryptology ePrint Archive, Paper 2013/599; Joachim Breitner and Nadia Heninger. (2019). Biased Nonce Sense: Lattice Attacks against Weak ECDSA Signatures in Cryptocurrencies. Cryptology ePrint Archive, Paper 2019/023. Um exemplo mais recente, de 2022, é a CVE-2022-26320, encontrada por Hanno Böck, que evidencia ainda mais a necessidade de se detectar tais fraquezas. A Paranoid inclusive já encontrou de forma independente chaves fracas a partir do teste de Fermat. Os autores preveem que o projeto ainda tenha potencial para encontrar novas vulnerabilidades, já que estão generalizando as detecções ao máximo.
 
Chamada para contribuições

Fonte: opensource.guide
 
Abrindo o código da Paranoid, os autores objetivam aumentar sua transparência, permitindo que ela seja utilizada também por outros tipos de usuários como Autoridades de Certificação - CAs que precisam fazer checagens semelhantes) e, é claro, receber contribuição de pesquisadores externos. Então, estão fazendo uma chamada para tal, com a esperança de que ao encontrar uma nova vulnerabilidade, depois de reportá-la, incluam as checagens na Paranoid. Dessa forma, não só a Google, mas também o resto do mundo poderá responder de forma rápida às novas ameaças.
A biblioteca foi construída para ser leve computacionalmente falando, de forma que, mesmo trabalhando com números extremamente grandes, ainda faça sentido no contexto de produção do mundo real. Existem projetos com menos restrições para outros casos de aplicação, como o RsaCtfTool, geralmente usado em competições de segurança da informação do tipo CTF.
Os autores destacam que além de contribuições de novas checagens, também são muito bem-vindas eventuais melhorias nas checagens já existentes na biblioteca, cujo código está disponível no repositório do GitHub. Um dos exemplos que fornecidos é o das assinaturas ECDSA, cujos segredos são gerados por java.util.random, para as quais a biblioteca tem um modelo pré-computado capaz de detectar a vulnerabilidade na maioria dos casos dadas duas assinaturas secp256r1, mas que para curvas maiores como secp384r1, não foi possível pré-computar um modelo com efetividade tão significante.
Também foram implementadas checagens para chaves públicas RSA e EC, e fluxos de bits pseudo aleatórios, para o qual foram feitas algumas melhorias em relação ao teste NIST SP 800-22e incluídos alguns testes adicionais usando técnicas de redução de lattice.
 
Resultados preliminares

Resultados - Fonte: casadeimagem.com
 
Em caráter de teste, foram analisados artefatos criptográficos da Certificate Transparency (CT), que registra certificação de sites desde 2013 com o objetivo de torná-los transparentes e verificáveis, e cujo banco de dados possui mais de 7 bilhões de certificados.
No caso das checagens de chaves públicas EC e assinaturas ECDSA, não foram achados artefatos fracos no CT. Para as checagens de chaves públicas RSA com gravidades ALTA ou CRÍTICA, foram encontrados os seguintes resultados:
 
|            Teste                        |         CVEs relacionada       |    Gravidade    | Número de artefatos afetados|
 
|   CheckOpensslDenylist     |            CVE-2008-0166         |     CRÍTICA      |                    3989                         |
|         CheckROCA                 |            CVE-2017-15361       |       ALTA          |                    2875                          |
|        CheckGCD                    |                          -                    |     CRÍTICA      |                    1860                          |
|        CheckFermat                |            CVE-2022-26320      |     CRÍTICA      |                      36                            |
|  CheckContinuedFractions |                        -                      |     CRÍTICA      |                       16                            |
|     CheckBitPatterns             |                        -                      |     CRÍTICA      |                        6                            |
| CheckPermutedBitPatterns |                      -                        |     CRÍTICA      |                        6                            |
|   CheckKeypairDenylist         |           CVE-2021-41117        |     CRÍTICA      |                        4                            |
|      CheckPollardpm1              |                    -                         |     CRÍTICA      |                        1                             |
 

Fonte: nakedsecurity.sophos.com
 
Alguns desses certificados já expiraram ou foram revogados. Os que ainda estão ativos (a maioria dos que falharam no CheckGCD), foram imediatamente reportados, de forma a manter a internet segura, conforme as políticas das Autoridades Certificadoras, como a do Let's Encrypt. Temos abaixo o trecho exemplo da Digicert:
> Certificate revocation and certificate problem reporting are an important part of online trust. Certificate revocation is used to prevent the use of certificates with compromised private keys, reduce the threat of malicious websites, and address system-wide attacks and vulnerabilities. As a member of the online community, you play an important role in helping maintain online trust by requesting certificate revocations when needed.
Ou em português:
> A revogação de certificados e a notificação de problemas em certificados são partes importantes da confiança na internet. A revogação de certificados é usada para evitar o uso de certificados com chaves privadas comprometidas, reduzir a ameaça de sites mal-intencionados e abordar ataques e vulnerabilidades. Como membro da comunidade web, você desempenha um papel importante ao ajudar a manter a confiança na internet solicitando revogações de certificados quando necessário.
 
Próximos passos

Próximos Passos - Fonte: sindipetro.org.br
 
Os autores planejam continuar analisando o CT, e, agora com ajuda de contribuição externa, criar novas checagens e otimizar as já existentes. Estão também acompanhando de perto o processo Post-Quantum Cryptography Standardization do NIST para novos algoritmos que possam fazer sentido a implementação de checagens.
Novas implementações de criptografia trazem a possibilidade de novas falhas, portanto é importante que a Paranoid seja capaz de detectá-las, evoluindo sempre.
 
 
  • 2,532 views