• Партнер

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

    Хочешь разобраться в работе пресловутого
    протокола 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, помогу чем смогу!

    Исходник

    Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии