I was watching this video on youtube: https://www.youtube.com/watch?v=1S0aBV-Waeo and i was trying to do the same steps shown in the video, but i can't seem to overwrite the EIP. I don't know if it's because the gdb may have changed during the years, or if anything else has. What i get when i try to overflow is the following
Program received signal SIGSEGV, Segmentation fault.
0x080491ac in main (
argc=<error reading variable: Cannot access memory at address 0x41414141>,
argv=<error reading variable: Cannot access memory at address 0x41414145>)
at example.c:9
9 }
I can't seem to overwrite the eip, no matter how large my input is. The code is the same as shown in the video with a smaller buffer size.
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv){
char buffer[10];
strcpy(buffer, argv[1]);
return 0;
}
I also get asked the following when running my program in gdb for the first time
This GDB supports auto-downloading debuginfo from the following URLs:
<https://debuginfod.archlinux.org>
Enable debuginfod for this session? (y or [n])
This is the register info in gdb
(gdb) info reg
eax 0x0 0
ecx 0xffffd6b2 -10574
edx 0xffffd396 -11370
ebx 0x804bff4 134529012
esp 0xffffd390 0xffffd390
ebp 0xffffd3a8 0xffffd3a8
esi 0xffffd480 -11136
edi 0xf7ffcb60 -134231200
eip 0x80491a3 0x80491a3 <main+61>
eflags 0x286 [ PF SF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb) x/20x $esp
0xffffd390: 0xffffffff 0x4141d3d4 0x41414141 0x41414141
0xffffd3a0: 0xffff0041 0xf7e1fe2c 0x00000000 0xf7c20af9
0xffffd3b0: 0x00000000 0x00000000 0x080482e7 0xf7c20af9
0xffffd3c0: 0x00000002 0xffffd474 0xffffd480 0xffffd3e0
0xffffd3d0: 0xf7e1fe2c 0x0804907d 0x00000002 0xffffd474
I'm compiling with the following flags
gcc -o example2 -fno-stack-protector -no-pie -m32 -g -z execstack example2.c -w
The whole interaction on gdb
(gdb) disassemble main
Dump of assembler code for function main:
0x080497d5 <+0>: lea 0x4(%esp),%ecx
0x080497d9 <+4>: and $0xfffffff0,%esp
0x080497dc <+7>: push -0x4(%ecx)
0x080497df <+10>: push %ebp
0x080497e0 <+11>: mov %esp,%ebp
0x080497e2 <+13>: push %ebx
0x080497e3 <+14>: push %ecx
0x080497e4 <+15>: sub $0x10,%esp
0x080497e7 <+18>: call 0x804981c <__x86.get_pc_thunk.ax>
0x080497ec <+23>: add $0x9a808,%eax
0x080497f1 <+28>: mov %ecx,%edx
0x080497f3 <+30>: mov 0x4(%edx),%edx
0x080497f6 <+33>: add $0x4,%edx
0x080497f9 <+36>: mov (%edx),%edx
0x080497fb <+38>: sub $0x8,%esp
0x080497fe <+41>: push %edx
0x080497ff <+42>: lea -0x12(%ebp),%edx
0x08049802 <+45>: push %edx
0x08049803 <+46>: mov %eax,%ebx
0x08049805 <+48>: call 0x8049020
0x0804980a <+53>: add $0x10,%esp
0x0804980d <+56>: mov $0x0,%eax
--Type <RET> for more, q to quit, c to continue without paging--
0x08049812 <+61>: lea -0x8(%ebp),%esp
0x08049815 <+64>: pop %ecx
0x08049816 <+65>: pop %ebx
0x08049817 <+66>: pop %ebp
0x08049818 <+67>: lea -0x4(%ecx),%esp
0x0804981b <+70>: ret
End of assembler dump.
(gdb) break *0x08049805
Breakpoint 1 at 0x8049805: file example.c, line 6.
(gdb) break *0x08049812
Breakpoint 2 at 0x8049812: file example.c, line 9.
(gdb) run AAAAAAAAAAAAAAAAAAAAAAAAA
Starting program: /home/r3/buffer-overflows/bo in memory example/example AAAAAAAAAAAAAAAAAAAAAAAAA
This GDB supports auto-downloading debuginfo from the following URLs:
<https://debuginfod.archlinux.org>
Enable debuginfod for this session? (y or [n])
Debuginfod has been disabled.
To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit.
Breakpoint 1, 0x08049805 in main (argc=2, argv=0xffffd464) at example.c:6
6 strcpy(buffer, argv[1]);
(gdb) info reg
eax 0x80e3ff4 135151604
ecx 0xffffd330 -11472
edx 0xffffd306 -11514
ebx 0x80e3ff4 135151604
esp 0xffffd2f0 0xffffd2f0
ebp 0xffffd318 0xffffd318
esi 0x80e3ff4 135151604
edi 0x1 1
eip 0x8049805 0x8049805 <main+48>
eflags 0x292 [ AF SF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb) x/20x $esp
0xffffd2f0: 0xffffd306 0xffffd6a4 0x00000000 0x080497ec
0xffffd300: 0x080ade17 0x080e7c04 0x08049030 0x080ae037
0xffffd310: 0xffffd330 0x080e3ff4 0xffffd428 0x08049ceb
0xffffd320: 0x00000021 0xffffd338 0x00067e1c 0x08049ceb
0xffffd330: 0x00000002 0xffffd464 0xffffd470 0xffffd354
(gdb) c
Continuing.
Breakpoint 2, main (
argc=<error reading variable: Cannot access memory at address 0x41414141>,
argv=<error reading variable: Cannot access memory at address 0x41414145>)
at example.c:9
9 }
(gdb) info reg
eax 0x0 0
ecx 0xffffd6b0 -10576
edx 0xffffd312 -11502
ebx 0x80e3ff4 135151604
esp 0xffffd300 0xffffd300
ebp 0xffffd318 0xffffd318
esi 0x80e3ff4 135151604
edi 0x1 1
eip 0x8049812 0x8049812 <main+61>
eflags 0x286 [ PF SF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb) x/20x $esp
0xffffd300: 0x080ade17 0x41417c04 0x41414141 0x41414141
0xffffd310: 0x41414141 0x41414141 0x41414141 0x00414141
0xffffd320: 0x00000021 0xffffd338 0x00067e1c 0x08049ceb
0xffffd330: 0x00000002 0xffffd464 0xffffd470 0xffffd354
0xffffd340: 0x080e3ff4 0x0804968d 0x00000002 0xffffd464
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x0804981b in main (
argc=<error reading variable: Cannot access memory at address 0x41414141>,
argv=<error reading variable: Cannot access memory at address 0x41414145>)
at example.c:9
9 }
(gdb) info reg
eax 0x0 0
ecx 0x41414141 1094795585
edx 0xffffd312 -11502
ebx 0x41414141 1094795585
esp 0x4141413d 0x4141413d
ebp 0x41414141 0x41414141
esi 0x80e3ff4 135151604
edi 0x1 1
eip 0x804981b 0x804981b <main+70>
eflags 0x10286 [ PF SF IF RF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb) x/20x $esp
0x4141413d: Cannot access memory at address 0x4141413d
(gdb) c
Continuing.
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
This code
0x08049815 <+64>: pop %ecx
0x08049816 <+65>: pop %ebx
0x08049817 <+66>: pop %ebp
0x08049818 <+67>: lea -0x4(%ecx),%esp
0x0804981b <+70>: ret
restores registers from their saved location on stack. However, you've overwritten the stack contents, so all the registers are now set to 0x4141...
values. And that causes the lea -0x4(%ecx),%esp
instruction to SIGSEGV
, since ECX
points to inaccessible memory.
As ssbssa commented, this is happening due to stack realignment (which itself is needed to deal with 64-bit aligned (newer) AVX etc.).
If I turn stack realignment off with -mpreferred-stack-boundary=2
, the code becomes:
0x08049176 <+0>: push %ebp
0x08049177 <+1>: mov %esp,%ebp
0x08049179 <+3>: sub $0xc,%esp
0x0804917c <+6>: mov 0xc(%ebp),%eax
0x0804917f <+9>: add $0x4,%eax
0x08049182 <+12>: mov (%eax),%eax
0x08049184 <+14>: push %eax
0x08049185 <+15>: lea -0xa(%ebp),%eax
0x08049188 <+18>: push %eax
0x08049189 <+19>: call 0x8049050 <strcpy@plt>
0x0804918e <+24>: add $0x8,%esp
0x08049191 <+27>: mov $0x0,%eax
0x08049196 <+32>: leave
0x08049197 <+33>: ret
and the RIP
overwrite works:
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) x/i $pc
=> 0x41414141: Cannot access memory at address 0x41414141