########################################################################## ######################## CLUBE DOS MERCENARIOS ########################### ########################################################################## *** FAVOR MANTER PRIVATE *** Desenvolvido por Nash Leon vulgo coracaodeleao. nashleon@yahoo.com.br. Estes e outros textos podem ser obtidos em: http://XXXXXXX/ ou http://coracaodeleao.virtualave.net/ OBS: O autor nao se responsabiliza pelo mau uso dos dados e exemplos disponibilizados neste texto.Script kiddies(defacers), crackers e Analistas de Seguranca sem escrupulos nao devem ler este texto! ************************ * Introducao a LibNIDS * ************************ 1 - Introducao 2 - Manuseando LibNIDS 3 - Exemplos 3.1 - Sniffer Anti-Overflows 3.2 - Sniffer Anti-Obtencao de Shell 3.3 - Sniffer Anti-Format Bugs e Paranoia 3.4 - Sniffer Detect-Portscan 4 - Terminando 4.1 - Links e Referencias 4.2 - Consideracoes Finais --------------- 1 - Introducao | --------------- Vivemos em uma conjuntura de grande inseguranca. Para onde se olha, pode-se ver um furo, um problema de seguranca, uma condicao de invasao. Um Administrador de Rede ou ateh mesmo uma Equipe de Seguranca precisa estar estar armada ateh o pescoco para dificultar a acao de hackers/crackers com conhecimentos tecnicos avancados. Atualmente, um dos meios mais utilizados para dificultar a acao de invasores sao as NIDS(Network Intrusion Detection System). Essas ferramentas tem se popularizado como uma opcao de baixo custo e facil manuseio para empresas que desejam ter um empecilho a mais contra os ataques oriundos de redes externas/internas. No entanto, neste documento pretendo aborda a escrita de ferramentas de seguranca estilo NIDS utilizando uma biblioteca de alto nivel conhecida como LibNIDS. Conhecimentos basicos de C, Sniffers(Redes TCP/IP) e ambiente Linux se fazem necessarios. Todos os exemplos e dados disponibilizados nao devem ser utilizados em ambientes de producao, pois foram criados apenas para propositos educacionais. Este documento nao eh voltado para a Comunidade de Seguranca, mas eh apenas parte de um documento maior que descreve a quebra dos conceitos de NIDS, ou seja, este documento eh para hackers/fucadores. ----------------------- 2 - Manuseando LibNIDS | ----------------------- Antes de iniciarmos a escrita dos sniffers NIDS, precisamos instalar as bibliotecas necessarias. Em ambiente Linux, devemos baixar os seguintes pacotes: libnids-1.16.tar.gz libnet.tar.gz libpcap-0.7.2.tar.gz Instale-os no seu sistema. A LibNIDS eh uma ferramenta capaz de nos fornecer meios de criarmos sniffers capazes de gerar seguranca. A libNIDS interage com a libPcap e nos fornece uma API de altissimo nivel capaz de nos prover mecanismos simples de IDS(Sistemas de Deteccao de Intrusos). Criada por Rafal Wojtczuk (conhecidissimo por seus artigos sobre Return Into Libc/PLT), esta biblioteca consegue barrar uma variedade de ataques e no decorrer deste artigo, iremos ver apenas alguns que sao muito utilizados hoje em dia. Abaixo podemos ver algumas das funcoes da API: ----------------------------------------------------------------------- | Nome da Funcao | Objetivo | ----------------------------------------------------------------------- | nids_init() | Inicializa a aplicacao do sniffer | | | com base em valores setado na | | | variavel global "nids_param" | ----------------------------------------------------------------------- | nids_register_tcp() | Registra uma funcao callback | | | definida pelo usuario para | | | processar os pacotes TCP recebidos | ----------------------------------------------------------------------- | nids_killtcp() | Derruba a conexao especificada com | | | pacotes RST simetricos entre o | | | cliente e o servidor | ----------------------------------------------------------------------- Essas funcoes serao as utilizadas no decorrer deste artigo. Para um aprofundamento maior, veja a man page e os exemplos fornecidos juntos com a LibNIDS. Precisamos ressaltar que a variavel global "nids_param" utilizada pela funcao nids_init() eh declarada do seguinte modo: struct nids_prm { int n_tcp_streams; int n_hosts; char *device; int sk_buff_size; int dev_addon; void (*syslog)(int type, int err, struct ip *iph, void *data); int syslog_level; int scan_num_hosts; int scan_num_ports; int scan_delay; void (*no_mem)(void); int (*ip_filter)(struct ip *iph); char *pcap_filter; int promisc; int one_loop_less; } nids_params; Destacamos as seguintes variaveis: + device -> Nome da interface que executarah o sniffer(Exemplo: eth1); + scan_num_hosts -> Tamanho da tabela de Hash usada para armazenar informacoes de portscan, ou seja, o numero maximo de portscan que serao detectados simultaneamente. Se for setado para 0, a deteccao de portscan serah desabilitada. Valor padrao eh 256. + scan_num_ports -> Numero minimo de portas que devem ser scaneada pelo mesmo host origem antes de ser identificado como um ataque de portscan. O valor padrao eh 10. + scan_delay -> Delay(Tempo de espera) maximo, em milisegundos, entre conexoes para portas diferentes, que identifica como sendo um ataque de portscan. Valor padrao eh 300. + ip_filter -> Funcao callback para filtragem de IP que eh usada para descartar pacotes IP previamente selecionados. Essas serao as variaveis mais utilizadas nos nossos exemplos. Existem ainda varias que sao uteis de acordo a necessidade do Analista de Seguranca. Precisamos ainda dar uma olhada na estrutura tcp_stream que eh manuseada pela funcao callback "nids_register_tcp()". Vejamos: struct tcp_stream { struct tuple4 { u_short source; u_short dest; u_int saddr; u_int daddr; } addr; char nids_state; struct half_stream { char state; char collect; char collect_urg; char *data; u_char urgdata; int count; int offset; int count_new; char count_new_urg; ... } client; struct half_stream server; ... }; Quando utilizarmos a funcao callback nos nossos detectores, usaremos essas duas estruturas(tcp_stream e half_stream) e atraves dela, iremos manipular a conexao, lendo os pacotes, capturando informacoes dos cabecalhos e etc. A estrutura "tupple4" nao tem muito segredo. Ela identica uma conexao TCP: saddr -> Endereco IP de origem(cliente); daddr -> Endereco IP de destino(servidor); source -> Numero da porta origem(cliente); dest -> Numero da porta destino(servidor). A estrutura "half_stream" eh utilizada para cada parte da conexao(seja ela cliente ou servidora) e as seguintes variaveis nos serao mais uteis: + state -> Indica o estado da conexao(Exemplo TCP_ESTABLISHED); + collect -> Uma variavel booleana que indica se deseja selecionar dados de uma parte da conexao(cliente ou servidor) para o buffer "data"; + data -> Buffer que conterah os dados dos pacotes; E por fim, temos a variavel "nids_state" que nos fornece informacoes sobre o estado da conexao TCP que deve ser usada pela nossa funcao de callback. Seus valores podem ser: NIDS_JUST_EST -> Conexao Somente Estabelecida. NIDS_DATA -> Novos dados tem chegado numa conexao; NIDS_CLOSE -> Fecha uma conexao; NIDS_RESET -> Reseta ou Zera uma conexao; Com base nessas informacoes, estamos aptos a criarmos nossos primeiros sniffers NIDS capazes de detectar e bloquear alguns tipos de ataques. ------------- 3 - Exemplos | ------------- Uma IDS capaz de escutar atraves de uma interface se torna uma poderosa ferramenta, onde a capacidade tecnica do Analista de Seguranca tende a ser testada contra a capacidade tecnica de hackers e crackers. Veremos nesta secao alguns exemplos de ferramentas criadas usando libnids e libpcap capazes de detectar e barrar alguns tipos de ataques remotos bastante usados por atacantes na atualidade. 3.1 - Sniffer Anti-Overflows ------------------------------ Um exemplo de Sniffer Anti-Overflows eh a propria implementacao de uma ferramenta da Antiga Kimera, conhecida como K-SAO(Kimera - Sniffer Anti-Overflow).O codigo disponibilizado serve como prova de um conceito, onde atraves do uso da libnids eh possivel nao apenas detectarmos uma tentativa de buffer overflows remota, mas tambem neutralizarmos a mesma, com a derrubada da conexao ativa. O codigo fonte segue especificado abaixo: ----------------------------- k-sao.v05.c ------------------------------- /* Kimera - Sniffer Anti-Overflow. BETA TEST * http://www.kimera.com.br/ * Glaudson Ocampos. * Ultima Atualizacao - 13.09.2001. * Compile com: * # gcc -o ksao ksao.c -Wall -lnids `libnet-config --defines` * `libnet-config --libs` -lpcap -DNOFORK */ #include #include #include #include #include #include #include #include #include #include #include #include "regras.h" #define VERSAO "v0.5" #define ERRO -1 #define int_ntoa(x) inet_ntoa(*((struct in_addr *)&x)) unsigned int porta; char *string; unsigned int tamanho; /* Funcao receptora dos dados: * Porta para Escuta; * String para espera; * Tamanho maximo de buffer + string; */ int recebe(char *str, unsigned int p, unsigned int tam){ porta = p; string = str; tamanho = tam; return 0; } /* Funcao que serah chamada pela LIBNIDS e irah detectar tentativa de * overflow. */ void detecta_over(struct tcp_stream *a_tcp, struct half_stream *hlf){ int i; /* Se a conexao eh estabelecida Capturamos o que eh enviado para o * servidor */ if (a_tcp->nids_state == NIDS_JUST_EST){ a_tcp->server.collect++; return; } i = 0; /* Datas recebidas, hlf irah conter buffers de dados */ if (a_tcp->nids_state == NIDS_DATA) { while(1){ hlf = &a_tcp->server; recebe(comando[i],porta_def[i],tam_def[i]); if(!strcmp(comando[i],"FIM")){ return; } if(strstr(hlf->data,string) != NULL && (a_tcp->addr.dest == porta)){ /* Se o tamanho dos dados for maior que TAM gera o log e derruba o * processo. * OBS: Checar tamanho preciso subtraindo offset e checar anomalias de * daemons. */ if (strlen(hlf->data) > tamanho) { syslog(1,"\nTentativa de Exploitacao de: %s\n\n", int_ntoa(a_tcp->addr.saddr),80); /* Caso queira informacoes interativas sobre o ataque */ #ifdef NOFORK printf("\nTentativa de Exploitacao Registrada!\n"); printf("Porta: %d | string %s\n",a_tcp->addr.dest,string); printf("Endereco do atacante: %s\n\n",int_ntoa(a_tcp->addr.saddr)); #endif bzero(hlf->data,strlen(hlf->data)); nids_killtcp (a_tcp); return; } } i++; } // fim do while /* Zera a Estrutura de Recebimento de Dados evitando assim * falso positivos. */ bzero(hlf->data,strlen(hlf->data)); } return; } int main (int argc, char * argv[]){ if(argc < 2){ printf("K-SAO - Kimera - Sniffer Anti-Overflow %s\n\n",VERSAO); printf("Uso: %s [interface]\n\n",argv[0]); exit(0); } nids_params.device = argv[1]; /* inicializamos a Libnids para sniffar a interface */ if (!nids_init ()){ fprintf(stderr,"%s\n",nids_errbuf); exit(ERRO); } /* Setamos a funcao callback para processar TCP streams. * OBS: Conexoes UDP, IP Fragmentada usa-se outra funcao. */ nids_register_tcp(detecta_over); /* Executamos a ferramenta */ printf("Executando o Kimera Sniffer Anti-Overflow...\n\n"); nids_run (); return 0; } ---------------------------------------------------------------------- O header "regras.h" pode ser personalizado de acordo com a necessidade do sistema a ser protegido pelo Analista de Seguranca: ---------------------------- regras.h -------------------------------- /* Exemplo de Header de Regras * Caso deseja algo personalizado e eficaz * para o seu sistema.Consulte a Kimera. * falecom@kimera.com.br * http://www.kimera.com.br/ */ /* A ferramenta captura as arrays em ordem crescente e * as associa entre si.Por exemplo, servico da porta_def[1] vai ter como * tamanho maximo tam-def[1] para o comando comando[1]. */ /* A Ferramenta eh Case Sensitive, logo, necessita de regras diferenciadas * USER eh diferente de User, UsEr, USer, e etc. */ unsigned short porta_def[] = {21, 21, 21, 21, 110, 110, 110, 0}; char *comando[9] = {"USER","user", "PASS","pass","USER","user","PASS","FIM"}; unsigned short tam_def[] = { 20, 20, 20, 20, 20, 20, 20, 0}; ------------------------------------------------------------------- O exemplo acima eh apenas para demonstrar o conceito. A libnids eh bastante poderosa e pode ser usada em grande escala para dificultar inumeras tecnicas de exploitacao remota. Vejamos este exemplo executando num servidor Proftpd: *** Em um TTY(1): root@kimera:/crawling/projetos/k-sao-v05# ./k-sao lo Executando o Kimera Sniffer Anti-Overflow... *** Em outro TTY(2): root@kimera:~# telnet localhost 21 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 220 ProFTPD 1.2.5 Server (ProFTPD Default Installation) [kimera.localdomain] USER AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Connection closed by foreign host. *** Voltando ao primeiro TTY(1): Tentativa de Exploitacao Registrada! Porta: 21 | string USER Endereco do atacante: 127.0.0.1 Como vimos, podemos dificultar as coisas para um atacante. Geralmente um login de FTP nao ultrapassa 30 caracteres. De modo que, num ataque de buffer overflow, um shellcode deveria ter o minimo possivel de opcodes, dificultando consideravelmente a exploitacao. 3.2 - Sniffer Anti-Obtencao de Shell -------------------------------------- Se podemos derrubar uma conexao ativa, quando sofremos um ataque do tipo "Buffer Overflow", podemos ir mais longe. O exemplo disponibilizado nesta parte eh apenas conceitual e se encontra em fase de testes, de modo que nao recomendo o seu uso em ambientes de producao. Utilizando um "Wrapper" de shell, estaremos aptos a bloquear um ataque remoto, ateh mesmo um ataque utilizando Backdoor, TCP Tuneis, Race Conditions, Input Validations e ataques BindShell, alem de ataques de Buffer Overflows. Colocando uma string nos arquivos "Wrappers" de binarios essenciais, como /bin/sh, podemos capturar uma tentativa de execucao "externa" destes binarios e bloquear a sua acao. Isto nao protege os sistemas totalmente, mas impediria, por exemplo, grande parte dos ataques utilizando exploits publicos(como eh o caso dos ataques vindo de script kiddies, na atualidade). O esquema eh interessante tambem contra shellcodes polimorficos que visam programas especificos(/bin/sh) mas conseguem passar por muitos IDS pois se encontram encriptados. O codigo exemplo do conceito criado pela Kimera utilizando LibNIDS segue descrito abaixo: ----------------------------- k-sae.c -------------------------------- /* Kimera - Sniffer Anti-Exec. * http://www.kimera.com.br/ * * Criado em 30.09.2001. * Ultima Atualizacao - 25.01.2002. * Compile com: * # gcc -o k-sae k-sae.c -Wall -lnids `libnet-config --defines` * `libnet-config --libs` -lpcap -DNOFORK * * * Diferente das Ferramentas de IDS que checam por assinaturas * vindo de fora, o K-SAE checa se os dados de uma shell wrapper * estao sendo enviadas para fora e barra a execucao da mesma. * */ #include #include #include #include #include #include #include #include #include #include #include #include "regras.h" #define VERSAO "v0.2" #define ERRO -1 #define STRING_SW "Hacking" // String que a shell enviarah #define int_ntoa(x) inet_ntoa(*((struct in_addr *)&x)) unsigned int porta; char *string; /* Funcao receptora dos dados: * Porta para Escuta; // Note que a porta pode ser desnecessaria(nao web) * // No entanto, este codigo eh apenas para abrir * // mentes!:) * String para espera; */ int recebe(char *str, unsigned int p){ porta = p; string = str; return 0; } /* Funcao que serah chamada pela LIBNIDS e irah detectar tentativa de * invasao. */ void detecta_ataque(struct tcp_stream *a_tcp, struct half_stream *hlf){ int i; /* Se a conexao eh estabelecida Capturamos o que eh enviado do * servidor */ if (a_tcp->nids_state == NIDS_JUST_EST){ a_tcp->client.collect++; return; } /* Datas recebidas, hlf irah conter buffers de dados */ if (a_tcp->nids_state == NIDS_DATA) { hlf = &a_tcp->client; i = 0; while(1){ /* Abaixo nos passamos a filtragem de dados definidos na shell Wrapper */ recebe(STRING_SW, porta_def[i]); if(porta == 0){ return; } if(strstr(hlf->data,string) != NULL && (a_tcp->addr.dest == porta)){ syslog(1,"\nTentativa de Exploitacao de: %s\n\n",int_ntoa(a_tcp->addr.saddr)); /* Caso queira informacoes interativas sobre o ataque */ #ifdef NOFORK printf("\nTentativa de Exploitacao Registrada!\n"); printf("Porta: %d | string %s\n",a_tcp->addr.dest,string); printf("Endereco do atacante: %s\n\n",int_ntoa(a_tcp->addr.saddr)); #endif nids_killtcp(a_tcp); return; } i++; } bzero(hlf->data,strlen(hlf->data)); } return; } int main (int argc, char * argv[]){ if(argc < 2){ printf("K-SAE - Kimera - Sniffer Anti-Exec %s\n\n",VERSAO); printf("Uso: %s [interface]\n\n",argv[0]); exit(0); } nids_params.device = argv[1]; /* inicializamos a Libnids para sniffar a interface */ if (!nids_init ()){ fprintf(stderr,"%s\n",nids_errbuf); exit(ERRO); } /* Setamos a funcao callback para processar TCP streams. * OBS: Conexoes UDP e IP Fragmentada usa-se outra funcao. */ nids_register_tcp(detecta_ataque); /* Executamos a ferramenta */ printf("Executando o Kimera Sniffer Anti-Exec...\n\n"); nids_run (); return 0; } ----------------------------------------------------------------------- Abaixo temos um simples arquivo de regras para compilacao. ----------------------------- regras.h --------------------------------- /* Exemplo de um Arquivo de Regras * para o programa K-SAE. * Glaudson Ocampos. * glaudson@kimera.com.br */ /* Definimos apenas as portas que nao devem * executar shell. */ unsigned short porta_def[] = {21, 110, 31337, 30464, // Taeh Oh port bindshell 0}; ------------------------------------------------------------------------ Como podemos notar. A LibNIDS fornece-nos uma poderosa interface capaz de facilitar grandemente a construcao de Sistemas de Deteccao de Intrusos. Se fossemos criar um programa semelhante a este utilizando apenas os recursos do C padrao e as chamadas de sistemas do Sistema Operacional teriamos um trabalho grande. Para um funcionamento correto do programa acima, necessita-se de um Wrapper para o binario a ser defendido. Um exemplo de um Wrapper para /bin/sh em sistemas Linux pode ser visto abaixo: ------------------------------ sh.c --------------------------------- /* Exemplo de Wrapper de Shell para ser * usado em conjunto com Kimera Sniffer * Anti-Exec. * Glaudson - 30.09.2001. * * PS: Leia o Item "Problemas e Sugestoes". * Este eh apenas um exemplo para Provar o Conceito. */ #include #include #include #include #define SHELL "/bin/bash" int main(int argc, char *argv[]){ int i; char argumentos[1024]; char arg_temp[1024]; char comando[1024]; fprintf(stdout,"Hacking\n"); fflush(stdout); if(argc > 1){ bzero(argumentos,1024); for(i = 1; i < argc; i++){ snprintf(arg_temp,1024," %s",argv[i]); strncat(argumentos,arg_temp,sizeof(argumentos) - strlen(arg_temp) -2); } snprintf(comando,1024,"%s -c %s",SHELL,argumentos); system(comando); } else execl("/bin/bash","bash",0); return 0; } --------------------------------------------------------------------- Novamente nao recomendo o uso deste programa em ambientes que nao seja um ambiente de testes, e que sempre faca um backup antes da utilizacao. Bom, os testes aqui tem demonstrado que a ferramenta eh eficiente em barrar inumeros tipos de ataques. Os exploits que manuseiam select() e executam a shell pela propria porta do daemon alvo sao facilmente barrados(teste voce mesmo, e verah). Utilizando como exemplo, o daemon e o exploit fornecidos no meu Artigo I de Format Bugs(voce pode testar com qualquer daemon e/ou exploit que executa uma shell), teriamos: *** Em um TTY(1): root@kimera:/crawling/projetos/k-sae# rm /bin/sh root@kimera:/crawling/projetos/k-sae# ln -s /bin/sh_wrapper /bin/sh root@kimera:/crawling/projetos/k-sae# ./k-sae lo Executando o Kimera Sniffer Anti-Exec... *** Em outro TTY(2) abriremos o daemon vulneravel: root@kimera:/crawling/testes/fs# ./daemon 5000 *** Em outro TTY(3) exploitaremos o sistema localmente e depois executaremos netstat: nashleon@kimera:/crawling/testes/fs$ ./mexremot localhost Exemplo de exploit remoto Format Bug by NL Tentando Exploitar localhost... Usando return address 0xbffff4a4. Usando Format String %016x. Connecting... OK Tamanho: 509 Enviando exploit... OK Cheque se exploitou(telnet alvo 30464)!! nashleon@kimera:/crawling/testes/fs$ netstat -na Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:30464 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:5000 0.0.0.0:* LISTEN Active UNIX domain sockets (servers and established) Proto RefCnt Flags Type State I-Node Path unix 3 [ ] DGRAM 48 /dev/log unix 2 [ ACC ] STREAM LISTENING 54 /dev/gpmctl unix 2 [ ] DGRAM 51 O exploit obteve acesso ao sistema, o bug foi exploitado com sucesso! Mas agora nosso Sniffer(NIDS) entra em acao: *** No TTY(3) o atacante tenta se conectar na shell aberta: nashleon@kimera:/crawling/testes/fs$ telnet localhost 30464 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Hacking Connection closed by foreign host. *** No TTY(1) nossa ferramenta gera o alarme: Tentativa de Exploitacao Registrada! Porta: 30464 | string Hacking Endereco do atacante: 127.0.0.1 Como podemos ver, a ferramenta eh realmente efetiva e nos meus testes conseguiu ser bem sucedida em inumeros ataques. A grande maioria dos exploits utilizados por script kiddies usam /bin/sh como shellcode. Com base neste conceito, podemos ser bem sucedidos em barrar de forma efetiva acessos indesejados tambem por bindshell via outros esquemas como FTP+PHP, SSI, .procmail e qualquer bindshell que execute /bin/sh (sabemos que eh massificada na Internet, especial Perl CGI). Se nossa criatividade puder ir mais longe e se pudermos derrubar os empecilhos, estaremos aptos e dificultar cada vez mais os inumeros tipos de exploitacao existentes. Existem formas de se passar por esta ferramenta, em quero deixar bem frisado, FORMAS, para que todos saibam que nao eh apenas um meio que eu conheco de burlar isso, mas varios! E se eu sei, um atacante com maiores conhecimentos tecnicos que eu, saberah com certeza! E como eu disse lah no comeco, este nao eh um documento para Analistas de Seguranca.:) 3.3 - Sniffer Contra Format Bugs e Paranoia --------------------------------------------- Se podemos sniffar uma conexao e escutarmos literalmente tudo que estah transitando nela, entao estaremos aptos a bloquear inumeros tipos de ataques. Um ataque de Format Bug, tende a enviar determinadas strings para poder ser bem sucedido(%n, %x, %h). O manuseio destas strings podem variar, mas o conceito eh parecido e pode ser expandido de acordo com as necessidades do Analistas de Seguranca. Vejamos um exemplo de Sniffer contra Format String Exploit. ----> K-safb.c /* Kimera Sniffer Anti- Format Bug. * Codigo apenas para ilustrar uso * da LibNIDS - Documento Sobre Sniffers. * * Glaudson Ocampos. * glaudson@kimera.com.br * http://www.kimera.com.br/ */ /* * Compile com: * # gcc -o k-safb ksafb.c -Wall -lnids `libnet-config --defines` * `libnet-config --libs` -lpcap -DNOFORK */ #include #include #include #include #include #include #include #include #include #include #include #define VERSAO "v0.1a" #define ERRO -1 #define STRING "%n" // Exemplo de String para Format Bug //#define STRING "sh" // Exemplo de String para sh #define int_ntoa(x) inet_ntoa(*((struct in_addr *)&x)) /* Funcao que serah chamada pela LIBNIDS e irah detectar tentativa de * Format Bug. */ void detecta_fb(struct tcp_stream *a_tcp, struct half_stream *hlf){ /* Se a conexao eh estabelecida Capturamos o que eh enviado para o * servidor */ if (a_tcp->nids_state == NIDS_JUST_EST){ a_tcp->server.collect++; return; } /* Datas recebidas, hlf irah conter buffers de dados */ if (a_tcp->nids_state == NIDS_DATA) { hlf = &a_tcp->server; /* Se contem STRING, derruba conexao */ if(strstr(hlf->data,STRING)){ syslog(1,"\nTentativa de Exploitacao de: %s\n\n",int_ntoa(a_tcp->addr.saddr)); /* Caso queira informacoes interativas sobre o ataque */ #ifdef NOFORK printf("\nTentativa de Exploitacao Registrada!\n"); printf("Porta: %d | string %s\n",a_tcp->addr.dest,STRING); printf("Endereco do atacante: %s\n\n",int_ntoa(a_tcp->addr.saddr)); #endif bzero(hlf->data,strlen(hlf->data)); nids_killtcp (a_tcp); return; } /* Zera a Estrutura de Recebimento de Dados evitando assim * falso positivos. */ bzero(hlf->data,strlen(hlf->data)); } return; } int main (int argc, char * argv[]){ if(argc < 2){ printf("K-SAFB - Kimera - Sniffer Anti-Format Bug %s\n\n",VERSAO); printf("Uso: %s [interface]\n\n",argv[0]); exit(0); } nids_params.device = argv[1]; /* inicializamos a Libnids para sniffar a interface */ if (!nids_init ()){ fprintf(stderr,"%s\n",nids_errbuf); exit(ERRO); } /* Setamos a funcao callback para processar TCP streams. * OBS: Conexoes UDP, Fragmentada usa-se outra funcao. */ nids_register_tcp(detecta_fb); /* Executamos a ferramenta */ printf("Executando o Kimera Sniffer Anti-Format Bug...\n\n"); nids_run (); return 0; } <---- Fim do K-SAFB O programa acima detecta qualquer tentativa de envio da string "%n" para o servidor. Isto nao eh interessante e nem aconselhavel. O ideal seria um bom sistema de regras e capturas, onde, por exemplo, o caracter %n soh poderia ser enviado para um Servidor WEB. No exemplo, vimos a string definida como "%n", mas poderiamos colocar qualquer string, inclusive manusear com um arquivo de regras, onde poderias ter incluido nesse arquivos de regras, strings como "sh", ou mesmo NOPs(0x90), Jump(0xeb) e etc. A paranoia do Analista de Seguranca eh que definiria a elevacao da seguranca. Poderiamos logar desde ataques a Script CGIs, ateh mesmo ataques anomalos em portas e circunstancias pre-definidas. Novamente, ficaremos limitados apenas a nossa criatividade. 3.4 - Sniffer Detect-Portscan ---------------------------- Construir um sniffer capaz de detectar um portscan eh mais facil ainda. Como vimos no inicio deste artigo, existem variaveis em "nids.params" que nos dao poder de utilizar o proprio recurso detector de scan da LibNIDS, definido no source code scan.c. Abaixo nos temos um exemplo: ------------------------------- lsc.c --------------------------------- /* Sniffer Detect-Portscan tcp_connect() usando LibNIDS. * Desenvolvido por Nash Leon. * nashleon@yahoo.com.br * * Compile com: gcc -o lsc lsc.c -Wall -lnids `libnet-config --defines` * `libnet-config --libs` -lpcap -DNOFORK */ #include #include #include #include #include #include #include #include #include #include #include #define VERSAO "v0.1a" #define ERRO -1 #define int_ntoa(x) inet_ntoa(*((struct in_addr *)&x)) void detecta_scan(struct tcp_stream *a_tcp, struct half_stream *hlf){ /* Se o valor de scan_num_hosts for maior que 1, entao foi detectado * um portscan, ver syslog. */ if(nids_params.scan_num_hosts > 1){ #ifdef NOFORK printf("\n*** PortScan Detectado!\n"); printf("*** Endereco do atacante: %s\n\n",int_ntoa(a_tcp->addr.saddr)); #endif } return; } int main (int argc, char * argv[]){ if(argc < 2){ printf("NL - LibNIDS Sniffer Detect-Portcan %s\n\n",VERSAO); printf("Uso: %s \n\n",argv[0]); exit(0); } nids_params.device = argv[1]; if (!nids_init ()){ fprintf(stderr,"%s\n",nids_errbuf); exit(ERRO); } printf("Executando o NL - LibNIDS Sniffer Detect-Portcan....\n"); nids_register_tcp(detecta_scan); nids_run (); return 0; } ------------------------------------------------------------------------ A execucao eh bem trivial tambem: --- Em um TTY(1): root@kimera:/crawling/testes/sniff# ./lsc lo Executando o NL - LibNIDS Sniffer Detect-Portcan.... --- Em outro TTY(2): root@kimera:~# nmap 127.0.0.1 Starting nmap V. 2.54BETA34 ( www.insecure.org/nmap/ ) Interesting ports on localhost (127.0.0.1): (The 1555 ports scanned but not shown below are in state: closed) Port State Service 21/tcp open ftp Nmap run completed -- 1 IP address (1 host up) scanned in 1 second --- De volta ao TTY do Sniffer(1): *** PortScan Detectado! *** Endereco do atacante: 127.0.0.1 Lembrando que ele detecta apenas a tecnica tcp_connect() de portscan. --------------- 4 - Terminando | --------------- O basico sobre escrita de ferramentas NIDS utilizando alto-nivel estah aih. O entendimento dos conceitos eh mais importante que a programacao em si. Sabemos que ha inumeras ferramentas NIDS "completas" como Snort, Tamandua, que realmente executam tarefas bem mais abrangentes. No entanto, conhecendo os conceitos que estao por tras, somos capazes de "passar" por elas e deste modo demonstrar que a quebra da seguranca de ambientes protegidos por sistemas NIDS nao soh eh possivel como jah eh uma realidade. Se deseja saber mais sobre a quebra dos conceitos, entre em contato com o Clube dos Mercenarios. 4.1 - Links e Referencias -------------------------- "LibNIDS Man pages e Source Code" - http://www.packetfactory.net/ + Ferramentas NIDS: Snort - http://www.snort.org/ Tamandua- http://www.axur.org/ + Mail Lists: http://www.yahoogroups.com/group/clube_dos_mercenarios http://www.yahoogroups.com/group/frontthescene http://www.yahoogroups.com/group/virii_hacking + Outros Sites Interessantes: http://XXXXXX -> Clube dos Mercenarios http://www.microfobia.com/ http://www.infoshack.cjb.net/ http://int0x80.host.sk/ http://unsekurity.virtualave.net/ http://www.linuxsecurity.com.br/ http://www.txt.org/ 4.2 - Consideracoes Finais --------------------------- O conhecimento eh como uma perola escondida. Deve-se cavar, ir fundo, batalhar para obte-lo. Mas isso por sih soh nao eh util. De nada adianta, obter conhecimento se nao for para usa-lo de forma sabia, construtiva e benefica. Neste artigo eu frisei conceitos de seguranca que servirao para serem quebrados. Somente a elevacao da concientizacao e a troca de experiencia e conhecimentos pode tornar os sistemas menos inseguros. Para um fucador de verdade, uma ferramenta NIDS nao representa nenhum empecilho. Isso se aplica tambem a um firewall e qualquer sistema de protecao. Utilizar os conhecimentos de forma benefica nao eh lucrar com a desgraca alheia. Eh lamentavel ver que muitos que outrora estiveram compartilhando informacoes hoje possuem uma visao completamente diferente, chegando ateh mesmo a fazer coisas terriveis e inimaginaveis.Mas, cada cabeca eh um mundo e cada um sabe "aonde o calo aperta". Gostaria de agradecer a Jeovah Deus por tudo. Aos membros e colaboradores do Clube dos Mercenarios. Ao pessoal do #mecenaries, #alrg, #virii, e a todos que tem utilizados seus conhecimentos para elevar a concientizacao dos aspectos de seguranca. Um Abraco, Nash Leon. -------------------------------- EOF -------------------------------------