$ echo "Steve Zdancewic" | ./blame It's all Steve Zdancewic's fault. It's all Steve Zdancewic's fault. ... It's all Steve Zdancewic's fault.or, if you prefer:
$ echo "Bill Gates" | ./blame It's all Bill Gates's fault. ... It's all Bill Gates's fault. It's all Bill Gates's fault.The program is designed to operate as a network service, e.g., from the "inetd" daemon under Unix.
Source code for blame.c is attached below and is also available at http://www.cis.upenn.edu/~cis551/blame.c.
Simple-minded string processing aside (it would be more correct, after all, to say that "It's all Bill Gates' fault"), there is a serious problem with the blame program. Despite Feckless' best efforts, a bug allows anyone who can provide input to this program to run arbitrary code on the target machine. (What might happen if it is run as a network service under inetd, as suggested in the comments?)
Your job is to create input that will cause the blame service to print out the helpful message "Now I pwn your computer" and terminate the loop. For example:
$ cat exploit_file | ./blame ... Now I pwn your computerHere, the "..." may be additional output caused as a side-effect of your attack.
Submit the program that generates your exploit_file as well
as any tools you use to generate parameters and constants. Your
software should be sufficiently documented to allow a novice
programmer to port your code to other platforms or to modify it to
exploit similar weaknesses in other programs. In other words, your
submission should be suitable as a tutorial on exploiting (and
avoiding) this class of vulnerability.
project1 should be submitted online on eniac by using the command turnin.
There is also a turnin man page which explains the usage in more detail, including some additional arguments.
Feckless C. Coder, PhD wrote another code culpability.c available at http://www.cis.upenn.edu/~cis551/culpability.c. Due to recent changes in gcc 4.1.*, it is harder to perform stack-smashing attacks to culpability.c.
-fstack-protector: Emit extra code to check for buffer overflows, such as stack smashing attacks. This is done by adding a guard variable to functions with vulnerable objects. This includes functions that call alloca, and functions with buffers larger than 8 bytes. The guards are initialized when a function is entered and then checked when the function exits. If a guard check fails, an error message is printed and the program exits. -fstack-protector-all: Like \u2018-fstack-protector\u2019 except that all functions are protected. -fno-stack-protector: switch off stack-protector -fno-stack-protector-all: illegal for Suse. It works in FreeBSDFrom http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc.pdf
Carry out the stack smashing attack to culpability.c assuming that culpability.c
is compiled with the option -fno-stack-protector, and fix the implemetation so that it is not
vulnerable to this buffer overflow attack, but still has the same behavior as the original program.
DO THIS ONLY AFTER COMPLETING THE PROJECT WITH blame.c*
/* * Blame server. Assigns blame to the person of your choice. * * Usage: blame * (reads one line from standard input) * * To compile: * gcc blame.c -o blame * * Install under inetd as follows: * blame stream tcp nowait root /path/to/blame blame * * Copyright 2009 by Feckless C. Coder, PostDoc. */ #include#include #include #define INPUT_BUFFER 256 /* maximum name size */ int buffer[INPUT_BUFFER]; /* storing input data */ /* * read input, copy into p * gets() is insecure and prints a warning * so we use this instead */ void saveinput(int *p) { int c; while ((c=getchar()) != EOF) *p++ = c; *p = EOF; } /* * read data from p to s */ void getline(char *s, int *p) { int c; for(; (c=*p++)!= EOF; *s++ = c); *s = '\0'; } /* * convert newlines to nulls in place */ void purgenewlines(char *s) { int l; l = strlen(s); while (l--) if (s[l] == '\n') s[l] = '\0'; } /* * copy data from p to scapegoat * print on the screen after reformatting */ int loop(int *p) { char scapegoat[INPUT_BUFFER]; getline (scapegoat, p); /* this check ensures there's no buffer overflow */ if (strlen(scapegoat) < INPUT_BUFFER) { purgenewlines(scapegoat); printf("It's all %s's fault.\n", scapegoat); return 1; } else { return 0; } } /* * save input into buffer, then start loop */ int main() { saveinput(buffer); while(loop(buffer)); return 0; }
/* * Culpability server. Assigns culpability to the person of your choice. * * Usage: culpability * (reads one line from standard input) * * To compile: * gcc culpability.c -o culpability * * Install under inetd as follows: * culpability stream tcp nowait root /path/to/culpability culpability * * Copyright 2004 by Feckless C. Coder, PhD. */ #includeLast Revised: 15 Jan. 2009#include #define INPUT_BUFFER 256 /* maximum name size */ /* * read input, copy into s * gets() is insecure and prints a warning * so we use this instead */ void getline(char *s) { int c; while ((c=getchar()) != EOF) *s++ = c; *s = '\0'; } /* * convert newlines to nulls in place */ void purgenewlines(char *s) { int l; l = strlen(s); while (l--) if (s[l] == '\n') s[l] = '\0'; } int main() { char scapegoat[INPUT_BUFFER]; getline(scapegoat); /* this check ensures there's no buffer overflow */ if (strlen(scapegoat) < INPUT_BUFFER) { purgenewlines(scapegoat); printf("It's all %s's fault.\n", scapegoat); } return 0; }