ec_dissector_icq.c
上传用户:nilegod
上传日期:2007-01-08
资源大小:220k
文件大小:6k
源码类别:

网络截获/分析

开发平台:

C/C++

  1. /*
  2.     ettercap -- dissector for ICQ 2000 v5
  3.     Copyright (C) 2001 ALoR <alor@users.sourceforge.net>, NaGA <crwm@freemail.it>
  4.     Additional Copyright for this file:  LnZ <lnz@iname.com>
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU General Public License for more details.
  13.     You should have received a copy of the GNU General Public License
  14.     along with this program; if not, write to the Free Software
  15.     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  16. */
  17. #include "include/ec_main.h"
  18. #include <string.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <errno.h>
  22. #include "include/ec_dissector.h"
  23. #include "include/ec_inet_structures.h"
  24. #include "include/ec_error.h"
  25. #ifdef DEBUG
  26.    #include "include/ec_debug.h"
  27. #endif
  28. #define ICQ_HEADER_LENGTH              0x0018
  29. #define CMD_LOGIN                      0x03E8
  30. #define CMD_LOGIN_OFFSET               0x000E
  31. #define CMD_LOGIN_PASS_LENGHT_OFFSET   0x0008
  32. #define CMD_LOGIN_UIN_OFFSET           0x0006
  33. #define CMD_LOGIN_PASS_OFFSET          0x000A
  34. const u_char table [] = {
  35.    0x59, 0x60, 0x37, 0x6B, 0x65, 0x62, 0x46, 0x48, 0x53, 0x61, 0x4C,
  36.    0x59, 0x60, 0x57, 0x5B, 0x3D, 0x5E, 0x34, 0x6D, 0x36, 0x50, 0x3F,
  37.    0x6F, 0x67, 0x53, 0x61, 0x4C, 0x59, 0x40, 0x47, 0x63, 0x39, 0x50,
  38.    0x5F, 0x5F, 0x3F, 0x6F, 0x47, 0x43, 0x69, 0x48, 0x33, 0x31, 0x64,
  39.    0x35, 0x5A, 0x4A, 0x42, 0x56, 0x40, 0x67, 0x53, 0x41, 0x07, 0x6C,
  40.    0x49, 0x58, 0x3B, 0x4D, 0x46, 0x68, 0x43, 0x69, 0x48, 0x33, 0x31,
  41.    0x44, 0x65, 0x62, 0x46, 0x48, 0x53, 0x41, 0x07, 0x6C, 0x69, 0x48,
  42.    0x33, 0x51, 0x54, 0x5D, 0x4E, 0x6C, 0x49, 0x38, 0x4B, 0x55, 0x4A,
  43.    0x62, 0x46, 0x48, 0x33, 0x51, 0x34, 0x6D, 0x36, 0x50, 0x5F, 0x5F,
  44.    0x5F, 0x3F, 0x6F, 0x47, 0x63, 0x59, 0x40, 0x67, 0x33, 0x31, 0x64,
  45.    0x35, 0x5A, 0x6A, 0x52, 0x6E, 0x3C, 0x51, 0x34, 0x6D, 0x36, 0x50,
  46.    0x5F, 0x5F, 0x3F, 0x4F, 0x37, 0x4B, 0x35, 0x5A, 0x4A, 0x62, 0x66,
  47.    0x58, 0x3B, 0x4D, 0x66, 0x58, 0x5B, 0x5D, 0x4E, 0x6C, 0x49, 0x58,
  48.    0x3B, 0x4D, 0x66, 0x58, 0x3B, 0x4D, 0x46, 0x48, 0x53, 0x61, 0x4C,
  49.    0x59, 0x40, 0x67, 0x33, 0x31, 0x64, 0x55, 0x6A, 0x32, 0x3E, 0x44,
  50.    0x45, 0x52, 0x6E, 0x3C, 0x31, 0x64, 0x55, 0x6A, 0x52, 0x4E, 0x6C,
  51.    0x69, 0x48, 0x53, 0x61, 0x4C, 0x39, 0x30, 0x6F, 0x47, 0x63, 0x59,
  52.    0x60, 0x57, 0x5B, 0x3D, 0x3E, 0x64, 0x35, 0x3A, 0x3A, 0x5A, 0x6A,
  53.    0x52, 0x4E, 0x6C, 0x69, 0x48, 0x53, 0x61, 0x6C, 0x49, 0x58, 0x3B,
  54.    0x4D, 0x46, 0x68, 0x63, 0x39, 0x50, 0x5F, 0x5F, 0x3F, 0x6F, 0x67,
  55.    0x53, 0x41, 0x25, 0x41, 0x3C, 0x51, 0x54, 0x3D, 0x5E, 0x54, 0x5D,
  56.    0x4E, 0x4C, 0x39, 0x50, 0x5F, 0x5F, 0x5F, 0x3F, 0x6F, 0x47, 0x43,
  57.    0x69, 0x48, 0x33, 0x51, 0x54, 0x5D, 0x6E, 0x3C, 0x31, 0x64, 0x35,
  58.    0x5A, 0x00, 0x00
  59. };
  60. // protos
  61. FUNC_DISSECTOR(Dissector_icq);
  62. unsigned long get_key(u_char *data, short datalen);
  63. int Decode_icq(u_char *data, short datalen);
  64. // --------------------
  65. unsigned long get_key(u_char *data, short datalen)
  66. {
  67.    u_long A[6] = {0, 0, 0, 0, 0, 0};
  68.    u_long key;
  69.    u_long check;
  70.    check = *(u_long *)(data + 0x14);
  71.    A[1] = check & 0x0001F000;
  72.    A[2] = check & 0x07C007C0;
  73.    A[3] = check & 0x003E0001;
  74.    A[4] = check & 0xF8000000;
  75.    A[5] = check & 0x0000083E;
  76.    A[1] = A[1] >> 0x0C;
  77.    A[2] = A[2] >> 0x01;
  78.    A[3] = A[3] << 0x0A;
  79.    A[4] = A[4] >> 0x10;
  80.    A[5] = A[5] << 0x0F;
  81.    check = A[5] + A[1] + A[2] + A[3] + A[4];
  82.    key = datalen * 0x68656C6C;
  83.    key += check;
  84.    return key;
  85. }
  86. int Decode_icq(u_char *data, short datalen )
  87. {
  88.    unsigned long key,i,k;
  89.    if (datalen <= 0x14 + sizeof(unsigned long)) return 0;// Not enough data to decode
  90.    key = get_key(data, datalen);
  91.    for (i=0x0a; i < datalen+3; i+=4 )
  92.    {
  93.       k = key+table[i&0xff];
  94.       if ( i != 0x16 )
  95.       {
  96.          data[i] ^= (u_char)(k & 0xff);
  97.          data[i+1] ^= (u_char)((k & 0xff00)>>8);
  98.       }
  99.       if ( i != 0x12 ) {
  100.          data[i+2] ^= (u_char)((k & 0xff0000)>>16);
  101.          data[i+3] ^= (u_char)((k & 0xff000000)>>24);
  102.       }
  103.    }
  104.    return 0;
  105. }
  106. FUNC_DISSECTOR(Dissector_icq)
  107. {
  108.    UDP_header *udp;
  109.    u_char *payload;
  110.    char *password = NULL; // ;)
  111.    u_long pwdlen = -1;
  112.    u_char collector[MAX_DATA];
  113. DATA_DISSECTOR;
  114.    udp = (UDP_header *) data;
  115.    payload = (char *) (int)udp + UDP_HEADER;
  116.    if (ntohs(udp->source) == 4000) return 0;       // Skip server messages...
  117.    if (data_to_ettercap->datalen == 0) return 0;   // No data...
  118.    memset(collector, 0, MAX_DATA);
  119.    if (Conn_Mode)
  120.     memcpy(collector, payload, data_to_ettercap->datalen);
  121.    else
  122.     memcpy(collector, payload, sniff_data_to_ettercap->datasize);
  123.    if( ptohs(collector) != 5) return 0;    // Not the right version
  124. if (Conn_Mode)
  125. {
  126. Decode_icq(collector, data_to_ettercap->datalen); // decrypting....
  127.    if ( ptohs(collector + CMD_LOGIN_OFFSET) != CMD_LOGIN) return 0; // Not a login packet
  128.     snprintf(data_to_ettercap->user, 30, "%ld (ICQ UIN)n", ptohl(collector + CMD_LOGIN_UIN_OFFSET));  // the login (UIN)
  129. #ifdef DEBUG
  130.     Debug_msg("tDissector_ICQ - LOGIN ");
  131. #endif
  132.     pwdlen = ptohs(collector + ICQ_HEADER_LENGTH + CMD_LOGIN_PASS_LENGHT_OFFSET);
  133.     password = (char *) calloc(pwdlen+1, sizeof(char) );
  134.     strncpy(password,(char *)(collector + ICQ_HEADER_LENGTH + CMD_LOGIN_PASS_OFFSET), pwdlen);
  135.     snprintf(data_to_ettercap->pass,30,"%sn", password);
  136.     sprintf(data_to_ettercap->type, "ICQ");
  137. #ifdef DEBUG
  138.     Debug_msg("tDissector_ICQ - PASS ");
  139. #endif
  140. }
  141. else
  142. {
  143. Decode_icq(collector, sniff_data_to_ettercap->datasize); // decrypting....
  144. memcpy(sniff_data_to_ettercap->data, collector, sniff_data_to_ettercap->datasize);
  145. }
  146.    return 0;
  147. }
  148. /* EOF */