CompOrg Fall 2003 Homework #4

CompOrg Buffer Overflow Assignment

Due Date: 11/9/2003 (by 11:59:59PM)
Submit to WebCT

Late Penalty: 10% per day (7 day max)

Assignment

Given the source code for a C program, you need to change only the main function so that you overflow a buffer, and make the program do your bidding. The progam you are to work on does the following:

  1. reads a username as a line of text

  2. reads a password as a line of text

  3. verifies that the name and password are correct

  4. removes $100 from the user's account

The actual code for the program is available here: bufbomb.c and is also included at the bottom of this document.

Based on your superior knowledge of the IA32 instruction set, the stack, and buffer overflow, you need to design a string that can be sent to the authenticate function that will result in the program adding $1000 to your account.

The code you are targeting is somewhat contrived, although the principles involved are realistic (although the code has some silly stuff in it to make this assignment work, the general ideas apply to any program with a potential buffer overflow). The contrived stuff includes:

You are allowed to modify only the main function, but you obviously can't just change it to call credit_account directly. The only part of the main function you are allowed to change is where the strings come from (you can set either or both of name, password to a string literal that contains your machine code program and will overflow a buffer).

It's more difficult to leave the program as it is and to write a program that generates input that can be sent to bufbomb, but this is possible (this is what the code we went over in class did). If you do this successfully you can get 10 points extra credit.

To accomplish this you will need to write some assembly code that inserted in a string that eventually overflows a buffer. You will also need to arrange it so that when the function with the overflowed buffer returns, your code is executed (you need to overwrite the return address that is on the stack).

Feel free to use the makestring perl script available in the sample stack overflow code - this can generate a C string declaration directly from the output of objdump.

How to submit

Submission of your homework is to Webct (webct.rpi.edu).

Your submission must include the either your modified bufbomb.c program (if you choose to replace some of the code in the main function), or the program you wrote that generates a string that will cause an unmodified bufbomb to add $1000 to your account. You must also submit your assembly language progam (the assembly code that is in a string passed to authenticate.

You can also submit partially working code along with a description of how far you got (what problems remain). You can expect generous partial credit for a well described attempt at this assignment.

Grading

If you are able to modify the main in bufbomb so that the call to authenticate results in a call to credit_account with your name and $1000, you get full credit for the assignment.

If you can generate a string that is sent (via stdin) to an unmodified bufbomb program you get 10 points extra credit. The best approach here is to write a program that generates the right string, then feed the output to bufbomb like this: ./genpgm | ./bufbomb

Lots of partial credit is available for the both approaches, although this requires that you describe what you have done (for example include the assembly code you want to run when the buffer overflows, the problems you had getting the buffer to overflow, determining the right return address, how to call credit account, etc).

HINTS:
CODE:


#include <stdio.h>
/* HW4 bufbomb progam */

/* Password checking function. This one always returns false,
   the general idea is to somehow bypass this...
*/

int checkpw(char *name,char *password) {
  char s[100];		/* where we make a copy of the password */

  strcpy(s,password);		/* blind copy */

  /* Here is some real passwod checking code that 
     for our purposes always returns false (0). */

  return(0);
}

/* authenticate returns a 1 if the user,password are OK,
   otherwise it returns 0

   The only valid username is "rotor" 
*/


int authenticate(char *user, char *password) {
  if (strcmp(user,"rotor")==0) {
	return( checkpw(user,password) );
  } else {
	return(0);
  }
}

/* This procedure adds some money to an account */

void credit_account(char *name, int amount) {
  printf("Crediting account for %s with %d\n",name,amount);
  /* The real system has database update code here
     that would execute right after the printf */
}

/* main program for stack bomb assignment */

int main() {

  char name[1000];	/* buffer used to read in a name from stdin */
  char password[1000];	/* buffer used to hold password */

  /* You may replace the code here that reads the name and password
     from standard input (this is the only code you can replace). */

  fgets(name,1000,stdin);        /* read one line from standard input */
  name[strlen(name)-1]=0;	 /* strip newline */

  fgets(password,1000,stdin);	/* read the second line */
  password[strlen(password)-1]=0;	/* strip newline */

  /* -------------------------------------------------------------
     You can't change any code below this line !
  */
  if (authenticate(name,password)) {
    credit_account(name,-100);
  } else {
    printf("Boom! (sorry)\n");
  }
}