Aug 15, 2006

Capturando e-mails da rede interna com mailsnarf

Introdução e Justificativa



Em um ambiente profissional, a empresa tem a necessidade e a obrigação de controle de todos os dados que trafegam em sua rede.
Empresas que tercerizam o servidor de e-mail, tem algumas dificuldades de implantarem um maior controle em relação ao e-mail.

Com o Mailsnarf é possível ter uma cópia de todos os e-mails que são enviados ou recebidos e posteriormente baixá-los em seu gerenciador de e-mails.

Para isto será necessário que os e-mails sejam divididos em arquivos, e depois um servidor pop para baixar estes e-mails. Como servidor pop iremos utilizar o courier-pop.

Antes de começar este artigo devo avisar que não se deve abusar deste serviço.
Em qualquer que seja a situação todos os usuário devem estar cientes de que seus e-mails estão sendo capturados, e isto deve ser feito por escrito.

Justificativa



A empresa ao fornecer recursos de informação aos seus funcionários visa otimizar a comunicação e o controle das informações. Toda e qualquer informação que chegue a empresa é de sua propriedade. O funcionário em seu setor é um representante da empresa.

A empresa tem o direito e o dever em manter o controle sobre a utilização dos recursos de informação que possui. A “Negligência na Vigilância” estende a culpa dos atos do funcionário até a empresa.

Outro ponto polêmico é a questão da "Negligência na Vigilância", uma vez que "a culpa do responsável consiste em não haver exercido, como deveria, o dever de vigiar, de fiscalizar ou de não haver retirado do serviço ou de haver aceito quem não podia exercer com toda correção o encargo". (Pontes de Miranda).

Baseado no artigo de Marcio Cots “Não existe privacidade no trabalho

O Mailsnarf



É um programa que captura todos os dados que trafegam pelas portas 25,110 e 1109, este último é referente ao KPOP (A única coisa que encontrei na web sobre o Kpop foi música coreana, se alguem souber fique a vontade para esclarecer).

O Mailsnarf faz parte do pacote DSniff, que contém váriados tipos de programas de captura.
Para você obter mais informações e download do DSniff visite o
site: http://monkey.org/~dugsong/dsniff/

Funcionamento



Este programa exibe em tela todos os e-mails capturados. Bom para testes ou para uma rápida verificação.
A execução do programa é extremamente simples:

serv:/# mailsnarf


Somente com a chamada, ele irá capturar todos os pacotes de e-mails que estão trafegando pela eth0.
É possível definir qual interface de rede se deseja capturar através da flag "-i"

serv:/# mailsnarf -i eth1


Isto é muito interessante pois desta forma você poderá definir que somente quer capturar os pacotes que irão para o seu provedor, caso você também possua um servidor de e-mail para a rede interna.

Também será muito útil quando se for fazer o download dos e-mails, como eles são feitos via pop, você irá gerar um ciclo vicioso se o mailsnarf estiver escutando os pacotes da sua interface interna.

Também é possível a utilização de expressões regulares para a captura de pacotes. Excelente opção para se filtrar o que deve ser capturado, obtenha informações sobre esta funcionalidade em:
http://downloads.openwrt.org/people/nico/man/man8/mailsnarf.8.html

serv:/# mailsnarf -i eth1 pattern [expressão]


Salvando em arquivo



Como o mailsnarf imprime em tela todo os e-mails, é possível que redirecione todo a sua saída para um único arquivo.

serv:/# mailsnarf -i eth1 > /path/arquivo


Isto é bom para que você possa manter um histórico sobre os e-mails enviados e recebidos em sua rede.

O problema disto que é todos os e-mails estarão em um único arquivo, e dependendo do tamanho da rede, este arquivo ficará grade, e será dificil analisá-lo.

Outro problema são os anexos, não haverá como visualizá-los, pois estarão em formato caracter no arquivo, e dificultarão a verificação dos e-mails.

O problema



Temos todos os e-mails em um único arquivo. A leitura destes e-mails é muito dificil, primeiro pelo seu tamanho, e depois por que todos os e-mails estão nos fontes.

Há a necessidade de se melhorar isto. Pesquisando soluções na internet, encontrei comentários sobre direcionar o arquivo para um diretório de pop e fazer o download via gerenciador de e-mail, ou visuáliza-los em um webmail.

O problema é como dividir estes e-mails em arquivos separados e salvá-los no diretório de e-mail do usuário desejado.

Solução



Para resolver este problema é usado a liberdade oferecida pelo Código Aberto. Pegamos o fonte e alteramos o programa para a situação que nós precisamos.

Baixando, descompactando e acessando os fontes



Como o mailsnarf faz parte do pacote dsniff, faça o download do pacote completo pelo site deles
http://monkey.org/~dugsong/dsniff/

Descompacte o pacote:

serv:/# tar -xzvf dsniff-2.3.tar.gz


Lendo README, ou, nas mensagens do ./configure, será verificado que o pacote dsniff possui algumas dependências:


