Ir para conteúdo
  • Cadastre-se
  • Entre para seguir isso  

    Artigos


    Fernando Mercês
    Desde 2013 que estamos trabalhando duro numa nova versão do pev, nosso toolkit para análise de binários PE (Portable Executable), o formato utilizado pelos executáveis (EXE, DLL, OCX, etc) do Windows.
    O pev é um projeto em que me sinto muito feliz de fazer parte e o principal motivo é que existe algo de muito forte e especial nele: colaboração.  Quase 30 pessoas contribuíram com o projeto de alguma forma (código, testes, empacotamento, etc) e hoje ele está presente nos repositórios das principais distribuições Linux, inclusive as focadas em segurança de alguma forma.
    Outro ponto importante é que ele começou como um projeto de faculdade lá em 2010, junto com outros alunos. Como a faculdade nem laboratório de pesquisa tinha, fizemos o nosso próprio grupo, batizado de Coding 40°, em homenagem ao calor da nossa cidade.
    O projeto atraiu muitos colaboradores, incluindo um que já commitou mais que eu no repositório e redefiniu, de forma muito profissional, toda a infraestrutura por trás do pev e da libpe. Foi o Jardel Weyrich. Sério, dá pra detectar que um projeto teve sucesso quando aparece alguém que já contribuiu com mais código para ele do que você!
    Por último, mas não menos importante: o pev é livre. E na boa, até agradeço as centenas de programadores que fizeram analisadores de PE proprietários, porque me motivaram a iniciar o pev. Era preciso um analisador de binários PE de código aberto, que permitisse estudantes e curiosos entender como um PE é parseado, que campos são importantes, por que a análise estática é tão poderosa, etc. Hoje, mesmo com todos os bugs que ainda hão de surgir (fora os que já surgiram e ainda não conseguimos corrigir!).
    Quero agradecer, de forma permanente, a todos que se envolvem ou se envolveram de alguma forma com o pev: usando, avisando-nos sobre bugs, contribuindo com código, ideias, testes, tudo importa! Obrigado, de coração.
    Emoções à parte, vamos partir para a análise de binários e falar das novidades do pev 0.80, lançado hoje!
    Acontece que um binário PE pode esconder muitas informações importantes antes mesmo de ser executado. Por exemplo, com a ferramenta readpe, do pev, você vai descobrir que um executável PE é dividido em cabeçalhos e seções e eles armazenam várias informações interessantes, por exemplo:
    $ readpe arquivo.exe DOS Header Magic number: 0x5a4d (MZ) Bytes in last page: 144 Pages in file: 3 Relocations: 0 Size of header in paragraphs: 4 Minimum extra paragraphs: 0 Maximum extra paragraphs: 65535 Initial (relative) SS value: 0 Initial SP value: 0xb8 Initial IP value: 0 Initial (relative) CS value: 0 Address of relocation table: 0x40 Overlay number: 0 OEM identifier: 0 OEM information: 0 PE header offset: 0x80 COFF/File header Machine: 0x14c IMAGE_FILE_MACHINE_I386 Number of sections: 3 Date/time stamp: 1425562907 (Thu, 05 Mar 2015 13:41:47 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 Optional/Image header Magic number: 0x10b (PE32) Linker major version: 11 Linker minor version: 0 Size of .text section: 0x2a800 Size of .data section: 0x3400 Size of .bss section: 0 Entrypoint: 0x2c78e Address of .text section: 0x2000 Address of .data section: 0x2e000 ImageBase: 0x400000 Alignment of sections: 0x2000 Alignment factor: 0x200 Major version of required OS: 4 Minor version of required OS: 0 Major version of image: 0 Minor version of image: 0 Major version of subsystem: 4 Minor version of subsystem: 0 Size of image: 0x34000 Size of headers: 0x200 Checksum: 0 Subsystem required: 0x2 (IMAGE_SUBSYSTEM_WINDOWS_GUI) DLL characteristics: 0x8540 DLL characteristics names IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE IMAGE_DLLCHARACTERISTICS_NX_COMPAT IMAGE_DLLCHARACTERISTICS_NO_SEH IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE Size of stack to reserve: 0x100000 Size of stack to commit: 0x1000 Size of heap space to reserve: 0x100000 Size of heap space to commit: 0x1000 Data directories Directory IMAGE_DIRECTORY_ENTRY_IMPORT: 0x2c738 (83 bytes) Directory IMAGE_DIRECTORY_ENTRY_RESOURCE: 0x2e000 (12728 bytes) Directory IMAGE_DIRECTORY_ENTRY_BASERELOC: 0x32000 (12 bytes) Directory IMAGE_DIRECTORY_ENTRY_IAT: 0x2000 (8 bytes) Directory IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR: 0x2008 (72 bytes) Imported functions Library Name: mscoree.dll Functions Function Name: _CorExeMain export directory not found Sections Section Name: .text Virtual Address: 0x2000 Physical Address: 0x2a794 Size: 0x2a800 (174080 bytes) Pointer To Data: 0x200 Relocations: 0 Characteristics: 0x60000020 Characteristic Names IMAGE_SCN_CNT_CODE IMAGE_SCN_MEM_EXECUTE IMAGE_SCN_MEM_READ Section Name: .rsrc Virtual Address: 0x2e000 Physical Address: 0x31b8 Size: 0x3200 (12800 bytes) Pointer To Data: 0x2aa00 Relocations: 0 Characteristics: 0x40000040 Characteristic Names IMAGE_SCN_CNT_INITIALIZED_DATA IMAGE_SCN_MEM_READ Section Name: .reloc Virtual Address: 0x32000 Physical Address: 0xc Size: 0x200 (512 bytes) Pointer To Data: 0x2dc00 Relocations: 0 Characteristics: 0x42000040 Characteristic Names IMAGE_SCN_CNT_INITIALIZED_DATA IMAGE_SCN_MEM_DISCARDABLE IMAGE_SCN_MEM_READ Só olhando para este cabeçalho, já dá pra dizer muita coisa sobre esse binário. Por exemplo, é possível inferir que ele foi compilado em 5 de março de 2015, é um executável de janelas (GUI – Graphical User Interface) e na Import Table dele tem apenas uma entrada, uma função chamada _CorExeMain importada da biblioteca mscoree.dll. Isso já dá a dica que esse é binário foi compilado em .NET. Como eu sei disso? É que eu já vi vários binários em .NET e todos eles importam somente essa função. Não se preocupe, com o tempo você também pega os macetes!
    Claro que, para estudar os binários de forma eficiente é legal ler também outros tutoriais sobre o assunto. O que mais gosto em Português é O formato PE, da Vovó Vicky, isso mesmo, uma simpática senhora, médica, do Sul do país que adora arquivos PE. ❤️
    Voltando ao nosso binário, vamos dar uma olhada nas strings presentes nele com o pestr:
    $ pestr -so arquivo.exe 0x2d81e .rsrc FileDescription 0x2d840 .rsrc Gynx 0x2d852 .rsrc FileVersion 0x2d86c .rsrc 1.0.0.0 0x2d882 .rsrc InternalName 0x2d89c .rsrc Gynx.exe 0x2d8b6 .rsrc LegalCopyright 0x2d8d4 .rsrc Copyright 0x2d8ea .rsrc 2015 0x2d8fe .rsrc OriginalFilename A lista de strings completa é bem maior, mas eu cortei só para mostrar algumas.
    Primeira pergunta que pode surgir aqui é: por que fizemos um programa pestr se já existe o programa strings? Bem, você pode notar pela saída que dizemos muito mais que a string (texto) em si. Sabemos em que seção ela está e o offset (posição) no arquivo. Além disso, o pestr imprime strings ASCII e Unicode.
    No meio das strings tem outra informação de data, que reforça o ano da data de compilação. Tem também o nome original do arquivo (quando o programador compilou). Se você pesquisar no Google pelo nome do arquivo, já vai encontrar muita coisa!
    Continuando nossa análise, vamos ver com o pescan se tem algo estranho neste arquivo:
    $ pescan -v ~/dotnet file entropy: 5.252392 (normal) fpu anti-disassembly: no imagebase: normal - 0x400000 entrypoint: normal - va: 0x2c78e - raw: 0x2a98e DOS stub: normal TLS directory: not found timestamp: normal - Thu, 05 Mar 2015 13:41:47 UTC section count: 3 sections section .text: normal section .rsrc: normal section .reloc: small length A baixa entropia sugere que o binário não está comprimido (packed) e tudo parece estar normal. Isso significa que o binário não está protegido, não que seu código não seja malicioso.
    Agora, já entrando nos novos recursos, que tal saber os hashes deste arquivo? Buscando por eles no Google também é possível encontrar algumas informações. Ao invés de calcular um por um, utilizando vários programas, o pev conta com o pehash, que faz tudo pra você:
    $ pehash -a arquivo.exe file filepath: /home/user/arquivo.exe md5: 1f4c40ff46297bdc5a595cd574e0db64 sha1: 2bc6fa6558988d628dd4b95d0741405685c1c232 sha256: b823a04f49463e410c9f823baade182eb283ba073b40c6d8cc443a570a9a1df6 ssdeep: 3072:yLYmWbfXGKJy7DFR9KwHS+MASjB5jL0S9Q0VwuUcu:AYmWbfX3y7DFR9KwHS+MAS/js0VhU imphash: f34d5f2d4577ed6d9ceec516c1f5a744 headers header header_name: IMAGE_DOS_HEADER md5: 919f1c12cf0d1cd93d7f1077f13ac374 sha1: 3d43712e5606b4640b85f5f0e25e9db8ed552074 sha256: c46a3fc444808f3b86a7e757e5202d16f8ea9bf1c6aff2cabc593e7d0f2c9ad2 ssdeep: 3:WlWUqt/vllnln:idqP header header_name: IMAGE_COFF_HEADER md5: 15174f39bbe557d104f169053af5c7a2 sha1: 21f9311fa5e1a7c8724c657db39ef2fbb1b896ce sha256: 7430166bd1b2d5c400f2f5fb60c90393b50388b97e877aa7cf0c3057a413a85f ssdeep: 3:HHJl/fkn:HHJlkn header header_name: IMAGE_OPTIONAL_HEADER md5: 3b079fa2a88b6901db907bc47dee2d67 sha1: 21c1c517743170c94d1ade608ff7d2746fd7e3ea sha256: 0fec7657e9361e8262af5872bf3784a7647b6978f3d0e35a419d2f410c8654a0 ssdeep: 3:6FZ//llAlFlllXNB//llrllel/dglPt1l9tllH:pfGwlN sections section section_name: .text md5: 973d11759194c14071aa6963de8f55c7 sha1: 1934e0085c8776e3243bf658e95b8943d4f91bc9 sha256: e68349bfcb04b20c11973ce27770570ebb22c8c7750133d073f15f7ec9eeda38 ssdeep: 3072:XLYmWbfXGKJy7DFR9KwHS+MASjB5jL0S9Q0VwuUc:bYmWbfX3y7DFR9KwHS+MAS/js0VhU section section_name: .rsrc md5: 9d498bee08b1cf075d8aca022f1e16e9 sha1: f938a8c23185b023bb5dd12082013c2a628bc0d3 sha256: eb7454309df90fea2d01c887b0040e8237353919efc06a7081a7abb15091283a ssdeep: 24:3A5t/ug9GXBEiViKZWIDDOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO:weg90VWIDZ6Kp+l4BhDqFWSfbNtm section section_name: .reloc md5: 37ab911460a0b274ffa9f4e388ec933b sha1: 7c9eac3b843c9a7ab8ef08aac5c14e4c51b2c703 sha256: fb50df3b064d126999295b35f1a151f8fbe7e3593e306a9255a534999843f5b2 ssdeep: 3:LlQl:S Achou que teria os hashes do arquivo somente? Pois é, o pev surpreende mesmo! O pehash calcula MD5, SHA1, SHA-256 e ssdeep (uma técnica de fuzzy hash que vale a pena pesquisar sobre!) para cada cabeçalho e seção. Além disso, a partir das funções importadas do binário o pehash calcula o imphash, que já expliquei no artigo Entendendo o imphash.
    Tanto o imphash quanto o ssdeep podem ser utilizados, de maneiras diferentes, para saber se um arquivo é parecido com outro, se são variantes do mesmo código-fonte, mas neste caso o imphash não ajuda por ser um binário .NET (todos eles importam aquela mesma função única que comentei acima).
    Também é possível, com o peres (criação do Marcelo Fleury),  extrair os recursos e checar, por exemplo, o manifesto em XML dos arquivo:
    $ peres -x arquivo.exe Save On: resources/icons/2.ico Save On: resources/icons/3.ico Save On: resources/icons/4.ico Save On: resources/icons/5.ico Save On: resources/icons/6.ico Save On: resources/icons/7.ico Save On: resources/icons/8.ico Save On: resources/groupicons/32512.ico Save On: resources/versions/1.rc Save On: resources/manifests/1.xml $ cat resources/manifests/1.xml <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <security> <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> <requestedExecutionLevel level="asInvoker" uiAccess="false"/> </requestedPrivileges> </security> </trustInfo> </assembly> O ícone utilizado também é extraído (groupicons) mas ele é quebrado em várias imagens (icons) e precisam ser reconstruídos se você precisar do ícone original do arquivo. De qualquer forma, você pode calcular o hash deles e comparar com os dos ícones de outros arquivos, se for essa a intenção.
    Uma outra novidade é o programa cpload, para analisar arquivos .cpl (Control Panel Applets). Ele é presente somente na versão do pev para Windows, pois serve para analisar binários dinamicamente. Este formato é um pouco diferente do EXE convencional (na verdade um CPL é uma “DLL que executa com dois cliques”). Na época o formato desses arquivos era muito pouco conhecido e até escrevi um artigo para a Wikipédia em Português sobre. Com o cpload, é possível enviar para a função presente no arquivo .cpl todas as mensagens que ela deve reconhecer. Assim o analista pode ver qual delas dispara o código. No exemplo abaixo, a mensagem CPL_DBLCLK (clique duplo) foi enviada para um .cpl presente no Windows chamado joy.cpl. Veja que o programa executa e mostra uma janela:

    Adicionalmente, se você fizer isso no contexto de um debugger, passando os argumentos como na imagem abaixo:

    O cpload força um software breakpoint antes do carregamento do arquivo .cpl pela função LoadLibrary() e antes da entrada na CPLApplet(), que é a função principal de um arquivo .cpl, o que permite ao analista enxergar o trecho exato de código dele, sem precisar debugar processos do sistema como o rundll32.exe.

    E ainda sobre o pev, os plugins de formato de saída estão dando um show (ideia do Jan Seidl e portada para plugins pelo Jardel). Olha só como fica a saída se você pedir ao pedis, nosso disassembler, para disassemblar o entrypoint  de um binário PE em JSON:
    $ pedis --format json --entrypoint PUTTY.EXE { "54eb0": "6a 60 push 0x60", "54eb2": "68 70 7b 47 00 push 0x477b70", "54eb7": "e8 08 21 00 00 call 0x456fc4", "54ebc": "bf 94 00 00 00 mov edi, 0x94", "54ec1": "8b c7 mov eax, edi", "54ec3": "e8 b8 fa ff ff call 0x454980", "54ec8": "89 65 e8 mov [ebp-0x18], esp", "54ecb": "8b f4 mov esi, esp", "54ecd": "89 3e mov [esi], edi", "54ecf": "56 push esi", "54ed0": "ff 15 e0 d2 45 00 call dword [0x45d2e0]", "54ed6": "8b 4e 10 mov ecx, [esi+0x10]", "54ed9": "89 0d 48 e1 47 00 mov [0x47e148], ecx", "54edf": "8b 46 04 mov eax, [esi+0x4]", "54ee2": "a3 54 e1 47 00 mov [0x47e154], eax", "54ee7": "8b 56 08 mov edx, [esi+0x8]", "54eea": "89 15 58 e1 47 00 mov [0x47e158], edx", "54ef0": "8b 76 0c mov esi, [esi+0xc]", "54ef3": "81 e6 ff 7f 00 00 and esi, 0x7fff", "54ef9": "89 35 4c e1 47 00 mov [0x47e14c], esi", "54eff": "83 f9 02 cmp ecx, 0x2", "54f02": "74 0c jz 0x454f10", "54f04": "81 ce 00 80 00 00 or esi, 0x8000", "54f0a": "89 35 4c e1 47 00 mov [0x47e14c], esi", "54f10": "c1 e0 08 shl eax, 0x8", "54f13": "03 c2 add eax, edx", "54f15": "a3 50 e1 47 00 mov [0x47e150], eax", "54f1a": "33 f6 xor esi, esi", "54f1c": "56 push esi", "54f1d": "8b 3d d8 d2 45 00 mov edi, [0x45d2d8]", "54f23": "ff d7 call edi0x454f25", "54f25": "66 81 38 4d 5a cmp word [eax], 0x5a4d", "54f2a": "75 1f jnz 0x454f4b", "54f2c": "8b 48 3c mov ecx, [eax+0x3c]", "54f2f": "03 c8 add ecx, eax", "54f31": "81 39 50 45 00 00 cmp dword [ecx], 0x4550", "54f37": "75 12 jnz 0x454f4b", "54f39": "0f b7 41 18 movzx eax, word [ecx+0x18]", "54f3d": "3d 0b 01 00 00 cmp eax, 0x10b", "54f42": "74 1f jz 0x454f63", "54f44": "3d 0b 02 00 00 cmp eax, 0x20b", "54f49": "74 05 jz 0x454f50", "54f4b": "89 75 e4 mov [ebp-0x1c], esi", "54f4e": "eb 27 jmp 0x454f77", "54f50": "83 b9 84 00 00 00 0e cmp dword [ecx+0x84], 0xe", "54f57": "76 f2 jbe 0x45504b", "54f59": "33 c0 xor eax, eax", "54f5b": "39 b1 f8 00 00 00 cmp [ecx+0xf8], esi", "54f61": "eb 0e jmp 0x454f71", "54f63": "83 79 74 0e cmp dword [ecx+0x74], 0xe", "54f67": "76 e2 jbe 0x45504b", "54f69": "33 c0 xor eax, eax", "54f6b": "39 b1 e8 00 00 00 cmp [ecx+0xe8], esi", "54f71": "0f 95 c0 setnz al", "54f74": "89 45 e4 mov [ebp-0x1c], eax", "54f77": "56 push esi", "54f78": "e8 b4 28 00 00 call 0x457831", "54f7d": "59 pop ecx", "54f7e": "85 c0 test eax, eax", "54f80": "75 21 jnz 0x454fa3", "54f82": "83 3d 94 e1 47 00 01 cmp dword [0x47e194], 0x1", "54f89": "75 05 jnz 0x454f90", "54f8b": "e8 56 44 00 00 call 0x4593e6", "54f90": "6a 1c push 0x1c", "54f92": "e8 d8 42 00 00 call 0x45926f", "54f97": "68 ff 00 00 00 push 0xff", "54f9c": "e8 be fb ff ff call 0x454b5f", "54fa1": "59 pop ecx", "54fa2": "59 pop ecx", "54fa3": "e8 65 47 00 00 call 0x45970d", "54fa8": "89 75 fc mov [ebp-0x4], esi", "54fab": "e8 e9 25 00 00 call 0x457599", "54fb0": "85 c0 test eax, eax", "54fb2": "7d 08 jge 0x454fbc", "54fb4": "6a 1b push 0x1b", "54fb6": "e8 d0 fe ff ff call 0x454e8b", "54fbb": "59 pop ecx", "54fbc": "ff 15 a8 d1 45 00 call dword [0x45d1a8]", "54fc2": "a3 00 e9 47 00 mov [0x47e900], eax", "54fc7": "e8 af 4d 00 00 call 0x459d7b", "54fcc": "a3 8c e1 47 00 mov [0x47e18c], eax", "54fd1": "e8 03 4d 00 00 call 0x459cd9", "54fd6": "85 c0 test eax, eax", "54fd8": "7d 08 jge 0x454fe2", "54fda": "6a 08 push 0x8", "54fdc": "e8 aa fe ff ff call 0x454e8b", "54fe1": "59 pop ecx", "54fe2": "e8 bf 4a 00 00 call 0x459aa6", "54fe7": "85 c0 test eax, eax", "54fe9": "7d 08 jge 0x454ff3", "54feb": "6a 09 push 0x9", "54fed": "e8 99 fe ff ff call 0x454e8b", "54ff2": "59 pop ecx", "54ff3": "6a 01 push 0x1", "54ff5": "e8 95 fb ff ff call 0x454b8f", "54ffa": "59 pop ecx", "54ffb": "89 45 d8 mov [ebp-0x28], eax", "54ffe": "3b c6 cmp eax, esi", "55000": "74 07 jz 0x455009", "55002": "50 push eax", "55003": "e8 83 fe ff ff call 0x454e8b", "55008": "59 pop ecx", "55009": "89 75 bc mov [ebp-0x44], esi", "5500c": "8d 45 90 lea eax, [ebp-0x70]", "5500f": "50 push eax", "55010": "ff 15 ac d1 45 00 call dword [0x45d1ac]", "55016": "e8 2e 4a 00 00 call 0x459a49", "5501b": "89 45 e0 mov [ebp-0x20], eax", "5501e": "f6 45 bc 01 test byte [ebp-0x44], 0x1", "55022": "74 06 jz 0x45502a", "55024": "0f b7 45 c0 movzx eax, word [ebp-0x40]", "55028": "eb 03 jmp 0x45502d", "5502a": "6a 0a push 0xa", "5502c": "58 pop eax", "5502d": "50 push eax", "5502e": "ff 75 e0 push dword [ebp-0x20]", "55031": "56 push esi", "55032": "56 push esi", "55033": "ff d7 call edi0x455035", "55035": "50 push eax", "55036": "e8 93 3b ff ff call 0x448bce", "5503b": "8b f8 mov edi, eax", "5503d": "89 7d d4 mov [ebp-0x2c], edi", "55040": "39 75 e4 cmp [ebp-0x1c], esi", "55043": "75 06 jnz 0x45504b", "55045": "57 push edi", "55046": "e8 6f fc ff ff call 0x454cba", "5504b": "e8 8c fc ff ff call 0x454cdc", "55050": "eb 2b jmp 0x45507d", "55052": "8b 45 ec mov eax, [ebp-0x14]", "55055": "8b 08 mov ecx, [eax]", "55057": "8b 09 mov ecx, [ecx]", "55059": "89 4d dc mov [ebp-0x24], ecx", "5505c": "50 push eax", "5505d": "51 push ecx", "5505e": "e8 75 48 00 00 call 0x4598d8", "55063": "59 pop ecx", "55064": "59 pop ecx", "55065": "c3 ret" Os formatos de saída suportados por todos os programas do toolkit incluem JSON, XML, CSV e o padrão, texto. Assim o pev se faz útil para quem quer automatizar o processo de análise estática de binários PE, para salvar em um banco de dados para consulta posterior, por exemplo.
    A documentação para a versão 0.80 está pronta e recomendo fortemente que você a leia se quiser aproveitar o máximo do toolkit. O changelog completo também está disponível. Despeço-me com a certeza de que fizemos um bom trabalho e de que o software livre é viável, funciona e é, principalmente, algo prazeroso de se manter, que pode ajudar pessoas e empresas a atingirem seus objetivos, sem custo.
    Confere lá: https://github.com/merces/pev

    Fernando Mercês

    eXaminando dados

    Por Fernando Mercês, em Artigos,

    No dia-a-dia da programação, análise de binários e outras áreas relacionadas à segurança da informação é comum profissionais precisarem de conversões rápidas de dados, normalmente números e strings. Muitas vezes recorremos a sites, scripts, programas gráficos, calculadores e outros, mas como nos sentimos mais confortáveis na linha de comando, foi lá que decidi fazer algo.
    Há alguns anos iniciei um projeto que chamei de bashacks, que é um conjunto de funções em bash para as mais variadas tarefas, mas percebi que muitas vezes não sei que tipo de informação estou tratando e gostaria de ver rapidamente diversas conversões para um certo tipo de dado (um número por exemplo), para ver qual deles faz mais sentido. Foi aí que pensei em criar o eXamine, cujo nome veio do comando homônimo do gdb (GNU Debugger). Trata-se de um software de linha de comando para o que chamo de conversão indiscriminada e irresponsável de dados.
    Para ficar ainda mais enxuto, e também roubando a ideia do gdb, eu o chamo de x. Então supondo que você na sua análise você tenha encontrado um número hexadecimal, por exemplo, 0x585ca92c e deseja ver as conversões possíveis para ele. É só mandar pro x:
    $ echo 0x585ca92c | x Hex string: 30783538356361393263 Byte array: \x30\x78\x35\x38\x35\x63\x61\x39\x32\x63 URL encoding: %30%78%35%38%35%63%61%39%32%63 ROT13: 0k585pn92p Signed int: 1482467628 Unsigned int: 1482467628 Float: 9.70477e+14 Hexadecimal: 0x585ca92c Octal: 013027124454 Binary: 0b1011000010111001010100100101100 IPv4: 88.92.169.44 Timestamp: Fri, 23 Dec 2016 04:33:48 UTC/GMT-0 O jeito correto de interpretar a saída do eXamine é: se a entrada for tratada como x, então é y, ou seja, no exemplo, se o número for tratado como string (texto), então os bytes em hexadecimal equivalente são 30 78 35 38 35 63 61 39 32 e 63. Já se for tratado como número, então a conversão para inteiro fica 1482467628. Ainda tratando como número, pode ser o endereço IPv4 88.92.169.44 ou a data/hora de hoje. Qual é o certo? A resposta é: depende de como você quer tratar. Vê o que faz mais sentido pra sua análise e vai na fé.
    Sabemos que bytes são bytes e como serão usados depende da interpretação dada. 0x41 pode ser utilizado num programa como um inteiro de 8 bits, ou como parte de um inteiro de 16, 32 ou 64-bits, ou mesmo como o caractere ‘A’ (depende de como o programa usa essa informação). O eXamine não te ajuda nisso, mas imprime como saída algumas conversões possíveis e deixa você decidir.
    Por exemplo, você pode passar uma string para ele:
    $ echo 'feliz natal' | x Hex string: 66656c697a206e6174616c Byte array: \x66\x65\x6c\x69\x7a\x20\x6e\x61\x74\x61\x6c URL encoding: %66%65%6C%69%7A%20%6E%61%74%61%6C ROT13: sryvm angny Signed int: 0 Unsigned int: 0 Float: 0 Hexadecimal: 00 Octal: 0 Binary: 0b ASCII char: NUL RGB: (0, 0, 0) IPv4: 0.0.0.0 Timestamp: Thu, 01 Jan 1970 00:00:00 UTC/GMT-0 As saídas numéricas neste caso ficam zeradas e cabe a você saber que isso faz sentido, afinal, não passei um número como entrada.
    É possível também utilizá-lo no modo interativo. Neste caso, primeiro comandei x, depois digitei o número 65:
    $ x 65 Hex string: 3635 Byte array: \x36\x35 URL encoding: %36%35 ROT13: 65 Signed int: 65 Unsigned int: 65 Float: 0 Hexadecimal: 0x41 Octal: 0101 Binary: 0b1000001 ASCII char: A RGB: (0, 0, 65) IPv4: 0.0.0.65 Timestamp: Thu, 01 Jan 1970 00:01:05 UTC/GMT-0 Ainda há muito o que fazer no eXamine. Há várias conversões possíveis com strings, inteiros de outros tamanhos, hashes, etc. Se você tiver alguma sugestão de conversão, basta abrir uma issue na página do projeto no Github e a discutimos lá. Se souber programar em C, ficarei feliz em receber seu pull request após a discussão.

    Fernando Mercês
    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.

    Fernando Mercês
    No início de 2014, a Mandiant publicou que estava calculando o hash MD5 das funções importadas por binários PE para buscar variantes de malware [1]. Eles também fizeram um patch na biblioteca pefile [2] para suportar o novo cálculo. A ideia colou e até o Virus Total passou a utilizar [3]. Eu mesmo utilizei um tempo sem entender direito até que um dia decidi estudá-lo para implementar no pev [4] (que ainda não fiz) e hoje decidi escrever sobre.
    Todo binário PE que se preze usa funções de bibliotecas. Assim sendo, desde os primórdios da especificação PE, há o que é conhecido por IT – Import Table, que é uma tabela contendo uma lista de cada módulo (DLL) que o binário utiliza (importa) com suas respectivas funções. Por exemplo, vamos analisar o programa no estilo “Hello, world” abaixo:
    #include <stdio.h> int main(void) { puts("Quem avisa chato eh!"); return 0; } Ao compilar usando o Dev-Cpp [5] no Windows 7, podemos checar quais funções são importadas por ele:
    C:\> readpe --imports hello.exe Imported functions Library Name: KERNEL32.dll Functions Function Name: DeleteCriticalSection Function Name: EnterCriticalSection Function Name: GetCurrentProcess Function Name: GetCurrentProcessId Function Name: GetCurrentThreadId Function Name: GetLastError Function Name: GetStartupInfoA Function Name: GetSystemTimeAsFileTime Function Name: GetTickCount Function Name: InitializeCriticalSection Function Name: LeaveCriticalSection Function Name: QueryPerformanceCounter Function Name: RtlAddFunctionTable Function Name: RtlCaptureContext Function Name: RtlLookupFunctionEntry Function Name: RtlVirtualUnwind Function Name: SetUnhandledExceptionFilter Function Name: Sleep Function Name: TerminateProcess Function Name: TlsGetValue Function Name: UnhandledExceptionFilter Function Name: VirtualProtect Function Name: VirtualQuery Library Name: msvcrt.dll Functions Function Name: __C_specific_handler Function Name: __dllonexit Function Name: __getmainargs Function Name: __initenv Function Name: __iob_func Function Name: __lconv_init Function Name: __set_app_type Function Name: __setusermatherr Function Name: _acmdln Function Name: _amsg_exit Function Name: _cexit Function Name: _fmode Function Name: _initterm Function Name: _lock Function Name: _onexit Function Name: _unlock Function Name: abort Function Name: calloc Function Name: exit Function Name: fprintf Function Name: free Function Name: fwrite Function Name: malloc Function Name: memcpy Function Name: puts Function Name: signal Function Name: strlen Function Name: strncmp Function Name: vfprintf Pois é, apesar de eu ter chamado apenas a função puts(), o binário precisa de muito mais para funcionar.
    Agora um segundo exemplo, com um recurso a mais, mas sem chamar nenhuma outra função da mesma biblioteca:
    #include <stdio.h> char *superfuncaonova(int n) { if (n >= 666) return "arre, porra!"; else return "eu quero eh rock, diabo!"; } int main(void) { puts("Quem avisa chato eh!"); puts(superfuncaonova(1)); return 0; } Após compilar e listar os imports deste hello2.exe, você vai confirmar que é exatamente a mesma lista do primeiro hello.exe. Isto porque, apesar de ter uma função interna nova, não utiliza outra função de biblioteca nova, o que não altera a IAT. Isso é comum em variantes de uma mesma família de malware já que as funcionalidades estão prontas e o que difere de uma variante para outra normalmente são informações como servidor de comando e controle, algumas strings, etc. Sendo assim, é inteligente utilizar essa lista para buscar famílias. Parabéns para quem pensou nisso.
    E como o imphash foi implementado?
    Comparar cada item da lista não seria prático então alguém teve a ideia de tirar o hash MD5 da lista, obedecendo o seguinte padrão:
    Varrendo a import table (IT), na ordem em que aparecem os imports:
    Prefixar cada função com o nome do módulo sem extensão (mas mantendo o ponto) da qual ela é importada. Por exemplo, se o binário importa DeleteCriticalSection() da KERNEL32.DLL, esse import reescrito ficaria KERNEL32.EnterCriticalSection. Caso não haja nome da função, tentar resolver e, caso não consiga, utilizar seu número ordinal. Converter tudo para minúsculo. Criar uma string com os imports no padrão acima, separados por vírgula. Calcular o hash MD5 da string acima. Eu salvei a saída do readpe para um arquivo de texto e, usando expressões regulares, o editei até que ficasse no padrão definido acima:
    $ cat hello.imports kernel32.deletecriticalsection,kernel32.entercriticalsection,kernel32.getcurrentprocess,kernel32.getcurrentprocessid,kernel32.getcurrentthreadid,kernel32.getlasterror,kernel32.getstartupinfoa,kernel32.getsystemtimeasfiletime,kernel32.gettickcount,kernel32.initializecriticalsection,kernel32.leavecriticalsection,kernel32.queryperformancecounter,kernel32.rtladdfunctiontable,kernel32.rtlcapturecontext,kernel32.rtllookupfunctionentry,kernel32.rtlvirtualunwind,kernel32.setunhandledexceptionfilter,kernel32.sleep,kernel32.terminateprocess,kernel32.tlsgetvalue,kernel32.unhandledexceptionfilter,kernel32.virtualprotect,kernel32.virtualquery,msvcrt.__c_specific_handler,msvcrt.__dllonexit,msvcrt.__getmainargs,msvcrt.__initenv,msvcrt.__iob_func,msvcrt.__lconv_init,msvcrt.__set_app_type,msvcrt.__setusermatherr,msvcrt._acmdln,msvcrt._amsg_exit,msvcrt._cexit,msvcrt._fmode,msvcrt._initterm,msvcrt._lock,msvcrt._onexit,msvcrt._unlock,msvcrt.abort,msvcrt.calloc,msvcrt.exit,msvcrt.fprintf,msvcrt.free,msvcrt.fwrite,msvcrt.malloc,msvcrt.memcpy,msvcrt.puts, msvcrt.signal,msvcrt.strlen,msvcrt.strncmp,msvcrt.vfprintf NOTA: O arquivo tem somente uma linha, sendo que não há um caractere de nova linha (\n ) no final dela, veja:
    $ hdump hello.imports | tail 000003c0 74 2e 65 78 69 74 2c 6d 73 76 63 72 74 2e 66 70 |t.exit,msvcrt.fp| 000003d0 72 69 6e 74 66 2c 6d 73 76 63 72 74 2e 66 72 65 |rintf,msvcrt.fre| 000003e0 65 2c 6d 73 76 63 72 74 2e 66 77 72 69 74 65 2c |e,msvcrt.fwrite,| 000003f0 6d 73 76 63 72 74 2e 6d 61 6c 6c 6f 63 2c 6d 73 |msvcrt.malloc,ms| 00000400 76 63 72 74 2e 6d 65 6d 63 70 79 2c 6d 73 76 63 |vcrt.memcpy,msvc| 00000410 72 74 2e 70 75 74 73 2c 6d 73 76 63 72 74 2e 73 |rt.puts,msvcrt.s| 00000420 69 67 6e 61 6c 2c 6d 73 76 63 72 74 2e 73 74 72 |ignal,msvcrt.str| 00000430 6c 65 6e 2c 6d 73 76 63 72 74 2e 73 74 72 6e 63 |len,msvcrt.strnc| 00000440 6d 70 2c 6d 73 76 63 72 74 2e 76 66 70 72 69 6e |mp,msvcrt.vfprin| 00000450 74 66 |tf| O imphash deste arquivo então deve ser o hash MD5 do conteúdo de hello.imports. Vamos ver?
    $ python imphash.py hello.exe # usando a pefile 3856e6eb1020e4f12c9b8f75c966a09c $ md5 hello.imports MD5 (hello.imports) = 3856e6eb1020e4f12c9b8f75c966a09c Legal! Agora que sabemos como calcular o imphash de binários PE, podemos implementar em qualquer software, certo? Mais ou menos. Você percebeu que ignoramos o passo 2? Pois é, no próximo artigo sobre o assunto vou explicar o motivo pelo qual o imphash está quebrado. Até lá. o/
     
    Referências
    [1] https://www.fireeye.com/blog/threat-research/2014/01/tracking-malware-import-hashing.html
    [2] https://github.com/erocarrera/pefile
    [3] http://blog.virustotal.com/2014/02/virustotal-imphash.html
    [4] https://github.com/merces/pev
    [5] https://sourceforge.net/projects/orwelldevcpp/

    Fernando Mercês
    Recebo com alguma frequência e-mails de pessoas perguntando algo sobre carreira em segurança da informação. Naturalmente não tenho todas as respostas, até porque sou novo na área, mas tento ajudar tanto quanto possível. Sendo assim, vou colocar aqui o que normalmente respondo, assim pode ser criticado e melhorado por outros pesquisadores, de modo que nos ajudemos mais e a partir de diferentes pontos de vista.
    Eu baseio uma carreira profissional em 4C, de prática diária:
    Comportamento
    Ética e disponibilidade para ajudar. Sempre.
    Crítica
    Infelizmente (ou felizmente, porque assim você as conhece), pessoas mentem pra você o tempo todo. Nas empresas, mais ainda. Leitura obrigatória aqui são os artigos da série “Profissão: escovador de bit” do Rodrigo Strauss.
    Conhecimento
    Sem o real conhecimento da sua área de atuação, todo o resto vai por água abaixo. De posse dele, você se torna necessário.
    Coexistência
    Ou “engolimento de sapo”. Nem sempre faremos o que achamos que gostaríamos de fazer, nem lidaremos com pessoas legais o tempo todo. São só testes, relaxe. Em tudo tem algo a ser aprendido, mesmo que você ache a tarefa chata ou ruim. É importante que você faça e, se caiu pra você, tem que ser você. Agradeça por isso e só faça.
    Se o objetivo é atuar na área técnica segurança da informação, eu penso que há 5 domínios de conhecimento, ou “blocos”, que precisam ser preenchidos ao máximo, que formam a base da atuação técnica em SI: Hardware, SO, Redes, Software Livre e Programação.
    O quanto você vai avançar em cada item (você pode nivelar em básico, intermediário e avançado) vai depender de qual sub-área de SI você deseja. Eu enxergo as macro: Teste de intrusão, hardening, computação forense, análise de malware e pesquisa de vulnerabilidades. Esqueci algo?
    O estudo nessas áreas é constante e sempre com foco na (in)segurança e geração de certezas mediante provas de conceito, testes e mais testes. Por exemplo, se ao estudar hardware alguém disser pra você que desconectar um teclado PS/2 da placa-mãe com o PC ligado “queima a saída da placa”, teste, mesmo que isso custe sua placa. Você vai aprender o certo e isso não tem preço.
    Voltando aos blocos, vou colocar umas dicas do que fazer neste caminho, baseadas na minha experiência e na de amigos. Definitivamente não é o “caminho para o sucesso”, mas só mais uma sugestão de jornada que pode – e deve – ser adaptada, alterada ou até mesmo completamente ignorada, de acordo com suas opiniões, necessidades e condições. Ou você pode seguir à risca e ver no que dá. Sua conta em risco.
    Hardware
    Acho que desmontar e montar um PC por completo é obrigação de qualquer profissional de TI. Soa um pouco ilógico um programador web, por exemplo, que “chama um técnico” para trocar o HD ou reinstalar o sistema operacional. Adicionalmente estudar eletrônica é muito interessante e é essencial para o que é conhecido por hardware hacking. As dicas são:
    Ser usuário ativo (perguntar e responder) no Fórum do Clube do Hardware. É uma comunidade gigante de técnicos de hardware e até encontros regionais (muito bons por sinal) são promovidos pelos membros. Recomendo muito. Estudar o terceiro volume (Física 3) da série Ramalho, Nicolau e Toledo. Prepare-se para gastar pois este livro é caro. Ah, estudar é diferente de ler. Os primeiros capítulos do livro Sistemas Digitais (Tocci/Widmer). Quando você chegar num capítulo que foge muito da computação, você saberá que pode parar de estudá-lo. O livro CompTIA A+ Complete Study Guide Authorized Coursewar (Quentin Docter, Emmett Dulaney, Toby Skandier) foi o que mais me deu base sobre hardware, mas ele é antigo. Recomendo buscar literatura autorizada pela CompTIA para a certificação A+, além de fazer esta prova e passar! Essa certificação não é lá muito valorizada no Brasil mas o estudo para ela dá uma base incrível sobre computadores. Eu achava que entendia alguma coisa de hardware até ler este livro. Sistemas operacionais
    No estudo de hardware você já deve lidar com os SOs no sentido de instalá-los e configurá-los por demais, no entanto, este item diz respeito a entendê-los.
    Aqui o estudo dos livros dos Tanembaum não podem faltar. Buscar o Minix (SO desenvolvido por ele) e seguir junto com seus livros pode ser um exercício e tanto. A wiki OSDev tem tudo o que é preciso para entender (e até criar) um SO deste o bootloader. O Linux From Scratch também é um excelente recurso e te ensina, dentre outras coisas, a criar sua própria distribuição Linux. Não é que você precise manter uma distribuição Linux, mas criar uma sem dúvida vai te dar uma base de Linux sem igual. A coleção do Windows Internals é o que há de mais profundo, oficialmente, de material para o SO Windows. Redes
    Sem TCP/IP você está perdido. Não conheço literatura específica além do excelente TCP/IP Illustrated (W. Richard Stevens), mas deve haver umas legais em português. O importante é estudar e por em prática os conceitos! Recomendo tirar uma certificação mínima na área como a Network+ ou CCNA, da Cisco e procurar empregos onde você possa trabalhar junto a administradores de rede, ou até se tornar um. Montar um laboratório em casa com alguns PCs também é essencial. Ao conectar este bloco com programação, também é legal programar para redes e, num futuro próximo, conectando também com servidores web e programação, chegar na web entendendo o HTTP com base de quem entende a pilha TCP/IP, os handshakes, os sockets, etc. Outro nível.
    Software livre
    Socialmente justo. Esta “modalidade” de desenvolvimento de software tem seus pilares nas comunidades. Estas, por sua vez, obrigam você a estudar e aprender, sempre ajudando. Você aprende muito mais numa comunidade de software livre, acredite. Aprende sobre todos os outros blocos que citei aqui. Muito. Muito mesmo.
    Fazer parte de um grupo de usuários de Linux da sua região e participar ativamente das suas atividades é obrigatório. Frequentar os eventos de software livre, tanto os regionais quanto os maiores, como o Latinoware constrói uma rede de networking profissional e aprendizado fantástica. Considere submeter propostas de palestras se você tem algo inédito a dizer. E eu acho que você tem. Ficar informado: BR-Linux e VivaOLinux. 4Linux. Essa empresa tem sempre uma equipe excelente de Linux. Fazer um curso lá, além de te dar conhecimento, pode te levar a monitor do curso, o que te ajuda a aprender ainda mais e até mesmo a ser contratado por eles. Livros: Descobrindo o Linux (Eriberto Mota), Servidores Linux (Morimoto), Programação em shell (Julio Neves). Seja qual for o sabor de Linux que você gostar, é essencial procurar se inteirar na comunidade oficial dele. Tem que ter uma conta no GitHub e mostrar o que você sabe fazer em software livre. Pode ser o script mais feio do mundo, mostra sem vergonha! A carreira de certificações LPI é obrigatória. Da LPIC-1 até a última. Programação
    Um dos, senão o mais importante bloco dessa base. Quem não sabe programar por certo não sabe como um computador funciona.
    Pra lógica de programação tem uma coisa chamada “portugol”. Funciona com algumas pessoas. Boa sorte! Estudar Assembly, por mais inútil que possa parecer, mesmo que o básico. Fazer uma calculadora em Assembly é necessário. Recomendo o nasm. Naturalmente, depois de Assembly, C. O livro C Completo e Total (Herbert Schildt) é excelente se você ignorar o último capítulo. Reimplementar programas existentes como ping, dir/ls etc é muito bom. Programar na web é essencial (PHP, Python, Ruby…). Entender o protocolo HTTP também. Mais livros: C++/Java (Deitel), Programação Avançada em Linux (Gleicon da Silveira Moraes) . Programar pra Linux é ótimo! Fazer seu código funcionar em OS X e também Windows (mesmo que via Cygwin) é muito legal/trabalhoso também! Noção de programação orientação a objeto é uma boa. O grupo C/C++ Brasil do Google é fantástico, mas se você pedir a resposta de um trabalho/exercício da escola/universidade lá, irá para o inferno sem escalas. Programar um Arduino é muito louco! Algumas dicas gerais, mas não menos importantes:
    Você só é útil se ajudar os outros. É só por isso que está aqui. Repasse todo o conhecimento que adquiriu, sem exceção. Do contrário ele morre. Você é ajudado. Escolha amigos para ajudar. Faça algum trabalho social envolvendo tecnologia em ONGs e afins. Prefira usar software livre sempre, mesmo no Windows e OS X. Quando gostar de um software livre, compartilhe isso nas suas redes sociais e mande um e-mail ao desenvolvedor (ou grupo de desenvolvedores) agradecendo e explicando porque o software te ajudou. Tenha ativo pelo menos 1 software livre seu. Não importa se é inovador ou não. Frequente eventos, conferências, palestras, workshops… Tire no mínimo uma certificação por ano. Faça coisas na empresa que só você sabe fazer, mas que ajude todo mundo. Faça um “hello, world” e uma função soma() em todas as linguagens que você sentir vontade de saber o básico sobre como ela funciona. Saiba fazer um site HTML/CSS/JavaScript, mesmo que feio. Não tenha medo de mandar currículo para empresas como Google, Microsoft, Oracle, Red Hat etc. Tem um monte de gente que não sabe o que você sabe e está ĺá. Tenha um site/blog onde você posta suas experiências, estudos e avanços. Após ler algo, faça o teste e aí sim, acredite. Se quer uma certificação, agenda a prova (e paga) pra daqui há alguns meses e aí sim começa a estudar. Não trapaceie em certificações (TestKing, Pass4Sure etc). O único idiota nesse ato é você. Agradeça publicamente! Admita erros publicamente! Se você não viver este vídeo, então seu objetivo é dinheiro. Está errado. Se você ainda pensa que é melhor que alguém, por favor assista este outro. Não fique obeso fazendo tudo isso.

    Fernando Mercês
    Este foi um problema que tive há bastante tempo, quando precisei fazer com que o módulo de kernel do antivírus Trend Micro ServerProtect funcionasse em versões de 64-bit do Linux. Acontece que este módulo utiliza o LSM (Linux Security Module) framework. Até aí tudo bem, foi como o jeito que programadores do módulo usaram para hookar a execve() nesta arquitetura, essencial para um antivírus por motivos óbvios: toda vez que um arquivo fosse executado no sistema, este seria escaneado por vírus.
    Apesar de um pouco defasado, decidi escrever agora pois me animei quando fui ao 11º Encontro da comunidade C/C++ Brasil [3]. De fato, atualmente um LSM não pode mais ser carregado num kernel rodando, como um LKM (Loadable Kernel Module) e isso tira toda a praticidade deste patch em específico, mas a técnica utilizada pode ser útil em outras ocasiões. Ou não.
    Indo direto ao ponto, a estrutura default_security_ops não era mais acessível diretamente na versão do kernel que trabalhei e por isso o seguinte trecho de código não funcionava num contexto LSM:
    unsigned long addr = kallsyms_lookup_name("default_security_ops"); Minha intenção não era reescrever todo o módulo, então tive que dar um jeito rápido. A ideia foi buscar uma função exportada que manipulasse a estrutura default_security_ops, assim eu teria acesso ao endereço dela. Várias funções o fazem, mas buscando pela mais simples/menor encontrei a reset_security_ops(), presente em security/linux.c:
    void reset_security_ops(void) { security_ops = &default_security_ops; } Essa função só faz uma coisa: coloca o endereço da estrutura que quero em outra. Sendo assim, é uma perfeita candidata para minha gambiarra.
    Pelo tamanho daria para tentar advinhar quão distante está o endereço da estrutura default_security_ops do endereço da função reset_security_ops(), mas vamos disassemblar só pra garantir:
    1. Extraindo a imagem do kernel
    O kernel fica comprimido em /boot e no próprio fonte existe um script para descomprimi-lo chamado extract-vmlinux. Usei da seguinte maneira:
    $ sudo cp /boot/vmlinuz-$(uname -r)-generic vmlinuz # trabalhar com um backup, só pra garantir ;) $ sudo chown $(whoami): vmlinuz $ /usr/src/linux-headers-$(uname -r)/scripts/extract-vmlinux vmlinuz > vmlinux O arquivo vmlinux (com “x” ao invés de “z”) criado é a imagem descomprimida do kernel, que precisamos disassemblar.
    2. Disassemblando a imagem
    Por padrão a imagem do kernel não contém símbolos, então minha tentativa com o gdb foi frustrada:
    $ gdb -q ./vmlinux Reading symbols from ./vmlinux...(no debugging symbols found)...done. (gdb) disassemble reset_security_ops No symbol table is loaded. Use the "file" command. Mas nem tudo está perdido. No kernel rodando, dá pra ver o endereço das funções no arquivo System.map:
    # grep reset_security_ops /boot/System.map-$(uname -r) ffffffff812d6be0 T reset_security_ops Sabendo o endereço, voltei ao gdb e pedi pra printar 8 intruções começando neste endereço, mas não antes de setar a sintaxe para Intel.
    (gdb) set disassembly-flavor intel (gdb) x/8i 0xffffffff812d6be0 0xffffffff812d6be0: call 0xffffffff81731480 0xffffffff812d6be5: push rbp 0xffffffff812d6be6: mov QWORD PTR [rip+0xcdd14f],0xffffffff81c80100 # 0xffffffff81fb3d40 0xffffffff812d6bf1: mov rbp,rsp 0xffffffff812d6bf4: pop rbp 0xffffffff812d6bf5: ret 0xffffffff812d6bf6: nop WORD PTR cs:[rax+rax*1+0x0] 0xffffffff812d6c00: call 0xffffffff81731480 (gdb) Essa call no início apontar para um ret e honestamente eu não sei por que ela existe:
      (gdb) x/i 0xffffffff81731480 0xffffffff81731480: ret    3. Contando os bytes
    Lembrando que esta função simplesmente implementa a atribuição do endereço que queremos (default_security_ops) para uma variável, fica fácil perceber que a varíavel (security_ops) é RIP+0xcdd14f e o endereço da estrutura que queremos é 0xffffffff81c80100. Mas claro, a ideia aqui é fazer de forma genérica, então não posso trabalhar com esse endereço fixo. Bem, admitindo que essa função não mude, é razoável dizer que o endereço é um número de 64-bits que tem seu primeiro byte em uma posição fixa a partir do endereço da função reset_security_ops(). Isto está longe de ser uma solução profissional, mas resolveu meu problema na época. Ao invés do x/i (examine as instruction), vou usar o disassemble pra poder contar melhor os bytes:
    (gdb) disassemble /r 0xffffffff812d6be0, 0xffffffff812d6bff Dump of assembler code from 0xffffffff812d6be0 to 0xffffffff812d6bf4: 0xffffffff812d6be0: e8 9b a8 45 00 call 0xffffffff81731480 0xffffffff812d6be5: 55 push rbp 0xffffffff812d6be6: 48 c7 05 4f d1 cd 00 00 01 c8 81 mov QWORD PTR [rip+0xcdd14f],0xffffffff81c80100 0xffffffff812d6bf1: 48 89 e5 mov rbp,rsp 0xffffffff812d6bf5: c3 ret End of assembler dump. Para disassemblar sem símbolo você precisa dizer ao gdb até onde ir, por isso fui até 0xffffffff812d6bff, mas cortei o que veio depois do ret no dump. Se contarmos, vamos perceber que o número começa em (endereço da função) + 13 e tem 4 bytes. Só pra confirmar:
    (gdb) x/x 0xffffffff812d6be0 + 13 0xffffffff812d6bed: 0x81c80100 Agora vamos seguir (#medo)!
    4. Implementação
    Ficou deste jeito:
    unsigned long default_security_ops = 0xffffffff00000000; unsigned long _reset_security_ops = 0; _reset_security_ops = kallsyms_lookup_name("reset_security_ops"); memcpy(&default_security_ops, (void *) (_reset_security_ops + 13), 4); A variável default_security_ops já é inicializada com sua parte alta toda setada, pois só a parte baixa do endereço está no assembly. A kallsyms_lookup_name() me dá o endereço da função reset_security_ops(). A memcpy() então copia os 4 bytes que compõem o segundo operando da instrução mov, que é o nosso endereço. O resultado abaixo foi obtido com este código implementado em um módulo:
    # grep default_security_ops /boot/System.map-3.13.0-44-generic ffffffff81c80100 d default_security_ops # rmmod teste; make >/dev/null && insmod teste.ko && dmesg | tail -1 [15999.471619] default_security_ops address: 0xffffffff81c80100 Os endereços batem, no entanto, essa coisa não foi para produção (graças ao Divino) e não recomendo que utilizem nada parecido em nenhum sistema crítico, mas será que dá pra aplicar essa técnica de “contagem de bytes” para outras coisas?

    Fernando Mercês
    No últmo artigo falei sobre como montar uma máquina virtual básica para ER em Windows. Agora chegou a vez do Linux, já que o mundo não é feito só de PE. A ideia aqui é montar um ambiente legal para reverter binários ELF. Dá uma olhada neste vídeo (em tela cheia de preferência) pra ter uma ideia do poder dessas ferramentas.
    Legal né? Então mãos à obra!
    Máquina virtual
    512 MB de memória Placa de rede em modo NAT Placa de rede em modo host-only Sistema operacional
    Utilizo a ISO netinstall do Debian 7 64-bits mas como sempre você é livre para utilizar a distribuição que quiser, só que este artigo é escrito com base nesta.
    Algumas dicas de instalação:
    Não utilizar seu nome verdadeiro na criação da conta de usuário. Não instalar as extensões do software virtualizador como VMware Tools ou VirtualBox Guest Additions. Não configurar nenhuma regra de firewall ou qualquer software de proteção. /etc/apt/sources.list
    Eu deixo do seguinte jeito:
    deb http://ftp.br.debian.org/debian/ jessie main contrib non-free deb http://security.debian.org/ jessie/updates main deb http://ftp.br.debian.org/debian/ jessie-updates main deb http://ftp.br.debian.org/debian/ jessie-backports main O importante aqui é ter o “contrib non-free” após o main, infelizmente, pois alguns programas como o rar não são livres.
    Depois de configurado este arquivo, é bom atualizar os pacotes existentes:
    # apt-get update # apt-get upgrade -y Pacotes básicos
    # apt-get install zip unzip rar unrar p7zip file sudo git vim rcconf openssh-server Git para clonar repositórios de outros software que precisamos, servidor ssh para acessar a máquina de forma fácil, descompactadores etc.
    Software específico
    wxHexEditor: Este é o melhor editor hexa que tem em minha opinião. Edita dispositivos e até processos em memória. Para compilá-lo, primeiro você vai ter que instalar suas dependências: # apt-get install autoconf libtool libwxgtk2.8-dev gettext Depois é só baixar o tarball, descomprimir, entrar no diretório e comandar os famosos:
    $ ./configure $ make # make install Bokken: IDE muito boa para o pyew e radare2 (especialmente este útlimo). Com o Bokken é possível gerar inclusive um diagrama de fluxo das funções utilizadas pelo ELF. Na prática, ele server como disassembler, não como debugger. Ele é escrito em Python. Vamos à instalação das dependências então: # apt-get install python-radare2 pyew python-gtk2 python-gtksourceview2 graphviz python-rsvg python-utidylib Depois baixe o tarball (não use o pacote .deb disponível, ele está desatualizado com relação às dependências), descompacte e mova o diretório bokken-1.6 para um de sua prefência (/opt em nosso caso). Aí basta editar a varíavel BOKKEN_DIR no script /opt/bokken-1.6/bokken para refletir o novo diretório do programa (BOKKEN_DIR=/opt/bokken-1.6) e criar um link simbólico para este script em /usr/local/bin, para que este possa ser chamado a partir de qualquer diretório:
    # ln -s /opt/bokken-1.6/bokken /usr/local/bin/bokken Evan’s Debugger: Este projeto é simplesmente fenomenal. A ideia do Evan foi criar um debugger livre com base no OllyDbg. Eu apresentei este projeto na conferência H2HC de 2010 (fiz algumas contribuições) e e de lá pra cá o edb, como é chamado seu binário principal, só melhora. Dependências: # apt-get install libqt4-dev libboost-dev xterm yasm Após baixar a última versão do debugger e descomprimir, para compilar e instalar:
    $ qmake $ make # make install Agora em ~/.config/codef00.com/edb.conf você precisa configurar os diretórios utilizados pelo edb:
    [Directories] directory.symbol.path=/home/<usuario>/.config/codef00.com/symbols directory.plugin.path=/lib64/edb directory.session.path=/tmp E criar o diretório de symbols:
    $ mkdir -p ~/.config/codef00.com/symbols bashacks: Valeria a pena só pelas funções asciitable e utf8table. Brincadeiras à parte, tem várias funções úteis para ER, como a hexcalc: $ hexcalc 4f + 2e 0x7d Para instalar, é clonar o repositório com o git, mover para um diretório /opt por exemplo e adicionar no ~/.bashrc:
    $ git clone https://github.com/merces/bashacks.git # mv bashacks /opt $ echo 'source /opt/bashacks/bashacks.sh' >> ~/.bashrc Pronto. Ao relogar todas as funções estarão disponíveis. Se quiser saber um pouco mais sobre basta assistir ao nosso vídeo sobre esta ferramenta.
     
    Utilizo ainda os seguintes pacotes (apt-get install neles):
    ht: instala o programa hte, um poderoso editor e disassembler de binários que utiliza a ncurses. Já me salvou onde não tinha X. strace: rastreia chamadas de sistema feitas por binários ltrace: rastreia chamadas de bibliotecas feitas por binários tcpdump: captura de tráfego de rede foremost: ajuda nos casos em que há binários dentro de binários unhide: mostra processos e conexões ocultas   E há ainda os nativos do Linux que também são úteis:
    readelf: mostra informações sobre binários ELF como symbols, cabeçalhos, seções etc objdump: tipo o anterior, mas suporta outros formatos. Disassembla também. Um comando legal com ele é: $ objdump -M intel -d <arquivo> Observações Após instalar todos os softwares, é de extrema utilidade criar um snapshot da máquina virtual, pra você voltar facilmente a este estado limpo após analisar um arquivo suspeito, por exemplo. Não precisa instalar um ambiente gráfico. Pode conectar na máquina com ssh -X e rodar os programas gráficos. Existe uma distribuição Linux chamada REMnux com foco em engenharia reversa. Eu sugeri ao autor que incluisse as ferramentas que menciono aqui.

    Fernando Mercês
    Resolvi montar este tutorial depois do grande trabalho que tive pra atualizar a máquina virtual que utilizo para analisar malware. Perdi horas procurando e instalando programas. Minha vontade era de distribuir um OVA com a máquina já pronta e talvez faça isso no futuro mas por hora vou discutir aqui os programas que utilizo para uma análise básica de malware ou engenharia reversa de algum software.
    Máquina virtual
    512 MB de memória Placa de rede em modo NAT Sistema operacional
    Utilizo o Windows 7 64-bits em Português do Brasil, para facilitar na análise de malware brasileiro que teste o idioma do SO. Claro que em alguns casos vale a pena você ter máquinas virtuais de outras versões do Windows e em diferentes idiomas para ver se o comportamento do seu alvo muda. “Alvo” aqui significa o arquivo que você vai analisar, seja porque ele é suspeito seja porque você quer conhecer seu funcionamento.
    Algums dicas durante de instalação:
    Não utilizar seu nome verdadeiro na criação da conta de usuário do Windows durante a instalação. Não há necessidade. Não instalar as extensões do software virtualizador como VMware Tools ou VirtualBox Guest Additions. Não instalar nenhum antivírus, firewall ou qualquer software de proteção. Desabilitar todos os itens na “Central de Segurança” do Windows, incluindo as atualizações automáticas. Arquivos diversos
    Costumo espalhar uns arquivos .doc, .xls etc pela máquina, a fim de parecer que é uma máquina real. Algumas ameaças (principalmente ransomware) tentam encriptar ou mesmo destruir arquivos das vítimas.
    Software geral
    7-Zip: Descomprime qualquer formato! E é livre. Firefox: Browser livre. Flash: Caso precise analisar SWF ou visualizar algum site que exija, mas cuidado pra não baixar tralha da McAfee junto. Java: Somente a JRE (Java Runtime Environment), para analisar classes Java. .NET Framework: Para permitir que ferramentas e alvos escritos nesta linguagem rodem. Notepad++: o único editor de arquivos que você precisa no Windows! Software específico
    API Monitor: Pode monitorar qualquer chamada a uma função específica da API do Windows ou de uma DLL específica. Muito bom. CFF Explorer: Analisador de PE. DeDe: Descompilador para Delphi. Extremamente útil para os malwares brasileiros! DIE (Detect It Easy): Detector de packer novo e promissor com suporte a regras personalizadas. Dis#: Descompilador para .NET. E2A (Event to Address): Somente para alvos escritos em Borland C++, dá os endereços dos eventos, como o clique de um botão por exemplo. Impressionante. FileGrab: Monitora o filesystem e copia para um diretório qualquer arquivo criado nele. Útil pra monitorar comportamento de malware que se deleta. Hex Workshop: Editor hexa animal, mas pago (não se preocupe, há um livre no final da lista). IDA Free: Disassembler e debugger. Tem uma função graph muito útil, além de suporte a vários tipos de binários e muitos recursos. ImpRec (Import Reconstructor): Útil para unpacking manual, para reconstruir a IAT (Import Address Table) de binários. JD-GUI: Descompilador Java (gera código Java a partir dos .class). .NET Reflector: Outro descompilador pra .NET. Assim como o Dis#, gera MSIL (Microsoft Intermeddiate Language) como saída, não Assembly. OllyDbg: Debugger e disassembler. O principal programa para análise. PeStudio: Analisador de arquivos PE. pev: Toolkit para análise de binários. ProcessExplorer: Monitora o que os processos estão fazendo no sitema (chaves de registro que estão abrindo, outros arquivos etc). RawCap: Sniffer de pacotes que usa raw sockets. É muito rápido e simples de usar. Gera o PCAP pra ser analisado no Wireshark futuramente, o que pode ser feito fora da máquina virtual. RDG Packer Detector: Melhor detector de packer que conheço. RegShot: Usado para tirar uma “foto” do sistema antes e outra depois da execução de um aplicativo, a fim de compará-las para investigar o que foi alterado. ResHack (Resource Hacker): Editor de recursos (ícones, telas e afins dentro do binário). wxHexEditor: Editor hexadecimal livre, cheio de recursos. Tem a capacidade de editar discos inclusive. Software opcional, caso precise programar
    Orwell Dev-C++: Versão em constante atualização do Dev-C++, para quem precisar codar em C/C++ para ver o comportamento de uma função da API do Windows por exemplo. Visual Studio Express: Para desenvolver em .NET, a Microsoft oferece uma versão gratuita (Express) do Visual Studio. IMPORTANTE: Após instalar todos os softwares, é de extrema utilidade criar um snapshot da máquina virtual, pra você voltar facilmente a este estado limpo após analisar um arquivo suspeito, por exemplo.
    Se você é iniciante, recomendo baixar e testar um programa de cada vez, até entender o motivo pelo qual ele pode ser útil. Alguns programas da lista acima são redundantes entre si pois possuem o mesmo objetivo, mas às vez um é mais preciso que outro dependendo do alvo, por isso é interessante mantê-los.
    Recomendo colocar as ferramentas que não possuem programa de instalação, como o E2A, num diretório tipo C:tools e criar atalhos para os executáveis principais na área de trabalho.
    O artigo é curto mas o trabalho que o leitor terá é grande.

    Fernando Mercês

    As gafes do mundo da TI

    Por Fernando Mercês, em Artigos,

    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.

    Fernando Mercês
    Configurar um servidor de mídia pode ser uma boa maneira de aproveitar um PC de baixo desempenho (mas de razoável capacidade de armazenamento). Além de centralizar suas músicas, fotos e vídeos, torná-los acessíveis a dispositivos como smart TVs, smartphones, tablets, video games e outros que possam atuar como clientes de streaming é realmente interessante.
    Tudo que precisamos para configurar este servidor é de uma LAN ou WLAN e o Debian GNU/Linux. Sem complicação, sem custo.
    Configurar o Debian com IP fixo
    No media server, configuramos um Debian Wheezy com IP fixo. A máquina que eu utilizei acessa a WLAN através de um adaptador wireless USB, então eu coloquei uma reserva de IP (através do MAC address) no próprio roteador wireless, fazendo com que o mesmo IP seja entregue ao servidor, mas você configurar de acordo com a topologia da sua rede. A configuração de IP no Debian fica em /etc/network/interfaces. Lembrando que não precisamos de ambiente gráfico.
    Criando o diretório de mídia
    Tendo o IP, é hora de criar um diretório que mídia que vai armazenar seus arquivos. Escolhi /home/share, mas poderia ser qualquer outro. Dentro dele vamos criar diretórios separados para, por exemplo, filmes, shows e músicas:
    $ sudo mkdir -p /home/share/{filmes,shows,mp3} Eu optei por não compartilhar fotos por questões de privacidade.
    Agora é hora de colocar arquivos nos diretórios, de modo a popular o media server. Para poder gerenciar os arquivos sem privilégios de root, é interessante tornar seu usuário comum dono do diretório share. No meu caso, o nome de usuário é fernando:
    $ sudo chown -R fernando: /home/share Certifique-se de que os arquivos e diretórios possuem permissões para serem visualizados, mas nada de 777 hein. Se necessário, aplique as permissões padrão neles:
    $ find /home/share -type d -exec chmod 0755 {} ; $ find /home/share -type f -exec chmod 0644 {} ; Instalando e configurando o minidlna
    O minidlna [1] é um servidor de mídia para clientes DLNA/UPnP. Resumidamente, enquanto o UPnP é um conjunto de protocolos que permitem dispositivos compatíves se encontrarem numa rede (auto-discovery), o DLNA é um serviço que utiliza UPnP para streaming de mídia. Algumas pessoas preferem usar o MediaTomb, que tem mais recursos que o minidlna, mas este último é bem modesto e simplista.
    Para instalar é bem difícil:
    $ sudo apt-get install minidlna Após a instalação, vamos configurar três parâmetros em /etc/minidlna.conf:
    media_dir=/home/share root_container=B friendly_name=Debian Home Server A opção root_container=B faz com que os dispositivos vejam os três diretórios que criamos abaixo de /home/share, por padrão. Eu configurei assim porque não gosto de localizar mídia por artista, gênero, ano etc já que não mantenho tags IDv3 e similares atualizadas. Se não é o seu caso, pode comentar essa opção para que ela seja configurar com seu valor padrão.
    Em friendly_name você configura um nome pelo qual os dispositivos clientes reconhecerão seu media server.
    E por fim, a única opção realmente necessária para o servidor entrar em funcionamento, media_dir, define qual o diretório raiz de mídia.
    Após salvar o arquivo, é preciso forçar que o banco de dados de mídia (em /var/lib/minidlna) seja recriado:
    $ sudo /etc/init.d/minidlna force-reload Por padrão, as portas UDP 1900 e TCP 8200 são utilizadas. Se você configurou um firewall no servidor, deve liberá-las.
    Isto é tudo que você precisa fazer para ter um media server funcional. Vamos agora para o lado cliente.
    Usando clientes no Linux e Windows
    Em minha humilde opinião, tá pra nascer um player melhor que o VLC [2]. Além de fazer café, ele é multiplataforma (apt-get install vlc) e age como cliente UPnP tranquilamente. Para isso, instale-o numa máquina que está na mesma rede que o servidor e faça o seguinte:
    Abra o VLC e vá em “View -> Playlist”. Na navegação do lado esquerdo, expanda “Local Network” e vá em “Universal Plug’n’Play”. O friendly_name do seu media server deve aparecer do lado direito em alguns segundos e você já pode começar o streaming.

    Usando cliente no Android
    Usuários de smartphones Samsung já possuem um clinte instalado chamado AllShare. Na verdade ele é um servidor também, e você pode compartilhar os arquivos de mídia do seu aparelho na rede, se for de seu interesse.
    O VLC para Android [3]  suporta UPnP, mas os testes foram feitos com uma alternativa para a época que ainda não havia suporte. A ferramenta utilizado foi o UPnPlay [4], que é gratuito e dá conta do recado. Depois de instalar, basta abri-lo e começar o streaming:

     


     
    Outros clientes
    Qualquer dispositivo compatível com o UPnP na sua rede vai encontrar seu servidor. Smart TVs, DVD/Blu-ray players, video games (como o PS3) e outros. No caso de outros smartphones como iPhone ou Blackberry, pode ser necessário instalar algum aplicativo, mas duvido que seja difícil. Segue uma lista com vários softwares servidores e clientes [5]. Agora não tem desculpa.
     
    Referências
    [1] http://sourceforge.net/projects/minidlna/
    [2] http://www.videolan.org/vlc/
    [3] https://www.videolan.org/vlc/download-android.html
    [5] http://en.wikipedia.org/wiki/List_of_UPnP_AV_media_servers_and_clients#Android

×