Ir para conteúdo
  • Cadastre-se

Pesquisar na Comunidade

Mostrando resultados para as tags ''hardening''.



Mais opções de pesquisa

  • Pesquisar por Tags

    Digite tags separadas por vírgulas
  • Pesquisar por Autor

Tipo de Conteúdo


Fóruns

  • Conteúdo Mente Binária
    • Núcleo
    • Projeto Bumerangue
    • Fale com a gente!
  • Comunidade
    • Engenharia Reversa
    • Programação
    • Redes
    • Análise de malware
    • Teste de intrusão
    • Sistemas operacionais
    • Certificações
    • Oportunidades
    • Outros
  • Segurança na Internet's Discussão

Categorias

  • Crackmes
  • Documentação
  • Debuggers
  • Ferramentas para PE
  • Utilitários
  • Packers
  • Unpackers

Encontrar resultados em...

Encontrar resultados que...


Data de Criação

  • Início

    FIM


Data de Atualização

  • Início

    FIM


Filtrar pelo número de...

Data de Registro

  • Início

    FIM


Grupo


Website


Github


LinkedIn

Encontrado 6 registros

  1. Fernando Mercês

    Desativando LD_PRELOAD no Linux

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

    Informações demais em fotos

    Com as vantagens óbvias das câmeras digitais, incluindo as dos smartphones, mais e mais pessoas tiram fotos todos os dias, em todos os lugares, fazendo as mais variadas “tripulias”. O que pouca gente sabe é que esses arquivos de fotos podem conter dados um tanto quanto comprometedores, como data, condições em que a foto foi tirada e até mesmo onde você estava! Se você olhar as propriedades de uma foto em .jpg tirada com uma câmera digital, poderá se surpreender com as informações que estão nela. No GNU/Linux: No Windows XP: Percebeu a marca e modelo da câmera, além da data quando a foto foi tirada? Por alguma razão o Windows não mostrou, mas o Linux sim, então este tipo de informação está em algum lugar no arquivo. Vamos ver… Eu não lembro de ter visto câmera digital que não salvasse os arquivos no formato JPEG. Por um lado é bom: padronização e compressão, já que o formato tem uma boa compressão e perde pouca qualidade, se bem ajustado. O formato JPEG, assim como qualquer outro formato de arquivo que se preze, define campos que serão interpretados pelos aplicativos que vão trabalhar com ele. Ou seja, poderia dizer que do primeiro byte de um arquivo .jpg até o enésimo byte, está a informação X. Deste em diante até um outro byte, está a informação Y e assim por diante. Claro que a imagem em si (leia-se o que é renderizável) ocupa um campo geralmente grande e de tamanho variável. Sem problemas se estudarmos o formato JPEG um pouquinho… No cabeçalho do formato JPEG, cada campo (chamado de “marker”) é iniciado por um byte 0xff e o próximo byte define que tipo de campo é. De acordo com a especificação [1], o campo “0xff 0xd8” é o SOI (Start Of Image) e marca o início da imagem. Então se olharmos o conteúdo com um visualizador hexa, podemos observar: $ hd -n 64 tracking.jpg 00000000 ff d8 ff e1 48 88 45 78 69 66 00 00 4d 4d 00 2a |….H.Exif..MM.*| 00000010 00 00 00 08 00 0a 01 0f 00 02 00 00 00 08 00 00 |…………….| 00000020 00 86 01 10 00 02 00 00 00 0a 00 00 00 8e 01 12 |…………….| 00000030 00 03 00 00 00 01 00 01 00 00 01 1a 00 05 00 00 |…………….| A documentação prevê campos para abrigar as dimensões da imagem, compressão utililizada, cores etc. Inclusive há um campo para comentários definido por “0xff 0xfe”, de tamanho variável. Vamos procurá-lo? Pode ser que nossa informação esteja lá: Nada encontrado. O arquivo tem várias informações mas nem consta o campo de comentários previsto na especificação JPEG. Neste caso, vamos dar uma olhada com mais carinho nos bytes: $ hd -n 512 tracking.jpg 00000000 ff d8 ff e1 48 88 45 78 69 66 00 00 4d 4d 00 2a |….H.Exif..MM.*| 00000010 00 00 00 08 00 0a 01 0f 00 02 00 00 00 08 00 00 |…………….| 00000020 00 86 01 10 00 02 00 00 00 0a 00 00 00 8e 01 12 |…………….| 00000030 00 03 00 00 00 01 00 01 00 00 01 1a 00 05 00 00 |…………….| 00000040 00 01 00 00 00 98 01 1b 00 05 00 00 00 01 00 00 |…………….| 00000050 00 a0 01 28 00 03 00 00 00 01 00 02 00 00 01 32 |…(………..2| 00000060 00 02 00 00 00 32 00 00 00 a8 02 13 00 03 00 00 |…..2……….| 00000070 00 01 00 01 00 00 87 69 00 04 00 00 00 01 00 00 |…….i……..| 00000080 00 da 88 25 00 04 00 00 00 01 00 00 02 56 00 00 |…%………V..| 00000090 02 c4 53 41 4d 53 55 4e 47 00 47 54 2d 49 35 35 |..SAMSUNG.GT-I55| 000000a0 30 30 42 00 00 00 00 48 00 00 00 01 00 00 00 48 |00B….H…….H| 000000b0 00 00 00 01 32 30 31 30 2d 31 31 2d 31 38 20 30 |….2010-11-18 0| 000000c0 30 3a 34 36 3a 32 33 20 00 00 00 00 00 00 00 00 |0:46:23 ……..| 000000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |…………….| 000000e0 00 00 00 00 00 00 00 11 82 9a 00 05 00 00 00 01 |…………….| 000000f0 00 00 01 ac 82 9d 00 05 00 00 00 01 00 00 01 b4 |…………….| 00000100 88 22 00 03 00 00 00 01 00 03 00 00 88 27 00 03 |.”………..’..| 00000110 00 00 00 01 00 c8 00 00 90 00 00 02 00 00 00 0f |…………….| 00000120 00 00 01 bc 90 03 00 02 00 00 00 32 00 00 01 cc |………..2….| 00000130 90 04 00 02 00 00 00 32 00 00 01 fe 91 01 00 07 |…….2……..| 00000140 00 00 00 04 01 02 03 00 92 07 00 03 00 00 00 01 |…………….| 00000150 00 02 00 00 92 0a 00 05 00 00 00 01 00 00 02 30 |……………0| 00000160 a0 00 00 07 00 00 00 04 30 31 30 30 a0 01 00 03 |……..0100….| 00000170 00 00 00 01 00 01 00 00 a0 02 00 04 00 00 00 01 |…………….| 00000180 00 00 06 40 a0 03 00 04 00 00 00 01 00 00 04 b0 |…@…………| 00000190 a0 05 00 04 00 00 00 01 00 00 02 38 a4 03 00 03 |………..8….| 000001a0 00 00 00 01 00 00 00 00 a4 06 00 03 00 00 00 01 |…………….| 000001b0 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 08 |…………….| 000001c0 00 00 00 87 00 00 00 32 56 65 72 73 69 6f 6e 20 |…….2Version | 000001d0 32 2e 32 00 00 00 00 00 32 30 31 30 2d 31 31 2d |2.2…..2010-11-| 000001e0 31 38 20 30 30 3a 34 36 3a 32 33 20 00 00 00 00 |18 00:46:23 ….| Opa, começamos a achar as informações que queremos, mas em qual campo estamos? Veja que começou o “0xff 0xe1” e até o fim deste dump de 512 bytes não começou outro campo, ou seja, ainda estamos nele. A documentação do formato JPEG diz que os campos “0xff 0xeN”, onde “N” pode variar, representa um campo chamado APPN (no nosso caso, N=1, entao nosso campo é APP1). Este campo é usado para gravar metadados no formato EXIF, usado por vários tipos de arquivo para abrigar informações adicionais. O objetivo agora é destrinchar o EXIF e ver como ele está estruturado. O primeiro passo é olhar a documentação [2] em busca da especificação de seus campos. O EXIF é usado “dentro” de outros formatos. Não vou comentar sobre a estrutura do EXIF aqui, pois demandaria um longo texto. Por hora, basta otimizarmos procurando um software que seja capaz de ler os metadados EXIF em um JPG, certo? O software que mais me atendeu foi o jhead [3]. Além de ser livre, é cheio de recursos interessantes, inclusive pode apagar todas as informações EXIF de um arquivo .jpg, a fim de evitar rastros. $ jhead tracking.jpg File name : tracking.jpg File size : 314085 bytes File date : 2011:03:30 02:13:53 Camera make : SAMSUNG Camera model : GT-I5500B Date/Time : 2010-11-18 00:46:23 Resolution : 1600 x 1200 Focal length : 2.7mm Exposure time: 0.125 s (1/8) Aperture : f/2.7 ISO equiv. : 200 Whitebalance : Auto Metering Mode: center weight Exposure : aperture priority (semi-auto) GPS Latitude : ? 12d 23m 28.937s GPS Longitude: ? 13d 20m 33.702s Epa! Latitude e longitude? Por que isso não apareceu no Windows, nem no Linux, no ambiente gráfico? Sério que dá pra saber onde eu estou? Sério… Qualquer pessoa que tiver sua foto (Facebook?) pode pegar essas informações e converter para coordenadas de GPS, existem até conversores na internet. Depois é só usar alguma API de “Reverse Geocoding”, que é a técnica de obter um mapa de um lugar a partir de suas coordenadas GPS. Moral da história: muito cuidado onde coloca suas fotos. Se quiser um pouquinho menos de exposição, você pode remover todas as informações EXIF com a opção -purejpg do jhead: $ jhead -purejpg tracking.jpg Modified: tracking.jpg $ jhead tracking.jpg File name : tracking.jpg File size : 295533 bytes File date : 2011:03:30 02:13:53 Resolution : 1600 x 1200 Veja que agora só ficam informações básicas como resolução e data de modificação do arquivo (o mesmo usado pelo SO). É, a vida digital tem um preço… [1] http://en.wikipedia.org/wiki/JPEG#Syntax_and_structure [2] http://www.exif.org/Exif2-2.PDF [3] http://www.sentex.net/~mwandel/jhead/
  3. Fernando Mercês

    (Des)protegendo mídias USB

    1. Introdução As mídias USB, e em especial os pen drives, são responsáveis por boa parte das infecções por vírus e malwares nas estações de trabalho e até servidores utilizados por usuários incautos. Um simples “espetar” de um pen drive USB pode passar por cima de todas as medidas segurança implementadas no ambiente de rede. Pensando nisso, resolvi buscar uma forma de imunizar uma mídia USB, de forma passiva, de modo que a proteção fique na mídia e não na máquina. Não existe milgare, mas é possível diminuir bastante o risco de infecção com a técnica que apresentarei. 2. Como a infecção ocorre Quando uma mídia USB é inserida numa máquina com Windows, o recurso de autoreprodução é iniciado. Se na raiz da mídia existir um arquivo autorun.inf, este é lido pelo sistema e suas instruções são processadas, tudo de forma automática. A técnica mais eficiente para infectar uma mídia USB é, então, copiar para a mídia o malware em si (geralmente um binário PE) e criar também um autorun.inf na raiz da mídia que execute o malware toda vez que a mídia é inserida numa máquina com Windows. Este processo é explicado no texto “Como remover vírus de pen drive” [1], que escrevi em janeiro de 2010. 3. A ideia da proteção Há várias tentativas de evitar essas infecções, desde programas simples que tentam remover indícios de vírus nas mídias USB até softwares mais complexos, apelidados de “firewalls” USB, que permitem controlar todo o tráfego. O problema é que a máquina é protegida, mas não a mídia USB. Se você usa o pen drive, por exemplo, em outra máquina, ele pode ser infectado e servir de meio de disseminação, pois os softwares que protegem a USB estão na sua máquina e não no pen drive. Como todos os malwares que analisei criam um autorun.inf para se autoreproduzir, a ideia é criar um autorun.inf sadio no raíz da mídia USB, que seja “inalterável”, “indeletável”. Dessa forma, o malware não conseguirá sobrescrever o autorun.inf saudável pelo seu malicioso e o executável do malware pode até ser copiado para a mídia, mas não será inicializado quando a mídia for inserida num Windows qualquer, ou seja, ficará simplesmente armazenado na mídia, mas inofensivo (a não ser que algum usuário encontre manualmente o executável e o execute). Mas será possível? Vamos aos testes. Verificando a possibilidade Depois de algumas buscas sobre criação de arquivos “indeletáveis”, encontrei o Panda USB Vaccine [2], que promete fazer exatamente o proposto. Ele realmente funciona e cria um autorun.inf “indeletável” no raíz da mídia USB. O inconveniente, para mim, é que ele é um software de código fechado e não há documentação sobre como ele faz isso, além de rodar somente em Windows. Eu estava desenvolvendo o USBForce [3], um software livre para proteção contra pragas em mídias USB quando encontrei o Vaccine. Naturalmente eu gostaria de implementar essa funcionalidade de criação de um autorun.inf “indeletável” no meu software. Além disso, não conseguiria dormir sem saber como (tecnicamente) este arquivo é criado e se era mesmo indeletável. 4. Revertendo a técnica do Vaccine: Utilizei algumas ferramentas para saber como o Vaccine funciona, começando pelo RDG Packer Detector [4], que além de outras funcionalidades, consegue saber qual o compilador utilizado para gerar o binário, informação muito útil antes do debugging: O RDG informa que não há packer e que o software foi escrito no Borland C++. Não se pode tomar tudo como verdade, mas é um bom ponto de partida. Além disso, o RDG detecta uma chamada à função IsDebuggerPresent [5]. Alguns softwares se encerram ao perceberem que estão sendo debugados e esta função é uma das formas de ter essa percepção. Geralmente o compilador coloca algumas informações interessantes na seção .data do executável gerado. Não custa olhar rapidamente o que tem lá. Para isso eu usei o pev [6] com a opção “-s”, para exibir informações sobre as seções do executável: > pev -s USBVaccine.exe | more Sections: Name: .text Virtual size: 0xd9000 Virtual address: 0x1000 Data size: 0xd8600 Data offset: 0x600 Characteristics: 0x60000020 (01100000000000000000000000100000) contains executable code is executable is readable Name: .data Virtual size: 0x1d000 Virtual address: 0xda000 Data size: 0x12c00 Data offset: 0xd8c00 Characteristics: 0xc0000040 (11000000000000000000000001000000) contains initialized data is readable is writable Sabendo o offset (posição) onde a seção .data começa, usei o hdump [7] para espiar os bytes: > hdump USBVaccine.exe | findstr “d8c[0-9]0″ 000d8c00 43 6f 64 65 47 65 61 72 20 43 2b 2b 20 2d 20 43|CodeGear C++ –C| 000d8c10 6f 70 79 72 69 67 68 74 20 32 30 30 38 20 45 6d|opyright 2008Em| 000d8c20 62 61 72 63 61 64 65 72 6f 20 54 65 63 68 6e 6f|barcaderoTechno| 000d8c30 6c 6f 67 69 65 73 00 00 00 10 40 00 b2 12 40 00|logies….@…@.| 000d8c40 b2 12 40 00 22 15 40 00 01 00 00 00 00 00 00 00|..@.”.@………| 000d8c50 fc 64 40 00 00 00 00 00 00 00 00 00 00 00 00 00|.d@………….| 000d8c60 30 99 4e 00 4c ad 4e 00 50 ad 4e 00 68 d0 4b 00|0.N.L.N.P.N.h.K.| 000d8c70 c0 d1 4b 00 50 d2 4b 00 e4 d3 4b 00 b0 93 4e 00|..K.P.K…K…N.| 000d8c80 00 00 f8 ac 4e 00 74 ad 4e 00 ec aa 4e 00 00 00|….N.t.N…N…| 000d8c90 00 00 00 00 00 00 00 00 00 00 00 90 00 00 00 00|…………….| De fato, parece que o binário foi escrito em Borland C++, mas com uma versão mais atual (a Embarcadero comprou a divisão CodeGear da Borland). Vamos à execução do software: O que procuramos é o código do evento “click” do botão “Vaccinate USB”, certo? Existem ferramentas específicas para se trabalhar com binários gerados em versões específicas de compiladores. No caso do BC++, há uma ferramenta particularmente interessante chamada E2A (Event To Address), que consegue dizer o endereço de cada evento do software, o que facilita muito a vida: O endereço da função que o evento “click” do botão chama é 0x404C58. Agora é debugar. Usei o OllyDbg [8] para isso. A ideia é colocar um breakpoint neste endereço, rodar o Vaccine no debugger, clicar no botão para vacinar a mídia e seguir passo a passo o que o software faz, a partir do breakpoint. 5. Entendendo a proteção: Conforme é mostrado no vídeo, o Vaccine cria um arquivo AUTORUN.INF normal na raíz da mídia, mas depois busca pela entrada deste arquivo na FAT para localizar o byte que controla os atributos. Segundo a documentação [9], é o byte depois da extensão do arquivo. Para facilitar a compreensão, usei o Hex Workshop [10], que tem o recurso de editar discos e volumes lógicos. Além disso, ele permite a criação de estruturas personalizadas para interpretar os bytes visualizados. Criei uma estrutura simples (fat32-directory-table.hsl) para reproduzir a Directory Table da FAT-32. O byte em questão é um bitfield, onde cada bit corresponde a um atributo:Bit Máscara Atributo 0 0x01 Somente leitura 1 0x02 Oculto 2 0x04 Sistema 3 0x08 Nome de volume 4 0x10 Subdiretório 5 0x20 Arquivo 6 0x40 Não usado 1 7 0x80 Não usado 2 Lembrando que no vídeo mostrei que o Vaccine grava esse byte como 0x20 (Arquivo) e depois o busca em disco e altera para 0x42 (Não usado 1 + Oculto). É aí que mora a mágica. Não sei o motivo, mas quando o atributo 0x40 está setado, não é possível ler, executar, modificar ou excluir o arquivo. Fiz testes com os outros atributos mas o comportamento esperado só se dá com este bit 6 setado mesmo. Tentativas de implementação Eu tentei, ingenuamente, implementar o recurso no USBForce, que foi escrito em VBScript, mas a propriedade “Attributes” é um enum de valores pré-definidos e não aceita qualquer valor, portanto não aceitou o 0x42: Set objFSO = CreateObject(“Scripting.FileSystemObject”) Set objFile = objFSO.GetFile(“F:AUTORUN.INF”) objFile.Attributes = &H20 ‘Arquivo WScript.Echo “0x” + Hex(objFile.Attributes) objFile.Attributes = &H40 ‘Não usado 1 WScript.Echo “0x” + Hex(objFile.Attributes) O código acima prevê que já haja um arquivo autorun.inf no volume F. Ele imprime 0x20 e depois 0x0, ou seja, a tentativa de ativar o atributo não usado falha. Tentei também usando a API do Windows diretamente, em 😄 #include <windows.h> int main(void) { HANDLE out = CreateFile(“f:\autorun.inf”, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0x40, NULL); CloseHandle(out); return 0; } O resultado foi um arquivo criado com 0x20 (Arquivo) e não com o 0x40 que pedi. Por enquanto vou adotar como solução possível a busca diretamente na FAT pela entrada do arquivo e modificação bruta do byte de atributos, como o Vaccine faz. 6. Prova de Conceito Como incentivador do software livre, não poderia deixar de implementar esta técnica em código aberto e para funcionar no GNU/Linux. Por isso escrevi um programa para realizar o trabalho, que batizei de OpenVaccine [11]. Por enquanto ele é só uma prova de conceito e seu uso não é encorajado em ambientes de produção. Referências [1] https://www.mentebinaria.com.br/artigos/segurança/como-remover-vírus-de-pen-drive-r5/ [2] http://www.pandasecurity.com/homeusers/downloads/usbvaccine [3] https://github.com/merces/usbforce [4] http://www.rdgsoft.net [5] http://msdn.microsoft.com/en-us/library/ms680345(VS.85).aspx [6] https://github.com/merces/pev [7] https://github.com/merces/hdump [8] http://www.ollydbg.de [9] http://www.nationmaster.com/encyclopedia/VFAT#Directory_Table [10] http://www.hexworkshop.com [11] http://openvaccine.sf.net
  4. Fernando Mercês

    Como remover malware de pen drive

    É notória a quantidade de pen drives e cartões de memória infectados com vírus. Freqüentemente nos deparamos com vírus novos, que os antivírus não conhecem (a vacina é criada depois de certo tempo). Essas pragas disseminadas por pen drives são tão perigosas quanto as disseminadas pela internet e às vezes até mais destruidoras, ou seja, o cuidado deve ser redobrado. Veja neste artigo como se defender de um pen drive ou cartão de memória infectado e saiba como remover o vírus destes dispositivos. O primeiro ponto a entender é como um vírus infecta um pen drive. Sabemos que vírus são programas (executáveis) e a infecção de um pen drive acontece quando o inserimos em um PC infectado (ou quando o PC infectado já possui um pen drive inserido na porta USB). Se o pen drive infectado é inserido em PC saudável e sem proteção adequada, este PC é infectado e passa a infectar todos os pen drives inseridos nele posteriormente, ou seja, a disseminação da praga fica fora de controle. Infelizmente, tudo funciona muito bem graças a uma ajudinha da arquitetura e controle de permissões do Windows. Acontece que normalmente o usuário logado num sistema Windows pertence ao grupo “Administradores”, isto é, possui todas as permissões de escrita e leitura em praticamente todo o disco rígido e áreas de memória. Para um vírus, isto é um prato cheio. Da mesma maneira que um programa de instalação qualquer pode ser executado com sucesso pelo usuário logado (copiando arquivos para diretórios de sistema e criando processos privilegiados), um vírus também pode, pois rodará com as permissões do usuário, que são as de administrador do sistema (as máximas). Quando o usuário incauto executa um vírus, este normalmente carrega-se em memória, copia-se para vários locais (backup), tenta infectar outras máquinas na rede e faz com que seja inicializado a cada reinicialização do sistema. É mais ou menos a definição de um worm. Tratamos de algumas técnicas manuais utilizadas para remover estes vírus no artigo Remoção manual de malware no Windows. Assim que um pen drive sadio é inserido na porta USB, a praga copia-se para ele. Até aí, nenhuma novidade. Mas como, ao inserir este pen drive em outro computador, ocorre a infecção? Acontece que o Windows possui uma facilidade chamada autorun (ou auto-inicialização) para drives montados e com letra atribuída. Como os pen drives são reconhecidos como uma unidade de disco (recebem inclusive uma letra disponível para serem acessados, por exemplo, F:), esta facilidade pode ser usada nestes dispositivos. Funcionamento da auto-inicialização: O autorun serve para executar algum aplicativo assim que o drive é montado. O exemplo clássico são os CD-ROMs que, ao serem inseridos no drive de CD, abrem uma aplicação com menus e outros recursos. A questão é que o autorun pode ser utilizado em qualquer drive, seja uma partição do disco, CD-ROM, DVD, pen-drive, câmera digital, etc. Para usar esta facilidade, basta adicionar um arquivo chamado autorun.inf no diretório raiz do drive em questão. Neste arquivo são escritas rotinas que o Windows deverá seguir quando assim que o drive for montado. Veja um exemplo: [autorun] open=menu.exe icon=menu.ico Se você salvar o conteúdo do exemplo acima num arquivo de texto, nomeá-lo autorun.inf e movê-lo para o diretório raiz de um drive, ao montar ou acessar este drive, as instruções contidas neste arquivo serão executadas. Creio que as instruções sejam auto-explicativas. Basicamente o ícone do drive exibirá agora o ícone menu.ico, contido no diretório raiz do drive (do CD-ROM, por exemplo) e a aplicação menu.exe será carregada. À esta altura você deve imaginar como o vírus de pen-drive é executado assim que ele é inserido. Isso mesmo, usando essa técnica. Todos os pen-drives infectados que analisei continham um arquivo autorun.inf, com instruções para execução do vírus. Evitando a contaminação: Ficar imune é impossível. Nunca poderemos prever as técnicas de contaminação que serão inventadas. Aliás, cá entre nós, são muito “boas”. No entanto, algumas medidas podem ser tomadas para diminuir os riscos de contaminação. São elas: 1. Desabilitar a auto-reprodução em unidades removíveis. No registro, navegue até a chave HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionpoliciesExplorer e sete o valor NoDriveTypeAutoRun para 4. Isso desabilitará a auto-reprodução em unidades removíveis. Se quiser desabilitar em qualquer tipo de unidade (recomendo), utilize o valor ff. 2. Sempre abrir a unidade removível (pen-drive, cartão de memória, etc) pelo Windows Explorer, ao invés de dar duplo-clique no ícone. Basta clicar com o botão direito na unidade e escolher “Explorar” ou abrir o Windows Explorer e clicar sobre a unidade. 3. Desabilitar a execução do arquivo autorun.inf, geralmente responsável pela infecção.Copie e cole as linhas abaixo para o Bloco de Notas e salve como inf.reg: REGEDIT4 [HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionIniFileMappingAutorun.inf] @=”@SYS:DoesNotExistSEUNOME” Substitua SEUNOME pelo seu primeiro nome (sem acento ou espaços). Depois basta executar este inf.reg que você gerou. Para facilitar as coisas, escrevi um software que faz este trabalho. Chamei-o de USBForce. Funciona assim: Na primeira vez que é executado na máquina, o USBForce: Desabilita a auto-reprodução em todas as unidades. Desabilita o reconhecimento de arquivos autorun.inf. Habilita sua proteção. A partir deste momento, ao inserir um pen-drive, cartão de memória ou qualquer dispositivo removível, o Windows o reconhecerá mas nenhuma tela será aberta. Você deve então clicar no ícone do USBForce em sua área de trabalho. Ele abrirá o dispotivo pra você e tentará detectar se existe algum vestígio de infecção de vírus no dispositivo. Em caso afirmativo, ele tentará localizar o vírus e deletar (você será avisado antes). Naturalmente é interessante colocá-lo em alguma pasta e criar um atalho pra ele na área de trabalho, para facilitar o acesso.
  5. Fernando Mercês

    Remoção manual de malware no Windows

    A maioria dos vírus e pragas virtuais compartilham de certos métodos de auto-inicialização com o SO. Isto inclui os spywares e seus similares. Os sistemas Windows possuem métodos para inicializar programas junto ao seu carregamento limitados. Na maioria das vezes os vírus iniciam justamente por eles e daí a importância de conhecê-los e saber gerenciá-los. Desta forma, o técnico pode remover manualmente muitas pragas, o que economizará tempo com scans de softwares antivírus e anti-spys, além de ser extremamente útil quando o vírus ataca estes softwares de proteção, impedindo sua inicialização. Primeiro vamos ver de que jeito um aplicativo pode ser iniciado junto ao Windows. A maior parte dos vírus age deste jeito. Em sistemas baseados em Windows NT, o que inclui os Windows 2000, XP e 2003, os métodos de inicialização de programas são: Através da pasta Inicializar do Menu Iniciar. No registro do sitema. Por serviço de sistema (o que inclui certa parte do registro). Na primeira maneira, basta colocar um atalho para o programa que se deseja executar na pasta Inicializar do Menu Iniciar. Por exemplo, na imagem abaixo, a cada inicialização do Windows, inicializaremos a Calculadora junto. Obviamente um vírus pode se aproveitar deste recurso e colocar um atalho para si neta pasta mas não é comum isso acontecer pois o vírus ficaria facilmente visível e uma das intenções de vírus complexos é passar despercebido ao usuário/técnico. De qualquer forma, não custa conferir. Agora vamos ao método mais usado, o registro do sistema. Aqui precisaremos explicar resumidamente como o registro destas versões do Windows funciona. O registro é um banco de dados que armazena informações essenciais sobre diversos softwares instalados no Windows, além de informações pertinentes ao próprio sistema. Por conta disto, é comum apelidar o registro de “alma do sistema”. Esse banco de dados possui, além de outros dados, chaves, sub-chaves e valores numa organização hierárquica (similar ao Windows Explorer). Para o artigo, precisaremos conhecer essas três chaves: HKEY_LOCAL_MACHINE – Esta é a chave mais importante do registro. Nela estão contidas informações sobre o PC (hardware instalado, softwares com sua opções e configurações e outros itens). Inclusive veremos que um programa pode ser inicializado por uma sub-chave desta chave. HKEY_USER – Nesta chave são definidas configurações personalizadas para cada usuário do sistema, já que as versões do Windows mais novas permitem logon simultâneo ou não de usuários diferentes. De maneira similar à chave anterior, um vírus pode inicializar-se junto ao SO somente para um usuário específico, usando uma sub-chave desta chave. HKEY_CURRENT_USER – Como o nome sugere, mantém informações sobre o usuário que está atualmente logado no sistema. Todo o registro é dinâmico mas esta chave merece uma definição de dinamismo especial pois muda os valores de suas sub-chaves completamente quando logamos com outro usuário no Windows. Não é difícil de deduzir que ela é um atalho para uma sub-chave de HKEY_USER, já que esta última mantém uma sub-chave para cada usuário cadastrado no sistema. Por exemplo, se logarmos com o usuário “Fernando”, esta chave será uma cópia da sub-chave HKEY_USER. SID (Security Identifier) é uma identificação única que cada usuário tem e o SO conhece os usuários através deste SID. Abaixo, o utilitário “regedit” (Registry Editor), usado para visualizar o conteúdo do registro do sitema. Perceba a igualdade entre as áreas destacadas em vermelho. É justamente o que falamos na explicação da chave HKEY_CURRENT_USER. Note o SID do meu suário também. Depois desta breve introdução ao registro do sistema, podemos partir para as sub-chaves que realmente importam na questão da remoção manual de vírus. São elas: HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionRun HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionRunOnce HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionRunOnceEx HKEY_USERS\SOFTWAREMicrosoftWindowsCurrentVersionRun HKEY_USERS\SOFTWAREMicrosoftWindowsCurrentVersionRunOnce As duas últimas chaves acima dependem do SID do usuário mas se a suspeita de vírus for no usuário que está logado, você pode acessá-las pelo atalho como comentamos acima. Tudo o que estiver nestas chaves será inicializado junto ao sistema. Faça o teste: verifique o que tem nas sub-chaves de seu PC e veja os caminhos para os arquivos que incializam. No exemplo HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionRun da máquina que usei, está assim. Como podemos ver, só há três valores, que são os caminhos absolutos dos executáveis que inicializam junto à máquina usada. Esta é uma máquina virtual. Numa máquina real, os valores normais são outros. Para remover programas da inicialização, basta remover os valores desejados. É importante salientar que muitos arquivos presentes nestas sub-chaves são essenciais ao sistema e não devem ser removidos. Cabe ao técnico saber identificar caminhos e nomes de executáveis suspeitos. Se você tiver dúvida quando à procedência de algum arquivo, pode digitar seu nome no site Process Library, que mantém uma lista atualizadas de processos (programas em execução) para nos ajudar a identificar se são do sistema ou não. Há ainda o método de serviços que podem ser utilizado por alguns vírus mais complexos. A tela de serviços você tem acesso indo no menu Iniciar > Executar, digitando services.msc e clicando no botão OK. Eis a da máquina que usamos para o artigo. Esses serviços são na verdade processos (programas) inicializados que recebem este nome pela capacidade de poderem ser muito melhor gerenciados pelo sistema operacional que um processo comum. Perceba a coluna “Status” na imagem. Um serviço pode ser iniciado, reiniciado, pausado ou parado e seu método de inicialização pode ser manual (quando clicado), automático (a cada inicialização do sistema) ou desativado. Um vírus obviamente se aproveitaria do método automático e poderíamos pará-lo e depois desativá-lo numa remoação manual. Assim como os processos comuns, a maioria dos serviços é essencial ao sistema, portanto, é bom que se faça uma pesquisa sobre ele (no Google e sites similares) antes de parar ou desativar um serviço suspeito ou não. Ao entrarmos nas propriedades de um serviço, vemos o caminho do executável ao qual ele se refere além de uma caixa drop-down para alterar o tipo de inicialização, como mostra a imagem abaixo. Com este básico conhecimento, muitos vírus podem ser removidos mas é claro que não basta. Recomendamos sempre um scan com um bom antivírus atualizado e com um anti-spy, mesmo após a remoção manual. Existem alguns programas que podem ajudar na identificação de vírus e na remoção manual. Abaixo segue uma lista com descrição: Process Explorer – monitora os processos em execuçao em tempo real, o que permite identificarmos se algum processo suspeito está sendo executado. O Process Explorer também mostra o que o processo está fazendo ou tentou fazer (quando bloqueado pelo SO). HiJackThis – gera uma lista e um arquivo de log com todos os processos que inicializam junto ao sistema, podendo ser utlizado inclusive para remover o que sejam julgados suspeitos (muito cuidado com seu julgamento). NOTA: O projeto original foi descontinuado, mas o usuário Polshyn Stanislav da Ucrânia o continuou. Gmer - uma aplicação que detecta e remove rootkits (dentro de um limite, claro). A ideia é procurar por uma lista de coisas escondidas, tais como processos, threads, serviços, arquivos etc. MSCONFIG – utilitário presente no Windows XP mas que pode ser copiado a partir do arquivo msconfig.exe para outros sitemas Windows. Ele mostra de forma interativa o que está sendo inicializado junto ao sistema além de permitir a consulta de outras informações. Você pode chamá-lo a partir do menu executar.
  6. Fernando Mercês

    Extensões perigosas no Windows

    Apesar de ser um assunto que já foi tratado em muitos sites e fóruns, continuo a observar que alguns usuários do Windows devem ter mais atenção com o tipo de arquivo que aplica o famoso duplo-clique. Identificar se o arquivo é inofensivo ou se é uma ameaça pode ser mais fácil do que se imagina. Este artigo tem como intenção desmistificar as lendas sobre as extensões de arquivos maliciosos e alertar sobre as extensões perigosas. O sistema operacional Windows reconhece (deduz o conteúdo) dos arquvios por sua extensão. Mas o que é extensão de arquivo? Extensão de arquivo para o MS-Windows, comumente são os três caracteres após o ponto, no nome completo do arquivo. Por exemplo, documento001.txt, é um arquivo com extensão .TXT, logo, o Windows deduzirá que é um documento de texto e associará este documento à um certo programa, que poderá abrí-lo (recebendo seu caminho como parâmetro) mediante um duplo-clique neste documento. Confundiu? Bom, em termos práticos, cada extensão de arquivo que mereça, possui um determinado programa responsável por interpretar um duplo-clique num arquivo que possua tal extensão. Essas informações (quais extensões são abertas por qual programa) ficam no registro do Windows. Ainda com o exemplo do documento001.txt, vamos analisar sua associação: ao dar um duplo-clique nele, vemos que ele é aberto pelo Bloco de Notas (notepad.exe). A chave do registro responsável por armazenar as informações desta associação é, no Windows XP: HKEY_CLASSES_ROOT\txtfile\shell\open\command. Veja a imagem: Perceba que na coluna "Dados" há o caminho completo do notepad.exe (usando uma variável de sistema sim, mas não deixa de ser o caminho absoluto), seguido de %1. Já sabemos que é o Bloco de Notas (notepad.exe) que abrirá arquivos de texto, agora vamos entender o parâmetro. Eu escrevi mais acima que o caminho do arquivo a ser aberto era passado por parâmetro. É justamente isso que o "%1" faz. Essa variável armazena o caminho absoluto do arquivo que está sendo acessado, no instante do acesso. Portanto, se você clicou no arquivo documento001.txt e ele está em C:\docs\, esta variável conterá o valor C:\docs\documento001.txt. Isso informa ao Bloco de Notas onde está o arquivo. Agora que já sabemos o que é e como funciona a extensão, vamos aos riscos. Um arquivo executável precisa ter uma extensão de executável para ser executado. As extensões mais comuns de arquivos executáveis são: EXE, COM, BAT, VBS, MSI, SCR, arquivos do Office (porque podem conter macros, que são executáveis). Um vírus, obrigatoriamente, tem que ter uma dessas extensões. Ou seja, ele tem que ser um executável. O problema é que há certos disfarces utilizados pelos disseminadores de vírus. Um deles é colocar um nome de arquivo do tipo: "arquivo.jpg .exe". Assim mesmo, com vários espaços entre o .jpg e o .exe. A extensão deste arquivo de exemplo é .EXE e ele será executado como tal! Não é .jpg! O texto ".jpg" neste caso faz parte do nome do arquivo e não da extensão. A "técnica" de colocar espaços é para que os programas de email e webmail identifiquem um nome muito grande e exibam reticências após o .jpg, dando a impressão que é um arquivo de imagem. Detalhe que o ícone de um executável pode ser facilmente alterado para o ícone de uma imagem, o que aumenta as chances da vítima de ser enganada. Os vírus são programas. Logo, repito, são executáveis. Um arquivo de áudio puro, por exemplo, não pode ser vírus! A extensão .mp3 estaria associada ao Windows Media Player, ou Winamp, ou qualquer outro. Esses software não executam rotinas de executáveis. Só entendem fluxo de mídia, portanto, não executam as rotinas virais diretamente. Mas eles podem conter falhas que sejam exploradas através de payloads maliciosos de arquivos de mídia ou playlists (como os .m3u). Tenha certeza da extensão do arquivo e de sua procedência, e estará praticamente livre de ser infectado por um vírus anexo à um e-mail ou disponível para download. Mas lembre-se que os arquivos podem também estar zipados (.ZIP) ou compactados com outro compactador (RAR, LZIP, GZIP, LHA, JAR, etc). Dentro deles é que você deve examinar a extensão do arquivo.
×