Capturando e-mails da rede com Mailsnarf

Empresas que terceirizam 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.

[ Hits: 52.320 ]

Por: Edson Marco Ferrari Junior em 14/02/2007 | Blog: http://www.edmafer.com.br


Baixando, descompactando e acessando os fontes



Como o mailsnarf faz parte do pacote dsniff, faça o download do pacote completo pelo site deles:
Descompacte o pacote:

# 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:

# 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.

# 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 != '{TEXT0}'; p++)
                        putchar(*p);
                putchar('\n');
        }
        putchar('\n');
        fflush(stdout);
}

Entendendo a função

Esta função recebe como parâmetros 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("\n<!>Erro 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 != '{TEXT0}'; 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.

Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. O Mailsnarf
   3. Salvando em arquivo
   4. Baixando, descompactando e acessando os fontes
   5. Instalando o servidor pop
   6. Executando o mailsnarf
Outros artigos deste autor
Nenhum artigo encontrado.
Leitura recomendada

Autenticação por desafio e resposta no SSH

Mudança de hábito: autenticando usuários em base de dados MySQL

Monitorando máquinas Windows com o Nagios

Hardening, se adequando as normas ISO 27000

Chkrootkit - Como determinar se o sistema está infectado com rootkit

  
Comentários
[1] Comentário enviado por removido em 14/02/2007 - 16:12h

Muito bom!!!
10!!!

[2] Comentário enviado por mafioso em 14/02/2007 - 17:05h

gcc -g -O2 -D_BSD_SOURCE -D_BSD_SOURCE -D__BSD_SOURCE -D__FAVOR_BSD -DHAVE_NET_ETHERNET_H -DDSNIFF_LIBDIR=\"/usr/local/lib/\" -I. -I/usr/local/include -I/usr/local/ssl/include -I/usr/X11R6/include -I./missing -c ./arpspoof.c
./arpspoof.c: In function `arp_send':
./arpspoof.c:49: warning: passing arg 1 of `libnet_get_hwaddr' from incompatible pointer type
./arpspoof.c:49: error: too many arguments to function `libnet_get_hwaddr'
./arpspoof.c:60: warning: passing arg 6 of `libnet_build_ethernet' from incompatible pointer type
./arpspoof.c:60: error: too few arguments to function `libnet_build_ethernet'
./arpspoof.c:64: error: `ETH_H' undeclared (first use in this function)
./arpspoof.c:64: error: (Each undeclared identifier is reported only once
./arpspoof.c:64: error: for each function it appears in.)
./arpspoof.c:64: error: too few arguments to function `libnet_build_arp'
./arpspoof.c: In function `main':
./arpspoof.c:181: warning: assignment makes pointer from integer without a cast
make: *** [arpspoof.o] Error 1

Eu havia instalado todas as dependências e o "configure" identificou todas as biblioteca e validou o sistema para instalação.

[3] Comentário enviado por y2h4ck em 14/02/2007 - 17:53h

Acho que o mailsnarf é muito limitado.
Existem maneiras profissionais de configurar um MTA como por exemplo, postfix a encaminhar uma copia de todo email que sai para uma conta por exemplo:

auditor@dominio.com


Abraços.

[4] Comentário enviado por removido em 17/02/2007 - 20:17h

Respondendo a y2h4ck

Concordo com vc, mas isso não é uma proeza apenas do postfix, qualquer MTA que se preze tem controle de auditoria, qmail, postfix, etc.
Mas como nosso amigo edson disse em seu artigo, isso é uma solução para empresas que não tem acesso ao servidor de e-mail. Um exemplo pra vc, para o QMAIL fazer essa auditoria é necessário sua recompilação e um servidor que cuida de muitos dominios, fica complicado.

"Empresas que terceirizam o servidor de e-mail, tem algumas dificuldades de implantarem um maior controle em relação ao e-mail."


Ótima artigo Edson.

[]'s


[5] Comentário enviado por utikawa em 20/02/2007 - 13:30h

Eu concordo plenamente com o dbaio!
Já quanto ao mafioso, não seria o problema você estar tentando compilar o mailsnarf para o BSD?

[6] Comentário enviado por aldemar.moreira em 01/03/2007 - 16:34h

preciso de ajuda nao estou conseguindo compilar o dsniff para apresenta o seguinte erro.

checking for Berkeley DB with 1.85 compatibility... configure: error: Berkeley DB with 1.85 compatibility not found

A distr. é o CentOS o mais engraçado que se eu pegar um o pacote rpm vai numa boa, mas ai eu fico salvando os e-mails em apenas um arquivo

[7] Comentário enviado por edmafer em 01/03/2007 - 18:06h

Aldemar, experimenta utilizar o ./configure com a flag --with-db=DIR onde dir é onde está o Berkeley DB.

Dá uma olhada em ./configure --help que pode te ajudar.

[8] Comentário enviado por ifc0nfig em 19/04/2007 - 16:42h

Gostaria de saber se eu poderia usar algum dominio de fora por que aqui meus usuarios usam muito o gmail e hotmail tem como eu fazer essa captura pelo meu servidor de internet (Gateway), para esses dominios??

[9] Comentário enviado por edmafer em 19/04/2007 - 21:10h

Não, pois o programa captura e-mails enviados por um gerenciador de e-mail.

O Acesso ao gmail e ao hotmail geralmente são feitos pela web. Para capturar este tipo de informação seria necessário outro sniffer. No pacote dsniff tem um que captura as páginas acessadas, ai você teria que fazer o tratamento para não ficar lendo código.

Mas se eles acessarem por https, esquece, pois estará criptografado.

[10] Comentário enviado por randra em 12/07/2007 - 19:02h

depende do software que a empresa usa, utilizo qmail e com ctz tem solucao bem melhor, postfix rlz!


Mais tah ai um tipo sniffer =)

