[Python, Программирование] Перехват и анализ сетевого трафика с помощью библиотеки pcap
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Сегодня многие крупные компании для увеличения производительности открывают доступ сотрудников с рабочих компьютеров в Интернет. Однако не все сотрудники используют его продуктивно и безопасно для рабочих сетей, по этой причине требуется контроль доступа. Из нежелательных явлений работы в Интернете можно назвать: ● посещение нежелательных сайтов;● скачивание файлов, потенциально зараженных;● просмотр видеозаписей и скачивание изображений;● общение в соц. сетях, онлайн-игры.Для обеспечения эффективной работы сети необходимо управлять потоком трафика, например, с помощью интернет-запросов. Packet Capture позволяет создавать программы, анализирующие данные, поступающие на сетевую карту компьютера, и (в более новых версиях), передающие пакеты в сеть. В различных подходах к мониторингу и тестированию сети, так называемых программах-снифферах (англ. sniff - нюхать), используют эту библиотеку. Она предназначена для использования совместно с языками C/C++, а для работы с библиотекой на других языках используют обертки. Для Unix-подобных систем - библиотека libpcap, а для Microsoft Windows - WinPcap.В качестве примера, создадим простейшее консольное приложение, демонстрирующее работу библиотеки pcap под ОС Microsoft Windows, которое будет состоять из двух частей: отправителя, формирующего каждый байт сообщения, и получателя.Отправитель1. Определим IP-адрес отправителя. В действительности компьютер может входить в несколько подсетей одновременно и для каждой из них иметь отдельный IP-адрес. Для простоты кода ограничимся единственным IP.
u_char* learn_IP()
{
addrinfo hnts, *pRes;
char hostName[1024];
u_char* ip_addr = NULL;
if (gethostname(hostName, sizeof hostName) == 0)
{
memset(&hnts, 0, sizeof hnts);
hnts.ai_family = AF_INET; hnts.ai_socktype = SOCK_DGRAM; hnts.ai_flags = AI_PASSIVE;
if (getaddrinfo(hostName, NULL, &hnts, &pRes) == 0)
{
struct addrinfo* res;
char buffer[INET_ADDRSTRLEN];
for (res = pRes; (res != NULL) && (res->ai_family != AF_INET); res = res->ai_next);
ip_addr = (u_char* )inet_ntop(AF_INET, &((struct sockaddr_in *)res->ai_addr)->sin_addr, buffer, INET_ADDRSTRLEN);
freeaddrinfo(pResults);
}
WSACleanup();
}
return ip_addr;
}
Далее специальная функция определяет MAC-адрес сетевой карты компьютера, отправляющего сообщение.
u_char* learn_MAC()
{
IP_ADAPTER_INFO ip_ainf[128];
PIP_ADAPTER_INFO pip_ainf = ip_ainf;
u_long bufLen = sizeof(ip_ainf);
GetAdaptersInfo(ip_ainf, &bufLen);
u_char* mac_addr = pip_ainf->Address;
return mac_addr;
}
2. В Интернет-заголовке необходимо указать MAC-адреса отправителя и получателя, которые определяются посредством ARP-запроса по известному IP-адресу. Если отправитель и получатель находятся в разных локальных сетях, то ARP-запросом требуется определить MAC-адрес маршрутизатора сети отправителя и его же указывать в сообщении. Если отправитель и получатель в одной сети, то конечного адресата. В любом случае ARP-пакет шлется в широковещательном режиме.
IPAddr DestIp = 0, SrcIp = 0;
static u_long MacAddr[2];
u_long PhysAddrLen;
SrcIpAddr = inet_addr(SrcIpString); // IP-адрес отправителя
DestIpAddr = inet_addr(destIpString);// IP-адрес маршрутизатора или конечного получателя
memset(&MacAddr, 0xff, sizeof(MacAddr)); // Указатель на широковещательную рассылку
if (SendARP(DestIpAddr, SrcIpAddr, &MacAddr, &PhysAddrLen) == NO_ERROR)
*bPhysAddr = (BYTE *) & MacAddr; // Искомый MAC-адрес
3. Далее с помощью стандартных функций библиотеки pcap определяем интерфейс, который будет использоваться для передачи сообщений.
pcap_if_t *alldevs, *dev;
char errbuf[PCAP_ERRBUF_SIZE];
int inum, i = 0;
pcap_findalldevs(&alldevs, errbuf);
scanf_s("%dev", &inum);
for (dev = alldevs, i = 0; i < inum - 1; dev = dev->next, i++);
Открываем его.
pcap_t *adhandle;
adhandle = pcap_open_live(dev->name, 65536, 0, 1000, errbuf);
4. Далее собираем воедино пакет для отправки. Определяем его Интернет, IP и UDP-заголовки, канального, сетевого и транспортного уровней. Особого внимания заслуживает функция вычисления контрольной суммы для IP и UDP-заголовков.
u_short checksum(u_char *buffer, int size)
{
u_long chksum = 0;
while (size > 1)
{
chksum += *buffer++;
size -= sizeof(u_short);
}
if (size)
chksum += *(u_char*)buffer;
chksum = (chksum >> 16) + (chksum & 0xffff);
chksum += (chksum >> 16);
return (u_short)(~chksum);
}
Затем пакет отправляется посредством стандартной функции библиотеки pcap.
pcap_sendpacket(adhandle, packet, 43);
adhandle – ранее определенный указатель на интерфейс отправки пакета, packet – сам пакет, последний параметр – размер пакета в байтах.Получатель1. С помощью стандартных функций pcap определяем интерфейс, который будет использоваться для перехвата сетевого трафика и открываем его (по аналогии с отправкой пакетов). Далее специальной функцией библиотеки pcap настраиваем и устанавливаем фильтр пакетов.
char pckfilter[] = "ip dst host 192.168.1.1";
struct bpf_program fcode;
if (d->addresses != NULL)
netmask = ((struct sockaddr_in *)(d->addresses->netmask))-> sin_addr.S_un.S_addr;
else netmask = 0xffffff;
pcap_compile(adhandle, &fcode, pckfilter, 1, netmask);
pcap_setfilter(adhandle, &fcode);
2.Далее запускается функция, которая в бесконечном цикле обрабатывает перехваченные пакеты.
void packet_handler(u_char *param, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)
а) Для начала из заголовка функции выуживается время передачи пакета и преобразуется в удобный для чтения формат.
time_t local_tv_sec = header->ts.tv_sec;
char strtime[16];
struct tm ltime;
localtime_s(&local_tv_sec, <ime);
strftime(strtime, sizeof strtime, "%H:%M:%S", <ime);
б) Из всего заголовка выделяется та часть, которая соответствует IP-протоколу сетевого уровня. Проверяется контрольная сумма, и в случае ее совпадения сообщение обрабатывается вверх по стеку TCP/IP, иначе – сообщение игнорируется.
ip_header *ip_hd;
ip_hd = (ip_header *)(pkt_data + 14);
if (!Count_ip_check_sum(ip_hd))
return;
в) Определяем UDP-заголовок принятого пакета и проверяем его контрольную сумму. Для этого формируем псевдозаголовок, состоящий из IP-адресов отправителя и получателя, поля, определяющего протокол нижележащего уровня, и длины UDP-заголовка и данных. Контрольная сумма вычисляется по UDP-заголовку плюс псевдозаголовок. От нее зависит дальнейшая судьба пакета: принять или отбросить.
u_int ip_len = (ip_hd->ver_ihl & 0xf) * 4;
udp_header *udp_hd;
udp_hd = (udp_header *)((u_char*)ip_hd + ip_len);
u_char* pshd = new u_char[12]; // псевдозаголовок
pshd[0] = ip_hd->src_ip.byte1; pshd[1] = ip_hd->src_ip.byte2;
pshd[2] = ip_hd->src_ip.byte3; pshd[3] = ip_hd->src_ip.byte4;
pshd[4] = ip_hd->dest_ip.byte1; pshd[5] = ip_hd->dest_ip.byte2;
pshd[6] = ip_hd->dest_ip.byte3; pshd[7] = ip_hd->dest_ip.byte4;
pshd[8] = 0x00; pshd[9] = 0x11; pshd[10] = 0x00; pshd[11] = 0x09;
if (!Count_udp_check_sum(udp_hd, pshd))
return;
г) Далее определяем значение портов в UDP-заголовке и выводим на экран сводную информацию о сообщении: время отправки, длина, IP-адреса отправителя и получателя и их порты.
u_short sendport = ntohs(udp_hd->src_port);
u_short destport = ntohs(udp_hd->dest_port);
printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
printf("%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\n",
ip_hd->src_ip.byte1, ip_hd->src_ip.byte2, ip_hd->src_ip.byte3, ip_hd->src_ip.byte4, sendport,
ip_hd->dest_ip.byte1, ip_hd->dest_ip.byte2, ip_hd->dest_ip.byte3, ip_hd->dest_ip.byte4, destport);
В результате разработано приложение, наглядно демонстрирующее применение библиотеки pcap в задачах контроля и анализа сетевого трафика. Оптимизация использования сетевых ресурсов является обязанностью системного администратора, и данная библиотека является хорошим помощником в этом.
===========
Источник:
habr.com
===========
Похожие новости:
- [Программирование, Машинное обучение, Микросервисы, Natural Language Processing] Честные глаза плагиатора, или еще один взгляд на будущее систем обнаружения заимствований
- [Ненормальное программирование, Python, Data Mining, Искусственный интеллект] интуиция Искусственного Интеллекта — миф или реальность?
- [Python, Математика, Машинное обучение] Двумерные тестовые функции для оптимизации (перевод)
- [Программирование, Delphi] Delphi 7 на костылях: автоматизация подготовки ресурсов
- [Oracle, Программирование] Логирование событий в Oracle PL/SQL
- [Python, Машинное обучение, Лайфхаки для гиков] Как проверить подлинность банкнот с помощью нейросети (перевод)
- [Программирование, Разработка под Linux] Программа для создания desktop-файлов
- [Python, Алгоритмы, Машинное обучение, Искусственный интеллект] DialoGPT на русском
- [Python, Программирование, Машинное обучение] Telegram bot + ML: универсальный алгоритм совмещения
- [Программирование, Java, ReactJS] YAHW на React
Теги для поиска: #_python, #_programmirovanie (Программирование), #_pcap, #_python, #_analiz_trafika (анализ трафика), #_python, #_programmirovanie (
Программирование
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 20:02
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Сегодня многие крупные компании для увеличения производительности открывают доступ сотрудников с рабочих компьютеров в Интернет. Однако не все сотрудники используют его продуктивно и безопасно для рабочих сетей, по этой причине требуется контроль доступа. Из нежелательных явлений работы в Интернете можно назвать: ● посещение нежелательных сайтов;● скачивание файлов, потенциально зараженных;● просмотр видеозаписей и скачивание изображений;● общение в соц. сетях, онлайн-игры.Для обеспечения эффективной работы сети необходимо управлять потоком трафика, например, с помощью интернет-запросов. Packet Capture позволяет создавать программы, анализирующие данные, поступающие на сетевую карту компьютера, и (в более новых версиях), передающие пакеты в сеть. В различных подходах к мониторингу и тестированию сети, так называемых программах-снифферах (англ. sniff - нюхать), используют эту библиотеку. Она предназначена для использования совместно с языками C/C++, а для работы с библиотекой на других языках используют обертки. Для Unix-подобных систем - библиотека libpcap, а для Microsoft Windows - WinPcap.В качестве примера, создадим простейшее консольное приложение, демонстрирующее работу библиотеки pcap под ОС Microsoft Windows, которое будет состоять из двух частей: отправителя, формирующего каждый байт сообщения, и получателя.Отправитель1. Определим IP-адрес отправителя. В действительности компьютер может входить в несколько подсетей одновременно и для каждой из них иметь отдельный IP-адрес. Для простоты кода ограничимся единственным IP. u_char* learn_IP()
{ addrinfo hnts, *pRes; char hostName[1024]; u_char* ip_addr = NULL; if (gethostname(hostName, sizeof hostName) == 0) { memset(&hnts, 0, sizeof hnts); hnts.ai_family = AF_INET; hnts.ai_socktype = SOCK_DGRAM; hnts.ai_flags = AI_PASSIVE; if (getaddrinfo(hostName, NULL, &hnts, &pRes) == 0) { struct addrinfo* res; char buffer[INET_ADDRSTRLEN]; for (res = pRes; (res != NULL) && (res->ai_family != AF_INET); res = res->ai_next); ip_addr = (u_char* )inet_ntop(AF_INET, &((struct sockaddr_in *)res->ai_addr)->sin_addr, buffer, INET_ADDRSTRLEN); freeaddrinfo(pResults); } WSACleanup(); } return ip_addr; } u_char* learn_MAC()
{ IP_ADAPTER_INFO ip_ainf[128]; PIP_ADAPTER_INFO pip_ainf = ip_ainf; u_long bufLen = sizeof(ip_ainf); GetAdaptersInfo(ip_ainf, &bufLen); u_char* mac_addr = pip_ainf->Address; return mac_addr; } IPAddr DestIp = 0, SrcIp = 0;
static u_long MacAddr[2]; u_long PhysAddrLen; SrcIpAddr = inet_addr(SrcIpString); // IP-адрес отправителя DestIpAddr = inet_addr(destIpString);// IP-адрес маршрутизатора или конечного получателя memset(&MacAddr, 0xff, sizeof(MacAddr)); // Указатель на широковещательную рассылку if (SendARP(DestIpAddr, SrcIpAddr, &MacAddr, &PhysAddrLen) == NO_ERROR) *bPhysAddr = (BYTE *) & MacAddr; // Искомый MAC-адрес pcap_if_t *alldevs, *dev;
char errbuf[PCAP_ERRBUF_SIZE]; int inum, i = 0; pcap_findalldevs(&alldevs, errbuf); scanf_s("%dev", &inum); for (dev = alldevs, i = 0; i < inum - 1; dev = dev->next, i++); pcap_t *adhandle;
adhandle = pcap_open_live(dev->name, 65536, 0, 1000, errbuf); u_short checksum(u_char *buffer, int size)
{ u_long chksum = 0; while (size > 1) { chksum += *buffer++; size -= sizeof(u_short); } if (size) chksum += *(u_char*)buffer; chksum = (chksum >> 16) + (chksum & 0xffff); chksum += (chksum >> 16); return (u_short)(~chksum); } pcap_sendpacket(adhandle, packet, 43);
char pckfilter[] = "ip dst host 192.168.1.1";
struct bpf_program fcode; if (d->addresses != NULL) netmask = ((struct sockaddr_in *)(d->addresses->netmask))-> sin_addr.S_un.S_addr; else netmask = 0xffffff; pcap_compile(adhandle, &fcode, pckfilter, 1, netmask); pcap_setfilter(adhandle, &fcode); void packet_handler(u_char *param, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)
time_t local_tv_sec = header->ts.tv_sec;
char strtime[16]; struct tm ltime; localtime_s(&local_tv_sec, <ime); strftime(strtime, sizeof strtime, "%H:%M:%S", <ime); ip_header *ip_hd;
ip_hd = (ip_header *)(pkt_data + 14); if (!Count_ip_check_sum(ip_hd)) return; u_int ip_len = (ip_hd->ver_ihl & 0xf) * 4;
udp_header *udp_hd; udp_hd = (udp_header *)((u_char*)ip_hd + ip_len); u_char* pshd = new u_char[12]; // псевдозаголовок pshd[0] = ip_hd->src_ip.byte1; pshd[1] = ip_hd->src_ip.byte2; pshd[2] = ip_hd->src_ip.byte3; pshd[3] = ip_hd->src_ip.byte4; pshd[4] = ip_hd->dest_ip.byte1; pshd[5] = ip_hd->dest_ip.byte2; pshd[6] = ip_hd->dest_ip.byte3; pshd[7] = ip_hd->dest_ip.byte4; pshd[8] = 0x00; pshd[9] = 0x11; pshd[10] = 0x00; pshd[11] = 0x09; if (!Count_udp_check_sum(udp_hd, pshd)) return; u_short sendport = ntohs(udp_hd->src_port);
u_short destport = ntohs(udp_hd->dest_port); printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len); printf("%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\n", ip_hd->src_ip.byte1, ip_hd->src_ip.byte2, ip_hd->src_ip.byte3, ip_hd->src_ip.byte4, sendport, ip_hd->dest_ip.byte1, ip_hd->dest_ip.byte2, ip_hd->dest_ip.byte3, ip_hd->dest_ip.byte4, destport); =========== Источник: habr.com =========== Похожие новости:
Программирование ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 20:02
Часовой пояс: UTC + 5