these programs require:

Berkeley DB - http://www.sleepycat.com/
OpenSSL - http://www.openssl.org/
libpcap - http://www.tcpdump.org/
libnids - http://www.packetfactory.net/Projects/Libnids/
libnet - http://www.packetfactory.net/Projects/Libnet/


Baixe-as e instale-as. Usuários Debian contam com a facilidade:

serv:/# apt-get build-dep dsniff


Ele fará o download e instalação de todas as dependências do pacote dsniff, mas não irá baixar o dsniff.

Acesse o diretório dsniff-2.3. Para aqueles que utilizam o debian irão acessar o diretório dsniff-2.4 se fizeram o download dos fontes de www.debian.org.

Vamos abrir o fonte do mailsnarf.

serv:/# vi mailsnarf.c


Localizando e editando a função responsável por imprimir em tela



Apesar de não estar comentado, é um código simples, então o entendimento será fácil.

Na linha 88 inicia a nossa função procurada:


static void
print_mbox_msg(char *from, char *msg)
{
char *p;
time_t t;

t = time(NULL);

if (from == NULL)
from = "mailsnarf";

printf("From %s %s", from, ctime(&t));

while ((p = strsep(&msg, "\n")) != NULL) {
if (strncmp(p, "From ", 5) == 0)
putchar('>');
for (; *p != '\r' && *p != '{TEXTO}'; p++)
putchar(*p);
putchar('\n');
}
putchar('\n');
fflush(stdout);
}


Entendendo a função



Esta função recebe como parametros o remetente, e o fonte de todo o e-mail.

É feita uma verificação para caso não haja um from, isto acontece quando o e-mail é enviado.
Mas o from do e-mail é mantido, isto é apenas uma informação adicional.

É impresso o from e a data e hora do momento da captura.

Neste loop while, será impresso caracter a caracter da mensagem na tela.

Para finalizar e separar um e-mail do outro é impresso ao final da função um "\n" e depois é limpo o buffer de video.

Alterando o fonte



Não será necessário adicionar nenhuma biblioteca ao arquivo.
Vamos adicionar algumas variáveis e redirecionar a saída para o arquivo. Simples assim!

Eu não criei outra função simplesmente redirecionei a saída da função original.


static void
print_mbox_msg(char *from, char *msg)
{
/*
* Foi declarada uma variável global
* de nome cont.
* int cont = 0;
*/

char *p;
time_t t;

FILE *fl; //ponteiro para o arquivo

/*
* Neste ponteiro char, armazenaremos o
* diretório onde iremos salvar nossos
* arquivos.
*/
char *dir = "/home/edmafer/Maildir/new/";

/*
* path será a concatenação do diretório
* com o nome do arquivo.
*/
char path[30];

t = time(NULL); //Pegando a data e hora de agora

/*
* Estamos concatenando em path, o diretorio
* o nome do arquivo, e a extensão eml
* e incrementa 1 em cont
*/
sprintf(path,"%s%d.%s",dir,cont++,"eml");

fl = fopen(path,"w"); //Abrindo o arquivo para escrita

if (!fl) { //Verificando se houve erro ao abrir
printf("\nErro ao tentar criar arquivo\n");
return;
}

if (from == NULL) //Definindo o from
from = "mailsnarf";

fprintf(fl,"From %s %s", from, ctime(&t)); //Direcionando para o arquivo com data

while ((p = strsep(&msg, "\n")) != NULL) { //Todas as saidas para o arquivo
if (strncmp(p, "From ", 5) == 0)
putc('>',fl);
for (; *p != '\r' && *p != '{TEXTO}'; p++)
putc(*p,fl);

putc('\n',fl);
}

putc('\n',fl);
fflush(stdout); //Limpando buffer de tela (pra que? Não sai mais nada lá)

fclose(fl); //Fechando o arquivo
}


Analisando o código alterado



Adicionamos ao código, um ponteiro para o arquivo, um ponteiro char com o caminho do diretório onde será salvo os arquivos e um char[30] que receberá o caminho do diretório e o nome do arquivo. Também foi declarada a variável global cont, esta será responsável por ser o contador dos arquivos.


int cont = 0;

FILE *fl;
char *dir = "/home/edmafer/Maildir/new/";
char path[30];


Com sprintf nós adicionamos a path um string formatada com os valores das outras strings.

sprintf(path,"%s%d.%s",dir,cont++,"eml");


A abertura do arquivo para escrita.


fl = fopen(path,"w");


E agora o redirecionamento da saída do programa.

A função fprintf que é similar a printf, com a diferença que redireciona para um arquivo.


fprintf(fl,"From %s %s", from, ctime(&t));


Da mesma forma putc é similar a putchar, só que redirecionando para um arquivo.


putc(*p,fl);


E finalizando fechamos o arquivo


fclose(fl);


Compilando



Após editado o fonte e salvo o arquivo, vamos compilar.

