Еще один вопрос о перехвате пакетов. Раньше уже задавал, но сейчас должен еще раз спросить: как лучше реализовывать перехват входящих и исходящих сетевых пакетов? Можно делать перехват WinSock функций или некоторых внутренних функций браузеров. Какие еще эффективные методы можете посоветовать?
WinPCAp (хватает все) RawSocket (хватает все что открыто на локальном компе) NDIS (можно повыеживаться но в функционале не догнать WinPCap) LCP (путь пройденный Comodo)
примерно так .... тут многие говорят с дрожью в голосе о неблокируемых сокетах..... дык вот вам откровение от делимитера 8)) Code: s = socket(AF_INET, SOCK_RAW, IPPROTO_IP); if (s != INVALID_SOCKET) { addr.sin_family = AF_INET; addr.sin_port = htons(0); addr.sin_addr = ((sockaddr_in*)(*(DWORD*)&addrlist[4]))->sin_addr; if (bind(s, (sockaddr*)&addr, sizeof(addr)) != SOCKET_ERROR) { #define SIO_RCVALL 0x98000001 DWORD optval = 1; int res = WSAIoctl(s, SIO_RCVALL,&optval, sizeof(optval), 0,0,&bytesret,0,0); if (res != SOCKET_ERROR) { int err=WSAAsyncSelect(s,hWnd,TCP_READ,FD_ACCEPT|FD_READ|FD_WRITE|FD_CONNECT); } } } { ну и обработчик события TCP_READ Code: if(WSAGETSELECTERROR(lParam)) break; arg=0; ioctlsocket(s,FIONREAD,&arg); inquire=new char[arg+2]; len=recv(s,inquire,arg,0); ..... извращаемся delete[] inquire;
То есть самое основное здесь, это константа SIO_RCVALL. Раньше немного читал об этом. Можно ли с помощью данного способа перехватывать исходящие пакеты?
конечно и входящие и исходящие 8)) обрати внимание на FD_WRITE .... в функии СЕЛЕКТА с помощью ИЛИ "|" перечисляются какие FD события я обьединяю в событие TCP_READ ... можешь добывить FD_CLOSE 8)) .... как то оно выпало кудато сам не паму!
Code: /*************************************************************************** "Впервые исходный текст такого сниффера был опубликован в шестом номере журнала #29A, затем его передрал Z0mnie, переложивший ассемблерный код на интернациональный программистский язык Си++ (странно, а почему не Си?) и унаследовавший все ляпы оригинала. Ниже приведен его ключевой фрагмент с моими комментариями, а полный исходный текст содержится в файле sniffer.с. Другой источник вдохновления - демонстрационный пример IPHDRINC, входящий в состав Platform SDK 2000. Рекомендую." (c)Крис Касперски changed by Gar|k 2010 GNU GPL ***************************************************************************/ #pragma optimize("gsy",on) #pragma comment(linker, "/MERGE:.data=.text") #pragma comment(linker, "/MERGE:.rdata=.text") #pragma comment(linker, "/SECTION:.text,EWR") #include <stdio.h> #include <winsock2.h> // Wincosk2.h должен быть раньше windows! #pragma comment(lib,"Ws2_32.lib") #include <windows.h> //#define SIO_ADDRESS_LIST_QUERY _WSAIOR(IOC_WS2,22) /* во избежании ошибки переполнения 10014 SIO_ADDRESS_LIST_QUERY -- Gar|k Windows* Sockets 2 / Application Programming Interface / August 7, 1997 "If output buffer is not large enough to contain the address list, SOCKET_ERROR is returned as the result of this IOCTL and WSAGetLastError() returns WSAEFAULT." */ struct SSOCKET_ADDRESS_LIST { int iAddressCount; SOCKET_ADDRESS Address[50]; }; #define MAX_PACKET_SIZE 0x10000 struct SIPHEADER { unsigned char VerLen; unsigned char ServiceType; unsigned short PacketLength; unsigned short Id; unsigned short Offset; unsigned char TTL; unsigned char Protocol; unsigned short XSum; unsigned char SrcIP[4]; unsigned char DestIP[4]; }; typedef struct SIPHEADER IPHEADER; struct SIPPACKET { unsigned char Header[sizeof(IPHEADER)]; unsigned char Data[MAX_PACKET_SIZE]; }; typedef struct SIPPACKET IPPACKET; int main(void){ char buf[512]; SOCKET raw_socket; SSOCKET_ADDRESS_LIST addrlist; SSOCKET_ADDRESS_LIST *llist=&addrlist; SOCKADDR_IN addr; unsigned long N,rcv_all_enabled=1; int n_addr=0,a,len; IPPACKET IPPacket; IPHEADER *IPHeader; if (WSAStartup(0x202, (WSADATA *)buf)) return printf("-ERR:WSAStart error %d\n", WSAGetLastError()); // создаем сырой сокет //------------------------------------------------------------------------ if ((raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_IP)) == INVALID_SOCKET) return printf("-ERR:socket(,SOCK_RAW,) -> %d\n", WSAGetLastError()); // (не)устанавиваем атрибут IP_HDRINCL (ибо он на фиг не нужен) // ------------------------------------------------------------------------ // if (setsockopt(raw_socket,IPPROTO_IP,IP_HDRINCL,(char*)&rcv_all_enabled, // sizeof(optval)) == SOCKET_ERROR) return printf("-ERR:setsockopt(,,IP_"\ // "HDRINCL) -> %d\n", WSAGetLastError()); // перечисляем все интерфейсы // ----------------------------------------------------------------------- if (WSAIoctl(raw_socket, SIO_ADDRESS_LIST_QUERY, 0, 0, (LPVOID)&addrlist, sizeof(addrlist), &N, 0, 0) == SOCKET_ERROR) return printf("-ERR:WSAIoctl(SIO_ADDRESS_LIST_QUERY) error %d\n", WSAGetLastError()); // найден хоть один интерфейс? if (!(n_addr = llist->iAddressCount)) return printf("-ERR:list is empty\n"); // распечатываем список имеющихся интерфейсов // ------------------------------------------------------------------------ for (a = 0; a < n_addr; a++) printf("IP - %s\n", inet_ntoa(((struct sockaddr_in*)llist->Address[a].lpSockaddr)->sin_addr)); // биндим последний интерфейс (последний - для простоты понимания) addr.sin_family = AF_INET; addr.sin_addr = ((struct sockaddr_in*)llist->Address[a - 1].lpSockaddr)->sin_addr; if (bind(raw_socket, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) return printf("-ERR:bind\n"); #define SIO_RCVALL 0x98000001 // сообщаем системе, что мы хотим получать все IP-пакеты, проходящие мимо // ------------------------------------------------------------------------ if (WSAIoctl(raw_socket, SIO_RCVALL, &rcv_all_enabled, sizeof(rcv_all_enabled), \ 0, 0, &N, 0, 0) == SOCKET_ERROR) return printf("-ERR:WSAIoctl(SIO_RCVALL)-->%d\n", WSAGetLastError()); // получаем все пакеты, приходящие на данный интерфейс while(1) { if ((len = recv(raw_socket, (char *)&IPPacket,sizeof(IPPacket),0)) < 1) return printf("-ERR:recv()->%d,WSAErr=%i\n", len, WSAGetLastError()); if(len>=sizeof(IPHEADER)) { IPHeader=(IPHEADER *)&IPPacket.Header; printf("%d.%d.%d.%d -> %d.%d.%d.%d %d %d\n",IPHeader->SrcIP[0],IPHeader->SrcIP[1],IPHeader->SrcIP[2],IPHeader->SrcIP[3],IPHeader->DestIP[0],IPHeader->DestIP[1],IPHeader->DestIP[2],IPHeader->DestIP[3],IPHeader->Protocol,len); } } WSACleanup(); return 0; } как бы вариант на блокирующих сокетах.
да лана ... репа это от лукавого! 2 Gar|k ... + .... пример на блокирующих сокетах! только имя z0mbie (нужно писать правиьно) .... передрал его из англоязычного источника с developer-sources! ... читал с удовольствием его рассуждения ! 8)) когда он еще был в A29
Всё бы то хорошо, но вот главный вопрос как получить через сырые сокеты исходящие данные?. Ведь через сырые сокеты можно получать исходящие данные. А также получать события. Но из событие FD_WRITE ты никак не выдеришь данные исходящие. Темболее что флаг FD_WRITE не даст тебе толком ничего для получения исходящего трафа.
2 slesh // слишком много теории и уверенности если запощу .... сюда дебаг версию своего сырого снифера и увидишь исходящий трафик, поверишь? 8)))))))))))) дебуг версион только не судите строго (делал 8 лет назад) сейчас работаю только в WinPCap... редко использую raw_socket только для перехвата паролей на web-почту,паролей к социальным сетям, icq паролей (для тех юзеров кто не понимает моего запрета) 8)) для тех кому лень запускать снифер или нет дебаг библиотек ,даю вырезку "вывода-ЧУДА" Code: #003b# R:192.168.1.66>188.40.76.205 TCP ps:4089 pd:80 >---AU< 47 45 54 20 2f 61 6e 74 69 63 68 61 74 2f 70 69 | GET /antichat/pi 63 2f 6f 6e 2e 67 69 66 20 48 54 54 50 2f 31 2e | c/on.gif HTTP/1. 31 0d 0a 41 63 63 65 70 74 3a 20 2a 2f 2a 0d 0a | 1__Accept: */*__ 52 65 66 65 72 65 72 3a 20 68 74 74 70 3a 2f 2f | Referer: http:// 66 6f 72 75 6d 2e 61 6e 74 69 63 68 61 74 2e 72 | forum.antichat.r 75 2f 74 68 72 65 61 64 6e 61 76 31 37 35 34 36 | u/threadnav17546 33 2d 31 2d 31 30 2e 68 74 6d 6c 0d 0a 41 63 63 | 3-1-10.html__Acc 65 70 74 2d 4c 61 6e 67 75 61 67 65 3a 20 72 75 | ept-Language: ru 0d 0a 55 73 65 72 2d 41 67 65 6e 74 3a 20 4d 6f | __User-Agent: Mo 7a 69 6c 6c 61 2f 34 2e 30 20 28 63 6f 6d 70 61 | zilla/4.0 (compa 74 69 62 6c 65 3b 20 4d 53 49 45 20 37 2e 30 3b | tible; MSIE 7.0; 20 57 69 6e 64 6f 77 73 20 4e 54 20 35 2e 31 3b | Windows NT 5.1; 20 54 72 69 64 65 6e 74 2f 34 2e 30 3b 20 57 65 | Trident/4.0; We 62 4d 6f 6e 65 79 20 41 64 76 69 73 6f 72 29 0d | bMoney Advisor)_ 0a 41 63 63 65 70 74 2d 45 6e 63 6f 64 69 6e 67 | _Accept-Encoding 3a 20 67 7a 69 70 2c 20 64 65 66 6c 61 74 65 0d | : gzip, deflate_ 0a 49 66 2d 4d 6f 64 69 66 69 65 64 2d 53 69 6e | _If-Modified-Sin 63 65 3a 20 4d 6f 6e 2c 20 30 33 20 41 75 67 20 | ce: Mon, 03 Aug 32 30 30 39 20 31 31 3a 31 34 3a 33 38 20 47 4d | 2009 11:14:38 GM 54 0d 0a 48 6f 73 74 3a 20 66 6f 72 75 6d 2e 61 | T__Host: forum.a 6e 74 69 63 68 61 74 2e 72 75 0d 0a 43 6f 6e 6e | ntichat.ru__Conn 65 63 74 69 6f 6e 3a 20 4b 65 65 70 2d 41 6c 69 | ection: Keep-Ali 76 65 0d 0a 43 6f 6f 6b 69 65 3a 20 61 62 62 6c | ve__Cookie: abbl 61 73 74 76 69 73 69 74 3d 31 32 36 35 30 34 33 | astvisit=1265043 38 38 35 3b 20 61 62 62 6c 61 73 74 61 63 74 69 | 885; abblastacti 76 69 74 79 3d 31 32 36 35 30 34 39 34 36 38 3b | vity=1265049468; 20 5f 5f 75 74 6d 61 3d 32 32 33 36 39 38 37 30 | __utma=22369870 30 2e 33 34 30 34 30 31 36 35 30 2e 31 32 36 35 | 0.340401650.1265 30 33 32 37 34 39 2e 31 32 36 35 30 35 33 33 37 | 032749.126505337 32 2e 31 32 36 35 30 35 37 30 39 31 2e 37 3b 20 | 2.1265057091.7; 5f 5f 75 74 6d 62 3d 32 32 33 36 39 38 37 30 30 | __utmb=223698700 2e 32 33 39 2e 31 30 2e 31 32 36 35 30 35 37 30 | .239.10.12650570 39 31 3b 20 5f 5f 75 74 6d 7a 3d 32 32 33 36 39 | 91; __utmz=22369 38 37 30 30 2e 31 32 36 35 30 33 32 37 34 39 2e | 8700.1265032749. 31 2e 31 2e 75 74 6d 63 73 72 3d 28 64 69 72 65 | 1.1.utmcsr=(dire 63 74 29 7c 75 74 6d 63 63 6e 3d 28 64 69 72 65 | ct)|utmccn=(dire 63 74 29 7c 75 74 6d 63 6d 64 3d 28 6e 6f 6e 65 | ct)|utmcmd=(none 29 3b 20 61 62 62 75 73 65 72 69 64 3d 31 30 38 | ); abbuserid=108 34 30 32 3b 20 61 62 62 70 61 73 73 77 6f 72 64 | 402; abbpassword 3d 35 38 61 66 39 39 30 30 39 62 63 31 30 66 31 | =58af99009bc10f1 33 36 65 63 39 38 35 31 30 65 61 31 37 66 38 34 | 36ec98510ea17f84 34 3b 20 61 62 62 73 65 73 73 69 6f 6e 68 61 73 | 4; abbsessionhas 68 3d 64 62 35 39 64 39 30 61 36 65 63 64 32 35 | h=db59d90a6ecd25 32 30 31 61 31 61 30 32 36 62 66 36 61 30 66 30 | 201a1a026bf6a0f0 32 66 3b 20 5f 5f 75 74 6d 63 3d 32 32 33 36 39 | 2f; __utmc=22369 38 37 30 30 3b 20 61 62 62 74 68 72 65 61 64 5f | 8700; abbthread_ 6c 61 73 74 76 69 65 77 3d 39 36 39 64 66 36 32 | lastview=969df62 61 63 34 62 31 65 32 61 65 62 39 64 65 63 39 37 | ac4b1e2aeb9dec97 63 35 61 61 63 36 33 31 30 61 78 31 31 78 2d 69 | c5aac6310ax11x-i 78 31 37 35 34 36 33 79 73 78 31 30 78 25 32 32 | x175463ysx10x%22 31 32 36 35 30 35 39 37 33 34 25 32 32 79 69 78 | 1265059734%22yix 31 37 35 33 30 38 79 73 78 31 30 78 25 32 32 31 | 175308ysx10x%221 32 36 35 30 36 31 39 30 39 25 32 32 79 69 78 31 | 265061909%22yix1 37 31 37 39 38 79 73 78 31 30 78 25 32 32 31 32 | 71798ysx10x%2212 36 35 30 35 39 32 30 33 25 32 32 79 69 78 31 37 | 65059203%22yix17 35 34 30 36 79 73 78 31 30 78 25 32 32 31 32 36 | 5406ysx10x%22126 35 30 35 39 31 38 39 25 32 32 79 69 78 31 37 35 | 5059189%22yix175 30 37 31 79 73 78 31 30 78 25 32 32 31 32 36 35 | 071ysx10x%221265 30 34 31 38 34 37 25 32 32 79 69 78 31 37 35 35 | 041847%22yix1755 30 35 79 73 78 31 30 78 25 32 32 31 32 36 35 30 | 05ysx10x%2212650 35 39 36 31 36 25 32 32 79 69 78 31 37 35 34 35 | 59616%22yix17545 31 79 73 78 31 30 78 25 32 32 31 32 36 35 30 36 | 1ysx10x%22126506 31 31 31 33 25 32 32 79 69 78 31 37 35 35 31 33 | 1113%22yix175513 79 73 78 31 30 78 25 32 32 31 32 36 35 30 36 30 | ysx10x%221265060 39 37 32 25 32 32 79 69 78 31 37 35 34 35 32 79 | 972%22yix175452y 73 78 31 30 78 25 32 32 31 32 36 35 30 35 30 35 | sx10x%2212650505 34 35 25 32 32 79 69 78 37 30 34 32 31 79 73 78 | 45%22yix70421ysx 31 30 78 25 32 32 31 32 36 35 30 35 37 37 35 36 | 10x%221265057756 25 32 32 79 69 78 31 31 35 34 30 33 79 73 78 31 | %22yix115403ysx1 30 78 25 32 32 31 32 36 34 39 32 32 30 36 33 25 | 0x%221264922063% 32 32 79 5f 0d 0a 0d 0a | 22y_____ это пакет из дампа .....эти дампы наверняка помнит algol в 2005-м ! /thread6014.html это ЧУДО работало уже в те времена!
2 Retimiled сирь что сказал что не пашет. Но фишка в том, что реально дома у меня никогда не пахало это. Сколько не писал сниферы, они всё равно не хватали исходящие. МОжет просто потому что всегда стоял фаер. Хотя хз.
2 slesh ..... однозначно файрвол виноват!!! первые эксперименты проводил на блокирующих ....но терял пакеты, а на грабли в виде файрвола наступал разззз 20-ть лоб хорошо помнит ! ...сделал на асинхроных смотрю все работает 8)) понял так что буфер задается указателем и на события FD_READ и FD_WRITE адрес различен, а recv считывает из непустого буфера!
делал оч давно и своими руками на базе пкапа перехватчик аси, причем с изменением данных. тестил в офисе на клиентах миранды. 1) арп спуфил гейт и юзеров на себя, 2) переделывал текст в пейлоде тсп, + пересчет цксум. альфа бета и эрси одновременно кончились на спуфере который если видел плейн привет в пакете то перебивал на пиздец) - работало повторюсь ток в миранде тк другие клиенты вроде по вебу слали в чем мне морочиться не хотелось)
2 snow писал: крут в винпкап лишь кольцевой буфер и конпелируемый фильтр) я ни понел тут ктото против кольцевого буфера или фильтров??? ... чуствую что счас придется выкладывать винпкап снифер 8))) (показывать на примере фильтров как хватать весь ip трафик либо выборочный ethernet) винпикар секьюре бридж (чтоб показывать как в сетке класса С я хватаю свои и чужие-проходные пакеты обходясь стандартным net xxx.yyy) или вам ключ от квартиры в которой правила на все 64Кило портов на все адреса класса С? тока не дождетесь ... может в разделе барыг выложу скриншоты так как это коммерческие продукты уже! Лучше оставайтесь при собственном мнении ... дешевле получится! думаю ТС .... уже получил достаточную порцию для размышлений и ушел! Далее будет только ФЛУД!
кладю .... 6-ти летней давности WinPCap снифер.... (нашел никоммерческий без записи в базу данных) для }{пирементофффф
Вот мне делать нефиг А я сидел втыкал про фрагментирование пакетов...так и не родил идею как их правильно обрабатывать (ну как определить то я понял, а как их хранить во временном буфере чтоле пакетов то много, да и вдруг мне этот пакет не нужен)... в итоге накатал сткрутурки (ну не нашел я нигде) это как бы дополнение к снифферу что я уже выкладывал Code: #pragma pack(1) #define BITTOBYTE(l) ((l*32)/8) #define HTONS(a) (((0xFF&a)<<8) + ((0xFF00&a)>>8)) struct garik_ip { unsigned char hdr_len:4; unsigned char version:4; unsigned char dscp; unsigned short len; unsigned short id; unsigned char frag_offset1; unsigned char frag_offset2:5; // flags unsigned char rb:1; unsigned char df:1; unsigned char mf:1; unsigned char ttl; unsigned char proto; unsigned short checksum; unsigned char SrcIP[4]; unsigned char DestIP[4]; }; struct garik_udp { unsigned short srcport; unsigned short dstport; unsigned short length; unsigned short checksum; }; struct garik_tcp { unsigned short srcport; unsigned short dstport; unsigned long seq; unsigned long ack; unsigned char reserved:4; unsigned char hdr_len:4; //flags; unsigned char fin:1; unsigned char syn:1; unsigned char reset:1; unsigned char push:1; unsigned char fack:1; unsigned char urg:1; unsigned char ecn:1; unsigned char cwr:1; unsigned short window_size; unsigned short checksum; }; #pragma pack() // это уже в main garik_ip *ip; garik_udp *udp; garik_tcp *tcp; // а это заместо старого цикла бесконечного while(1) { if ((len = recv(raw_socket, (char *)&IPPacket,sizeof(IPPACKET),0)) < 1) return printf("-ERR:recv()->%d,WSAErr=%i\n", len, WSAGetLastError()); if(len>=sizeof(garik_ip)) { ip=(garik_ip *)&IPPacket.Header; //if(ip->proto!=0x06){continue;} // фильтруем только TCP printf("\n================================================================\n\ Internet Protocol, Src: %d.%d.%d.%d, Dst: %d.%d.%d.%d\n\ Version: %d\n\ Header length: %d bytes\n\ Differentiated Services Filed: 0x%02X\n\ Total length: %d\n\ Identification: 0x%04X (%d)\n\ Flags: 0x%02X\n\ %d.. = Reserved Bit\n\ .%d. = Don't fragment\n\ ..%d = More fragments\n\ Fragment offset: %d\n\ Time to live: %d\n\ Protocol: 0x%02X\n\ Header Checksum: 0x%04X\n", ip->SrcIP[0],ip->SrcIP[1],ip->SrcIP[2],ip->SrcIP[3],ip->DestIP[0],ip->DestIP[1],ip->DestIP[2],ip->DestIP[3], ip->version, BITTOBYTE(ip->hdr_len), ip->dscp, HTONS(ip->len), ip->id,ip->id, ip->rb+ip->df+ip->mf,ip->rb,ip->df,ip->mf, MAKEWORD(ip->frag_offset1,ip->frag_offset2), ip->ttl, ip->proto, ip->checksum ); if(ip->proto==0x11){ udp=(garik_udp *)&IPPacket.Data; printf("\n- User Datagram Protocol\n\ Source port: %d\n\ Destination port: %d\n\ Length: %d\n\ Checksum: 0x%04X\n", HTONS(udp->srcport), HTONS(udp->dstport), HTONS(udp->length),udp->checksum); } if(ip->proto==0x06){ tcp=(garik_tcp *)&IPPacket.Data; printf("\n- Transmission Control Protocol\n\ Source port: %d\n\ Destination port: %d\n\ Sequence number: %d\n\ Acknowledgement number: %d\n\ Header length: %d bytes\n\ Flags\n\ %d... .... = Congestion Window Reduced (CWR)\n\ .%d.. .... = ECN-Echo\n\ ..%d. .... = Urgent\n\ ...%d .... = Acknowledgement\n\ .... %d... = Push\n\ .... .%d.. = Reset\n\ .... ..%d. = Syn\n\ .... ...%d = Fin\n\ Window Size: %d\n\ Checksum: 0x%04X\n", HTONS(tcp->srcport), HTONS(tcp->dstport), HTONS(tcp->seq), HTONS(tcp->ack), BITTOBYTE(tcp->hdr_len), tcp->cwr,tcp->ecn,tcp->urg,tcp->fack,tcp->push,tcp->reset,tcp->syn,tcp->fin, HTONS(tcp->window_size),tcp->checksum ); } } } Может где накосячил в стуктурах (с флагами сложновато) ибо хз как одновременно запустить свой сниффер и Wireshark, но сравнивал все долго... теперь в голове зреют идеи авто подстройки анализа пакетов (ну чтобы сразу лишнее отбрасывать например только tcp c определенного порта или там отслеживать конкретные соединения по SYN, ACK...) У меня еще где-то есть структура ARP завтра уже прикручу будет еще и маки показывать хехе. Если структуры можно красивше реализовать тыкните носом.