A2: Exploiting Format String Vulnerabilities
Authored by Professor Gang Tan of Penn State University. Slightly adjusted by Jie Zhou for this course.
This assignment requires a good understanding of of TESO’s Format String paper as specified for the 9/17 lecture.
Part 1
We will continue to use the vlab machine as specified in lecture 3. Make sure you have access to the machine.
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 would like to take advantage of this vulnerability so that the program generates lucky numbers for us.
Do this homework in the following steps:
- (1 point) Pinpoint which statement in the program has a format-string vulnerability. Explain why.
- (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. - (2 points) Try the password
"%16lx %16lx %16lx %16lx %16lx %16lx %16lx"
. What is the behavior of the program? Explain what happens. - (1 point) Try the password
"dddd%n"
. What is the behavior of the program? Explain what happens. - (4 points) We would like to use a password of the form
"%?c%?c...%?c%n"
to attack the program. The password starts with a series of"%?c"
, where ? stands for a number we need to figure out. The purpose of this password is to 1) move the internal stack pointer (notrsp
) of printf to point to the local variablep
ingoodPassword
; 2) use the series of"%?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 inp
. In the last step, sincep
contains the address of variablegood
, 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"%?c"
at the beginning of this password, and a number to replace"?"
in each"$?c"
.
Notes
- Compile the program by
clang lucky.c -o lucky
. -
clang -S lucky.c -o lucky.s
compiles the C program to assembly code. -
clang -ggdb lucky.c -o lucky
produces an executable with debugging information, which is used by gdb. - gdb might be useful for Part 5. Alternatively, manually inserting
printf
calls into the program might be sufficient to figure out which stack slot holds variable p and other information.
What you need to submit
Submit your work through Blackboard. The deadline is October 1st by midnight. The submission should be a PDF file that contains the answers to the required parts and also explanations of the process you took to get your answers and how your answers work to achieve the desired results. Screenshots of important steps, such as memory/register status shown by gdb or other tools, are not required, but you can include them if they think they facilitate your answers. Do not include screenshots for all steps. Note that it’s not enough to just give answers, you need to explain in detail how you got the answers.