在基础的软件安全实验中,缓冲区溢出是一个基础而又经典的问题。最基本的缓冲区溢出即通过合理的构造输入数据,使得输入数据量超过原始缓冲区的大小,从而覆盖数据输入缓冲区之外的数据,达到诸如修改函数返回地址等目的。但随着操作系统和编译器针对缓冲区溢出问题引入防护机制,初学者想要由简入繁的学习和实践缓冲区溢出的原理变得困难。在 Linux 环境下,用户可以通过设置编译和系统环境来去除某些防护措施,从而方便的完成某些简单的缓冲区溢出实验。

1.关闭SSP( Stack Smashing Protector )

  实现原理

  SSP 是 gcc 提供的针对栈上缓冲区溢出提供检查的机制。典型的缓冲区溢出攻击会通过构造输入数据覆盖缓冲区外的数据,实现一定的溢出效果,如修改函数返回地址等。启用 SSP 机制后,在编译器生成的代码中,对于那些存在缓冲区的函数,函数开始时会在对应栈帧中入栈一个随机值( canary ),在函数调用结束准备返回时,编译器生成的代码会检查上述引入的随机值是否发生了变化,若发生变化则说明出现了缓冲区溢出,控制流会转移至对应的处理函数处。

  以下列代码为例进行说明

    void simpleCopy( char *src ){char buff[10];strcpy( buff , src );          }

  上述代码将缓冲区 src 中的数据简单的拷贝至 buff 数组中,而没有考虑 src 中的数据量是否超出了 buff 数组的容纳能力。

  使用 gdb 查看得到 simpleCopy 的汇编如图所示。

  

  在开启了 SSP 机制的 gcc 生成的代码中,函数开始数据处理之前,将 gs:0x14 处的值存放在了 %ebp - 12 处,在函数返回时,对 %ebp - 12 处的值进行检查,若此时值不等于 gs:0x14 处的值,则说明存在数据的覆盖和修改,程序会转入 __stack_chk_fail 执行。通过 simpleCopy("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")调用函数的结果如下图所示。上述 simpleCopy 函数中,缓冲区 buff 首地址为 %ebp - 22 , 而引入的 canary 存放在 %ebp - 12 处,当缓冲区存在数据溢出时,会修改 canary 的值,从而在函数返回时被检测到。

    

  选项设置

  gcc的编译设置中,默认设置SSP机制是有效状态,用户可在编译时加入 -fno-stack-protector 参数禁用SSP机制。 

    -fstack-protector    //编译时启用SSP机制-fno-stack-protector //编译时禁用SSP机制