Parabens pelo artigo.

[11] Comentário enviado por ifc0nfig em 19/07/2007 - 16:54h

Eu tenho um postfix instalado aqui e to querendo fazer as capturas de entrada e saida dos meus usuarios na rede. Tanto os enviados como os recebidos tem como fazer pelo postfix isso ou só com o Mailsnarf.

fabiano

[12] Comentário enviado por removido em 19/07/2007 - 17:28h

Pelo postfix com certeza:

always_bcc = mail@dominio.com.br

O mailsnarf vc deve usar quando não se administra um servidor de e-mail, como o edmafer disse...

[13] Comentário enviado por angkor em 21/01/2008 - 14:48h

Estou com o mesmo problema do mafioso:
gcc -g -O2 -D_BSD_SOURCE -D_BSD_SOURCE -D__BSD_SOURCE -D__FAVOR_BSD -DHAVE_NET_ETHERNET_H -DDSNIFF_LIBDIR=\"/usr/local/lib/\" -I. -I./missing -c ./arpspoof.c
./arpspoof.c: In function âarp_sendâ:
./arpspoof.c:49: warning: passing argument 1 of âlibnet_get_hwaddrâ from incompatible pointer type
./arpspoof.c:49: error: too many arguments to function âlibnet_get_hwaddrâ
./arpspoof.c:60: warning: passing argument 6 of âlibnet_build_ethernetâ from incompatible pointer type
./arpspoof.c:60: error: too few arguments to function âlibnet_build_ethernetâ
./arpspoof.c:64: error: âETH_Hâ undeclared (first use in this function)
./arpspoof.c:64: error: (Each undeclared identifier is reported only once
./arpspoof.c:64: error: for each function it appears in.)
./arpspoof.c:64: error: too few arguments to function âlibnet_build_arpâ
./arpspoof.c: In function âmainâ:
./arpspoof.c:181: warning: assignment makes pointer from integer without a cast
make: ** [arpspoof.o] Erro 1

