Ir para conteúdo

Pimptech

Membros
  • Total de itens

    12
  • Registro em

  • Última visita

Reputação

6 Neutral
  1. Crackme - Level 0

    Primeira aula de Engenharia Reversa já tá no ar, mano. Dá uma olhadinha lá.. Abraço!
  2. Crackme - Level 0

    TLS Callback é coisa do MingW. Vou preparar mais alguns com o Build Tools do Windows, tem mais opções lá. GCC do MingW tem bastante código interno antes de chegar no OEP, contudo o código sempre começa de um determinado endereço de memória, porém não necessáriamente a main function. Vou anexar no post o source. No próximo (level1) vou manter a mesma linha. Valeu, Fernando! main.c
  3. Crackme - Level 0

    Fala pessoal! Codei um crackme aqui bem simplão mesmo. Eu ia postar o source junto, mas vou postar quando alguém conseguir quebrar. Depois eu vou postar um step-by-step. Abraço! crackme_level0.exe
  4. DLL Hijacking / DLL MITM (Man in The Middle)

    Fala, galera! Espero que todos estejam bem. Vou trazer aqui para vocês hoje algo que eu desenvolvi para aprendizado, para melhorar minha análise de Windows Internals no geral. Acredito que pode ser válido para o aprendizado da galera aqui também. Eu não vou fazer algo detalhado, portanto para compreender totalmente esse post é requerido um mínimo de conhecimento em: Arquivos PE PEB - Portable Environment Block Linguagem C Assembly --EDIT-- Esqueci de postar o projeto Projeto Github https://github.com/bernardopadua/blog-inversing/tree/master/dll-manual-hijack Eu escrevi sobre os dois primeiros tópicos, mas ambos estão em inglês. Contudo o @Leandro Fróes fez uma série de tópicos sobre arquivos PE muito mais completo do que o que eu escrevi. E o @Fernando Mercês fez uma série de vídeos sobre a linguagem C. Bom, como eu disse antes eu fiz esse PoC para aprendizado se você também gosta de aprender irá aproveitar bem. Não é algo muito difícil de ser feito, porém as áreas que são necessárias para entender como se faz são importantes em engenharia reversa / análise de malware em geral. Do que se trata ? Eu tenho estudado mais afundo sobre PEB hooking ultimamente, que já é uma técnica antiga no ramo de DLL injection. PEB Hooking basicamente tem o objetivo de se infiltrar em um módulo já carregado por um processo. Depois de se infiltrar em um módulo o processo acessará as funções do módulo injetado FAKE e não o original. Porém para isso acontecer é necessário que a DLL injetada exporte as mesmas funções que a DLL original. Com isso eu desenvolvi uma tool que eu chamei de "DLL Exporter" (sou péssimo em nomear haha), essa tool acessa o Export Directory para exportar as funçoes que uma determinada DLL exporta. Com essas funções a ferramenta vai gerar dois arquivos para NASM, um com a extensão ".ext" e outro com a extensão ".subs". Cada um dos arquivos foram gerados por essa tool para ser embutidos no código principal. O exemplo que eu estou trazendo faz algo bem trivial e comum nos dias de hoje. O exemplo é um protótipo de troca de mensagem (mesmo não havendo nenhuma troca real) com "encoding" da mensagem para uma troca "segura" de tais mensagens. O exemplo em questão acessa uma função da DLL chamada 'send' para encodar e enviar a mensagem. Para fazer essa DLL hijacking/MITM a ideia é codar uma DLL que exporte a mesma função e que dentro dessa função ela chame a DLL original após nosso código customizado ser executado. Não há alteração no processo que faz a chamada da DLL e também não qualquer alteração na DLL original. A DLL fake irá fazer o load manual da DLL original e chamar a função original dentro da funão fake. Para fazer isso eu codei a DLL fake com o NASM e linkei a DLL com o GoLink. GoLink se encarregou de linkar o objeto gerado com as libs Kernel32, msvcrt e a dllsend. O nome de DLL que eu utilizei no exemplo foi "dllsend.dll". Problemas ? Como tive que renomear a DLL fake com o mesmo nome da DLL original, quando o Windows Loader vai tentar fazer o load da DLL original (mesmo nome da DLL fake) ele já acha a DLL carregada no espaço de endereços de memória do processo (a fake DLL), com isso a IAT (Import Address Table) é carregada com os endereços da própria DLL fake. No fim isso acaba gerando um Deadlock, a fake DLL quando chamada pelo processo e tenta executar a função da DLL original acaba chamando a si mesma infinitamente. Solução! Para resolver esse problema eu tive que fazer o Load da DLL original com a API LoadLibraryA, acessar o "module" da DLL fake para guardar o endereço de IAT da DLL. Acessar o "module" da DLL original para acessar e guardar o endereço do campo AddressOfFunctions localizado dentro da Export Directory. A inteção aqui é iterar sobre a AddressOfFunctions e sobrescrever a IAT com os endereços da função original. Contudo as páginas de memória onde a IAT está localizada está protegida contra gravação e para resolver isso precisei utilizar outra API VirtualProtectEx para alterar a proteção do espaço de memória onde a IAT está localizada. Divisão do projeto Cada pasta do projeto possui um make.ps1 para compilar o objeto de cada pasta. dll Esta pasta contém o código da dllsend.dll dll-consume Esta pasta contém o código do programa que consome a dllsend.dll. dll-exporter Esta pasta contém a tool "DLL Exporter" que exporta as funções de uma determinada dll. A ferramenta gera dois arquivos {NOME_DLL}.DLL.EXT E {NOME_DLL}.DLL.SUBS. .EXT: Este arquivo contém o código NASM para indicar uma função importada com a diretiva "extern". .SUBS: Este arquivo contem a declaração NASM da função exportada. dll-fake-asm Esta pasta contém a DLL fake codificada. É totalmente codada em NASM com uma section especial chamada drectve. Essa section especial é lida pelo GoLink para importar as libs informadas lá. make.ps1: Tem toda a lógica para compilar e linkar a DLL. Análise do processo A ordem de compilação é indiferente, porém pode fazer dll-consume, dll e dll-fake-asm. Vou assumir que você tenha compilado tudo certo. The program dll-consume é bastante simples e bem intuitivo. Você digita a mensagem e o programa faz o "encoding" da mensagem e faz o envio (não de verdade). Para fazer processo funcionar eu renomeei a DLL original com o final "2". Como a DLL fake foi codada em NASM o tamanho é muito diferente, pois não tem todos os apetrechos da GCC. Vamos ver como fica a lista de arquivos na pasta. Talvez alguns de vocês ainda não estjam cientes, porém o entry point dos programas compilados com o GCC não são diretamente da main. O entry point criado pelo GCC é um "pré-código" de inicialização de todo o ambiente para então executar o OEP (original entry point). Você pode debugar linha a linha e achar o entry point ou pode ir direto ao assunto e procurar pelas "inter-modular calls" feitas pelo módulo m.exe para o módulo dllsend.dll. Esta é a main function do programa: Se você não esta muito acostumado com assembly, minha dica seria treinar. Resolva crackmes, codifique em C e debug seu próprio programa, mas não em IDE, ao invés disso direto no assembly. É necessário treinar os olhos para ler assembly e idenficar padrões de chamada/instruções. Eu coloquei o mouse na linha que faz a chamada para a função send e o x64dbg gerou um preview do destino da chamada. Esse jmp faz um salto para o endereço da função send gravado na IAT do módulo m.exe. Nesse ponto de execução a DLL fake já foi inicializada e já inicializou a DLL original também. Essas informações podem ser chacadas na aba de Memory Map. Se você quiser debugar todo o processo de inicialização (recomendo MUITO) da DLL original e do processo de reescrita da IAT você vai precisar debugar a entry function da dllsend.dll (fake dll). Para fazer isso é necessário habilitar no x64dbg a opção DLL Entry. Ele vai pausar a execução no início de cada DLL, só ir dando F9 até chegar na dllsend.dll. Eu achei função send da dllsend.dll e coloquei um break point lá para debugar. Dentro da execução podemos ver o código que loga todas as menssagens enviadas pelo programa. Como você pode ver no código assembly gerado, estou utilizando fopen, fwrite e fclose. Com esse padrão de chamada fica visível que eu estou logando as informações em algum arquivo antes de efetuar o JMP (salto) para a função send original. Usei pushad e popad para salvar o contexto de registradores antes de executar minha função custom. E não podemos esquecer que a lib msvcrt é __cdecl(calling convention) o chamador (caller) que limpa a stack. Eu recomendo a debugar o processo de escrita da IAT para aprender (se quiser). Abre a DLL no CFF Explorer e vai debugando ao mesmo tempo. Como evitar isso ? Até existem algumas medidas para tentar bloquear esse tipo de coisa. Podemos checar a MD5 da DLL antes de efetuarmos a chamada para ela, se for diferente da MD5 armazenada, então seu programa foi comprometido. Podemos também checar na PEB (LdrModules) quantos módulos existem dentro do espaço de endereços do processo, se tiver qualquer módulo a mais podemos concluir que houve uma dll injection ou algo parecido, como esse hijacking/MITM. Mas a gente sabe que é mais complicado do que isso. O que o programadores realmente podem fazer é deixar a engenharia reversa muito mais difícil de ser realizada. E para isso o programador tem que saber usar as técnicas de engenharia reversa. Bom galera, sei que não é muita coisa, mas acho que talvez ajude alguém. Qualquer dúvida, crítica, sugestão ou correção fique à vontade para comentar. Estamos ai para aprender. Abraço! Post Original https://verseinversing.blogspot.com/2017/11/manually-hijacking-dll-mitm-dll.html
  5. Sou novo e estou perdido.

    Cara, acho que deve fazer o que o Leandro indicou. Tira um tempo para ler sobre as áreas que vocês tem interesse. Procura no google/youtube como é a vida daquele profissional e vai afunilando o que você gosta mais. Só que independente da área que você escolha computação é uma coisa só, aquela velha história "é tudo 0 e 1 com operações lógicas". Outra coisa, não se desespere. Se você realmente gosta da área leia com calma, tente entender os conceitos e como aplicá-los. Não adianta tentar aprender tudo de uma vez só. Em computação o raciocínio lógico é imprescindível, então tente treinar essa parte. Se você já programa, procure desafios de lógica para resolver. Só não se atole de informação por que se não vai agonizar muito mesmo. Redes é chatinho até o momento que você começa a entender como funciona. No fim de tudo e abstraindo ao máximo é só organização e interpretação de dados. Uma forma de aprender que eu utilizo é a seguinte. Primeiro pega papel e caneta, e abra o google. Procure algo que você gostaria de fazer, qualquer coisa. Tu escreve essa coisa no centro da folha, é o tópico principal. Você vai pesquisar por ela, ler sobre (não se desespere, você talvez não entenda 90%), anote os pontos que você não entende e que sejam críticos para desenvolver. Agora você vai fazer a mesma coisa com os pontos críticos, pesquisar e anotar. Vai fazer isso até chegar no tópico mais profundo que você entendeu bem o que é e vai subindo pros tópicos que você não entendia por causa desses pontos chaves. Vai chegar uma hora que as coisas vão começar a se relacionar. Nosso cérebro funciona assim, ligando fatos, conectando pontos chaves. Só que para isso você precisa ser paciente, pq é algo que leva tempo. Quando você estudar e ferver a cabeça, dá um tempo, faça algo tranquilo que você curta. Nesse tempo seu subconsciente estará conectando esses pontos para você. Depois volte ao mesmo tópico que eu garanto que você vai estar entendo melhor. Espero ter ajudado de alguma forma. Abraço!
  6. Reptile rootkit

    Bacana o conteúdo! Vou estudar esse código com mais calma, ainda to estudando melhor a arquitetura do Linux. Essa vida de pesquisas de rootkit deixa a gente meio paranóico hahaha. We never know! ahaha Acho que a melhor maneira de tentar detectar é por log do que tá circulando na rede, né. E geralmente melhor se for por fora do sistema. Alguma dica para fazer isso ? Se tiver alguma coisa deixa ai pra gente =) Abraço!
  7. Crackme 01 - Linux - Geyslan

    Claro! Com maior prazer! No gdb deve ser puxado hein.. Sem uma interface amigável! LOL! Esse é monstro! hahah Sigo teu blog desde da dark era do BLOG. Só coisa boa. Chegamos a trocar alguns e-mails, mas acho que n lembra haha.. Seu BLOG foi uma das portas de entrada em ER p mim. Até montei um blog de er, mas acabei fechando. Anyway, é noiz!! HOWTO Desculpem qualquer erro de PTBR hahaha Bom galera, vou estender um pouco somente no início pq eu acho mais importante deixar claro como desabilitar a checagem do GDB. O resto eu vou passar mais rápido, mas essa parte é mais essencial até pra você poder sondar melhor o crackme. Primeiramente instale o radare2. Tudo que vocês precisam para instalar o radare2 está no link abaixo: https://github.com/radare/radare2 Caso tenham algum problema em instalar, deixa um post ai que se eu puder ajudar, eu ajudo :). Para abrir o crackme no radare2 (r2) é bem simples: -A: Analyze. Ele já vai abrir com o binário analizado. Você também pode utilizar o comando aaaa. -d: Vai abrir em modo debugger. -w: Abre em modo de escrita. Ou seja, você pode usar w? para ver os comandos para escrever direto no binario. E também quando "patchar" algo ele ap´licar no binário "físico", pois do contrário ele só aplica no binário in-memory. Poderia ser -Adw Bom, aqui você pode usar o comando ie pra achar o entry point que é a function entry0 e dar o comando s entry0 pro r2 te levar direto na function. O radare2 ele tem uma curva de aprendizado meio "tensa", pq até você entender todos os comandos e etc, leva um tempo. Você pode usar ? para listar os comandos e usar o ? junto com algum comando para ter o help de determinado comando, por exemplo, a?, af?, afl? e assim por diante. afl: Esse comando vai listar todas as functions que ele conseguiu identificar após a análise (-A). ii: Vai listar todos os imports. Outra forma de achar o início seria achando a função que inicia o processo. Com o comando ii você achar os imports e com eles você é capaz de achar a function: http://refspecs.linuxbase.org/LSB_3.0.0/LSB-PDA/LSB-PDA/baselib---libc-start-main-.html Essa function prepara o sistema para rodar o programa em si. Notem nessa especificação que ela receber como primeiro argumento int *(main) e se você usar o comando s entry0 você vai notar que o endereço da main é pushado na stack assim como outros valores também. Contudo antes de ir definitivamente para a main essa function passa por outra function apontada pelo parâmetro void (*init). Que nesse caso se você analisar no entry0 acaba sendo a sym.__libc_csu_init. Abaixo uma imagem para ilustrar como se chega na entry0 pelo comando ii. Bom, agora sabemos como iniciar o debugging. Se você simplemente abrir o crackme e usar o comando dc que seria o continue para rodar o programa ele já apresenta a mensagem que não é possível rodar dentro do GDB. Então precisamos desabilitar essa detecção. E para isso precisamos saber de onde o GDB é chamado: Dentro da function _init você pode observar primeiro um endereço dinâmico e um loop que o radare2 já mostro pra gente. Se você debugar aqui vai ver que a mensagem do GDB acontece depois dessa call em detaque. Copie o endereço apontado pela call 0x080487ab no meu caso e adicione um breakpoint nessa linha. db 0x080487ab. você pode usar o comando d? para ver a possibilidade que a ferramenta te dá na hora do debugging. Se você fez alguma mudança ou já passou desse ponto, o comando ood é útil para que você possa reabrir o arquivo em modo de debugging. Ok, tudo pronto e breakpoint colocado e só dar o comando dc. Após para a execução nesse ponto vamos usar um pouco o Visual mode. Para entrar nesse modo visual use o comando V (maiúsculo) quando você entrar no modo visual ele te dá VÁRIOS modos visuais de navegar pelo binário, gaste um tempo navegando por ele. Para saber como navegar use pressione o ? para entrar no help do modo visual. Ok vamos la, pressione p para correr para o modo de disassembly e então pressione ! você irá entrar em um modo parecido (lembra de alguma forma) com o debugging do OllyDbg/x64dbg. Com o breakpoint na linha da call vamos ver onde essa call nos leva. Se você pressionar a tecla : você poderá executar comandos como se estivesse na parte não visual do radare2. E nesse ponto vamos utilizar o pxw que seria a impressão hex em formato DWORD de um determinado endereço. Podemos ver que somente ebx tem valor, ou seja edi*4 dá 0, então podemos imprimir diretamente pxw @ ebx-0xfc lembrando que o @ é utilizado para representar um endereço. Se você usar simplesmente pxw ele vai mostrar os valores onde seu ponteiro está, no caso poderia ser utilizado após um s, por exemplo. Bom, voltando as imagens vemos que existe 3 endereços na memória (array) de ponteiros e eles estão em vermelho o que indica que são funções. Você pode, mesmo com o programa parado no breakpoint, usar o comando s em cada uma dessas functions seguido do comando pdf que printa o disassembly da function apontada pelo s e verá que a function do endereço 0x080485ab é a function sym.detect_gdb. SHOW! E agora ? Agora vamos assemblar para não executar ela, na minha opinião o jeito MAIS fácil é apenas sair dela quando o programa entrar nela. Para isso eu fiz o seguinte. A forma mais fácil para sair dela é usar ela contra ela mesmo. Então vamos usar a instrução JMP essa instrução é muito simples vai simplesmente fazer o ponteiro de execução pular para o endereço que está na contido na instrução. Eu pulei para a instrução leave que fica no endereço 0x08048632, contudo para fazer isso primeiro vamos dar uma olhada na sua referência: http://x86.renejeschke.de/html/file_module_x86_id_154.html Atentem para "Releases the stack frame set up by an earlier ENTER instruction.". Ou seja o stack frame tem que estar setado já e para setar um stack frame são as primeiras instruções até o 0x080485b1 nesse ponto o stack frame tá setado. Então vamos assemblar aqui. No ponto da imagem eu sai do modo visual pressionando q, ok ? Em modo visual pressione : e use o comando s 0x080485b1 e em seguida q para sair dos comandos no modo visual. Nesse ponto o radare2 deve ter te levado exatamente para esse endereço, agora você só precisa pressionar A (maiúsculo) para entrar no modo de edição do assembly. Digite jmp 0x08048632 e pressione Enter 2 vezes. Pronto! Assemblado. Você pode entrar em modo de -Aw e fazer exatamente isso novamente que quando você entrar no modo -Ad de novo você já vai ter gravado essa instrução direto no binário, sem precisar fazer isso toda hora. Bom, agora vamos para a parte da senha. A partir desse ponto vou considerar que você já tá mais esperto com o radare2 e seus comandos. Vou fazer um recap do que eu vou usar e só vou descrever o comando, ok ? Recap: Vamos lá. Agora já podemos debugar a main. Mande o ponteiro para main e entre em modo visual. No modo visual pressione espaço para entrar no modo de branchs. Analise ela por um estante e você irá perceber (se você programa qualquer coisa) pelas calls e pelo o que o radare já analisou pra gente o que é feito. Vemos então a string que é printada pedindo o password, depois a função para pegar os valores digitados e logo em seguida a chamada em uma função sym.xor nome bastante sugestivo. Você pode usar o modo de cursor no visual para ir até essa call e pressionar Enter que você vai direto para ela. Ou pode usar os comandos normais como s. Bom, lá dentro da function do XOR eu printei ela para analisar: Vamos aos indicativos. Ponteiro/argumento para a o password digitado. Indicativo de loop. Mov 0, indicativo de index de loop. Indico fortemente que você gaste um tempo debugando essa parte e entendo exatamente o que ela faz (use o visual mode com o modo olly, fica muito fácil debugar), assim vai melhorando a habilidade de ler assembly sem ter que ficar debugando toda hora. Basicamente ele move o ponteiro para o registrador e vai xoreando byte a byte o password e logo em seguida na main ele compara esse valor xoreado com o valor que já está xoreado em mem´ória. O valor já xoreado já está indicado no disasembly obj.passwd. Você pode usar o comando s para seguir até esse ponto em memória para ver o verdadeiro valor do password, lembrando que esse valor já está xoreado. Então faremos o inverso do xor que é o próprio xor. Para isso usamos o comando wox que vai sobreescrever em memória determinado valor xoreando ele com a key que você indicar. Nesse caso usei a key 0x6c. Agora você pode usar q para sair do visual, q no r2 e executar o crackme com a senha. Para patchar e fazer funcionar com qualquer senha, use como exemplo a parte do detect_gdb. Certo ? Qualquer dúvida é só falar. Bom galera, é isso. Espero que eu tenha conseguido passar certinho como fazer para reversar esse crackme. Qualquer coisa só falar ai. Abraço!
  8. Crackme 01 - Linux - Geyslan

    Falai, Fernando! Bacana esse crackme. Eu não sou super user de Linux, então tive alguns problemas no início, pq esqueci que eu estava rodando um x86_64 e tava sem a libc pra x86. Fiquei achando que fazia parte do desafio hahaha Perdi um tempinho ali! hahaha Eu tinha mexido pouco no radare2, aconselho muito a usarem. Depois que pega o jeitão vai embora. O Visual mode dos caras ta muito poderoso! Vale a pena dar uma conferida! Fica a dica. Bom, vou deixar 2 binários. Um que ta patched pra abrir no GDB e debugar a vontade. E outro ta patched com o resultado final. crackme01-geyslan_opGdb => Abre com GDB. crackme01-geyslan_patched => Qualquer senha funciona. E a senha:
  9. Solução de Crackme

    Legal, Danilo! Curti a idéia! Quando eu tiver um pouco mais de tempo vou tentar codar um crackme, ai solto o source junto. Segue meu keygen. https://github.com/bernardopadua/blog-inversing/blob/master/crackme-1-mentebinaria/crackme_keygen.py Abraço!
  10. Sugestões

    Passando pra deixar um link para quem se interessa por exploitation: https://github.com/jaybosamiya/security-notes Conteúdo todo em inglês, vale muito a pena. Quem sabe se juntar mais gente não rola de abrir uma sub área em ER. Formar um grupo de estudos ai. @F0rb1dd3n Vai postar aqui quando sair, @Ygor Da Rocha Parreira ? Abraço!
  11. Dezenas de ferramentas para ER

    Só pra complementar seu post, Fernando. A tuts4you também tem um ótimo acervo de tools e papers. Vale muito a pena dar uma conferida. https://tuts4you.com/download.php Abraço!
  12. livros - currículo

    Olá, morgao. Bom estar com todo esse gás para aprender. Melhor momento é agora. Sobre o CV perfeito é muito complicado, é difícil você ver alguém que é o bom em todas as áreas. Minha dica para você seria, primeiro escolha o que quer fazer dentro de TI. Você quer programação ? Então foque em programação, estudar tudo de uma vez acredito que irá sobrecarregá-lo. Sobre o inglês é MUITO importante, comece em ler e pesquisar tudo em inglês. Dessa forma você ensina o seu cérebro a pensar em inglês. Sobre português, desconfie de tudo que você escrevre (será que é assim ?). Uma linha de raciocínio legal para aprender e que tem funcionado comigo é a seguinte. Depois de entender o que você quer fazer, você pega um projeto bacana que gostaria de desenvolver se tivesse trabalhando com isso e extrai o que você precisa entender para desenvolver esse projeto, pesquisa sobre os temas e vá desenvolvendo. Pode ser que o projeto saia todo torto, porém nessa altura você já adiquiriu mais conhecimento para aprimorar o projeto. O melhor jeito de aprender é botar a mão na massa. Quando você for ver estará tudo mais nítido no decorrer do desenvolvimento. No canal do próprio Mercês ele dá uma tonelada de dicas e livros. Se não assistiu, eu recomendo são bem esclarecedores e didáticos. Comentou sobre os cursos de eng. e cinência da computação, então deduzo que tem muito interesse em baixo nível. Sem querer fazer jabá, fiz um post em meu blog que eu tento passar de uma forma didática, uma forma de se pensar em computação. Utilizando essa base pensamento acredito que com o tempo a forma como vemos a computação muda e tudo fica mais tranquilo a partir do momento que começamos a entender toda essa abstração. No meu post eu sempre deixo as referências. Se só quiser os livros e só descer no fim do post. Nos demais posts tem mais um monte de referências. Recomendo todas as referências. Quando você entende a máquina na qual você trabalha tudo fica mais fácil, até programação melhora. Você se torna uma programador mais consciente. Não está SUPER bem escrito, mas eu tentei hehe Fica a dica: https://verseinversing.blogspot.com.br/2017/06/engenharia-reversa-ponto-de-vista.html Caso tenha alguma dúvida, manda ai que se eu puder ajudar ajudarei com maior prazer. Abraço!
×