Compilei todo o pacote dsniff, para isto


./configure
make


Não é necessário utilizar o make install, pois o mailsnarf já estará pronto para execução.

Instalando o servidor pop



Utilizando o courier, para usuários debian o courier-pop.

Download e manual do courier: http://www.courier-mta.org/

Usuários debian


serv:/# apt-get install courier-pop


Eu não alterei a configuração padrão do courier. A instalação foi feita pelo apt-get do Debian, e o servidor somente aceita a conexão de um host específico, então não me preocupei com outras seguranças. Verifique o manual do courier para mais informações de configuração.

Feita a instalação do mesmo, somente precisamos criar o diretório de e-mails para o usuário


serv:/# maildirmake /home/usuario/Maildir


Agora é só configurar o gerenciador de e-mail
login: usuario_linux
senha: senha_linux
pop:ip_servidor do courier.

Os e-mails serão iguais aos recebidos pelos usuários da sua rede, no campo from é quem enviou e no campo to para quem é destinado.
Os anexos estarão disponíveis, da mesma forma como se o e-mail fosse direcionado para você.

Executando o mailsnarf



Como ele se trata de apenas um executável, você simplesmente tem que chamá-lo e definir alguns argumentos


serv:/# mailsnarf -i eth1


Eu coloco sempre como exemplo a eth1, para diferenciar justamente a questão da definição da interface de rede, mas isto deve ser definido pelo seu esquema.

Para colocá-lo em daemon, é necessário somente adcionar o "&" ao final da chamada do comando


serv:/# mailsnarf -i eth1 &


É possível verificar a sua execução pelo comando ps aux


serv:/# ps aux | grep mailsnarf


E isto irá te retornar


serv:/# ps aux | grep mailsnarf
root 18962 1.0 5.7 47488 28004 ? S Apr19 13:41 mailsnarf -i eth1
root 24902 0.0 0.1 1852 728 pts/2 S+ 13:19 0:00 grep mailsnarf
serv:/#


Para sempre iniciáliza-lo com o sistema, adicione esta chamada em /etc/init.d/rc.

Ou leia o artigo de Rubens Queiroz de Almeida para uma melhor configuração de inicialização
http://www.dicas-l.com.br/dicas-l/20060127.php

Conclusão



Este é um sistema de controle, que justifico sua necessidade no início do artigo. Lembro que o meu objetivo era o controle de e-mails, e não montar um servidor robusto de pop, a segurança deste servidor eu deixei por conta do iptables, onde libero acesso somente de host específico.

Acredito que a justificativa possa vir a gerar algumas discussões, mas o escopo não é discutir se é ético ou não este controle. Ensinei como se faz, se deseja utilizar ou não a opção é da instituição onde você trabalha.

A distribuição utilizada foi o Debian Sarge 3.0. Peço desculpas a usuários de outras distribuições que eu possa ter deixado faltar algumas informações específicas.

2 comments:

Elias Ricardo - Dual Soluções said...

Edmafer, parabéns pelo artigo. Estou tentando compilar o dsniff e estou tendo problemas, vc poderia me ajudar? Já baixei varios fontes, versao 2.3, 2.4, direto do monkey, baixei do repositorio debian e nada. Qdo dou make aparece o seguinte erro:
./arpspoof.c: In function âarp_sendâ:
./arpspoof.c:51: warning: passing argument 1 of âlibnet_get_hwaddrâ from incompatible pointer type
./arpspoof.c:51: error: too many arguments to function âlibnet_get_hwaddrâ
./arpspoof.c:62: warning: passing argument 6 of âlibnet_build_ethernetâ from incompatible pointer type
./arpspoof.c:62: error: too few arguments to function âlibnet_build_ethernetâ
./arpspoof.c:66: error: âETH_Hâ undeclared (first use in this function)
./arpspoof.c:66: error: (Each undeclared identifier is reported only once
./arpspoof.c:66: error: for each function it appears in.)
./arpspoof.c:66: error: too few arguments to function âlibnet_build_arpâ
./arpspoof.c: In function âmainâ:
./arpspoof.c:185: warning: assignment makes pointer from integer without a cast
make: *** [arpspoof.o] Error 1

Uso Debian Etch.

Edmafer said...

Olá Elias! Obrigado!

Rapaz... faz tempo que eu não mechia com o dsniff...

Então, acontece que o dsniff está com problema com a libnet, e vendo alguns fóruns encontrei a solução dada por eles é o downgrade das bibliotecas.

vide:
http://forum.soft32.com/linux2/dsniff-make-error-ftopict43253.html

então na compilação use:
../configure \
--with-libpcap=/path/to/libpcap-0.7.2 \
--with-libnet=/path/to/libnet-1.0 \
--with-libnids=/path/to/libnids-1.16

And "make", and all should be well.

Aviso que ainda não testei, tentarei fazer isto este fim de semana.

Se tu conseguir, me avise.
[]'s