Trying to reproduce buffer overflow on Ubuntu 24 for learning purposes.
So the goal is to call call_me_twice second time by passing its address into input string.
$ cat bof.c
#include <stdio.h>
#include <string.h>
void return_input (char *s) {
char array[10];
strcpy(array,s);
printf("%s\n", array);
}
char call_me_twice () {
printf("Example\n");
}
int main (int argc, char *argv[]) {
call_me_twice();
return_input(argv[1]);
return 0;
}
Compiling for 32 bit and disabling stack protection.
$ gcc -m32 -fno-stack-protector bof.c
Running with correct/incorrect input
$ ./a.out HelloWorld
Example
HelloWorld
$ ./a.out HelloWorld##########
Example
HelloWorld##########
Segmentation fault (core dumped)
Getting dump
$ coredumpctl list | tail -1
$ coredumpctl dump 15761 > core.15761
Running gdb
$ gdb ./a.out core.15761
and
(gdb) disassemble main
Dump of assembler code for function main:
0x66405201 <+0>: lea 0x4(%esp),%ecx
0x66405205 <+4>: and $0xfffffff0,%esp
0x66405208 <+7>: push -0x4(%ecx)
0x6640520b <+10>: push %ebp
0x6640520c <+11>: mov %esp,%ebp
0x6640520e <+13>: push %ebx
0x6640520f <+14>: push %ecx
0x66405210 <+15>: call 0x66405244 <__x86.get_pc_thunk.ax>
0x66405215 <+20>: add $0x2dbf,%eax
0x6640521a <+25>: mov %ecx,%ebx
0x6640521c <+27>: call 0x664051d6 <call_me_twice>
0x66405221 <+32>: mov 0x4(%ebx),%eax
0x66405224 <+35>: add $0x4,%eax
0x66405227 <+38>: mov (%eax),%eax
0x66405229 <+40>: sub $0xc,%esp
0x6640522c <+43>: push %eax
0x6640522d <+44>: call 0x6640519d <return_input>
0x66405232 <+49>: add $0x10,%esp
0x66405235 <+52>: mov $0x0,%eax
0x6640523a <+57>: lea -0x8(%ebp),%esp
=> 0x6640523d <+60>: pop %ecx
0x6640523e <+61>: pop %ebx
0x6640523f <+62>: pop %ebp
0x66405240 <+63>: lea -0x4(%ecx),%esp
0x66405243 <+66>: ret
End of assembler dump.
Now if I understand it correctly I need to take an adress for call 0x664051d6 <call_me_twice> which is 0x6640521c and put it into input in reversed order which is \x1c\x52\x40\x66after some number of characters.
I tried to call from 1 # symbol to 100 # symbols but each time getting
$ ./a.out #\x1c\x52\x40\x66
Example
Segmentation fault (core dumped)
...
$ ./a.out ####################################################################################################\x1c\x52\x40\x66
Example
Segmentation fault (core dumped)
Example was never printed twice.
What am I doing wrong? How to actually call call_me_twice second time?
I checked Stack smashing detected but probably I missed something.
PS.
$ gcc -v
Using built-in specs.
...
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04)
PIEbinary, which will load at different address one invocation to the next (the goal ofPIEis precisely to make these kinds of attacks harder). You should probably start by building withgcc -fno-PIE -no-pie ...../a.out #\x1c...to invoke your program withargv[1]pointing at bytes0x1c..., but it invokes your program withargv[1] == NULL.