I'm trying to understand how simple stack overflow works (On Linux 32 bits) but I'm in front of a strange problem.
I'm using https://www.pwnerrank.com/tasks/stack-based-buffer-overflow-code-execution to test my code. Everything works great. My shellcode is perfectly executed, so I think I understand (a little bit) what I'm doing.
BUT, when I'm trying the same thing on my own computer (same code, same GCC options, ASLR off), I'm facing a strange problem. I simply can't overwritte EIP :/
First of all, this is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char*argv[])
{
char buffer[256];
if(argc < 2) {
perror("Usage: ./pwnme twitt\n");
return 1;
}
strcpy(buffer,argv[1]);
printf("%s", buffer);
return 0;
}
On the challenge's server, EIP is overwritten (Good news !):
$> lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 8.6 (jessie)
Release: 8.6
Codename: jessie
$> uname -a
Linux binary-challenges-pwnerrank-com 3.2.0-4-amd64 #1 SMP Debian 3.2.82-1 x86_64 GNU/Linux
$> file ./pwnme
./pwnme: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.26, BuildID[sha1]=b49c31fc047654c28f93910c8e04cecb6a19ac30, not stripped
$> gdb -q ./pwnme
(gdb) r `python -c 'print "A" * 280'`
[SEGFAULT]
(gdb) i r
eax 0x0 0
ecx 0x0 0
edx 0xf7fc9878 -134440840
ebx 0xf7fc8000 -134447104
esp 0xffffd5e0 0xffffd5e0
ebp 0x41414141 0x41414141
esi 0x0 0
edi 0x0 0
eip 0x41414141 0x41414141
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)
=====================================================================
Now, I'll try on my own Linux (with the same C code):
$> lsb_release -a
No LSB modules are available.
Distributor ID: LinuxMint
Description: Linux Mint 18 Sarah
Release: 18
Codename: sarah
$> uname -a
Linux 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
Compilation:
$> gcc bof.c -o pwnme -fno-stack-protector -z execstack -m32
ASLR off:
$> $ sudo cat /proc/sys/kernel/randomize_va_space
0
$> file pwnme
pwnme: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=bf0e63dc240cb7a8e72fd656677a2d03a93588ed, not stripped
$ gdb -q ./pwnme
Reading symbols from ./pwnme...(no debugging symbols found)...done.
(gdb) r `python -c 'print "A" * 280'`
Starting program: /home/n3r0x/Documents/BoF/pwnme `python -c 'print "A" * 280'`
Program received signal SIGSEGV, Segmentation fault.
0x080484db in main ()
(gdb) i r
eax 0x0 0
ecx 0x41414141 1094795585
edx 0xf7fac870 -134559632
ebx 0x0 0
esp 0x4141413d 0x4141413d
ebp 0x41414141 0x41414141
esi 0xf7fab000 -134565888
edi 0xf7fab000 -134565888
eip 0x80484db 0x80484db <main+112>
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)
As you can see, this time, only EBP is overwritten. And I don't understand why :/ Maybe an other security feature somewhere ? Do you have an idea ? And off course, if I replace 280 'A' by 300 or more 'A', it's the same thing.
Thank a lot :)
[EDIT] - Sorry, I found the answer on this forum. It was just a question of stack alignment. Everything is here: Compiling a buffer overflow example in modern Linux?
I moved the strcpy on a different function, it works great. And the last reply gives a good explanation.
Thanks for you help !