2.关闭DEP( Data Execution Prevention )

  在某些栈缓冲区数据溢出实践中,会将构造好的机器指令序列通过输入写入位于栈上的输入缓冲区中,同时,构造数据覆盖位于数据缓冲区外的函数调用的返回地址,将其值修改为缓冲区中构造好的机器指令序列的地址,这样当函数调用返回时,程序控制流会跳转至输入缓冲区中的构造指令序列,从而实现执行流的修改和劫持。而现代编译器中,为防止用户通过栈上的缓冲区构造数据,使用了DEP机制,即限制内存的属性,使得某些可写内存不可执行( 如栈 )或可执行内存不可写( 如.text段),从而达到防护的效果。

  使用 gcc 进行编译时,可通过 -z execstack 参数,使得最终生成的程序中栈内存段具备可执行权限。

    -z execstack    //设置栈内存段具备可执行权限

  在程序运行时,可通过查看 cat /proc/pid/maps 文件查看 pid 所对应的进程的内存映射情况,其中包括对进程的段的属性描述。

 3.关闭ASLR( address space layout randomization )

  在基础栈缓冲区溢出实践中,一个重要的步骤为定位某些目标的内存映射地址,如最简单的 shellcode 需定位注入栈上的构造指令序列的地址( 从而修改函数返回地址指向该指令序列),ret2libc 方法则需要攻击者定位位于内存中的标准库函数的内存映射地址等。ASLR ,即内存布局随机化机制由操作系统实现,其主要被划分为映像随机化、栈随机化和堆随机化这几类,分别针对程序的加载基地址、栈基址和堆基址进行随机化。

  设计原理

  已经编译完成的程序的各个段在内存中的加载基位地址是固定的,也就是说程序运行时的内存映射情况是固定的,攻击者可以通过多次调试运行程序,获得他们所需的目标地址。在编译好的 ELF 文件中,段头部表描述了程序需加载入内存的各个段的基地址,可通过 readelf -h filename 对其进行查看。对于运行中的程序,可以通过 cat /proc/pid/maps 查看 pid 对应的进程的内存映射情况,包括栈、堆的基地址等。

        objdump -h hello    //查看可执行文件hello的段头部表cat /proc/pid/maps  //pid为进程号,查看pid对应进程的内存映射情况

  (1)通过 objdump -h hello 查看该 ELF 文件的.text 加载基地址为 0x08048370,而.rodata段的加载基地址为 0x08048558。

    

  (2)通过 cat /proc/$$/maps 查看 shell 的内存映射情况(64位Ubuntu),可以看到 shell 进程的 stack 段的内存范围以及其属性为可读可写但不可执行,p 表示该虚拟内存段为私有的( private ),s 表示该虚拟内存段为共享的( shared )。

    

  在过去的编译环境中,程序的数据段包括.text、.bss、.rodata 段加载进内存的基地址在编译时即已确定,程序运行时进程中 stack 和 heap 的起始地址也总是固定的,这就使得攻击者可以较容易的定位内存中目标的地址,从而进行攻击尝试。在引入 ALSR 机制后,对于程序的某个特定的段( .text 、stack 、heap ),操作系统会在加载时自其原始的起始基地址处加入一个随机大小的“填充”,对应的程序数据总是自“填充”区域后开始,由于每次使用的“填充”的大小并不固定,同一程序多次运行时的内存布局会发生变化,从而使得攻击者较难通过固定的地址去访问其所需要的目标。

  选项设置

  用户可通过cat /proc/sys/kernel/randomize_va_space 查看当前 ALSR 机制的运行情况。其中,为 0 表示 ALSR 机制未启用,为 1 表示 ALSR 机制会随机化 stack、vdso和 mmap 的起始基地址,为 2 表示除对上述目标进行随机化外还会对堆基地址进行随机化。用户可通过 echo 0 > /proc/sys/kernel/randomize_va_space 设置关闭 ALSR

     cat /proc/sys/kernel/randomize_va_space       //查看 ALSR 机制的运行情况echo 0 > /proc/sys/kernel/randomize_va_space    //设置关闭 ALSR 机制,需要 root 用户进行操作

  上述对 /proc/sys/kernel/randomize_va_space 的操作为针对系统的全局设置,需要 root 权限且存在弊端,用户可通过以下命令将当前终端 /bin/bash 的 ALSR 机制关闭,则通过该 shell 运行的程序均不会启动 ALSR 机制。该终端关闭后上述设置即失效。

   setarch `uname -m` -R /bin/bash

4.通过 gdb 获得目标地址

  基础的缓冲区溢出实践通常需要确定运行状态下程序中的某些地址,如需要确定输入缓冲区的起始地址从而获得注入缓冲区中的机器指令的地址等。在 Linux 环境下,可通过 gdb 对程序进行动态调试,从而获得程序运行状态下的信息( 关闭 ALSR 机制后效果更好 ),基础的 gdb 操作可参见笔者的文章Linux下编辑、编译、调试命令总结——gcc和gdb描述。使用 gdb 可以方便的获取程序动态运行状态下的信息,但通过 gdb 动态调试获取的诸如缓冲区的起始地址等信息可能与程序实际运行时的信息并不相同,从而影响缓冲区溢出实践的效果。关于保证通过 gdb 动态调试程序获得的局部变量的地址与直接运行该程序时的地址一致的问题,笔者另外通过博文针对 Linux 环境下 gdb 动态调试获取的局部变量地址与直接运行程序时不一致问题的解决方案进行描述。

5.总结

  为了完成基础的缓冲区溢出实践,用户可通过 gcc 的编译选项 -fno-stack-protector 关闭 SSP 保护机制,通过 -z execstack 选项使得生成的可执行程序的栈可执行,通过 setarch `uname -m` -R /bin/bash 设置关闭当前终端中运行程序的 ALSR 机制,并通过 gdb 动态调试获取某些所需要的程序局部变量的信息。

6.参考资料

  1.Stack Smashing Protector - OSDev Wiki

  2.protect against buffer overflow exploits

  3.Address space layout randomization - Wiki

转载于:https://www.cnblogs.com/yhjoker/p/9148092.html

