4

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 !

n3r0x
  • 41
  • 4
  • Security.se doesn't use the "SOLVED" flag in title convention. In this case, it might be worth marking this question as a duplicate, or including the relevant parts of that answer as an answer to this question (it's valid to answer your own question!) and marking that as the accepted answer. – Matthew Jan 04 '17 at 09:56

3 Answers3

3

This difference might be there due to different stack alignment used on the server side. For setting up the stack alignment, "mpreferred-stack-boundary" option is used. More: https://stackoverflow.com/questions/10251203/gcc-mpreferred-stack-boundary-option

Hope this helps!

1

The hardening-check command included in the hardening-includes package should also give you some extra insight into any security features within the executable. I think relro is included by default. This can be disabled with the following gcc flag.

-Wl,-z,norelro
mcgoosh
  • 29
  • 5
0

There's a bit more protecting a modern linux kernel than ASLR and GCC options on compiled binaries.

It looks like you're running Mint - I'm not super familiar with Mint but I know it's built on Ubuntu and Debian and it looks to be running an Ubuntu kernel.

The Ubuntu Kernel has quite a few security features by default, some likely cannot be disabled.

The security folks at Ubuntu have a regression test script that's designed to ensure that security features are working. Running that locally might shed some light on the issue or at least point you in the right direction.

Rob C
  • 186
  • 3
  • OP is not trying to exploit a buffer overflow *in* kernel. – domen Jan 04 '17 at 10:16
  • That's true, I didn't mean to imply that he was. Some operations in userspace can be governed by security features in the kernel. In the case of this user, it's more likely that hardening in Glibc is what tripping OP up. – Rob C Jan 04 '17 at 13:09