$ echo "Steve Zdancewic" | ./blame It's all Steve Zdancewic's fault.or, if you prefer:
$ echo "Bill Gates" | ./blame 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/~cse331/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" before it terminates. 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.
/* * Blame server. Assigns blame to the person of your choice. * * Usage: blame * (reads one line from standard input) * * To compile: * cc blame.c -o blame * * Install under inetd as follows: * blame stream tcp nowait root /path/to/blame blame * * Copyright 2004 by Feckless C. Coder, PhD. */ #include <stdio.h> #include <string.h> #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; }Last Revised: 08 Jan. 2007