Domanda

I am testing a simple buffer overflow in c++. The example is a test where given that checks are not in place, a malicious user could overwrite variables using a buffer overflow.

The example defines a buffer and then a variable, this means that space should be allocated for the buffer, and then space for the variable. The example reads from cin to a buffer of length 5, and then checks if the admin variable is set to something other that 0, if it is, the user conceptually gained admin access.

#include <iostream>
using namespace std;

int main()
{
    char buffer[5];
    int admin = 0;

    cin>>buffer;
    if(strcmp(buffer,"in") == 0)
    {
        admin = 1;
        cout<<"Correct"<<endl;
    }
    if(admin != 0)
        cout << "Access" << endl;
    return 0;
}

I have 3 machines, 1 Windows and 2 Linux systems.

When I test this on windows (CodeBlocks) it works (logically) entering more than 5 characters overflows and rewrites the the admin variable's bytes

Now my first linux system also works but only when I enter 13 characters, is this to do with different compilers and how they allocate memory to the program?

My second linux machine can't overflow at all. It will give a dump error only after the 13th character.

Why do they differ that much?

È stato utile?

Soluzione

You should examine disassembly. From there you will see what happens precisely.

Generally speaking, there are two things to consider:

  1. Padding done by the compiler to align stack variables.

  2. Relative placement of the stack variables by the compiler.

The first point: Your array char buffer[5]; will be padded so int admin; will be properly aligned on stack. I would expect it to be generally padded to 8 bytes on both x86 or x64 and so 9 symbols to overwrite. But compiler might do differently depending on what it sees fit. Nonetheless, it appears that Windows and Linux machines are x86 (32bit).

The second point: compiler is not required to put stack variables on stack in order of their declaration. On Windows and first Linux machine compiler does indeed place char buffer[5]; below int admin;, so you can overflow into it. On second Linux machine, compiler chooses to place it in reverse order, so instead of overflowing into int admin;, you are corrupting stack frame of the caller of main() after writing beyond space allocated for char buffer[5];.

Here is shameless link to my own answer to a similar question - an example of examining of such overflow.

Altri suggerimenti

Undefined behavior is, as you have discovered, undefined. Trying to explain it is in general not terribly productive.

In this case it's almost certainly due to the arrangement of your stack and padding bytes inserted by/between the local variables varying between compiler/system.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top