[TOOL] MSN CAPTURE - MSN Messenger Packet Parser

From: SecuriTeam (support_at_securiteam.com)
Date: 10/26/05

  • Next message: SecuriTeam: "[EXPL] HP-UX LPD Service Remote "Root" Command Execution Exploit (meta)"
    To: list@securiteam.com
    Date: 26 Oct 2005 19:22:13 +0200
    
    

    The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
    - - promotion

    The SecuriTeam alerts list - Free, Accurate, Independent.

    Get your security news from a reliable source.
    http://www.securiteam.com/mailinglist.html

    - - - - - - - - -

      MSN CAPTURE - MSN Messenger Packet Parser
    ------------------------------------------------------------------------

    SUMMARY

    DETAILS

    MSN CAPTURE captures MSN messenger packets and display it to the user in a
    human readable format.

    Tool Code:
    /* MSN CAPTURE is a software which capture packets of msn protocol and
    show to user in */
    /* a good format to see the important things in networks with hubs or
    switched (arpspoof). */
    /* This program use libpcap.
                               */
    /* HOW TO USE:
                               */
    /* YOU MUST BE ROOT !!!!
                               */
    /* root@slack:/home/gabriel/pcap# gcc msn-cap.c -o msn-cap -lpcap
                               */
    /* root@slack:/home/gabriel/pcap# msn-cap -n billgates@msn.com
                               */
    /*
    ------------------------------------------------------------------------------------- */
    /* billgates@msn.com <10.6.6.6> talk to steve_ballmer@hotmail.com
    <10.6.6.24> and says: */
    /* how do you want destroy gpl???
                               */
    /*
    --------------------------------------------------------------------------------------- */
    /*
    ------------------------------------------------------------------------------------- */
    /* steve_ballmer@hotmail.com <10.6.6.24> talk to billgates@msn.com
    <10.6.6.6> and says: */
    /* a pact with devil is very good!!!
                               */
    /*
    --------------------------------------------------------------------------------------- */
    /*
    ------------------------------------------------------------------------------------- */
    /* billgates@msn.com <10.6.6.6> talk to steve_ballmer@hotmail.com
    <10.6.6.24> and says: */
    /* but i already sold my soul to him...
                               */
    /*
    --------------------------------------------------------------------------------------- */
    /*
    ------------------------------------------------------------------------------------- */
    /* steve_ballmer@hotmail.com <10.6.6.24> talk to billgates@msn.com
    <10.6.6.6> and says: */
    /* ***...
                               */
    /*
    --------------------------------------------------------------------------------------- */
    /*
                               */
    /* You need to get a few of packets to take some nicks, because this
    program works with lists and */
    /* take it when a packet of type "TypingUser" comes and it associates
    the nick with the IP to form */
    /* the structures. It is very fast!!!! In case appear a "Unknown User"
    in the place of original user*/
    /* , is question of time to get the real user. MUCH LITTLE TIME !!!
                               */
    /*
                               */
    /* Tested on Linux SlackWare 10.1 - 2.6.13
                               */
    /*
                               */
    /*
                               */
    /*
                               */
    /* More about the use of program is below...
                               */
    /*
                               */
    /* Valew EccJr e a galera do SoftwareUpdateOnTheFuckers...
                               */
    /* Created by Gabriel Menezes Nunes < dragao_branco >
                               */
    /* UNESP -- IBILCE
                               */
    /*
                               */

     
                 
     
     
    #define __USE_BSD
    #include <stdio.h>
    #include <pcap.h>
    #define __FAVOR_BSD
    #include <netinet/tcp.h>
    #include <netinet/ip.h>
    #include <netinet/ip.h>
    #include <netinet/udp.h>
    #include <netinet/if_ether.h>
    #include <unistd.h>
     
     
     
    struct user {
      char ip[16];
      char nick[200];
      struct user *prox;
    } *l;
    char nick1[200], nick2[200], filename[200];
    int exclusive = 0, activate = 0;
    FILE *fd;

    char *get_my_nick(struct user *l, char *ip);
    void callfunc (u_char *args, const struct pcap_pkthdr *header, const
    u_char *packet);
    void print_msg(char *msg, char *nick_src, char *nick_dst, char *ip_src,
    char *ip_dst);
    void get_msg(u_char *payload, char *msg, int cont);
    void get_nick(u_char *payload, char *nick);
    struct user *insert(struct user *l, char *nick, char *ip);
     
    void callfunc (u_char *args, const struct pcap_pkthdr *header, const
    u_char *packet){
      struct ether_header *ethernet;
      struct ip *ip;
      struct tcphdr *tcp;
      struct udphdr *udp;
      int i = 0, k = 0, s1, len;
      char ascii[1024], nick[200], ip_dst[16], ip_src[16], teste[200],
    nick_src[200], nick_dst[200], *asc;
      char *payload, buffer[100], type[100], msg[200];
      ethernet = (struct ether_header*)(packet);
      ip = (struct ip*)(packet + sizeof(struct ether_header));
      tcp = (struct tcphdr*)(packet + sizeof(struct ether_header) +
    sizeof(struct ip));
      payload = (char *)(packet + sizeof(struct ether_header) + sizeof(struct
    ip) + sizeof(struct tcphdr));
      len = (ntohs(ip->ip_len)) - 40;
      asc = ascii;
      while(--len >= 0 && k++ < 1022){
        s1 = *payload++;
        if(s1 == '\r'){
          *asc++ = '\r';
          continue;
        }
        *(asc++) = (isgraph(s1) ? s1 : ' ');
      }
       *asc = '\0';
      if((strstr(ascii, "msmsgscontrol"))){
        get_nick(ascii, nick);
        strcpy(ip_src, (char*)inet_ntoa(ip->ip_src));
        l = insert(l, nick, ip_src);
      }

      if((strstr(ascii, "plain")) && strstr(ascii, "MSG")) {

        get_msg(ascii, msg, 5);
        strcpy(ip_src, (char*)inet_ntoa(ip->ip_src));
        strcpy(ip_dst, (char*)inet_ntoa(ip->ip_dst));
        strncpy(nick_src, get_my_nick(l, ip_src), 199);
        strncpy(nick_dst, get_my_nick(l, ip_dst), 199);
        if(activate)
          print_msg(msg, nick_src, nick_dst, ip_src, ip_dst);
        if((!nick1[0]) && (!nick2[0]))
          print_msg(msg, nick_src, nick_dst, ip_src, ip_dst);
        if((nick1[0]) && (nick2[0])){
          if(!exclusive){
     if((!(strcmp(nick_src, nick1))) || (!(strcmp(nick_src, nick2))) ||
    (!(strcmp(nick_dst, nick2))) || (!(strcmp(nick_dst, nick1))))
       print_msg(msg, nick_src, nick_dst, ip_src, ip_dst);
          }
          if(exclusive){
     if(((!(strcmp(nick_src, nick1))) && (!(strcmp(nick_dst, nick2)))) ||
    ((!(strcmp(nick_src, nick2))) && (!(strcmp(nick_dst, nick1)))) )
       print_msg(msg, nick_src, nick_dst, ip_src, ip_dst);
          }
        }
        if((nick1[0]) && (!nick2[0])){
          if((!(strcmp(nick_src, nick1))) || (!(strcmp(nick_dst, nick1))))
     print_msg(msg, nick_src, nick_dst, ip_src, ip_dst);
        }
        if((!nick1[0]) && (nick2[0])){
          if((!(strcmp(nick_src, nick2))) || (!(strcmp(nick_dst, nick2))))
     print_msg(msg, nick_src, nick_dst, ip_src, ip_dst);
        }
      }
    }
    main(int argc, char **argv){
      char *dev, errbuf[PCAP_ERRBUF_SIZE] , ip1[200], ip2[200], buffer[200],
    filter_app[200] = "(port 1863)";
      pcap_t *man;
      struct bpf_program filter;
      unsigned char packet[65535];
      bpf_u_int32 mask, net;
      int control;
      memset(nick1, '\0', sizeof(nick1));
      memset(nick2, '\0', sizeof(nick2));
      memset(ip1, '\0', sizeof(ip1));
      memset(ip2, '\0', sizeof(ip2));
      memset(filename, '\0', sizeof(filename));
      if(argc < 2){
        
    printf("---------------------------------------------------------------------------------------------\n");
        printf("\t\t\tMSN CAPTURE by < dragao_branco >\n\n");
        printf("You MUST be ROOT\n");
        printf("%s -a [0 or 1] -n [nick1] -m [nick2] -i [IP1] -y [IP2] -x [0
    or 1] -f [filename]\n\n", argv[0]);
        printf("-a --> ALL PACKETS!!!\n");
        printf("-x --> eXclusive\n");
        printf("-f --> filename to log the packets\n");
        printf("Choose 0 or 1 to activate or not the capture of ALL packets
    and the eXclusive mode\n");
        printf("You can choose one or two nicks to capture\n");
        printf("The same thing can be done with IPS\n");
        printf("Whether you choose the '-x' option, just the IPs or nicks (or
    both) will be capture\n");
        printf("Or you capture everything in your lan!!!\n");
        printf("Ex: %s -n smallville@hotmail.com\n", argv[0]);
        printf("You will capture packets from/to this nick\n");
        printf("Ex: %s -n smallville@hotmail.com -m lex_luthor@msn.com\n",
    argv[0]);
        printf("Will capture packets from/to this nicks\n");
        printf("Ex: %s -n smallville@hotmail.com -m lex_luthor@msn.com -x
    1\n", argv[0]);
        printf("Will capture packets ONLY between this nicks\n");
        printf("The same thing can be done with IPs\n");
        
    printf("---------------------------------------------------------------------------------------------\n");
        exit(-1);
      }
      while ((control = getopt(argc, argv, "n:m:i:y:x:a:f:")) != -1){
        switch(control){
        case 'n': strncpy(nick1, optarg, 199);
          break;
        case 'm': strncpy(nick2, optarg, 199);
          break;
        case 'i': strncpy(ip1, optarg, 199);
          break;
        case 'y': strncpy(ip2, optarg, 199);
          break;
        case 'x': exclusive = atoi(optarg);
          break;
        case 'a': activate = atoi(optarg);
          break;
        case 'f': strncpy(filename, optarg, 199);
                  fd = fopen(filename, "w");
          break;
        }
      }
      if(activate){
        memset(nick1, '\0', sizeof(nick1));
        memset(nick2, '\0', sizeof(nick2));
        memset(ip1, '\0', sizeof(ip1));
        memset(ip2, '\0', sizeof(ip2));
      }
      if(ip1[0] != '\0' && ip2[0] != '\0'){
        if(!exclusive)
          sprintf(buffer, " and (host %s or host %s)", ip1, ip2);
        else
          sprintf(buffer, " and (host %s and host %s)", ip1, ip2);
        strncat(filter_app, buffer, strlen(buffer));
      }
      if(ip1[0] == '\0' && ip2[0] != '\0'){
        sprintf(buffer, " and host %s", ip2);
        strncat(filter_app, buffer, strlen(buffer));
      }
      if(ip1[0] != '\0' && ip2[0] == '\0'){
        sprintf(buffer, " and host %s", ip1);
        strncat(filter_app, buffer, strlen(buffer));
      }
      printf("Using the rule: %s\n", filter_app);
      if(filename[0])
      printf("Save data in %s\n", filename);
      dev = pcap_lookupdev(errbuf);
      pcap_lookupnet(dev, &net, &mask, errbuf);
      man = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf);
      pcap_compile(man, &filter, filter_app, 0, net);
      pcap_setfilter(man, &filter);
      pcap_loop(man, 1000000, callfunc, NULL);
    }
     
     
    void get_nick(u_char *payload, char *nick){
      int i, k = 0;
      u_char *p = payload;
      for(i = 0; i < 3; i++){
        while(*p != '\r')
          p++;
        p++;p++;
      }
      while(*p != ':')
        p++;
      p++;p++;
      while(*p != '\r' && k++ < 199)
        *nick++ = *p++;
      *nick = '\0';
    }
     
    struct user *insert(struct user *l, char *nick, char *ip){
      struct user *q = l;
      struct user *p = (struct user*)malloc(sizeof(struct user));
      if(!l){
        strncpy(p->nick, nick, 199);
        strncpy(p->ip, ip, 15);
        p->prox = NULL;
        return p;
      }
      while(q){
        if(!(strcmp(q->ip, ip))){
          strncpy(q->nick, nick, 199);
          break;
        }
        q = q->prox;
      }
      if(!q){
        strncpy(p->nick, nick, 199);
        strncpy(p->ip, ip, 15);
        p->prox = l;
        return p;
      }
      return l;
    }
     
    char *get_my_nick(struct user *l, char *ip){
      struct user *p = l;
      while(p){
        if(!(strcmp(p->ip, ip)))//{
          return p->nick;
        //}
        p = p->prox;
      }
      return "Unknown User";
    }
     
    void get_msg(u_char *payload, char *msg, int cont){
      u_char *p = payload;
      memset(msg, '\0', sizeof(msg));
      int i, j = 0;
      for(i = 0; i < cont; i++){
        while(*p != '\r')
          p++;
        p++; p++;
      }
      if(cont == 2){
        strncpy(msg, p, 24);
        msg[25] = '\0';
      }
      if(cont == 5){
        while(*p && j++ < 1020)
          *msg++ = *p++;
        *msg = '\0';
      }
    }
    void print_msg(char *msg, char *nick_src, char *nick_dst, char *ip_src,
    char *ip_dst){
    if(!filename[0]){
      
    printf("-----------------------------------------------------------------------------------------------\n");
     
      printf("%s <%s> talk to %s <%s> and says:\n", nick_src, ip_src,
    nick_dst, ip_dst);
     
      printf("%s\n", msg);
     
      
    printf("-----------------------------------------------------------------------------------------------\n");
    }
    else {
      fprintf(fd,
    "-----------------------------------------------------------------------------------------------\n");
     
      fprintf(fd, "%s <%s> talk to %s <%s> and says:\n", nick_src, ip_src,
    nick_dst, ip_dst);
     
      fprintf(fd, "%s\n", msg);
     
      fprintf(fd,
    "-----------------------------------------------------------------------------------------------\n");
      fflush(fd);
    }
    }

    #EoF

    ADDITIONAL INFORMATION

    The information has been provided by <mailto:supergabriel28@gmail.com>
    Gabriel.
    To keep updated with the tool visit the project's homepage at:
    <http://dragonf.v10.com.br/msn.html> http://dragonf.v10.com.br/msn.html

    ========================================

    This bulletin is sent to members of the SecuriTeam mailing list.
    To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
    In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

    ====================
    ====================

    DISCLAIMER:
    The information in this bulletin is provided "AS IS" without warranty of any kind.
    In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.


  • Next message: SecuriTeam: "[EXPL] HP-UX LPD Service Remote "Root" Command Execution Exploit (meta)"
  • Quantcast