Поясните пожалуйста, почему происходит вот так: Я сделал ОЧЕНЬ, ОЧЕНЬ простой сниффер (если конечно его можно так назвать). Работает как правило iptables. Зарегистрирован перехватчик hooknum = NF_INET_LOCAL_OUT ; Так вот, перехватчик ловит передаваемые TCP пакеты с локального компа в сеть. Делаю проверку по 21 порту (FTP) так как его проверить легче всего. Запускаю wireshark и FileZilla. Через FileZilla шлю к какомуто ftp логин и пароль =) .. В wireshark вижу, что они отправились в сеть, простым открытым текстом USER anonimus PASS 123456789. Значит их может перехватить мой фильтр. Но вот незадача! Нихрена то он их не перехватывает. Думал, думал что за хз. Додумал до того, что wireshark показывает, что в тех пакетах в которых содержится USER и PASS, не верна контрольная сумма (но на стороне сервера, эти пакеты нормально принемаются и создаётся коннект). Собственно вопрос, почему мой перехватчик не может обнаружить эти самые пакеты.
было бы неплохо увидеть кусочек кода. можно было бы кстати просто воспрользоваться сокетами AF_PACKET - не было бы необходимости лезть в ядро
Всё видно. stmia AF_PACKET .... никак нельзя =) вот кусочек кода Код (Text): Срабатывает на каждый исходящий пакет struct iphdr *iphdr_ptr = NULL; struct tcphdr *tcphdr_ptr = NULL; iphdr_ptr = skb->network_header; // получаем заголовок ip пакета tcphdr_ptr = skb->transport_header; unsigned int i = 0; unsigned short count = 0; unsigned short data_len = 0; unsigned char *data = (unsigned char *)tcphdr_ptr + (tcphdr_ptr->doff)*4; // начала данных data_len = (unsigned char *)skb->tail - (unsigned char *)data; // printk("skb->tail = %p \n", skb->tail); printk("data = %p \n", data); if(data_len>0) // {printk("data_len больше нуля %i \n", data_len); for(count=0; count<ASCII_PASS_TEXT_COUNT; count++) // для всех возможых комбинаций текста { unsigned char *seach_string = "PASS"; // указатель на строку if(strncmp(data, &seach_string, 4) == 0) { printk("Найден паролик! \n"); printk("ip = %s \n", in_ntoa(iphdr_ptr->daddr)); printk("\n"); printk("data = %s \n", data); } } } printk("\n*************************************************\n"); Сорри за код, написал его на скорую руку.
Код (Text): unsigned char *seach_string = "PASS"; // указатель на строку if(strncmp(data, &seach_string, 4) == 0) кхм, и не мудрено что не получается
ohne Сейчас постараюсь пояснить =) Мой "сниффер" вообще не видет пакеты, где данные>0 (когда проверяет пакеты на исходящий порт 21).. Токачто проверил, это верно, так как FileZilla не шлёт на удалённый хост, данные в TCP пакете! =) Вот, а единственные TCP пакеты содержащие данные, это те, в которых находятся USER и PASS. И у которых не верна контрольная сумма(но на эти пакеты сервер исправно отвечает, так как будто они верны). Так вот, а мой "сниффер" их не видет! по его словам, не было отосланных пакетов, в которых содержались бы данные.
Ну да).. щас приведу этот участок кода, так как он записан в моём коде. (то что привёл сверху..это то, что с ходу накалякал..) Вейт плиз 10мин
мде, нормально filezilla по tftp работает что ли? думаю врядли. они бы не дошли до сервера, если бы сумма не была верна вобщем вопрос не ясен + тот баг на который указали
ascii_pass_array[ASCII_PASS_TEXT_COUNT][ASCII_PASS_LENGHT]; // это массив строк, которые возможно, могут содержаться в TCP пакете #define SNIF_TEXT_1 "login" #define SNIF_TEXT_2 "pass" #define ASCII_PASS_TEXT_COUNT = 2 /* ... и тд определения */ unsigned char ascii_pass_array[ASCII_PASS_TEXT_COUNT][ASCII_PASS_LENGHT] = { {SNIF_TEXT_1}, {SNIF_TEXT_2}}; // в цикле, оходим весь массив ascii_pass_array unsigned short str_len = strlen(&ascii_pass_array[count]); // узнаём длинну искомой строки unsigned char *seach_string = &ascii_pass_array[count]; // указатель на строку //data указывает на начало данных пакета if(strncmp(data, &seach_string, str_len) == 0) { ........ В кратце, както так
Код (Text): if(strncmp(data, &seach_string, str_len) == 0) { такая же ошибка как и в приведенном ранее коде, вы передаете в функцию указатель на указатель на строку вместо того чтобы передавать указатель на строку. как следствие - strncmp() пытается искать бог знает где - но только не там где нужно (в tcp пакете)
У меня всёже с кодом беда. У всех отправляемых пакетов, мой код определяет что длинна данных равна 0 =) вот грешу на это unsigned short data_len = 0; struct iphdr *iphdr_ptr = NULL; struct tcphdr *tcphdr_ptr = NULL; iphdr_ptr = skb->network_header; // получаем заголовок ip пакета tcphdr_ptr = skb->transport_header; unsigned char *data = (unsigned char *)tcphdr_ptr + (tcphdr_ptr->doff)*4; а вот примерный вывод для каждого пакета skb->head = f3705c00 skb->data = f3705cdc skb->tail = f3705d10 skb->end = f3705d20 начало data = f3705d10 // unsigned char *data = (unsigned char *)tcphdr_ptr + (tcphdr_ptr->doff)*4; Как видно, data(начало данных для проверки) = tail ...тоесть концу данных в пакете. Что-то я совсем запутался.. я что? начало проверяемых данных не верно высчитываю?если да, то как верно?
_ir4_Y_ Linux Сетевая Архитектура. Но там мало только книжку выучить =) .. надо ещё по ядру пройтись, всякие там #define посмотреть, и разобраться в том, чего в книге нету.
mowgli А чего там показывать то? всё стандартно. Самый обычный перехватчик iptables hooknum = NF_INET_LOCAL_OUT