使用Linux进行缓冲区溢出实验的配置记录相关推荐

  1. Kali学习笔记21:缓冲区溢出实验(漏洞发现)

    上一篇文章,我已经做好了缓冲区溢出实验的准备工作: https://www.cnblogs.com/xuyiqing/p/9835561.html 下面就是Kali虚拟机对缓冲区溢出的测试: 已经知道 ...

  2. Linux下缓冲区溢出攻击的原理及对策

    前言 从逻辑上讲进程的堆栈是由多个堆栈帧构成的,其中每个堆栈帧都对应一个函数调用.当函数调用发生时,新的堆栈帧被压入堆栈:当函数返回时,相应的堆栈帧从堆栈中弹出.尽管堆栈帧结构的引入为在高级语言中实现 ...

  3. linux缓冲区攻击实验报告,linux 下缓冲区溢出攻击原理及示例

    一.溢出目标 无论是在windows下还是在linux下,溢出攻击基本上都是以控制计算机的执行路径为目标,而x86下执行哪条指令是由eip寄存器来控制的,所以如果能够修改eip寄存器的值,就可以修改计 ...

  4. (SEED-Lab)Buffer Overflow Vulnerability Lab缓冲区溢出实验

    (SEED-Lab)Buffer Overflow Vulnerability Lab 欢迎大家访问我的GitHub博客 https://lunan0320.cn 文章目录 一.实验目的 二.实验步骤 ...

  5. 基于SeedUbuntu16.04的缓冲区溢出实验

    写本文的万恶之源是提前到七月份的暑期学校,大二忙了一整年,本来以为终于可以好好休息下了,结果万恶的暑期学校被提前到七月份了,好不容易熬到七月底准备放假,又遇上疫情(摊手).大部分学生都被关在学校,本人 ...

  6. Linux攻击原理,转:Linux下缓冲区溢出攻击的原理及对策

    前言 从逻辑上讲进程的堆栈是由多个堆栈帧构成的,其中每个堆栈帧都对应一个函数调用.当函数调用发生时,新的堆栈帧被压入堆栈:当函数返回时,相应的堆栈帧从堆栈中弹出.尽管堆栈帧结构的引入为在高级语言中实现 ...

  7. linux dns 漏洞,Linux报缓冲区溢出漏洞,恶意DNS响应就能实施远程攻击

    研究人员在Linux Systemd中发现一个严重漏洞,当系统试图在攻击者控制的DNS服务上查询主机名时,特制的恶意DNS响应能远程使"systemd-resolved'"程序崩溃 ...

  8. 缓冲区溢出攻击实验(一)

    无聊之余,想弄一下缓冲区溢出实验,之前一直听说这个,也没有亲自动手做一下,发现真正弄起来的时候还是没那么简单的,其实学到的东西还是不少的.特此记下学习的过程. 一.基础知识 这一部分主要是关于程序内存 ...

  9. 网络安全实验:CCProxy缓冲区溢出攻击

    CCProxy缓冲区溢出实验 一.实验环境说明 溢出对象:CCProxy(一款代理服务器软件,支持FTP和Telnet) 调试工具:CDB.WinDbg.OllyDBG.IDA Pro etc 实验环 ...

最新文章

  1. Class.forName解析以及使用
  2. 快手,字节面试题,将IP地址转换成整数类型,再转换回来。C++代码
  3. socket websocket
  4. 安卓使用intent切换到同级窗口和子窗口,并从子窗口中获取返回数据
  5. Java Web 高性能开发,第 1 部分: 前端的高性能
  6. 从零开始学Symbian (基于carbid.c++、S60第三版)
  7. Atitit spring springboot 集成mybatis法 目录 1.1. 使用spring管理数据源。。需要修改spring、 配置 1 1.2. 直接代码集成,无需修改任何配置 1
  8. 《Redis设计与实现》读书笔记
  9. 如何用计算机模拟光的传播,菲涅尔计算全息干涉图的制作与模拟再现.doc
  10. BP神经网络(BPNN)
  11. python apkg_GitHub - cansou/pc_wxapkg_decrypt_python: PC微信小程序 wxapkg 解密
  12. 电脑一直跳出 不支持16位的应用程序该如何解决
  13. macOS连接ftp服务器
  14. 5GgNB和ng-eNB的主要功能
  15. OAM 与 KubeVela:下一代云原生应用交付和管理实践
  16. 服务器集群技术的特点和功能
  17. python 解码js escape,encodeURI
  18. 1.OpenHarmony
  19. PDF文件解密方法是什么?PDF转换器有什么优点?
  20. 考取PMP证书后,如何进一步提升自己?

热门文章

  1. codevs——1220 数字三角形(棋盘DP)
  2. 要立刷金组flag了T_T
  3. PDF文件如何转成markdown格式
  4. 【智能家居篇】wifi网络结构(上)
  5. 数据库高性能读写分离集群操作说明
  6. 结对编程——单元测试
  7. socks5   代理
  8. hdu5185 dp:和为n且满足后一项是前一项或者+1的数列个数
  9. 从 PoS 进化 SPoS:无能耗共识机制
  10. kotlin ++ --_顺便说一句-探索Kotlin代表团