понедельник, 19 марта 2012 г.

libpcap hello

Надо граббить ip,tcp и http хэдеры для последующего анализа. Пока вот для теста наваял этакий хелловорлд:

#include <pcap/pcap.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>

int main() {

        char* device;                    // Sniffing device
        char errbuf[PCAP_ERRBUF_SIZE];   // Error message buffer
        pcap_t* handle;                  // Session handle
        struct bpf_program fp;           // The compiled filter expression
        char filter_exp[] = "port 80";   // The filter expression
        bpf_u_int32 mask;                // The netmask of our sniffing device
        bpf_u_int32 net;                 // The IP of our sniffing device
        struct pcap_pkthdr header;       // The header that pcap gives us
        const u_char* packet;            // The actual packet
        struct iphdr* ipheader = NULL;   // Pointer to the IP header
        struct tcphdr* tcpheader = NULL; // Pointer to the TCP header
        device = NULL;
        memset(errbuf, 0, PCAP_ERRBUF_SIZE);
        int count;

        device = pcap_lookupdev(errbuf);
        printf("Device: %s\n", device);
        printf("filter: %s\n", filter_exp);
        if (pcap_lookupnet(device, &net, &mask, errbuf) == -1) {
                fprintf(stderr, "Can't get netmask for device %s\n", device);
                net = 0;
                mask = 0;
        }

        handle = pcap_open_live(device, 2048, 0, 512, errbuf);

        if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
                fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
                exit(1);
        }

        if (pcap_setfilter(handle, &fp) == -1) {
                fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
                exit(1);
        }
        count = 100;
        while (count) {
                // Try to get packet. If capture fail - try next.
                if ( (packet = pcap_next(handle, &header)) == NULL) {
                        fprintf(stderr, "ERROR: Error getting the packet\n", errbuf);
                        continue;
                } else
                        fprintf(stderr, "Packet captured\n");

                // Extract IP header
                ipheader = (struct iphdr *)(packet + 14);
                printf("IP header lengh:  %d\n", ipheader->ihl);
                printf("Source IP:        %s\n", inet_ntoa( *(struct in_addr *) &ipheader->saddr));
                printf("Destination IP:   %s\n", inet_ntoa( *(struct in_addr *) &ipheader->daddr));
                // Extract TCP header
                tcpheader = (struct tcphdr *)(packet + 14 + ipheader->ihl * 4);
                printf("Source port:      %d\n", ntohs(tcpheader->source));
                printf("Destination port: %d\n", ntohs(tcpheader->dest));
                printf("Flags:            ");
                if (tcpheader->syn)
                        printf("SYN ");
                if (tcpheader->ack)
                        printf("ACK ");
                if (tcpheader->fin)
                        printf("FYN ");
                printf("\n");
                printf("\n");

        }
        pcap_close(handle);
        return 0;
}

Вывод такой (запрос простой html странички):
# ./pcap
Device: wlan0
filter: port 80
ERROR: Error getting the packet
ERROR: Error getting the packet
ERROR: Error getting the packet
ERROR: Error getting the packet
ERROR: Error getting the packet
Packet captured
IP header lengh:  5
Source IP:        192.168.10.108
Destination IP:   178.21.10.7
Source port:      53375
Destination port: 80
Flags:            SYN

Packet captured
IP header lengh:  5
Source IP:        178.21.10.7
Destination IP:   192.168.10.108
Source port:      80
Destination port: 53375
Flags:            SYN ACK

Packet captured
IP header lengh:  5
Source IP:        192.168.10.108
Destination IP:   178.21.10.7
Source port:      53375
Destination port: 80
Flags:            ACK

Packet captured
IP header lengh:  5
Source IP:        192.168.10.108
Destination IP:   178.21.10.7
Source port:      53375
Destination port: 80
Flags:            ACK

Packet captured
IP header lengh:  5
Source IP:        178.21.10.7
Destination IP:   192.168.10.108
Source port:      80
Destination port: 53375
Flags:            ACK

Packet captured
IP header lengh:  5
Source IP:        178.21.10.7
Destination IP:   192.168.10.108
Source port:      80
Destination port: 53375
Flags:            ACK

Packet captured
IP header lengh:  5
Source IP:        192.168.10.108
Destination IP:   178.21.10.7
Source port:      53375
Destination port: 80
Flags:            ACK

Packet captured
IP header lengh:  5
Source IP:        178.21.10.7
Destination IP:   192.168.10.108
Source port:      80
Destination port: 53375
Flags:            ACK FYN

Packet captured
IP header lengh:  5
Source IP:        192.168.10.108
Destination IP:   178.21.10.7
Source port:      53375
Destination port: 80
Flags:            ACK FYN

Packet captured
IP header lengh:  5
Source IP:        178.21.10.7
Destination IP:   192.168.10.108
Source port:      80
Destination port: 53375
Flags:            ACK

ERROR: Error getting the packet

3 комментария:

Shakirov комментирует...

Свой snort пишешь? :)

AccessD комментирует...

типа того )) у мну тема диплома про защиту вебсерваков от ддосов, решил сделать софтинку для автоматизации тех действий, которые мы обычно делаем.
Работать так будет - грабим в мускуль часть параметров из ip, tcp и http хэдеров и анализируем типа - вот за последние 5 сек с такого-то адреса стопицот пакетов чисто с син флагом, значит суём в фаерволл.

кстати, снортом пользовался?

Shakirov комментирует...

с snort-ом мы начинали делать по такой схеме: выделенный сервер со снортом, на него зеркалится (на каталисте) порт сервера под ддосом, снорт анализирует по своим шаблонам и дает команды на маршрутизатор (в нашем случае опять на каталист) залочить такие-то и такие-то подсети.