Alguem pode ajudar?
antecipadamente agradeço
angkor

[14] Comentário enviado por eliasricardo em 25/04/2008 - 13:12h

Pessoal, também estou tendo memos problema do angkor e mafioso.
gcc -g -O2 -D_BSD_SOURCE -D_BSD_SOURCE -D__BSD_SOURCE -D__FAVOR_BSD -DHAVE_NET_ETHERNET_H -DDSNIFF_LIBDIR=\"/usr/local/lib/\" -I. -I./missing -c ./arpspoof.c
./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

Procurei em vários lugares e ainda não achei a solução, se alguem puder dar uma força.

Obrigado
Elias Ricardo

[15] Comentário enviado por aldemar.moreira em 09/05/2008 - 17:15h

cc -g -O2 -D_BSD_SOURCE -D_BSD_SOURCE -D__BSD_SOURCE -D__FAVOR_BSD -DHAVE_NET_ETHERNET_H -DDSNIFF_LIBDIR=\"/usr/local/lib/\" -I. -I/usr/local/include -I/usr/local/ssl/include -I/usr/X11R6/include -I./missing -c ./arpspoof.c
./arpspoof.c: In function `arp_send':
./arpspoof.c:49: warning: passing arg 1 of `libnet_get_hwaddr' from incompatible pointer type
./arpspoof.c:49: error: too many arguments to function `libnet_get_hwaddr'
./arpspoof.c:60: warning: passing arg 6 of `libnet_build_ethernet' from incompatible pointer type
./arpspoof.c:60: error: too few arguments to function `libnet_build_ethernet'
./arpspoof.c:64: error: `ETH_H' undeclared (first use in this function)
./arpspoof.c:64: error: (Each undeclared identifier is reported only once
./arpspoof.c:64: error: for each function it appears in.)
./arpspoof.c:64: error: too few arguments to function `libnet_build_arp'
./arpspoof.c: In function `main':
./arpspoof.c:181: warning: assignment makes pointer from integer without a cast
make: *** [arpspoof.o] Error 1
alguem já resolveu isso????

[16] Comentário enviado por guilhermerezende em 14/07/2008 - 17:44h

Pessoal, estou com esse mesmo problema conforme os amigos também. Está dificil de resolver e na verdade achei que fosse problema de incompatibilidade de versão da libnet, mas tbm só consegui instalar a mesma de pacotes pré-compilados e não consegui compilar uma versão se quer da libnet. Ja instalei pacotes pré compilados da série 1.0 e 1.1 e com os dois o erro continua.
Alguém ja conseguiu solução p/ isso ?!?!
Abs..

cc -g -O2 -D_BSD_SOURCE -D_BSD_SOURCE -D__BSD_SOURCE -D__FAVOR_BSD -DHAVE_NET_ETHERNET_H -DDSNIFF_LIBDIR=\"/usr/local/lib/\" -I. -I/usr/local/include -I/usr/local/ssl/include -I/usr/X11R6/include -I./missing -c ./arpspoof.c
./arpspoof.c: In function `arp_send':
./arpspoof.c:49: warning: passing arg 1 of `libnet_get_hwaddr' from incompatible pointer type
./arpspoof.c:49: error: too many arguments to function `libnet_get_hwaddr'
./arpspoof.c:60: warning: passing arg 6 of `libnet_build_ethernet' from incompatible pointer type
./arpspoof.c:60: error: too few arguments to function `libnet_build_ethernet'
./arpspoof.c:64: error: `ETH_H' undeclared (first use in this function)
./arpspoof.c:64: error: (Each undeclared identifier is reported only once
./arpspoof.c:64: error: for each function it appears in.)
./arpspoof.c:64: error: too few arguments to function `libnet_build_arp'
./arpspoof.c: In function `main':
./arpspoof.c:181: warning: assignment makes pointer from integer without a cast
make: *** [arpspoof.o] Error 1

[17] Comentário enviado por eliasricardo em 30/10/2008 - 14:49h

