CMPSC 447: Software Security, Spring 2019


Experiencing Format String Attacks

This project 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 1

Read the document Exploiting Format String Vulnerabilities by scut / team teso. Reading the first 3 sections should be sufficient for this homework.

Part 2 (10 points)

We continue our study of the lucky program in the last homework. For the convenience of performing a format string attack, we have modified the program slightly, as shown below.

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


char Password[100]; // Memory storage for the password

char goodPassword() {
  int good='N';
  int *p = &good;
  fgets(Password, sizeof(Password), stdin); // Get input from keyboard

  printf("Password=");
  printf(Password);
  printf("\n");

  return (char)(*p);
}

int main() {
  struct timeval t;

  printf("Enter your password:");

  char r = goodPassword();
  printf("r=%c\n", r);

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

  return 0;
}
Similar to the previous version, the program refuses to generate a lucky number. What is different is that it uses fgets to get the user password instead of the insecure gets. The fgets function takes the size of the Password buffer as the bound of the number of characters to read (more accurately, if the buffer size is n, fgets will read at most n-1 characters and will terminate the buffer with a null byte). Therefore, there is no possibility of overflowing the Password buffer through the fgets function.

However, there is a format-string vulnerability in the program. The program tries to echo the password in the goodPassword function, but it uses printf in an insecure way. We'd like to take advantage of this vulnerability so that the program generates lucky numbers for us.

Do this homework in the following steps:

  1. (1 point) Pinpoint which statement in the program has a format-string vulnerability. Explain why.
  2. (2 points) Try the password "%s%s%s%s%s%s%s%s%s". What is the behavior of the program? Explain why it behaves this way for this password.
  3. (2 points) Try the password "%16lx %16lx %16lx %16lx %16lx %16lx %16lx". What is the behavior of the program? Explain what happens.
  4. (1 point) Try the password "dddd%n". What is the behavior of the program? Explain what happens.
  5. (4 points) We'd like to use a password of the form "%16lx%16lx...%16lx%?c%n" to attack the program. The password starts with a number of "%16lx", followed by "%?c%n", where ? stands for a number we need to figure out. The purpose of this password is to 1) move the internal stack pointer (not rsp) of printf to point to the local variable p in goodPassword; 2) use "%?c" to control the number of characters to print so that the number exactly equals the ASCII value of character 'Y'; 3) use "%n" to write 'Y' to memory location with the address in p. In the last step, since p contains the address of variable good, the effect is to change the value of good from 'N' to 'Y'. Given this attack, your job is to figure out the number of "%16lx" at the beginning of this password, and a number to replace "?" in "$?c".

Notes

What you need to submit

Submit your work through Canvas. The deadline is Feb 1st. The submission should be a text file that contains the answers to each step and also an 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 and why they work, especially for Part 2.5


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