Ir para conteúdo
  • Cadastre-se

Fernando Mercês

Administradores
  • Total de itens

    574
  • Registro em

  • Última visita

Tudo que Fernando Mercês postou

  1. Fernando Mercês

    Crackme 01 - Linux - Geyslan

    Fala galera, Hoje eu achei um fonte de um crackme de 2013 dum brother chamado Geyslan e recompilei. Dá pra aplicar 2 níveis nele: Patch Senha válida /* Crackme 01 - C Language - Linux/x86 and x86_64 Copyright (C) 2013 - Geyslan G. Bem, Hacking bits http://hackingbits.com geyslan@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by Bom pra treinar ER no Linux! Quem topa? Lembrando que há estes dois artigos que mostram o uso de algumas ferramentas pra ER no Linux: Além disso, há outras como radare2, peda e gef. Boa sorte! crackme01-geyslan
  2. Fernando Mercês

    Problema com Google autenticador

    Desabilitei e to investigando aqui. Obrigado por informar!
  3. Fernando Mercês

    AnalyseMe - Nível 05

    Humm, a tua resposta não parece ser em relação ao desafio 5, mas sim ao futuro do projeto. Vamos lá: A gente fez XOR com um byte e depois XOR multibyte. Depois focamos em anti-debug e por isso deixamos a ofuscação de strings de lado. Vamos voltar nisso em breve. Não temos esse interesse agora, porque queremos treinar as bases de Assembly. Linguagens como .Net ou Java fugiriam muito destes conceitos. Tempo zero pra investir nisso. Se optarmos por usar packers, vamos nos comerciais mesmo, talvez com pequenas alterações. A gente tá tentando tornar mais difícil gradualmente. No 5 foi adicionada a checagem de janelas, que não tinha nos anteriores. Estamos tentando adicionar um ou dois itens de dificuldade por vez. Pra gente parece ok. Nossa intenção é que as pessoas resolvam os desafios. Não que não resolvam. rs Uma coisa é compreender a análise de quem resolveu, outra é resolver mesmo, na mão. Acreditamos que assim que se aprende mesmo e para mais pessoas poderem estudar assim, temos que ir "devagar e sempre". 😉 Abraço, Fernando
  4. Fernando Mercês

    Livros de programação em C

    Olá! Criando esse tópico para recomendação de livros porque vi esse tweet: Se tiverem mais, recomendem! 🤗
  5. Fernando Mercês

    AnalyseMe - Nível 04

    @Wilson Junior pra ser sincero o algoritmo do XOR foi com um errinho... a chave não era pra mudar não, mas realmente muda. De qualquer forma, tá lá no binário e foi bom que foi uma simulação do que seria um erro real de um criador de malware hahaha 🤪 Uma implementação simples seria fazer o XOR do primeiro caractere com 1 mesmo e depois usar a chave {0, 2, 3, 4} começando da segunda posição: $ ./analyseme-xor C:\Program Files\Oracle\VirtualBox Guest Additions\DIFxAPI.dll Lembrando que XOR com 0 dá o próprio valor, o que é o mesmo que não fazer nada. hehehe Era aí tua dúvida? Abraço!
  6. Fernando Mercês

    AnalyseMe - Nível 05

    Não entendi. Você quis dizer que está fácil demais? Pode dar mais detalhes? Abraço, Fernando
  7. Fernando Mercês

    As gafes do mundo da TI

    Essas são algumas gafes que vez ou outra flagramos a galera de TI caindo. Na prática são termos confusos que já foram utilizado de forma inadequada muitas vezes e a intenção deste artigo é desmistificar, de uma vez por todas, alguns conceitos. 😌 Programação em HTML HTML (HyperText Markup Language), como o próprio nome sugere, é uma linguagem sim, mas não é de programação. Para ser, esta precisaria expressar um algoritmo que pudesse utilizar-se de estruturas de controle e loop, por exemplo, recursos fundamentais para qualquer linguagem de programação. Logo, quem sabe HTML sabe criar páginas em HTML. Programar é outra história… Estabilizador não serve pra nada Infelizmente ele serve pra estragar sua fonte. Isso mesmo, o trabalho de estabilização feito por estes componentes é tão mal feito e lento, que ao tentar corrigir uma anomalia na energia ele atrapalha a fonte, que seria capaz de corrigir sozinha, mas é obrigada a esperar o estabilizador fazer seu trabalho porco e corrigir a anomalia duas vezes! O investimento correto deve ser feito na fonte do computador, sem economia porca. Um filtro de linha pode ser prático no caso de um spike (grandes descargas de curto prazo, como as geradas por raios) porque o fuzível dele pode abrir e proteger o da fonte (que é mais chato de trocar porque tem que tirá-la do computador e abri-la), mas proteção mesmo é na fonte e por isso é interessante adquirir uma boa, mas só faz sentido para desktops montados. No mundo atual, onde os laptops dominam, estabilizadores não servem para nada mesmo. 😝 O positivo e negativo da tomada… O tipo de corrente que chega em nossas tomadas é chamado de alternada. Neste tipo não há pólos positivo ou negativo, mas sim fase e neutro. Na fase há a tal alternagem de polaridade, entre positivo e negativo, cerca de 60 vezes por segundo no caso das capitais brasileiras. O neutro é ligado à terra em algum momento e ao conectar algum componente (como uma lâmpada) entre este caminho fase-neutro você faz com que energia passe pelo componente. No caso da lâmpada, ela acende. 💡 Vale a pena estudar o básico sobre corrente contínua e corrente alternada porque o assunto é longo. Baixei o drive da placa de… Você baixou o driver, filhão. Com ‘r’ no final. Drive, sem ‘r’, diz respeito aos dispositivos físicos como drive de CD-ROM, drive de disquete, ZIP drive etc. Já driver, com ‘r’, é um programa responsável por controlar e permitir o uso de um determinado dispositivo em um sistema operacional. Essa placa é show, nem precisa de driver! Ah precisa. 🙏 O que ocorre é que seu sistema já vem com drivers para vários dispositivos e você pode notar o dispositivo funcionando sem precisar instalar nada além do próprio sistema. Na verdade o driver para aquele dispositivo não estava em uso, mas foi instalado e agora está em uso quando da inserção do dispositivo no PC. Vou formatar essa HD aqui Formatar é criar um formato. Não se formata HDs, mas sim partições. Dizer “vou formatar uma partição como NTFS” é correto. Tanto é que pra formatar você precisa especificar um sistema de arquivos desejado. Adicionalmente, o HD (Hard Disk), já que é um disco, possui gênero masculino, então o correto é dizer “o HD”, como em “o disco”. Meu HD não tá particionado! Em geral para instalar um sistema operacional é preciso, sim, criar nem que seja uma única partição e depois disso formatá-la com um filesystem para o qual o sistema operacional tenha driver e saiba trabalhar. Logo, seu disco deverá ter, no mínimo, uma partição e por isso ele está particionado sim. Uma partição. ☝️ Formatar não apaga tudo, rapá! Formatar é criar um formato. A ilusão de que a partição está vazia após a formatação deve-se ao fato de que a estrutura do filesystem presente naquela partição foi recriada e a referência aos arquivos é perdida, por isso os arquivos não são mais exibidos, mas nenhum foi apagado. Lembrando que nos dias atuais apagar de um disco via software é impossível. Uma vez que ele tenha sido escrito/magnetizado, por assim dizer, o que se pode fazer é substituir os bytes contidos nele por exemplo, para simular deleção. Remover os bits (energia) não é impossível, mas não é comum. Põe o HD no congelador que ele volta a funcionar! Embora haja um agrupamento de moléculas sob baixas temperaturas, que são responsáveis inclusive pela falsa sensação de carga de pilhas também colocadas no congelador, o efeito não é comprovado e, caso haja algum benefício, será fulminante. Duvido muito que dê tempo para recuperar algo. HD com problema na placa lógica pode ter a placa lógica substituída, mas HDs com problemas físicos, em geral, não têm conserto. Faz uma formatação de baixo nível que tira os bad blocks! Bad blocks (ou setores defeituosos) caracterizam um problema físico, um câncer que se espalha. Não se resolve hardware com software. É como tentar anexar um suricate num e-mail. Além disso, já parou para se perguntar o que significa formatação de baixo nível, também conhecida como LLF – Low Level Formatting? Uma dica: ZeroFill (famoso programa que preenche com zeros todos os setores do disco) não é. É possível recuperar dados de um HD formatado até X vezes! Repita comigo: HD não se formata (pelo menos não mais, com a extinção da LLF). NINOVO, a formatação de uma partição dá a ela um formato. Se você formatar 4, 7, 12 ou 7038 vezes, dá no mesmo. Os dados continuam íntegros. Agora, se você fizer um zerofill uma vez, já f*** tudo. Se ao invés de zeros, escrever bytes randômicos, piorou. Como comento na gafe 8, não se apaga nada de HD, só se sobrescreve. Esse barulho é a agulha do HD! Quem tem agulha é sua avó! HD tem cabeça de leitura e gravação e ela, pasme, não enconsta na superfície do prato. É eletromagnetismo. Favor esquecer a analogia com toca-discos. Venho por meio deste… Segue em anexo… Não precisa tentar enfeitar. Se você tá escrevendo um e-mail, é óbvio que é por meio dele que vai informar alguma coisa. Difícil seria informar algo “por meio de outro e-mail”. E o que tá anexo, tá anexo. De onde vem esse “em”!? Nunca minha rede foi atacada, nunca pegamos vírus! O ataque bem sucedido não faz ‘barulho’. Quando você não sabe é justamente quando dá certo. 😈 Instala um antivírus gratuito! Esse aqui é muito bom! Trabalhando na indústria de AV eu vi coisas horríveis. O esforço pra tentar ficar na frente dos criadores de vírus é gigante, caro e por vezes frustrante. Todos os antivírus mais caros das companhias com mais dinheiro sofrem para tentar chegar lá. Desculpe, mas os antivírus gratuitos não têm a menor chance de oferecer qualquer segurança. Quem não investe num antivírus pago hoje para computador e smartphone, pra mim, é maluco(a). Não existe vírus pra Linux Este sistema é o mais utilizado em webservers no mundo. Você acha mesmo que não haveria vírus capazes de se propagar neles? Faz uma busca por “linux malware” só. Ah, e o Android, sabia que já atingimos a marca de 1 milhão de vírus diferentes para esta plataforma (que é Linux)? Guarde isso: o crime segue o dinheiro. Não importa o sistema utilizado, se o cibercrime ver valor em ameaças para ele, vão surgir. Gateway da placa rede O Windows é craque em ensinar errado. O que ele chama de gateway na verdade é a rota padrão para pacotes fora da rede local. É Highlander: só pode haver um! Essa zona que ele cria colocando a configuração de gateway por placa de rede só confunde. E mais, tem gente que acha que sempre precisa de gateway ao configurar uma rede no Windows, o que não é verdade. Se você não vai sair da rede local (para internet ou outra rede), não precisa definir uma rota para fora dela. Hackers roubaram… Quem comete crime é criminoso. Quem faz hacking de qualquer coisa é hacker. Uma coisa não implica a outra. Tá fora do ar! ‘Pingei’ e ele não respondeu. O ping dispara pacotes ICMP. Se o alvo ignorar pacotes ICMP, você não vai ter resposta e mesmo assim ele pode estar na rede funcionando normalmente. Com o nmap você tem mais chances de saber se um host está realmente no ar ou não. Quebrei o SSL! Parece coisa de maluco mas já ouvi umas vezes. Não que seja impossível, mas não confunda man-in-the-middle com quebra da criptografia. Tem um abismo entre estes tópicos! Não uso software livre porque ninguém me dá suporte! Primeiro: sim, você já usa, mas não sabe. Segundo: várias empresas nacionais e internacionais oferecem suporte, é só procurar. Terceiro: Muitas das próprias organizações que fazem software livre oferecem versões pagas destes softwares, com suporte. Pois é, livre é diferente de gratuito. Um software pode ser gratuito e proprietário enquanto outro pode ser livre e pago. Legal né? Não dá pra ganhar dinheiro com software livre! Errou. Errou feio, errou rude. O modelo de negócios muda. Há várias empresas e investidores, grandes clientes como bancos e governos. Se você ainda pensa assim, não deve estar ganhando dinheiro no mundo proprietário também, porque o problema está em você! Linux é difícil Outro mito. Há vários casos de crianças que sempre usaram Linux dentro de casa e acharam o Windows difícil quando foram usar na casa de amigos. É questão de costume. MP3 com qualidade de CD Se existisse já seria ruim. Ao ripar de um CD há perda de qualidade, sempre. Na conversão de analógico para digital já há, por isso ainda há tantos amantes do vinil. Lembre-se que MP3 é um codec (compressor/decompressor), e se na maioria dos casos de compressão de áudio há perda, mesmo que seu ouvido não note! Java roda em qualquer lugar! Java só roda em “lugares” que possuem a JVM (Java Virtual Machine). Além disso, há várias máquinas virtuais Java diferentes, com suportes diferentes. Linguagem C é velha Velho é o seu professor que ensina como calcular a média de três alunos no Turbo C. A última atualização da linguagem C foi em 2011 e as principais suítes de compiladores como gcc, llvm, Visual Studio, continuam em constante desenvolvimento. Mais da metade do universo é escrito em C. Portanto, vá estudar C! 👨🏿‍💻 Aperta o Del pra entrar na BIOS! Pelo sangue de Chessus, não dá pra entrar lá não. Pressionando a tecla Del, F2, F10 ou qualquer que seja no seu computador, você acessa o SETUP, que é um software de configuração do BIOS. E é “o” BIOS porque ele é um sistema (Basic Input/Output System), logo, gênero masculino. A voltagem e a amperagem… Talvez de tão faladas já sejam aceitas, mas expressões como essas não soam muito elegantes. Em português, o que é medido em Volts (V) é a tensão elétrica (às vezes chamada de força eletro-motriz ou diferença de potencial). Já o ampère (A) é usado para intensidade de corrente [elétrica]. Espero que não criem ohmagem, wattagem, metragem (opa… essa já criaram!), quilagem, hertzagem… Senha forte: números, letras maiúsculas e minúsculas, caracteres espaciais plunct plact zum! Ok, ok. Aí vem o usuário danadinho e põe “Senha1”. Assim que expira ele muda: “Senha2”. O problema dessa gafe não é a validade técnica mas a efetividade de jogar essa responsa para o coitado do usuário que mal sabe o motivo de ele ter uma senha tão chata. Se você facilita, fica fácil pra força bruta, se dificulta, ele cola no monitor. Solução: PENSA. O sucesso de um ataque de força bruta depende de duas coisas: a complexidade da senha, o que inclui tamanho, não possuir palavras de dicionário, conter alta entropia etc e o poder computacional do atacante. Mas não precisa complicar muito. Uma senha “Meng0==========” pode ser mais forte que “5!8@6_(hiKij9” (que é bem ruim de decorar). Não é feitiçaria, o nome é entropia. Como o link enaltece, o padding (sinais de igual neste caso) deve ser criado pelo usuário, ou seja, se você ensinar seu usuário a criar algo pra colocar “antes e/ou depois” da senha várias vezes, ele vai se lembrar e ainda assim terá uma senha forte. Assim, uma pessoa sensível que queria usar a senha “Amor” agora pode.. Basta adicionar os amantes felizes e saltitantes: “\0/ Amor \0/”. Mais forte, mais fácil de lembrar, mais amor pro seu coração! Curso de hacker Você consegue ensinar alguém a ter ideias? Há vários picaretas no Brasil divulgando e ministrando “cursos hacker”. Todos não passam de leitura de slides e apostilas copiadas de páginas de manuais e tutoriais em sites na Internet. Na sala de “aula” o aluno vê e faz mágica, mas no cenário real a grama muda de cor. 🐴 No entanto, não fique triste, ainda dá tempo de aprender segurança de verdade. Minha internet é de 10 megabaites! O mercado (sempre ele) cria estas babaquices pra vender. A unidade de medida aqui é o Mb (megabit) e não MB (megabyte). Pois é, muda tudo. Se a sua internet é de 10 “megas”, ou seja, 10 Mbps (megabit por segundo) você baixaria aproximadamente 1,25 MB em um segundo, não 10. O macete é dividir por 8 já que 8 bits formam um byte. O mesmo se aplica às placas de rede de 100 Mbps, 1 Gbps, ou as sem fio de 54 Mbps, 108 Mbps, 3G de 1 Mbps etc: é tudo bit, não byte.
  8. Fernando Mercês

    Alterar EIP para decodificar Strings

    Fala Victor! Isso depende muito. Normalmente alterar o EIP "pra muito longe" do EIP atual não é uma boa ideia. Além disso, você deveria alterar o EIP para o momento em que o endereço da string ofuscada é passado para a função que desofusca e depois executar a CALL. Algo como: push <string_offset> call <função que desofusca> A IsDebuggerPresent() é só a mais básica das muitas técnicas anti-debug e o x64dbg consegue inutilizar essa função nativamente, mas não é automático: você tem que clicar lá em Debug -> Advanced -> Hide debugger (PEB) ou usar um plugin tipo o ScyllaHide. A gente explica como essa técnica funciona na aula 24 do CERO. 😉 Pelo próprio ScyllaHide você pode aprender sobre outras técnicas e ir testando opções pra ver se ele consegue dar cabo nas proteções que este binário tem. Não é perfeito, mas ajuda pra caramba! Abraço!
  9. Fernando Mercês

    Livro: Fundamentos de Engenharia Reversa

    Queridos amigos, No dia 12 de Maio de 2018 lançamos este livro online, em português e totalmente gratuito, graças ao apoio de vocês! O livro é de vocês: http://menteb.in/livro Este tópico é para discutir sobre o livro, sugestões, críticas, correções, etc. Por favor, usem e abusem dele! Toda a comunidade agradece! 😍
  10. Fernando Mercês

    AnalyseMe - Nível 03

    Salve, pessoal! Perdoem o atraso, mas aqui está o AnalyseMe-03, o quarto da série (começou com o nível 00). Lembra de postar a reposta com a tag spoiler, pra não dar a resposta de cara pra quem quer tentar. 😉 Esse tem umas surpresinhas. hehe Em tempo, podem dar feedback do que estão achando da série? Tá legal? Muito fácil? Muito difícil? Queremos saber. Olha o binário aí e manda seus comentários por favor! Grande abraço e boa sorte! AnalyseMe-03.exe
  11. Fernando Mercês

    Desafios suicidas x jogos sombrios

    Gostaria de divulgar aqui também o estudo sobre os desafios suicidadas ("Baleia Azul", etc) e jogos "de temática sombria" que publiquei no início do mês pela Trend Micro. Como falei no vídeo que publicamos no canal Papo Binário, é um tema sobre o qual gostaria de ter mais informações sobre, ouvir especialistas, etc. Recomendo a leitura para todos pois nunca se sabe se um amigo ou vizinho tem um filho(a) numa situação parecida. Qualquer feedback é muito bem vindo! 👍
  12. Fernando Mercês

    Desafios suicidas x jogos sombrios

    Eu entendo. Também não vejo problema. As variantes me assustaram mais, na real (Can You Escape Love/Fate). A linguagem direta foi algo inédito pra mim num jogo, que por definição é fantasioso. Muito difícil ser imparcial neste caso e confesso que não sou, mas sei que há vários lados. Provavelmente jogos como esses já salvaram pessoas da depressão, ao invés de afundá-las. Reconheço que só expus o aspecto "negativo" mas foi de propósito, com o intuito de alertar aos pais que tais temas rondam redes sociais, memes e jogos. 😉
  13. Fernando Mercês

    Livro: Fundamentos de Engenharia Reversa

    Pessoal, agradeço todos que colaboraram com o livro. Agora está bem mais fácil pois estamos com ele em nosso repositório no Github! É só mandar os pull requests por lá! 😎 Muito obrigado!
  14. Fernando Mercês

    Desafios suicidas x jogos sombrios

    As opiniões são divididas, mas convenhamos que a linguagem é forte e, sem orientação, pode ser nocivo, vide os relatos dos pais que constam nos relatório. 😉
  15. Fernando Mercês

    AnalyseMe - Nível 03

    Valeu, galera. Muito legais as análises! Alguém analisou a função que decripta as strings? Conseguiriam fazer, em Python ou em qualquer outra linguagem de programação, um decrypter? 🙂 Abraços, Fernando
  16. Fernando Mercês

    Boletins semanais

    Pessoal, o que estão achando dos boletins semanais? Estão ajudando? Falta algo? Abraços!
  17. Fernando Mercês

    Comparando executáveis

    Saudações, leitores do Mente Binária! Hoje me deu vontade de falar sobre uma tarefa que eventualmente preciso fazer na empresa onde trabalho, que é a de verificar as diferenças entre arquivos executáveis, normalmente de Windows, também conhecidos por executáveis PE. Há vários usos ao comparar binários. É possível avaliar o que mudou na versão atual de um software em relação à anterior, descobrir o que muda em cada sample diferente de uma mesma família de malware, etc. Esses dias mesmo me foi pedido que verificasse a diferença entre 6 arquivos maliciosos, que compartilho abaixo como fiz. Reconhecimento básico Os arquivos que recebi tinham seu hash SHA-256 como nome. A primeira coisa que fiz foi checar seu tipo (usando comandos do macOS, mas o Linux tem comandos similares): $ file * fdba340bb35635934aa43b4bddd11df31f2204e73394b59756931aa2f7f59e04: PE32 executable (GUI) Intel 80386, for MS Windows fdf3060eb9c39b1a2be168b1ac52c2f80171394e73fe03c4e0c57911cb9358a9: PE32 executable (GUI) Intel 80386, for MS Windows fedf9d9815b3d0ad28e62f99d5dcf92ec0f5fcb90135b4bdc30bb5709ab9ff05: PE32 executable (GUI) Intel 80386, for MS Windows ff2f1be6f64c91fa0a144cbc3c49f1970ba8107599d5c66d494ffb5550b0f7fd: PE32 executable (GUI) Intel 80386, for MS Windows ff53c7ba285ffdc2c29683bb79bb239ea59b3532f8b146523adf24d6d61fc640: PE32 executable (GUI) Intel 80386, for MS Windows ffee504e292a9f3ae6c439736881ebb314c05eac8b73d8b9c7a5a33605be658e: PE32 executable (GUI) Intel 80386, for MS Windows Só para garantir, também chequei o SHA-256 deles e realmente bateu com o nome, o que era esperado: $ shasum -a256 * fdba340bb35635934aa43b4bddd11df31f2204e73394b59756931aa2f7f59e04 fdba340bb35635934aa43b4bddd11df31f2204e73394b59756931aa2f7f59e04 fdf3060eb9c39b1a2be168b1ac52c2f80171394e73fe03c4e0c57911cb9358a9 fdf3060eb9c39b1a2be168b1ac52c2f80171394e73fe03c4e0c57911cb9358a9 fedf9d9815b3d0ad28e62f99d5dcf92ec0f5fcb90135b4bdc30bb5709ab9ff05 fedf9d9815b3d0ad28e62f99d5dcf92ec0f5fcb90135b4bdc30bb5709ab9ff05 ff2f1be6f64c91fa0a144cbc3c49f1970ba8107599d5c66d494ffb5550b0f7fd ff2f1be6f64c91fa0a144cbc3c49f1970ba8107599d5c66d494ffb5550b0f7fd ff53c7ba285ffdc2c29683bb79bb239ea59b3532f8b146523adf24d6d61fc640 ff53c7ba285ffdc2c29683bb79bb239ea59b3532f8b146523adf24d6d61fc640 ffee504e292a9f3ae6c439736881ebb314c05eac8b73d8b9c7a5a33605be658e ffee504e292a9f3ae6c439736881ebb314c05eac8b73d8b9c7a5a33605be658e PS.: No Linux o comando seria sha256sum ao invés de shasum -a256. O próximo passo foi checar o tamanho deles: $ wc -c * 396973 fdba340bb35635934aa43b4bddd11df31f2204e73394b59756931aa2f7f59e04 396973 fdf3060eb9c39b1a2be168b1ac52c2f80171394e73fe03c4e0c57911cb9358a9 396973 fedf9d9815b3d0ad28e62f99d5dcf92ec0f5fcb90135b4bdc30bb5709ab9ff05 396973 ff2f1be6f64c91fa0a144cbc3c49f1970ba8107599d5c66d494ffb5550b0f7fd 396973 ff53c7ba285ffdc2c29683bb79bb239ea59b3532f8b146523adf24d6d61fc640 396973 ffee504e292a9f3ae6c439736881ebb314c05eac8b73d8b9c7a5a33605be658e 2381838 total Aqui apresentou-se um caso atípico: os binários possuem exatamente o mesmo tamanho! Já pensei que havia grandes chances de as diferenças entre eles serem mínimas: provavelmente algo usado pelo autor do malware só para "mudar o hash" na tentativa de evitar que os antivírus detectem os arquivos idênticos, por exemplo. Essa tentativa é na verdade frustrada visto que, ao contrário do que muitos pensam, os antivírus não detectam malware por hash normalmente, já que isso seria muito custoso do ponto de vista do desempenho (seria preciso ler todos os bytes do arquivo!) e também seria muito fácil tornar um novo arquivo indetectável - bastaria alterar um único byte para um hash final completamente diferente. Comparação de estrutura Se estivéssemos tratando arquivos de texto, poderia simplesmente usar o comando diff, mas o assunto aqui é PE, então algo interessante de verificar é sua estrutura, que consiste basicamente em cabeçalhos, localizados antes das seções. Se você não sabe do que estou falando, recomendo os seguintes recursos: Posts do @Leandro Fróes sobre o formato PE e suas referências. Capítulo sobre PE do livro Fundamentos de Engenharia Reversa. Aulas 5 e 6 do CERO, nosso Curso de Engenharia Reversa Online em vídeo. Digitar "PE executable" no Google ler o que curtir. Depois dessa imersão no mundo dos executáveis PE, não tenho dúvidas de que você vai se apaixonar por eles também! 😍 Voltando à comparação, o que eu quero dizer com estrutura? Bem, os valores dos campos dos cabeçalhos. Por exemplo, para ver o cabeçalho COFF de um arquivo PE, usei o readpe, parte do kit de ferramentas pev: $ readpe -h coff fdba340bb35635934aa43b4bddd11df31f2204e73394b59756931aa2f7f59e04 COFF/File header Machine: 0x14c IMAGE_FILE_MACHINE_I386 Number of sections: 5 Date/time stamp: 1401620468 (Sun, 01 Jun 2014 11:01:08 UTC) Symbol Table offset: 0 Number of symbols: 0 Size of optional header: 0xe0 Characteristics: 0x102 Characteristics names IMAGE_FILE_EXECUTABLE_IMAGE IMAGE_FILE_32BIT_MACHINE Mas não, não usei o pev por saudosismo! A ideia de ter uma saída em texto da estrutura desses binários é depois usar o comando diff para compará-las. A primeira coisa que precisei então foi gerar um .txt contendo toda a estrutura, e não só o cabeçalho COFF, para cada um dos arquivos. Uma repetição em bash dá conta do recado: $ ls -1 readpe_output_* readpe_output_fdba340bb35635934aa43b4bddd11df31f2204e73394b59756931aa2f7f59e04.txt readpe_output_fdf3060eb9c39b1a2be168b1ac52c2f80171394e73fe03c4e0c57911cb9358a9.txt readpe_output_fedf9d9815b3d0ad28e62f99d5dcf92ec0f5fcb90135b4bdc30bb5709ab9ff05.txt readpe_output_ff2f1be6f64c91fa0a144cbc3c49f1970ba8107599d5c66d494ffb5550b0f7fd.txt readpe_output_ff53c7ba285ffdc2c29683bb79bb239ea59b3532f8b146523adf24d6d61fc640.txt readpe_output_ffee504e292a9f3ae6c439736881ebb314c05eac8b73d8b9c7a5a33605be658e.txt Eu usei o readpe sem nenhuma opção, assim ele imprime todos os cabeçalhos, incluindo os de seções. Só pra começar fiz um diff do primeiro para o segundo e não houve qualquer saída, ou seja, a estrutura dos arquivos eram idênticas! E eram mesmo: $ wc -c readpe_output_* 21627 readpe_output_fdba340bb35635934aa43b4bddd11df31f2204e73394b59756931aa2f7f59e04.txt 21627 readpe_output_fdf3060eb9c39b1a2be168b1ac52c2f80171394e73fe03c4e0c57911cb9358a9.txt 21627 readpe_output_fedf9d9815b3d0ad28e62f99d5dcf92ec0f5fcb90135b4bdc30bb5709ab9ff05.txt 21627 readpe_output_ff2f1be6f64c91fa0a144cbc3c49f1970ba8107599d5c66d494ffb5550b0f7fd.txt 21627 readpe_output_ff53c7ba285ffdc2c29683bb79bb239ea59b3532f8b146523adf24d6d61fc640.txt 21627 readpe_output_ffee504e292a9f3ae6c439736881ebb314c05eac8b73d8b9c7a5a33605be658e.txt 129762 total $ md5 !$ md5 readpe_output_* MD5 (readpe_output_fdba340bb35635934aa43b4bddd11df31f2204e73394b59756931aa2f7f59e04.txt) = 05b36b89b1165b3d619bee16f8a1d7f7 MD5 (readpe_output_fdf3060eb9c39b1a2be168b1ac52c2f80171394e73fe03c4e0c57911cb9358a9.txt) = 05b36b89b1165b3d619bee16f8a1d7f7 MD5 (readpe_output_fedf9d9815b3d0ad28e62f99d5dcf92ec0f5fcb90135b4bdc30bb5709ab9ff05.txt) = 05b36b89b1165b3d619bee16f8a1d7f7 MD5 (readpe_output_ff2f1be6f64c91fa0a144cbc3c49f1970ba8107599d5c66d494ffb5550b0f7fd.txt) = 05b36b89b1165b3d619bee16f8a1d7f7 MD5 (readpe_output_ff53c7ba285ffdc2c29683bb79bb239ea59b3532f8b146523adf24d6d61fc640.txt) = 05b36b89b1165b3d619bee16f8a1d7f7 MD5 (readpe_output_ffee504e292a9f3ae6c439736881ebb314c05eac8b73d8b9c7a5a33605be658e.txt) = 05b36b89b1165b3d619bee16f8a1d7f7 Os hashes MD5 da saída em texto da estrutura de todos os arquivos batem. Eles são mesmo iguais estruturalmente! Passado o choque, percebi que teria que comparar o conteúdo das seções (código, dados, talvez resources, etc). Aí fui obrigado a inicializar minha VM do Janelas mesmo... Comparação do conteúdo das seções Existem alguns softwares que trabalham com PE e possuem funções de comparação de dois executáveis. Eu costumava usar o Cold Fusion (um antigo gerador de patch) pra isso, mas ele tem alguns bugs que me impediram. Achei a mesma função no Stud_PE, mas ele localiza arquivos por extensão na janela de comparação, então renomeei o primeiro e o segundo arquivo que tinha para a.exe e b.exe respectivamente. Ao abrir o a.exe no Stud_PE, usei o botão "File Compare", selecionei o método "Binary", setei o "Starting from" pra "Raw" e cliquei em "Compare": Se você não entendeu por que fiz isso, volte uma casa ou leia os tutorias de PE que indiquei. Ou pergunte que eu falo. 😍 Bem, entre esses dois caras então havia 9 bytes que o diferenciavam e eu já tinha os offsets a partir do início do arquivo. Agora é descobrir em que seção eles estavam no PE, o que são, o que comem e como eles vivem. 😎 Descobrindo como as diferenças são usadas Abri o executável no x64dbg (na verdade no x32dbg, já que este binário é de 32-bits) mas percebi que o entrypoint estava no endereço 013706AA. Como o ImageBase deste binário é 00400000, percebi que o ASLR estava habilitado e, antes de continuar , desabilitei-o com o DIE, como mostro neste vídeo rápido no canal Papo Binário: Antes de reabrir o binário no x32dbg, convém lembrar que eu tinha um offset e precisava convertê-lo para endereço virtual (VA). Isso é feito com o que alguns analisadores de PE chamam de FLC (File Location Calculator). O DIE tem, o Stud_PE tem e o pev também tem, com a ferramenta ofs2rva: $ ofs2rva 0x4c451 a.exe 0x4dc51 Mas pra não você não me acusar de saudosismo de novo, vou mostrar no Stud_PE 😄 Percebe que o Stud_PE já diz que este byte pertence à seção .rdata, o que à esta altura você já sabe, caso tenha feito o trabalho de casa de estudo do PE, que é provavelmente uma seção de dados somente-leitura, então há grandes chances de nossa sequência diferentona pertencer à uma string constante, por exemplo. Fui ver no debugger como é que tava a festa. Abri o a.exe lá e dei um Ctrl+G no Dump pra ir pro endereço 44DC51: De fato tinha uma string lá: zuk0KRrGrP, mas ela na verdade começava em 44DC44 e pra saber quando ela era usada no malware, coloquei um breakpoint de hardware no acesso ao byte, que é o primeiro da string e cheguei à conclusão de que, como o nome sugere, é realmente uma string de identificação da campanha do malware, sempre no mesmo offset (calculei de novo usando FLC). Agora foi só ver a dos outros e novamente recorri à uma ferramenta do pev (💚), a pestr: $ for i in *; do echo $i; pestr -so $i | grep 0x4c444; echo; done fdba340bb35635934aa43b4bddd11df31f2204e73394b59756931aa2f7f59e04 0x4c444 .rdata identifierStrzuk0KRrGrP fdf3060eb9c39b1a2be168b1ac52c2f80171394e73fe03c4e0c57911cb9358a9 0x4c444 .rdata identifierStrAR0U4hr1wW fedf9d9815b3d0ad28e62f99d5dcf92ec0f5fcb90135b4bdc30bb5709ab9ff05 0x4c444 .rdata identifierStrswEYVkFWeg ff2f1be6f64c91fa0a144cbc3c49f1970ba8107599d5c66d494ffb5550b0f7fd 0x4c444 .rdata identifierStrKXaUzlBDIj ff53c7ba285ffdc2c29683bb79bb239ea59b3532f8b146523adf24d6d61fc640 0x4c444 .rdata identifierStrv91TJ5c3Lr ffee504e292a9f3ae6c439736881ebb314c05eac8b73d8b9c7a5a33605be658e 0x4c444 .rdata identifierStrOzJnvFQy2U Bom, daí o céu é o limite. Dá pra criar assinatura, criar um script pra extrair esse ID da campanha, enfim, missão cumprida. FAQ 1. Por que você não utilizou só um comparador de arquivos qualquer, que compara os bytes em hexadecimal? Eu queria saber exatamente onde estavam as diferenças entre os arquivos, se na estrutura ou não. Em caso negativo, é código? Se sim, que código? Que faz o que? São dados? Usados onde? Em qual seção? Um editor hexadecimal ignorantão não me daria isso. Além disso, se os arquivos fossem diferente estruturalmente, ou em tamanho, eu queria saber antes, pra não perder tempo analisando diferenças de bytes hexa que eu não sei o que é. 2. Existem softwares para comparar binários PE muito mais poderosos, como o BinDiff. Por que caralhas você não o usou? O BinDiff é pra comparar código. Minha diferença estava nos dados. Além disso, o BinDiff e seus amigos traduzem o Assembly original do binário para uma linguagem intermediária própria e comparam lógica, não instruções. É bem fodão, mas não me atendia neste caso, afinal eu já sabia que os binários eram idênticos em funcionalidade. Só queria saber onde estava a diferença exata. 3. Percebi pela screenshot do Stud_PE que ele também compara a estrutura dos arquivos PE, então todo aquele processo com o readpe foi à toa? Sim, foi só pra Inglês ver. Não, brincadeira! O Stud_PE compara os cabeçalhos COFF, Optional e os diretórios de dados somente. O readpe imprime todos os cabeçalhos, incluindo todas as seções mais os imports. É outro nível, moleque! 😏 4. E quanto à executáveis ELF? O título não fala somente de PE propositalmente, já que a mesma técnica pode ser usada para arquivos ELF, só mudando os programas (readelf, etc). Por hora é só. Se você deixar sua análise abaixo ou quiser fazer um comentário/pergunta, ficarei muito grato. Considera apoiar a gente também vai. 💚
  18. Fernando Mercês

    Jogo em C - migração

    Cara, que coisa legal! Sempre quis fazer um jogo, mas é um sonho não realizado. 😁 Sobre a conio2.h, se quiser portar, recomendo a ncurses. Seu jogo vai inclusive rodar no Unix, Linux, BSD's, etc. No Windows também, via Cygwin. Mas, você vai alterar o código todo. rs Mas se quiser fazer gráfico mesmo, talvez o @augustomoreira, que falou sobre desenvolvimento de jogos neste tópico, possa ajudar? 🙂 Parabéns! Achei muito maneiro!
  19. Fernando Mercês

    Vacina: Vírus atalho

    @Aof pode compartilhar sim. Só deixar claro que é um vírus e comprimir com a senha "infected" (padrão na indústria). 😉
  20. Fernando Mercês

    0right, Let's Talk About x86 Assembly Language: Windows Internals

    Esta será a segunda aula do Thiago Peixoto em sua série 0right, Let's Talk About x86 Assembly Language, que vai rolar ao vivo na terça, dia 18 de Dezembro de 2018 no canal Papo Binário. Marca presença e nos vemos lá!
  21. Fernando Mercês

    AnalyseMe - Nível 00

    Boa, @Euler Neto. Uma pergunta adicional seria especificar o valor literal dessa constante (ERROR_ACCESS_DENIED). Abraço!
  22. Fernando Mercês

    AnalyseMe - Nível 00

    Que maneiro @rcimatti! Obrigado mesmo pela análise. Curta e precisa. =) @Aof não tem nenhuma "pegadinha" não. É só isso mesmo. Este binário é super simples, justamente por ser o primeiro nível dos desafios. A ideia é ir dificultando nos próximos, pouco a pouco. Abraços!
  23. Fernando Mercês

    Curso de Engenharia Reversa Online (CERO)

    O que é Engenharia Reversa? Engenharia reversa de software é a técnica para entender como um trecho de código funciona sem possuir seu código-fonte. É aplicável em diversas áreas da tecnologia como: Análise de malware Reimplementação de software e protocolos Correção de bugs Análise de vulnerabilidades Adição/Alteração de recursos no software Proteções anti-pirataria Alguns termos e abreviações para a engenharia reversa incluem: RCE (Reverse Code Engineering), RE, e reversing. Como funciona? Quando um programa tradicional é construído, o resultado final é um arquivo executável que possui uma série de instruções em código de máquina para que o processador de determinada arquitetura possa executar. Com ajuda de software específicos, profissionais com conhecimentos dessa linguagem (em nosso caso, Assembly) podem entender como o programa funciona e, assim, estudá-lo ou até fazer alterações no mesmo. O treinamento O CERO (Curso de Engenharia Reversa Online) é um treinamento básico gratuito publicado no nosso canal no YouTube Papo Binário, graças ao suporte dos nossos apoiadores. A primeira fase do treinamento está completa e as aulas publicadas estão abaixo. Instrutor @Fernando Mercês Aulas publicadas Aula 0 - Como funciona a Engenharia Reversa Aula 1 - Sistemas de Numeração Aula 2 - Arquivos Aula 3 - Arquivos binários Aula 4 - Strings de texto Aula 5 - Executável PE - Apresentação Aula 6 - Executável PE - Seções e endereçamento Aula 7 - Executável PE - Imports Table Aula 8 - Executável ELF - Apresentação Aula 9 - Executável ELF - Símbolos, PLT e GOT Aula 10 - Win32 API Aula 11 - Linux syscalls Aula 12 - Assembly - Instruções e registradores Aula 13 - Assembly - Repetições e saltos Aula 14 - Assembly - Convenções de chamada de função Aula 15 - Funções e pilha Aula 16 - Breakpoints de software Aula 17 - Quebrando o crackme do Cruehead (Parte 1) Aula 18 - Quebrando o crackme do Cruehead (Parte 2) Aula 19 - Compressão de executáveis Aula 20 - Descompressão e reconstrução da IAT Aula 21 - Breakpoints de memória Aula 22 - Rastreando instruções (tracing) Aula 23 - Strings ofuscadas Aula 24 - Anti-debug Pré-requisitos Máquina virtual com Ubuntu Máquina virtual com Windows 7 Lógica de programação. Desejável assistir o treinamento gratuito Programação Moderna em C.
  24. Fernando Mercês

    Programação Moderna em C

    O que é? C é uma linguagem de programação criada na década de 60 e utilizada largamente até os dias atuais. É comum se ouvir que “metade do Universo é escrito em C” e de fato é impressionante o número de aplicações de base escritas nesta linguagem. Exemplos incluem: Linux, Apache httpd, PHP, Java, Perl, Ruby, Python e a API do Windows. Por que estudar C? Acreditamos que o estudo da linguagem C é muito benéfico para o profissional que lida com computadores, independente da área. Estudar C nos obriga a focar nas bases da computação, entender como os dados são manipulados em memória pelo sistema operacional e pelo processador, suas limitações e condições para funcionamento. Algumas vantagens de se estudar C são: Pouca coisa "vem pronta" em C, nos forçando a implementar e entender as limitações da computação atual. O programador tem controle quase total do contexto do programa. É uma linguagem comercial, principalmente na era dos embarcados. Mas C não é velho? A linguagem foi criada há muito tempo, mas continua sendo atualizada e utilizada. Basta olhar o índice TIOBE, que mede as linguagens mais em alta no mundo, para comprovar o que dissemos. A última atualização na especificação padrão foi em 2011 mas os compiladores adicionam extensões periodicamente. O gcc (GNU Compiler Collection) e o Visual Studio, da Microsoft, são bem famosos, mas há também o clang que ganhou bastante espaço recentemente. Instrutor @Fernando Mercês O treinamento O treinamento Programação Moderna em C aborda aspectos modernos da linguagem, bem como do ecossistema para desenvolvimento de aplicações em C, como o SO, editores de texto, IDE’s, etc. O curso está no YouTube, no nosso canal Papo Binário, sem nenhum custo. São 20 aulas em 23 vídeos. Segue a lista: Aula 0: Preparando o ambiente Aula 1: Funções main() e printf() Aula 2: Variáveis booleanas e do tipo char Aula 3: Variáveis do tipo int Aula 4: Variáveis do tipo float Aula 5: Arrays Aula 6: Operadores aritiméticos Aula 7: Operadores lógicos Aula 8: Operadores bit-a-bit Aula 9: Condicional if Aula 10: Repetições (Parte 1/2) Aula 10: Repetições (Parte 2/2) Aula 11: Ponteiros (Parte 1/2) Aula 11: Ponteiros (Parte 2/2) Aula 12: Indexação de arrays e ponteiros Aula 13: Alocação dinâmica de memória Aula 14 - Estruturas e Uniões Aula 15 - Funções Aula 16 - Macros Aula 17 - Escopo e classes de armazenamento Aula 18 - Projeto readpe (Parte 1/3) Aula 19 - Projeto readpe (Parte 2/3) Aula 20 - Projeto readpe (Parte 3/3)
  25. Fernando Mercês

    Desativando LD_PRELOAD no Linux

    O preloading é um recurso suportado pelo runtime loader de binários ELF implementado na glibc (GNU C Library), mais especificamente no arquivo rtld.c. Ele consiste em carregar uma biblioteca antes de todas as outras durante o carregamento de um programa executável. Assim é possível injetar funções em programas, inspecionar as funções existentes, etc. Por exemplo, considere o programa ola.c abaixo: #include <stdio.h> void main() { printf("ola, mundo do bem!"); } Ao compilar e rodar, a saída é conforme o esperado: $ gcc -o ola ola.c $ ./ola ola, mundo do bem! A função printf() foi utilizada com sucesso pois este binário foi implicitamente linkado com a glibc graças ao gcc. Veja: $ ldd ola linux-vdso.so.1 (0x00007ffe4892b000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8a3a2dd000) /lib64/ld-linux-x86-64.so.2 (0x00007f8a3a692000) E portanto a função printf() é resolvida. Até aí nenhuma novidade. Agora, para usar o recurso do preloading, temos que criar uma biblioteca, que será carregada antes da glibc (libc6). A ideia é fazer com o que o binário chame a nossa printf() e não a da glibc. Isso pode ser chamado de usermode hook (incompleto, porém, já que eu repassei o argumento para a função puts() ao invés da printf() original da glibc). Considere o código em hook.c: #include <stdio.h> int printf(const char *format, ...) { puts("hahaha sua printf tah hookada!"); return puts(format); } O protótipo da printf() é o mesmo do original (confira no manual). Eu não reimplementei tudo o que precisaria para ela aqui, somente o básico para ajudar na construção do artigo. E como expliquei antes, o hook não está completo uma vez que eu passo o que recebo na minha printf() para a função puts() da glibc. O ideal seria passar para a printf() original mas para isso eu precisaria buscar o símbolo, declarar um ponteiro de função, etc. E o assunto desde artigo não é hooking de funções. Por hora vamos compilar a biblioteca: $ gcc -shared -fPIC -o hook.so hook.c $ ldd hook.so linux-vdso.so.1 (0x00007ffffadb8000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f011dfbc000) /lib64/ld-linux-x86-64.so.2 (0x00007f011e572000) E agora precisamos instruir o loader a carregá-la antes de todas as outras quando formos executar o nosso programa (ola). Há pelo menos duas formas de acordo com a documentação oficial: Definir uma variável de ambiente LD_PRELOAD contendo o endereço de uma ou mais bibliotecas para serem carregadas. Colocar o path de uma ou mais bibliotecas num arquivo /etc/ld.so.preload (caminho e nome são fixos aqui). Então vamos testar. Primeiro uma execução normal, depois com a variável LD_PRELOAD setada e finalmente com o recurso do arquivo /etc/ld.so.preload: ## Execução normal $ ./ola ola, mundo do bem! ## Com caminho em variável de ambiente $ export LD_PRELOAD=$PWD/hook.so $ ./ola hahaha sua printf tah hookada! ola, mundo do bem! ## Com caminho em arquivo $ unset LD_PRELOAD # echo $PWD/hook.so > /etc/ld.so.preload $ ./oi hahaha sua printf tah hookada! hello world Percebe o perigo? Não é à toa que existem vários malware para Linux utilizando este recurso. Alguns exemplos são os rootkits Jynx, Azazel e Umbreon. Além disso, algumas vulnerabilidades como a recente CVE-2016-6662 do MySQL dependem deste recurso para serem exploradas com sucesso. É razoável então um administrador que não utilize este recurso num servidor em produção querer desabilitá-lo, certo? Desabilitando o preloading Não há mecanismo no código em questão da glibc que permita desabilitar este recurso. Pelo menos eu não achei. Uma saída é alterar os fontes e recompilar, mas a glibc demora tanto pra ser compilada que eu desisti e optei por fazer engenheira reversa no trecho necessário e verificar quão difícil seria um patch. Analisando o fonte do rtld.c fica fácil ver que a função do_preload() retorna o número de bibliotecas a serem carregadas no preloading. Primeiro a checagem é feita na variável de ambiente LD_PRELOAD: O número de bibliotecas é armazenado na variável npreloads., que mais tarde alimenta uma repetição para de fato carregar as bibliotecas. Mais abaixo, o vemos que o trecho de código que busca o arquivo /etc/ld.so.preload também usa a do_preload(): Sendo assim veio a ideia de encontrar essa função no loader (no meu caso /lib64/ld-linux-x86-64.so.2 – mas pode estar em /lib para sistemas x86 também) e patchear lá diretamente. PS.: Apesar de o código ser parte da glibc, a biblioteca do loader é compilada separadamente e tem um nome tipo ld-linux-$ARCH.so.2, onde $ARCH é a arquitetura da máquina. No meu caso, x86-64. Fiz uma cópia do arquivo /lib64/ld-linux-x86-64.so.2 para o diretório $HOME para começar a trabalhar. Pelo visto ela é compilada sem os símbolos, o que elimina a hipótese de achar a função por nome de forma fácil: $ nm ld-linux-x86-64.so.2 nm: ld-linux-x86-64.so.2: no symbols Sem problemas. Com o HT Editor, um editor de binários com suporte a disassembly, abri o arquivo e busquei pela string “/etc/ld.so.preload” já que ela é fixa na função, que deve referenciá-la. A ideia foi chegar no trecho de código que chama a função do_preload(). Os passos são: Abrir a biblioteca no hte: $ hte ld-linux-x86-64.so.2 No hte, facilita se mudarmos o modo de visualização para elf/image com a tecla [F6]. Depois é só usar [F7] para buscar pela string ASCII /etc/ld.so.preload: Após achar a string percebemos que ela é referenciada (; xref) em 4 lugares diferentes. Um desses trechos de código também deve chamar a função do_preload() que é a que queremos encontrar. Depois de analisar cada um deles, percebemos que tanto na r4294 quando na r4302 logo depois da referência à string tem uma CALL para uma função em 0xae0 que ao seguir com o hte (apertando [ENTER] no nome dela) é mostrada abaixo: Se comparamos com o código da função do_preload() vemos que se trata dela: A ideia é forçar que ela retorne 0, assim quando ela for chamada seja pelo trecho de código que carrega as bibliotecas a partir da variável LD_PRELOAD ou pelo trecho responsável por ler o arquivo /etc/ld.so.preload, ela vai sempre retornar 0 e vai fazer com que o loader não carregue as bibliotecas. Para isso, desça até o trecho de código do salto em 0xb37. Perceba que ele salta para 0xb56 onde o registrador EAX é zerado com um XOR, e depois o registrador AL (parte baixa de AX, que por sua vez é a parte baixa de EAX) é setado para 1 pela instrução SETNZ caso a condição em 0x58 não seja atendida (linha 675 no código-fonte). Só precisamos fazer com que esta instrução SETNZ em 0xb5e não seja executada para controlar o retorno da função. Ao pressionar [F4], entramos no modo de edição. Há várias maneiras de fazer com que esta instrução em 0xb5e não execute, mas vou fazer a mais clássica: NOPar seus 3 bytes. No modo de edição, substitua os bytes da instrução SETNZ AL (0f 95 c0) por 3 NOP’s (90 90 90), ficando assim: Dessa forma, o EAX é zerado em 0xb56, a comparação ocorre em 0xb58 mas ele não é mais alterado, tendo seu conteúdo zerado até o retorno da função. [F2] para salvar. Agora para testar vou usar duas técnicas combinadas. A primeira é de declarar uma variável de ambiente só para o contexto de um processo. A outra é de usar o loader como se fosse um executável (sim, ele pode receber o caminho de um binário ELF por parâmetro!). Veja: $ LD_PRELOAD=$PWD/hook.so ./ld-linux-x86-64.so.2 ./ola Inconsistency detected by ld.so: rtld.c: 1732: dl_main: Assertion `i == npreloads' failed! Para nosso azar, o loader checa o número de funções a serem carregadas dentro de uma repetição, fora da função do_preload(). Precisamos achar essa confirmação (assertion) para patchear também. Usando a mesma técnica de buscar pela string primeiro (nesse caso busquei pela string “npreloads” exibida no erro) você chega na referência r3148: Que te leva diretamente para a repetição da assert(): Comparando com o fonte: Para o salto em 0x3134 sempre acontecer e a CALL de erro em 0x3154 não executar, resolvi patchear a instrução JZ para que sempre pule para 0x2d60. No modo de edição dá pra ver que há um JMP negativo (salto para trás) em 0x315f de 5 bytes, conforme a figura: Podemos usá-lo só para copiar o opcode. Como em 0x3134 temos 6 bytes, NOPamos o primeiro e copiamos o opcode do JMP negativo (que é 0xe9), ficando assim: Após salvar e testar, voilà: ## Com variável de ambiente $ LD_PRELOAD=$PWD/hook.so ./ld-linux-x86-64.so.2 ./ola ola, mundo do bem! ## Com arquivo # echo $PWD/hook.so > /etc/ld.so.preload $ ./ld-linux-x86-64.so.2 ./ola ola, mundo do bem! Agora se você for bravo o suficiente é só substituir o loader original para desativar completamente o recurso de preloading e ficar livre de ameaças que abusam dele. Fica também o desafio para quem quiser automatizar este processo de alguma maneira e/ou trabalhar na versão de 32-bits do loader. O Matheus Medeiros fez um script maneiro para automatizar o patch! Valeu, Matheus! Patches de código e recompilação seriam melhores opções, de fato, mas quis mostrar uma maneira usando engenharia reversa por três motivos: Se automatizada, pode ser mais fácil de ser colocada em prática em um ambiente em produção. Recompilar a glibc demora muito. Se alguém souber de uma maneira de recompilar somente o loader, por favor, me avise! Engenharia Reversa é divertido.
×