Galera, resolvi o problema acima, porém estou com outro.

Removi a biblioteca libnet que estava na versão 1 e instalei a versao zero, libnet0, embora ela esteja absoleta, a compilação passou legal. Agora estou com erro em outra parte.

./sshcrypto.c:26: error: field âkeyâ has incomplete type
./sshcrypto.c:28: warning: useless storage class specifier in empty declaration
./sshcrypto.c:32: error: expected specifier-qualifier-list before âdes_key_scheduleâ
./sshcrypto.c:34: warning: useless storage class specifier in empty declaration
./sshcrypto.c: In function âblowfish_encryptâ:
./sshcrypto.c:133: error: âBF_ENCRYPTâ undeclared (first use in this function)
./sshcrypto.c:133: error: (Each undeclared identifier is reported only once
./sshcrypto.c:133: error: for each function it appears in.)
./sshcrypto.c: In function âblowfish_decryptâ:
./sshcrypto.c:145: error: âBF_DECRYPTâ undeclared (first use in this function)
./sshcrypto.c: In function âdes3_initâ:
./sshcrypto.c:158: error: âstruct des3_stateâ has no member named âk1â
./sshcrypto.c:159: error: âstruct des3_stateâ has no member named âk2â
./sshcrypto.c:162: error: âstruct des3_stateâ has no member named âk3â
./sshcrypto.c:164: error: âstruct des3_stateâ has no member named âk3â
./sshcrypto.c:166: error: âstruct des3_stateâ has no member named âiv1â
./sshcrypto.c:167: error: âstruct des3_stateâ has no member named âiv2â
./sshcrypto.c:168: error: âstruct des3_stateâ has no member named âiv3â
./sshcrypto.c: In function âdes3_encryptâ:
./sshcrypto.c:178: error: âstruct des3_stateâ has no member named âiv1â
./sshcrypto.c:178: error: âstruct des3_stateâ has no member named âiv2â
./sshcrypto.c:180: error: âstruct des3_stateâ has no member named âk1â
./sshcrypto.c:180: error: âstruct des3_stateâ has no member named âiv1â
./sshcrypto.c:180: error: âDES_ENCRYPTâ undeclared (first use in this function)
./sshcrypto.c:181: error: âstruct des3_stateâ has no member named âk2â
./sshcrypto.c:181: error: âstruct des3_stateâ has no member named âiv2â
./sshcrypto.c:181: error: âDES_DECRYPTâ undeclared (first use in this function)
./sshcrypto.c:182: error: âstruct des3_stateâ has no member named âk3â
./sshcrypto.c:182: error: âstruct des3_stateâ has no member named âiv3â
./sshcrypto.c: In function âdes3_decryptâ:
./sshcrypto.c:191: error: âstruct des3_stateâ has no member named âiv1â
./sshcrypto.c:191: error: âstruct des3_stateâ has no member named âiv2â
./sshcrypto.c:193: error: âstruct des3_stateâ has no member named âk3â
./sshcrypto.c:193: error: âstruct des3_stateâ has no member named âiv3â
./sshcrypto.c:193: error: âDES_DECRYPTâ undeclared (first use in this function)
./sshcrypto.c:194: error: âstruct des3_stateâ has no member named âk2â
./sshcrypto.c:194: error: âstruct des3_stateâ has no member named âiv2â
./sshcrypto.c:194: error: âDES_ENCRYPTâ undeclared (first use in this function)
./sshcrypto.c:195: error: âstruct des3_stateâ has no member named âk1â
./sshcrypto.c:195: error: âstruct des3_stateâ has no member named âiv1â
make: *** [sshcrypto.o] Error 1


Sei que trata-se de erro na declaração da variável dentro da estrutura, mais estou meio garrado, alguem poderia dar uma força?

[18] Comentário enviado por adsonrenato em 10/04/2010 - 18:51h

muito bom mesmo ;D


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts