CMPSC 447: Software Security, Spring 2019


Experiencing Buffer Overflows

Part 1 (1 points)

Search the web and fill in the blanks below.

"If you were to use a buffer overflow attack to knowingly gain unauthorized access or to cause damage to other people's computers, the Computer Fraud and Abuse Act provides a maximum penalty of ____ years in prison for a first offense. It was amended by USA PATRIOT Act later to provide a maximum penalty of ____ years for a first offense."

Part 2

Read the document Smashing The Stack For Fun And Profit by Aleph One.

Part 3 to 4 should be performed on machines in the CSE Linux Lab: cse-p204instXX.cse.psu.edu, which XX is a 2-digit number from 01 to at least 40. We will test your results on those machines.

Part 3 (4 points)

We have the following program lucky.c that generates lucky numbers. It takes a password as input, but always refuses to generate a lucky number. Luckily, the program is vulnerable to a buffer overrun in the goodPassword() procedure. The goal is to take advantage of the vulnerability so that it can generate lucky numbers for us.

#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>

long *ret;

char goodPassword() {
  int good='N';
  char Password[100]; // Memory storage for the password
  gets(Password); // Get input from keyboard

  return (char)good;
}

int main() {
  struct timeval t;

  printf("Enter your password:");

  if (goodPassword() == 'Y') {
    gettimeofday(&t, 0);
    srand((unsigned int) t.tv_usec);
    printf("Your lucky number today is %d!\n", rand()%100);
  }
  else {
    printf("No lucky numbers for you today.\n");
    exit(-1);
  }

  return 0;
}
For Part 3, figure out a password that can make the program output a lucky number. Explain how your password works. Hint: no need to overwrite the return address for Part 3; there is another easy target to overwrite in this program.

Compile the above program using "gcc lucky.c -o lucky" (in particular, without compiler optimizations) and verify your password works on the generated executable; ignore the warning about gets from gcc.

Part 4 (5 points)

Suppose you are allowed to add some code between "gets(Password);" and "return (char)good;" in the goodPassword() procedure. We intend to use the following code template to modify the return address on the stack so that the program jumps directly to the THEN branch without checking the result of goodPassword():
ret=(long *) ((long) Password+?);
*ret = *ret + ?;
Each ? above represents an integer constant. Figure out these constants. You'd need the help of a debugger such as gdb or ddd to figure out the offset between the Password buffer and the return address on the stack. On-paper calculation probably won't work, as the stack layout depends on the compiler.

Tools you may need

What you need to submit

Submit your work through Canvas. The deadline is Jan 25th by midnight. The submission should be a text file that contains the answers to the required parts and also explanation of the process you took to get your answers and how your answers work to achieve the desired results. Note that it's not enough to just give answers, you need to explain in detail how you got the answers


Author: Gang Tan, Penn State University, 2019. All rights reserved.