Бедному Диалапщику посвящается! 

Хочешь разобраться в работе пресловутого
протокола ICMP, о котором все так много говорят? Да, понимаю, 
читать толстенные книги по протоколам, в которых понятны только предлоги, или еще хуже — красными глазами читать RFC, держа перед собой толстенный англо-русский словарь, так как твои познания в английском заканчиваются фразой:
"Who`s on duty today? I am on duty today.» — кому хочется?! Ты прекрасно знаешь, что самый верный путь к знаниям — это практика.
Когда ты видишь как формируются пакеты, как они отправляются, ты сможешь в дальнейшем понять и более сложные вещи! Но у тебя гигантская проблема — Windows 9x!
К сожалению работать с пакетами на низком уровне
winsock (библиотека предоставляющая интерфейс работы с сокетами) в этих версиях
(9х) не позволит! Есть несколько способов решения этой проблемы: ставь другую ось
(или старшие версии Windows 2000, XP…) или ищи NDIS драйвер и учись его использовать
(можешь, конечно, сам его написать, но если ты его написал, то зачем тебе читать все это). Но никто не запрещал тебе работать с протоколами высокого уровня.

Чтобы спуфить пакеты, например ICMP, нужно хотя бы знать как они выглядят и для чего вообще предназначены. Я предлагаю тебе инструмент, с помощью которого ты сможешь анализировать ICMP пакеты — а это достаточно важно!
Что тебе нужно для создания своего собственного анализатора ICMP пакетов:
компилятор какого-либо языка (реализующего
winsock, все функции описанные ниже практически не меняют своего интерфейса),
пальцы чтобы написать код, мозги чтобы все это понять. 

Итак, начнем. Я написал все на С++ (Borland C++ v5.01). Сначала действуем по стандартному плану создания сервера: инициализируем структуру sockaddr_in таким образом:

sockaddr_in *addr;
addr = new sockaddr_in;
addr->sin_family = AF_INET; // Семейство адресов AF_INET или PF_INET — каму как нравится.
addr->sin_port = htons(0); // Номер порта нам неважен, мы работаем на низком уровне,
// где номера портов не имеют значение.
addr->sin_addr.s_addr = htonl(INADDR_ANY); // Выбираем любой интерфейс(обычно он один)

Затем инициализируем структуру protoent, чтобы winsock знал с каким протоколом мы будем работать:

protoent *protocol;
protocol = getprotobyname(«icmp»);

Создаем дескриптор сокета:

int sock;
sock = socket(AF_INET,SOCK_RAW,protocol->p_proto);

Обрати внимание, что мы работаем не с SOCK_DGRAM, и уж тем более не с SOCK_STREAM, а с SOCK_RAW, так называемые «сырые» сокеты. Затем, как обычно, проверяем на ошибки и идем далее
(если INVALID_SOCKET, то обломись дружок). Биндим наш сокет с
адресом, которой мы определили в указателе addr:

int err;
err = bind(sock,(sockaddr *)addr,sizeof(*addr));

Тоже проверяем на ошибки. Дальше начинается самое интересное: мы не вызываем функции listen() и
accept(),  как обычно, а сразу начинаем принимать пакеты функцией recvfrom():

int rc;
char buffer[1024];
while(true)
{
rc = recvfrom(sock,buffer,sizeof(buffer),0,(sockaddr *)addr,&len);
}

Проверяем на ошибки, если rc == -1 тогда ошибка, иначе все круто
и идем дальше (все это делается внутри бесконечного цикла).
Когда мы получили пакет из сети, в структуре addr у нас хранится
адрес того хорька,  который послал тебе этот ICMP пакет, только не в привычном для нас виде
(«четыре точки»), а в машинном. Надо привести его к читаемому виду.
Легко!

cout<<«received from: «<<inet_ntoa(addr->sin_addr)<<endl;

Теперь у нас в руках полученный пакет (в массиве buffer). Что с ним делать? Организуем процедуру для вывода содержимого пакета на экран. Я особо не заморачивался по поводу этой процедуры, так что кому не
нравиться может организовать все самостоятельно. Главное знать, что где находиться!

Теперь о некоторых нюансах. Прежде всего как узнать ось по пингу? Конечно, точно ось не определить, но если тебя пингуют стандартными прогами, входящими в пакет ОС
(ping…) с размером пакета по дефолту, можно точно сказать: если тебе пришло 32 байта,
то знай — это твой товарищ по Виндам, если 56, то это
обладатель UNIX машины!

Если поле тип содержит 0 или 8, то знай — это ping . Если
5 — запрос на переадресацию (советую тщательно изучить именно этот тип ICMP,
так как он бывает очень полезен при проведении некоторых видов атак!).

Если ты все сделаешь, откомпилишь и запустишь, затем
пропингуешь самого себя, ты получишь столько пакетов сколько отправил! Почему, спросишь ты? Дело в том что «сырым» сокетам передаются не все ICMP пакеты, некоторые ядро обрабатывает самостоятельно, это небольшой недостаток нашей с тобой проги.
Зато если вместо IPPROTO_ICMP в сокете написать IPPROTO_RAW, тогда ты получишь доступ и к IGMP пакетам, а также ко всем пакетам в поле протокол которых стоит неизвестное ядру значение, попросту говоря все пакеты, которые ядро не знает как обрабатывать!

С вопросами можете обращаться по адресу alpon83@mail.ru, помогу чем смогу!

Исходник

Оставить мнение

Check Also

Безумный олдскул. Самые необычные приставки и игровые аксессуары из прошлого

Если ты думаешь, что Guitar Hero, Kinect или Wii Remote — это странно, то спешим тебя заве…