简体   繁体   中英

Is there a buffer overflow helloworld for c++?

I tried the code provided by this question ,but it doesn't work.

How to contrive an overflow to wrap my head around?

Update:

    .file   "hw.cpp"
    .section .rdata,"dr"
LC0:
    .ascii "Oh shit really bad~!\15\12\0"
    .text
    .align 2
.globl __Z3badv
    .def    __Z3badv;   .scl    2;  .type   32; .endef
__Z3badv:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $8, %esp
    movl    $LC0, (%esp)
    call    _printf
    leave
    ret
    .section .rdata,"dr"
LC1:
    .ascii "WOW\0"
    .text
    .align 2
.globl __Z3foov
    .def    __Z3foov;   .scl    2;  .type   32; .endef
__Z3foov:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $4, %esp
    movl    LC1, %eax
    movl    %eax, -4(%ebp)
    movl    $__Z3badv, 4(%ebp)
    leave
    ret
    .def    ___main;    .scl    2;  .type   32; .endef
    .align 2
.globl _main
    .def    _main;  .scl    2;  .type   32; .endef
_main:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $8, %esp
    andl    $-16, %esp
    movl    $0, %eax
    addl    $15, %eax
    addl    $15, %eax
    shrl    $4, %eax
    sall    $4, %eax
    movl    %eax, -4(%ebp)
    movl    -4(%ebp), %eax
    call    __alloca
    call    ___main
    call    __Z3foov
    movl    $0, %eax
    leave
    ret
    .def    _printf;    .scl    2;  .type   32; .endef

You can use the C example you posted. It works the same in C as C++.

The smallest readable answer I can think of:

int main() {
    return ""[1]; // Undefined behaviour (reading past '\0' in string)
}

It would help to compile the example in the other question to assembly so you can get a feel for how the stack is laid out for your given compiler and processor. The +8 in the example may not be the correct number for your environment. What you need to determine is where the return address is stored on the stack relative to the array stored on the stack.

By the way, the example worked for me. I compiled on Win XP with Cygwin, gcc version 4.3.4. When I say it "worked", I mean that it ran code in the bad() function, even though that function was never called by the code.

$ gcc -Wall -Wextra buffer-overflow.c && ./a.exe
Oh shit really bad~!
Segmentation fault (core dumped)

The code really isn't an example of a buffer overflow, it's an example of what bad things can happen when a buffer overflow is exploited.

I'm not great with x86 assembly, but here's my interpretation of how this exploit works.

$ gcc -S buffer-overflow.c && cat buffer-overflow.s
_foo:
        pushl   %ebp           ;2
        movl    %esp, %ebp     ;3
        subl    $16, %esp      ;4
        movl    LC1, %eax      ;5
        movl    %eax, -4(%ebp) ;6
        leal    -4(%ebp), %eax ;7
        leal    8(%eax), %edx  ;8
        movl    $_bad, %eax    ;9
        movl    %eax, (%edx)   ;10
        leave
        ret

_main:
    ...
        call    _foo            ;1
    ...

When main calls foo (1), the call instruction pushes onto the stack the address within main to return to once the call to foo completes. Pushing onto the stack involves decrementing ESP and storing a value there.

Once in foo , the old base pointer value is also pushed onto the stack (2). This will be restored when foo returns. The stack pointer is saved as the base pointer for this stack frame (3). The stack pointer is decremented by 16 (4), which creates space on this stack frame for local variables.

The address of literal "WOW\\0" is copied into local variable overme on the stack (5,6) -- this seems strange to me, shouldn't it be copying the 4 characters into space allocated on the stack? Anyway, the place where WOW (or a pointer to it) is copied is 4 bytes below the current base pointer. So the stack contains this value, then the old base pointer, then the return address.

The address of overme is put into EAX (7) and an integer pointer is created 8 bytes beyond that address (8). The address of the bad function is put into EAX (9) and then that address is stored in memory pointed to by the integer pointer (10).

The stack looks like this:

     // 4 bytes on each row
ESP: (unused)
   : (unused)
   : (unused)
   : &"WOW\0"
   : old EBP from main
   : return PC, overwritten with &bad

When you compile with optimization, all the interesting stuff gets optimized away as "useless code" (which it is).

$ gcc -S -O2 buffer-overflow.c && cat buffer-overflow.s
_foo:
        pushl   %ebp
        movl    %esp, %ebp
        popl    %ebp
        ret

Something like this?

int main()
{
    char arr[1];
    arr[1000000] = 'a';
}

A simple buffer overflow would be something like this:

#include <stdio.h>
#include <string.h>

int main() {
   char a[4] = {0};
   char b[32] = {0};

   printf("before: b == \"%s\"\n", b);

   strcpy(a, "Putting too many characters in array a");

   printf("after:  b == \"%s\"\n", b);
}

A possible output:

before: b == ""
after:  b == " characters in array a"

The actual behavior of the program is undefined , so the buffer overflow might also cause different output, crashes or no observable effect at all.

#define _WIN32_WINNT 0x0400
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

void process_msg(const char *pSrc)
{
    char cBuff[5];
    strcpy(cBuff, pSrc);
}

void main()
{
    char szInput[] = "hello world!";
    process_msg(szInput);
}

Running this program at Visual Studio 2008 in Debug mode gives this message:

Run-Time Check Failure #2 - Stack around the variable 'cBuff' was corrupted.

The 'cBuff' char array is allocated on the stack in this example and it's of 5 bytes in size. Copying the given pointer's data (pSrc) to that char arrat (cBuff) overwrites the stack frame's data which will result in a possible exploit.

This technique is used by hackers - they send a specially crafted array of chars which will overwrite the pointer to the "return" address, on the stack, and change it to their desired location at the memory.

So, for example, they could point that "return" address to any system/program code that will open a port or establish a connection, and then they get to you PC, with the application's privileges (many times this means root/administrator).

Read more at http://en.wikipedia.org/wiki/Buffer_overflow .

In addition to the excellent article pointed out by Eric , you might also check out the following reading materials:

The following article focuses more on heap overflows:

This was copied from my answer here .

The term buffer overflow precisely means accessing past the end of the buffer (sloppily needing to include the idea of buffer underflow , too). But there's a whole class of "memory safety problems" having to do with buffer overflows, pointers, arrays, allocation and deallocation, all of which can produce crashes and/or exploit opportunities in code. See this C example of another memory safety problem (and our way to detect it).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM