This is an introductory challenge explaining a simple buffer overflow attack.
When a program is executed, the CPU processes instructions stored in computer memory. A stack is an area within that memory that is used to store variables, manage function calls, and help control the flow of the program.
When a program receives data from a user, it is stored on the stack in a “buffer”, which is a designated chunk of memory reserved for that data.
A buffer overflow occurs when more data is written to a buffer than it can hold. This extra data can overwrite adjacent memory, potentially leading to unexpected behavior or security vulnerabilities.
struct {
char buffer[16];
bool winner;
} memory;
memory.winner = false;
gets(memory.buffer);
if (memory.winner) {
win();
}
We’re also given the C code above. It creates a “struct” called “memory” containing two variables: “buffer” and “winner”. A struct (short for “structure”) is a user-defined data type that groups together variables under a single name. Generally, structs hold their data on the stack in adjacent memory blocks.
The code above allocates 16 bytes of memory for the variable “buffer”. The adjacent “winner” boolean is set to false. The user is then prompted to enter a value using “gets()”, which is stored in “memory.buffer”. If the “winner” boolean somehow turns out to be true, the “win()” function is called and we are given the flag.
So the challenge becomes overwriting the boolean from false to true. This can be done via a buffer overflow attack. We have to send more than 16 bytes to the buffer (aka overflow it), which will start writing to the “winner” variable. Any value that is not a null byte (0x00) will be generally interpreted as true.
To do this, we can enter any string that is 16 characters or longer. For example, “AAAAAAAAAAAAAAAAA” will give us the flag.
Enter the string in the input field to see the flag.
The circled byte is the one containing the boolean. Now that it’s not 00, it will be interpreted as true by the program.