Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# creating buffer overflow

I'm trying to create a buffer overflow with C# for a school project:

unsafe
{
    fixed (char* ptr_str = new char[6] {'H', 'a', 'l', 'l', 'o', ','})
    {
        fixed (char* ptr_str2 = new char[6] {'W', 'e', 'r', 'e', 'l', 'd'})
        {
            fixed (char* ptr_str3 = new char[6] {'!', '!', '!', '!', '!', '!'})
            {
                for (int i = 0; i < 8; i++)
                {
                    ptr_str2[i] = 'a';
                }

                for (int i = 0; i < 6; i++)
                {
                    this.Label2.Text += ptr_str[i];
                    this.Label3.Text += ptr_str2[i];
                    this.Label4.Text += ptr_str3[i];
                }
            }
        }
    }
}

I thought this would flood ptr_str2 and thereby overwriting chars in ptr_str. However that does not seem to happen. It does execute but the values in ptr_str are not overwritten.

Can anyone help with achieving this? I don't understand what I'm doing wrong.

like image 431
BigChief Avatar asked Feb 05 '11 12:02

BigChief


3 Answers

Stack overflow is an overflow of calling stack. It is done much easier:

int Test ()
{
    return Test ();
}

Console.WriteLine (Test ());

If you meant buffer overflow, there is a similar question.

like image 86
Dan Abramov Avatar answered Sep 22 '22 04:09

Dan Abramov


The traditional attack that exploits a buffer overflow overflows a stack buffer; you are overflowing a heap buffer. It is a lot easier to see a write to one buffer smashing another buffer when they're both on the stack. Try using stackalloc instead of new char to force the allocation into the stack.

like image 28
Eric Lippert Avatar answered Sep 23 '22 04:09

Eric Lippert


You are missing the fact that arrays are objects themselves. They have an object header like any managed reference type and a private field that stores the array size. You have to overwrite those first before you start overwriting the array elements. On a 32-bit machine, you'll start overwriting the first element of ptr_str2 with this:

                        for (int i = 0; i < 13; i++) {
                            ptr_str[i] = 'a';
                        }

Of course, it had to be 13.

Observe this by setting a breakpoint on the for loop. Debug + Windows + Memory + Memory 1, type "ptr_str" in the Address box. Step the code to see the memory getting changed. You'll see ptr_str2 right after that, 4 bytes for the syncblk, 4 bytes for the method table pointer and 4 bytes for the array length. 12 bytes total, 6 chars.

like image 22
Hans Passant Avatar answered Sep 24 '22 04:09

Hans Passant