堆栈认知——栈溢出实例(ret2text)_栈溢出以后他就能跳转到你指定的地(1)

在我们知道什么是栈溢出以及了解了栈的结构之后,我们就可以开始通过栈溢出破坏栈结构。

在破坏栈结构的时候,我们需要注意两个问题:

1、如何跳转?

2、跳转到哪里去?

3.1、解决如何跳转的问题

在上面栈结构的图中,在当前栈帧中向栈中某个变量中写入值的时候,我们就可以写入超过了这个变量本身所申请的字节数,不断的往上覆盖直到其返回值地址的地方,从而到我们想要的地址的地方写入我们要写入的地址。

简而言之:我们调用完一个函数后,函数会返回,并执行下一个函数。我们就需要把这个返回地址覆盖成我们的shellcode,进而让函数执行我们的shellcode,从而拿到shell,控制其程序的目的。(在此文章中是返回到系统的system(“/bin/sh”)函数上)

实例如下:

1、首先我们准备一个二进制程序
在这里插入图片描述
这是一个32位的程序

2、我们通过IDA来看一下汇编代码
在这里插入图片描述
我们先反汇编一下
在这里插入图片描述
看到这个函数调用了puts和gets函数,并且其中的s并未做大小的校验。此时我们的思路就活跃了起来,s作为gets函数的参数,并且保存在栈上,我们就可以通过向s的地址中写入数据的时候覆盖掉栈的其他数据。

我们通过GDB实战一下:

我们先调试起来,让其运行到gets函数:
在这里插入图片描述
此时汇编在向下走我们就需要输入数据了,并且S的地址为0xf7ffd000,栈的第一个参数的地址为0xffffd41c, 此时我们来看一下栈的栈结构
在这里插入图片描述
此时在栈中,我们发现我们输入的数据是从eax开始的,那么我们从上面的栈结构的图中了解到,我们就可以不断向上覆盖到ebp,返回地址,参数等等。

我们实验覆盖到ebp。

ebp的地址为0xffffd488,eax的地址为0xffffd41c,ebp-eax=0x6c。

此时我们输入0x6c个a看看实际效果:

在这里插入图片描述
在这里插入图片描述
此时会发现我们精准的覆盖了ebp到eax之间的内容。

不相信的话我们在试试覆盖一下ebp试一下呢?

我们写入 0x6c个a+0x04个b试试看效果:
在这里插入图片描述
此时我们的ebp就被覆盖成了bbbb,此时我们就完成了如何跳转的问题了。

3.2、跳转到哪里去?

在上面我们解决了如何跳转的问题,那么跳到哪里去呢?

根据上面的栈结构,毋庸置疑肯定跳到返回地址的地方嘛,调到返回地址的地方,如果此时我们填上了我们准备好的shell code,那岂不是就可以执行我们的shell code,从而获取shell了。

这里先实验第一种方法(后续方式另写文章补充):
本身程序具有system函数

我们使用IDA看一下:
在这里插入图片描述
我们发现程序中有system函数,并且在0x0804863A这个地址会把“/bin/sh”传给system函数,此时我们的目标就明了了。

覆盖到返回地址为0x0804863A并执行system函数从而反弹shell拿到这个程序的控制权限

4、实战

我们实战的时候使用Python来编写脚本,为什么呢?

因为Python集成的有pwn库,用来做栈溢出非常的方便。

# coding=UTF-8
from pwn import \* 

p = process("./ret2text")                   #指定程序
elf=ELF("./ret2text")                       # 加载ELF  为了pwn 可以解析./ret2text这个二进制文件                 
libc=ELF("/lib/i386-linux-gnu/libc-2.27.so")# 加载libc 
	

padding = 'a'\*0x6c                          # 准备0x6c个a覆盖到ebp
## 最后

**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。**

**因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**

![img](https://img-blog.csdnimg.cn/img_convert/22440b5a1d9a5baa387d40b62eef1219.png)

![img](https://img-blog.csdnimg.cn/img_convert/6f0a8ec888e7ccfcc98c3270da8f4c16.jpeg)

![img](https://img-blog.csdnimg.cn/img_convert/7417ea613a19f86c31a9fd2acf885368.png)

 ![img](https://img-blog.csdnimg.cn/img_convert/7586397d2459fdc2fa8b0b4887edc021.png)

![img](https://img-blog.csdnimg.cn/img_convert/2b9e3854bf925bb76cdd16ffeb464ada.png)

![img](https://img-blog.csdnimg.cn/img_convert/41ee22f2caf0da7b50325ccc4c843a64.png)

![](https://img-blog.csdnimg.cn/img_convert/e5fb7ed2a0458fdf6a84505f04aaa4d9.png)

 

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!**

[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618654289)

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**!!


要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618654289)

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**!!


  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 堆栈溢出实例: ```c #include <stdio.h> #include <stdlib.h> void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; int *ret; ret = buffer1 + 21; (*ret) += 8; } int main() { int x; x = 0; function(1,2,3); x = 1; printf("%d\n",x); return 0; } ``` 上述代码中,`function` 函数中声明了两个缓冲区 `buffer1` 和 `buffer2`,它们的大小分别为 5 和 10 字节。在 `function` 函数中,我们试图通过 `(*ret) += 8;` 来修改返回地址,从而实现栈溢出攻击。运行此程序时,会发现输出结果为 1,也就是说攻击成功。 2. 如何在 Linux 中发现堆栈溢出问题? 在 Linux 中,我们可以使用 `gdb` 来调试程序,以检查是否存在堆栈溢出问题。具体步骤如下: - 编译程序时添加 `-g` 选项,以便在调试时可以获取更多的信息。 - 使用 `gdb` 打开可执行文件。 - 使用 `run` 命令运行程序,程序会在 `function` 函数中出现段错误并崩溃。 - 使用 `backtrace` 命令查看函数调用栈,可以看到 `function` 函数中的返回地址已经被修改。 - 使用 `info frame` 命令查看当前帧的信息,可以看到修改后的返回地址。 - 使用 `info registers` 命令查看寄存器的值,可以看到 `eip` 寄存器的值已经被修改。 - 使用 `x/20x $esp` 命令查看栈的内容,可以看到返回地址已经被修改。 通过以上步骤,我们可以发现程序存在堆栈溢出问题,并进一步分析和修复这个问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值